choksi2212 opened a new pull request, #3547:
URL: https://github.com/apache/maven-surefire/pull/3547

   Fixes #3544.
   
   ## What went wrong
   
   `runOrder=random` on the JUnit Platform shuffles the classes twice with the 
same seed, in every configuration where all classes reach Jupiter in one 
discovery request - the default `forkCount=1`/`reuseForks=true` being the 
common case:
   
   - `DefaultRunOrderCalculator` sorts the classes alphabetically and shuffles 
them with `new Random(runOrder.random.seed)`;
   - `setupRunOrder()` configures Jupiter's `ClassOrderer$Random` and forwards 
the same seed;
   - the eager path in `execute()` then sends the already shuffled classes to 
Jupiter in one request, and `ClassOrderer$Random` shuffles them again with the 
same seed.
   
   `Collections.shuffle` with a fresh `Random(seed)` always applies the same 
permutation to a list of a given size, so the two shuffles compose to 
sigma-of-sigma. Only squares of permutations can occur: with two classes the 
result is always alphabetical, exactly the reproducer table in the issue shows 
(`AB x20` for `runOrder=random` vs `AB x9, BA x11` for the plain Jupiter 
orderer with the same seeds).
   
   ## The fix
   
   When all classes reach Jupiter in one discovery request *and* this provider 
configured the class orderer, hand the classes over **sorted, not shuffled**, 
and leave the single shuffle to Jupiter 
(`JUnitPlatformProvider.orderTestClasses`):
   
   ```java
   if (jupiterShufflesTheClasses
           && classOrdererSetByProvider
           && !runsOneClassAtATime()
           && !isVintageEngineDetected()) {
       return sortedAlphabetically(scannedClasses);
   }
   return parameters.getRunOrderCalculator().orderTestClasses(scannedClasses);
   ```
   
   The executed order now follows from the seed alone and matches what 
`ClassOrderer$Random` produces with that seed, which is also what the issue 
used as its control.
   
   The calculator keeps ordering the classes in every other case:
   
   - `getSuites()` hands the classes over one at a time (fork distribution, 
tests discovered in process), so Jupiter's orderer never sees more than one 
class;
   - JUnit 4-only suites run one class per request, where the surefire shuffle 
is the only ordering;
   - TestNG and vintage classes keep the discovery order, because the Jupiter 
orderer cannot re-order them - a mixed suite keeps its current behavior;
   - a class orderer configured by the user (system property, 
`junit-platform.properties`, or the `configurationParameters` option) is not 
necessarily `ClassOrderer$Random`, so the surefire shuffle must stay.
   
   `setupRunOrder` now records whether the provider actually installed 
`ClassOrderer$Random` (`putIfAbsent` returns the previous value, so a 
user-configured orderer reports as "not ours"), which is what the guard checks.
   
   ## Verification
   
   New `JUnitPlatformProviderRunOrderTest` (the existing provider test class is 
3 lines under the checkstyle file-length limit, so the tests live in their own 
class):
   
   - `runOrderRandomShufflesTheClassesOnceWhenJupiterSeesThemAll` - 12 large 
seeds through the real provider and launcher: both execution orders occur. **On 
pristine master this fails with only `TestClass1` ever running first** - the 
sigma-squared-always-alphabetical symptom from the issue;
   - `runOrderRandomDoesNotShuffleAgainWhenJupiterSeesAllClasses` - the 
calculator is not invoked in the governed path. On master the mock calculator 
throws the `AssertionError` it is wired with, because the double shuffle is 
live there;
   - four guard tests pin that the calculator *is* still invoked for the suites 
(`getSuites`), for JUnit 4-only suites, when the vintage engine is detected, 
and when the user configured their own class orderer.
   
   Full local runs (Windows, Maven 3.9.16, JDK 17): `mvn -pl 
surefire-providers/surefire-junit-platform test` - **173/173 with the fix (167 
pristine + the 6 new tests), 0 failures in both**, checkstyle clean. One note 
for reviewers: the per-class `Tests run` numbers in this module are noisy 
across runs on pristine master too (the provider tests execute real nested test 
fixtures through live adapters inside the running surefire instance, so report 
attribution between classes shifts); the totals are stable and every class is 
green with and without the change.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to