Skip to content

Commit dfc8b63

Browse files
committed
[SUREFIRE-756] Allow ability to capture executed random runOrder for re-play purposes
1 parent 6e895b1 commit dfc8b63

File tree

16 files changed

+253
-5
lines changed

16 files changed

+253
-5
lines changed

maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,22 @@ public class IntegrationTestMojo
310310
@Parameter( property = "failsafe.runOrder", defaultValue = "filesystem" )
311311
private String runOrder;
312312

313+
/**
314+
* Sets the random seed that will be used to order the tests if {@code failsafe.runOrder} is set to {@code random}.
315+
* <br>
316+
* <br>
317+
* If no seeds are set and {@code failsafe.runOrder} is set to {@code random}, then the seed used will be
318+
* outputted (search for "To reproduce ordering use flag -Dfailsafe.runOrder.random.seed").
319+
* <br>
320+
* <br>
321+
* To deterministically reproduce any random test order that was run before, simply set the seed to
322+
* be the same value.
323+
*
324+
* @since 3.0.0-M6
325+
*/
326+
@Parameter( property = "failsafe.runOrder.random.seed" )
327+
private Long runOrderRandomSeed;
328+
313329
/**
314330
* A file containing include patterns, each in a next line. Blank lines, or lines starting with # are ignored.
315331
* If {@code includes} are also specified, these patterns are appended. Example with path, simple and regex
@@ -891,6 +907,18 @@ public void setRunOrder( String runOrder )
891907
this.runOrder = runOrder;
892908
}
893909

910+
@Override
911+
public Long getRunOrderRandomSeed()
912+
{
913+
return runOrderRandomSeed;
914+
}
915+
916+
@Override
917+
public void setRunOrderRandomSeed( Long runOrderRandomSeed )
918+
{
919+
this.runOrderRandomSeed = runOrderRandomSeed;
920+
}
921+
894922
@Override
895923
public File getIncludesFile()
896924
{

maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,10 @@ public abstract class AbstractSurefireMojo
865865

866866
public abstract void setRunOrder( String runOrder );
867867

868+
public abstract Long getRunOrderRandomSeed();
869+
870+
public abstract void setRunOrderRandomSeed( Long runOrderRandomSeed );
871+
868872
protected abstract void handleSummary( RunResult summary, Exception firstForkException )
869873
throws MojoExecutionException, MojoFailureException;
870874

@@ -1129,6 +1133,7 @@ boolean verifyParameters()
11291133
warnIfNotApplicableSkipAfterFailureCount();
11301134
warnIfIllegalTempDir();
11311135
warnIfForkCountIsZero();
1136+
printDefaultSeedIfNecessary();
11321137
}
11331138
return true;
11341139
}
@@ -1285,7 +1290,7 @@ private RunResult executeProvider( @Nonnull ProviderInfo provider, @Nonnull Defa
12851290
ClassLoaderConfiguration classLoaderConfiguration = getClassLoaderConfiguration();
12861291
provider.addProviderProperties();
12871292
RunOrderParameters runOrderParameters =
1288-
new RunOrderParameters( getRunOrder(), getStatisticsFile( getConfigChecksum() ) );
1293+
new RunOrderParameters( getRunOrder(), getStatisticsFile( getConfigChecksum() ), getRunOrderRandomSeed() );
12891294

12901295
if ( isNotForking() )
12911296
{
@@ -3051,6 +3056,17 @@ private void warnIfIllegalTempDir() throws MojoFailureException
30513056
}
30523057
}
30533058

3059+
private void printDefaultSeedIfNecessary()
3060+
{
3061+
if ( getRunOrderRandomSeed() == null && getRunOrder().equals( RunOrder.RANDOM.name() ) )
3062+
{
3063+
setRunOrderRandomSeed( System.nanoTime() );
3064+
getConsoleLogger().info(
3065+
"Tests will run in random order. To reproduce ordering use flag -D"
3066+
+ getPluginName() + ".runOrder.random.seed=" + getRunOrderRandomSeed() );
3067+
}
3068+
}
3069+
30543070
final class TestNgProviderInfo
30553071
implements ProviderInfo
30563072
{

maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import static org.apache.maven.surefire.booter.BooterConstants.PLUGIN_PID;
5757
import static org.apache.maven.surefire.booter.BooterConstants.PROCESS_CHECKER;
5858
import static org.apache.maven.surefire.booter.BooterConstants.PROVIDER_CONFIGURATION;
59+
import static org.apache.maven.surefire.booter.BooterConstants.RUN_ORDER_RANDOM_SEED;
5960
import static org.apache.maven.surefire.booter.BooterConstants.REPORTSDIRECTORY;
6061
import static org.apache.maven.surefire.booter.BooterConstants.REQUESTEDTEST;
6162
import static org.apache.maven.surefire.booter.BooterConstants.RERUN_FAILING_TESTS_COUNT;
@@ -161,6 +162,7 @@ File serialize( KeyValueSource sourceProperties, ProviderConfiguration providerC
161162
{
162163
properties.setProperty( RUN_ORDER, RunOrder.asString( runOrderParameters.getRunOrder() ) );
163164
properties.setProperty( RUN_STATISTICS_FILE, runOrderParameters.getRunStatisticsFile() );
165+
properties.setProperty( RUN_ORDER_RANDOM_SEED, runOrderParameters.getRunOrderRandomSeed() );
164166
}
165167

166168
ReporterConfiguration reporterConfiguration = providerConfiguration.getReporterConfiguration();

maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,18 @@ public void setRunOrder( String runOrder )
839839

840840
}
841841

842+
@Override
843+
public Long getRunOrderRandomSeed()
844+
{
845+
return null;
846+
}
847+
848+
@Override
849+
public void setRunOrderRandomSeed( Long runOrderRandomSeed )
850+
{
851+
852+
}
853+
842854
@Override
843855
protected void handleSummary( RunResult summary, Exception firstForkException )
844856
{

maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2381,6 +2381,18 @@ public void setRunOrder( String runOrder )
23812381

23822382
}
23832383

2384+
@Override
2385+
public Long getRunOrderRandomSeed()
2386+
{
2387+
return null;
2388+
}
2389+
2390+
@Override
2391+
public void setRunOrderRandomSeed( Long runOrderRandomSeed )
2392+
{
2393+
2394+
}
2395+
23842396
@Override
23852397
protected void handleSummary( RunResult summary, Exception firstForkException )
23862398
{

maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,18 @@ public void setRunOrder( String runOrder )
709709

710710
}
711711

712+
@Override
713+
public Long getRunOrderRandomSeed()
714+
{
715+
return null;
716+
}
717+
718+
@Override
719+
public void setRunOrderRandomSeed( Long runOrderRandomSeed )
720+
{
721+
722+
}
723+
712724
@Override
713725
public String[] getDependenciesToScan()
714726
{

maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,22 @@ public class SurefirePlugin
292292
@Parameter( property = "surefire.runOrder", defaultValue = "filesystem" )
293293
private String runOrder;
294294

295+
/**
296+
* Sets the random seed that will be used to order the tests if {@code surefire.runOrder} is set to {@code random}.
297+
* <br>
298+
* <br>
299+
* If no seeds are set and {@code surefire.runOrder} is set to {@code random}, then the seed used will be
300+
* outputted (search for "To reproduce ordering use flag -Dsurefire.runOrder.random.seed").
301+
* <br>
302+
* <br>
303+
* To deterministically reproduce any random test order that was run before, simply set the seed to
304+
* be the same value.
305+
*
306+
* @since 3.0.0-M6
307+
*/
308+
@Parameter( property = "surefire.runOrder.random.seed" )
309+
private Long runOrderRandomSeed;
310+
295311
/**
296312
* A file containing include patterns. Blank lines, or lines starting with # are ignored. If {@code includes} are
297313
* also specified, these patterns are appended. Example with path, simple and regex includes:
@@ -794,6 +810,18 @@ public void setRunOrder( String runOrder )
794810
this.runOrder = runOrder;
795811
}
796812

813+
@Override
814+
public Long getRunOrderRandomSeed()
815+
{
816+
return runOrderRandomSeed;
817+
}
818+
819+
@Override
820+
public void setRunOrderRandomSeed( Long runOrderRandomSeed )
821+
{
822+
this.runOrderRandomSeed = runOrderRandomSeed;
823+
}
824+
797825
@Override
798826
public File getIncludesFile()
799827
{

surefire-api/src/main/java/org/apache/maven/surefire/api/testset/RunOrderParameters.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,34 @@ public class RunOrderParameters
3131

3232
private File runStatisticsFile;
3333

34+
private Long runOrderRandomSeed;
35+
3436
public RunOrderParameters( RunOrder[] runOrder, File runStatisticsFile )
3537
{
3638
this.runOrder = runOrder;
3739
this.runStatisticsFile = runStatisticsFile;
40+
this.runOrderRandomSeed = null;
3841
}
3942

4043
public RunOrderParameters( String runOrder, File runStatisticsFile )
4144
{
4245
this.runOrder = runOrder == null ? RunOrder.DEFAULT : RunOrder.valueOfMulti( runOrder );
4346
this.runStatisticsFile = runStatisticsFile;
47+
this.runOrderRandomSeed = null;
48+
}
49+
50+
public RunOrderParameters( RunOrder[] runOrder, File runStatisticsFile, Long runOrderRandomSeed )
51+
{
52+
this.runOrder = runOrder;
53+
this.runStatisticsFile = runStatisticsFile;
54+
this.runOrderRandomSeed = runOrderRandomSeed;
55+
}
56+
57+
public RunOrderParameters( String runOrder, File runStatisticsFile, Long runOrderRandomSeed )
58+
{
59+
this.runOrder = runOrder == null ? RunOrder.DEFAULT : RunOrder.valueOfMulti( runOrder );
60+
this.runStatisticsFile = runStatisticsFile;
61+
this.runOrderRandomSeed = runOrderRandomSeed;
4462
}
4563

4664
public static RunOrderParameters alphabetical()
@@ -53,6 +71,16 @@ public RunOrder[] getRunOrder()
5371
return runOrder;
5472
}
5573

74+
public Long getRunOrderRandomSeed()
75+
{
76+
return runOrderRandomSeed;
77+
}
78+
79+
public void setRunOrderRandomSeed( Long runOrderRandomSeed )
80+
{
81+
this.runOrderRandomSeed = runOrderRandomSeed;
82+
}
83+
5684
public File getRunStatisticsFile()
5785
{
5886
return runStatisticsFile;

surefire-api/src/main/java/org/apache/maven/surefire/api/util/DefaultRunOrderCalculator.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.Comparator;
2929
import java.util.LinkedHashSet;
3030
import java.util.List;
31+
import java.util.Random;
3132

3233
/**
3334
* Applies the final runorder of the tests
@@ -45,12 +46,21 @@ public class DefaultRunOrderCalculator
4546

4647
private final int threadCount;
4748

49+
private final Random random;
50+
4851
public DefaultRunOrderCalculator( RunOrderParameters runOrderParameters, int threadCount )
4952
{
5053
this.runOrderParameters = runOrderParameters;
5154
this.threadCount = threadCount;
5255
this.runOrder = runOrderParameters.getRunOrder();
5356
this.sortOrder = this.runOrder.length > 0 ? getSortOrderComparator( this.runOrder[0] ) : null;
57+
Long runOrderRandomSeed = runOrderParameters.getRunOrderRandomSeed();
58+
if ( runOrderRandomSeed == null )
59+
{
60+
runOrderRandomSeed = System.nanoTime();
61+
runOrderParameters.setRunOrderRandomSeed( runOrderRandomSeed );
62+
}
63+
this.random = new Random( runOrderRandomSeed );
5464
}
5565

5666
@Override
@@ -72,7 +82,7 @@ private void orderTestClasses( List<Class<?>> testClasses, RunOrder runOrder )
7282
{
7383
if ( RunOrder.RANDOM.equals( runOrder ) )
7484
{
75-
Collections.shuffle( testClasses );
85+
Collections.shuffle( testClasses, random );
7686
}
7787
else if ( RunOrder.FAILEDFIRST.equals( runOrder ) )
7888
{

surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ private BooterConstants()
4646
public static final String SOURCE_DIRECTORY = "testSuiteDefinitionTestSourceDirectory";
4747
public static final String TEST_CLASSES_DIRECTORY = "testClassesDirectory";
4848
public static final String RUN_ORDER = "runOrder";
49+
public static final String RUN_ORDER_RANDOM_SEED = "runOrderRandomSeed";
4950
public static final String RUN_STATISTICS_FILE = "runStatisticsFile";
5051
public static final String TEST_SUITE_XML_FILES = "testSuiteXmlFiles";
5152
public static final String PROVIDER_CONFIGURATION = "providerConfiguration";

0 commit comments

Comments
 (0)