This is an automated email from the ASF dual-hosted git repository.
olamy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git
The following commit(s) were added to refs/heads/master by this push:
new c67291400 [SUREFIRE-3239] allow override of statistics file checksum
(#3247)
c67291400 is described below
commit c672914006fcd5233e0e48cbd280f260342549e5
Author: Christopher Lambert <[email protected]>
AuthorDate: Fri Jan 30 00:47:34 2026 +0100
[SUREFIRE-3239] allow override of statistics file checksum (#3247)
This is an escape hatch in scenarios where the configuration keeps
changing for each CI run but the duration of test classes does not
depend on the configuration at all.
By setting a fixed checksum users can make sure that test execution data
from previous runs always gets used when balancing parallel execution
buckets.
---
.../maven/plugin/failsafe/IntegrationTestMojo.java | 19 ++++++++++++++
.../plugin/surefire/AbstractSurefireMojo.java | 27 +++++++++++---------
.../AbstractSurefireMojoJava7PlusTest.java | 8 ++++++
.../plugin/surefire/AbstractSurefireMojoTest.java | 8 ++++++
.../maven/plugin/surefire/MojoMocklessTest.java | 12 +++++++--
.../apache/maven/plugin/surefire/SurefireMojo.java | 19 ++++++++++++++
.../maven/surefire/its/XmlReporterRunTimeIT.java | 29 +++++++++++++++++++---
.../surefire/its/fixture/SurefireLauncher.java | 5 ++++
8 files changed, 109 insertions(+), 18 deletions(-)
diff --git
a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
index a15301ef4..9db1fc3df 100644
---
a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
+++
b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
@@ -368,6 +368,15 @@ public class IntegrationTestMojo extends
AbstractSurefireMojo {
@Parameter(property = "failsafe.runOrder.random.seed")
private Long runOrderRandomSeed;
+ /**
+ * Used to override the checksum in the name of the statistics file
+ * when {@code failsafe.runOrder} is set to "balanced".
+ *
+ * @since 3.5.5
+ */
+ @Parameter(property = "failsafe.runOrder.statisticsFile.checksum")
+ private String runOrderStatisticsFileChecksum;
+
/**
* A file containing include patterns, each in a next line. Blank lines,
or lines starting with # are ignored.
* If {@code includes} are also specified, these patterns are appended.
Example with path, simple and regex
@@ -930,6 +939,16 @@ public void setRunOrderRandomSeed(Long runOrderRandomSeed)
{
this.runOrderRandomSeed = runOrderRandomSeed;
}
+ @Override
+ public String getRunOrderStatisticsFileChecksum() {
+ return runOrderStatisticsFileChecksum;
+ }
+
+ @Override
+ public void setRunOrderStatisticsFileChecksum(String
runOrderStatisticsFileChecksum) {
+ this.runOrderStatisticsFileChecksum = runOrderStatisticsFileChecksum;
+ }
+
@Override
public File getIncludesFile() {
return includesFile;
diff --git
a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
index 5e81223e3..1e655f219 100644
---
a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
+++
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
@@ -898,6 +898,10 @@ public abstract class AbstractSurefireMojo extends
AbstractMojo implements Suref
public abstract void setRunOrderRandomSeed(Long runOrderRandomSeed);
+ public abstract String getRunOrderStatisticsFileChecksum();
+
+ public abstract void setRunOrderStatisticsFileChecksum(String
runOrderStatisticsFileChecksum);
+
protected abstract void handleSummary(RunResult summary, Exception
firstForkException)
throws MojoExecutionException, MojoFailureException;
@@ -1296,7 +1300,7 @@ private RunResult executeProvider(
ClassLoaderConfiguration classLoaderConfiguration =
getClassLoaderConfiguration();
provider.addProviderProperties();
RunOrderParameters runOrderParameters =
- new RunOrderParameters(getRunOrder(),
getStatisticsFile(getConfigChecksum()), getRunOrderRandomSeed());
+ new RunOrderParameters(getRunOrder(), getStatisticsFile(),
getRunOrderRandomSeed());
if (isNotForking()) {
Properties originalSystemProperties =
@@ -1824,8 +1828,12 @@ private static Map<String, String>
toStringProperties(Properties properties) {
return h;
}
- private File getStatisticsFile(String configurationHash) {
- return new File(getBasedir(), ".surefire-" + configurationHash);
+ private File getStatisticsFile() {
+ String checksum = getRunOrderStatisticsFileChecksum();
+ if (checksum == null || checksum.isEmpty()) {
+ checksum = getConfigChecksum();
+ }
+ return new File(getBasedir(), ".surefire-" + checksum);
}
private StartupConfiguration createStartupConfiguration(
@@ -2063,8 +2071,7 @@ private Artifact getShadefireArtifact() {
return
getPluginArtifactMap().get("org.apache.maven.surefire:surefire-shadefire");
}
- private StartupReportConfiguration getStartupReportConfiguration(
- String configChecksum, boolean isForking, ProviderInfo
providerInfo) {
+ private StartupReportConfiguration getStartupReportConfiguration(boolean
isForking, ProviderInfo providerInfo) {
SurefireStatelessReporter xmlReporter =
statelessTestsetReporter == null ? new
SurefireStatelessReporter() : statelessTestsetReporter;
@@ -2092,7 +2099,7 @@ private StartupReportConfiguration
getStartupReportConfiguration(
getReportsDirectory(),
isTrimStackTrace(),
getReportNameSuffix(),
- getStatisticsFile(configChecksum),
+ getStatisticsFile(),
requiresRunHistory(),
getRerunFailingTestsCount(),
getReportSchemaLocation(),
@@ -2330,9 +2337,7 @@ private ForkStarter createForkStarter(
testClasspathWrapper,
platform,
resolvedJavaModularityResult);
- String configChecksum = getConfigChecksum();
- StartupReportConfiguration startupReportConfiguration =
- getStartupReportConfiguration(configChecksum, true, provider);
+ StartupReportConfiguration startupReportConfiguration =
getStartupReportConfiguration(true, provider);
ProviderConfiguration providerConfiguration =
createProviderConfiguration(runOrderParameters);
return new ForkStarter(
@@ -2360,9 +2365,7 @@ private InPluginVMSurefireStarter createInprocessStarter(
testClasspathWrapper,
platform,
new ResolvePathResultWrapper(null, true));
- String configChecksum = getConfigChecksum();
- StartupReportConfiguration startupReportConfiguration =
- getStartupReportConfiguration(configChecksum, false, provider);
+ StartupReportConfiguration startupReportConfiguration =
getStartupReportConfiguration(false, provider);
ProviderConfiguration providerConfiguration =
createProviderConfiguration(runOrderParameters);
return new InPluginVMSurefireStarter(
startupConfiguration, providerConfiguration,
startupReportConfiguration, getConsoleLogger(), platform);
diff --git
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java
index 39007de0d..a73492838 100644
---
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java
+++
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java
@@ -786,6 +786,14 @@ public Long getRunOrderRandomSeed() {
@Override
public void setRunOrderRandomSeed(Long runOrderRandomSeed) {}
+ @Override
+ public String getRunOrderStatisticsFileChecksum() {
+ return null;
+ }
+
+ @Override
+ public void setRunOrderStatisticsFileChecksum(String
runOrderStatisticsFileChecksum) {}
+
@Override
protected void handleSummary(RunResult summary, Exception
firstForkException) {}
diff --git
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
index c2967b534..894bcf85a 100644
---
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
+++
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
@@ -2234,6 +2234,14 @@ public Long getRunOrderRandomSeed() {
@Override
public void setRunOrderRandomSeed(Long runOrderRandomSeed) {}
+ @Override
+ public String getRunOrderStatisticsFileChecksum() {
+ return null;
+ }
+
+ @Override
+ public void setRunOrderStatisticsFileChecksum(String
runOrderStatisticsFileChecksum) {}
+
@Override
protected void handleSummary(RunResult summary, Exception
firstForkException) {}
diff --git
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java
index 0f952d76e..74b679942 100644
---
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java
+++
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java
@@ -57,7 +57,7 @@ public class MojoMocklessTest {
public void testGetStartupReportConfiguration() throws Exception {
AbstractSurefireMojo surefirePlugin = new Mojo(null, null);
StartupReportConfiguration config =
- invokeMethod(surefirePlugin, "getStartupReportConfiguration",
"", false, mock(ProviderInfo.class));
+ invokeMethod(surefirePlugin, "getStartupReportConfiguration",
false, mock(ProviderInfo.class));
assertThat(config.getXmlReporter()).isNotNull().isInstanceOf(SurefireStatelessReporter.class);
@@ -77,7 +77,7 @@ public void testGetStartupReportConfiguration2() throws
Exception {
setInternalState(surefirePlugin, "statelessTestsetInfoReporter",
testsetInfoReporter);
StartupReportConfiguration config =
- invokeMethod(surefirePlugin, "getStartupReportConfiguration",
"", false, mock(ProviderInfo.class));
+ invokeMethod(surefirePlugin, "getStartupReportConfiguration",
false, mock(ProviderInfo.class));
assertThat(config.getXmlReporter()).isNotNull().isSameAs(xmlReporter);
@@ -545,6 +545,14 @@ public Long getRunOrderRandomSeed() {
@Override
public void setRunOrderRandomSeed(Long runOrderRandomSeed) {}
+ @Override
+ public String getRunOrderStatisticsFileChecksum() {
+ return "dummyStatistics";
+ }
+
+ @Override
+ public void setRunOrderStatisticsFileChecksum(String
runOrderStatisticsFileChecksum) {}
+
@Override
public String[] getDependenciesToScan() {
return dependenciesToScan;
diff --git
a/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefireMojo.java
b/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefireMojo.java
index 07406c557..e76d449a7 100644
---
a/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefireMojo.java
+++
b/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefireMojo.java
@@ -347,6 +347,15 @@ public class SurefireMojo extends AbstractSurefireMojo
implements SurefireReport
@Parameter(property = "surefire.runOrder.random.seed")
private Long runOrderRandomSeed;
+ /**
+ * Used to override the checksum in the name of the statistics file
+ * when {@code surefire.runOrder} is set to "balanced".
+ *
+ * @since 3.5.5
+ */
+ @Parameter(property = "surefire.runOrder.statisticsFile.checksum")
+ private String runOrderStatisticsFileChecksum;
+
/**
* A file containing include patterns. Blank lines, or lines starting with
# are ignored. If {@code includes} are
* also specified, these patterns are appended. Example with path, simple
and regex includes:
@@ -851,6 +860,16 @@ public void setRunOrderRandomSeed(Long runOrderRandomSeed)
{
this.runOrderRandomSeed = runOrderRandomSeed;
}
+ @Override
+ public String getRunOrderStatisticsFileChecksum() {
+ return runOrderStatisticsFileChecksum;
+ }
+
+ @Override
+ public void setRunOrderStatisticsFileChecksum(String
runOrderStatisticsFileChecksum) {
+ this.runOrderStatisticsFileChecksum = runOrderStatisticsFileChecksum;
+ }
+
@Override
public File getIncludesFile() {
return includesFile;
diff --git
a/surefire-its/src/test/java/org/apache/maven/surefire/its/XmlReporterRunTimeIT.java
b/surefire-its/src/test/java/org/apache/maven/surefire/its/XmlReporterRunTimeIT.java
index f193c0182..f68cf1fff 100644
---
a/surefire-its/src/test/java/org/apache/maven/surefire/its/XmlReporterRunTimeIT.java
+++
b/surefire-its/src/test/java/org/apache/maven/surefire/its/XmlReporterRunTimeIT.java
@@ -18,6 +18,8 @@
*/
package org.apache.maven.surefire.its;
+import java.io.File;
+
import org.apache.maven.plugins.surefire.report.ReportTestSuite;
import org.apache.maven.surefire.its.fixture.OutputValidator;
import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
@@ -28,6 +30,7 @@
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.lessThan;
+import static org.junit.Assert.assertTrue;
/**
* Test reported runtime
@@ -38,12 +41,28 @@
public class XmlReporterRunTimeIT extends SurefireJUnit4IntegrationTestCase {
@Test
public void testForkAlways() {
- // just generate .surefire-<hash> in order to apply runOrder
- unpack("/runorder-parallel").executeTest().verifyErrorFree(9);
+ runTest("");
+ }
+
+ @Test
+ public void testForkAlwaysWithChecksumOverride() {
+ OutputValidator validator = runTest("foobar");
+ File statisticsFile = new File(validator.getBaseDir(),
".surefire-foobar");
+ assertTrue("Statistics file (" + statisticsFile.getAbsolutePath() + ")
doesn't exist", statisticsFile.exists());
+ }
+
+ private OutputValidator runTest(String checksumOverride) {
+ // just generate .surefire-<checksumOverride> in order to apply
runOrder
+ unpack("/runorder-parallel")
+ .runOrderStatisticsFileChecksum(checksumOverride)
+ .executeTest()
+ .verifyErrorFree(9);
// now assert test results match expected values
- OutputValidator outputValidator =
- unpack("/runorder-parallel").executeTest().verifyErrorFree(9);
+ OutputValidator outputValidator = unpack("/runorder-parallel")
+ .runOrderStatisticsFileChecksum(checksumOverride)
+ .executeTest()
+ .verifyErrorFree(9);
for (ReportTestSuite report :
extractReports(outputValidator.getBaseDir())) {
if ("runorder.parallel.Test1".equals(report.getFullClassName())) {
@@ -62,5 +81,7 @@ public void testForkAlways() {
System.out.println("report = " + report);
}
}
+
+ return outputValidator;
}
}
diff --git
a/surefire-its/src/test/java/org/apache/maven/surefire/its/fixture/SurefireLauncher.java
b/surefire-its/src/test/java/org/apache/maven/surefire/its/fixture/SurefireLauncher.java
index dcd6a5779..22ffd92cc 100755
---
a/surefire-its/src/test/java/org/apache/maven/surefire/its/fixture/SurefireLauncher.java
+++
b/surefire-its/src/test/java/org/apache/maven/surefire/its/fixture/SurefireLauncher.java
@@ -197,6 +197,11 @@ public SurefireLauncher runOrderRandomSeed(String
runOrderRandomSeed) {
return this;
}
+ public SurefireLauncher runOrderStatisticsFileChecksum(String
runOrderStatisticsFileChecksum) {
+ mavenLauncher.sysProp("surefire.runOrder.statisticsFile.checksum",
runOrderStatisticsFileChecksum);
+ return this;
+ }
+
public SurefireLauncher failIfNoTests(boolean fail) {
mavenLauncher.sysProp("failIfNoTests", fail);
return this;