Repository navigation
test(it): rerun only failed methods on failsafe retry, and fail fast only in the merge queue - #38309
Conversation
… class With rerunFailingTestsCount=3, failsafe's JUnit4 provider reruns by building Request.aClass(<suite>).filterWith(<failed descriptions>) (JUnit4Provider.execute). MainBaseSuite wraps every suite member in DotRunner, which extended Runner but did not implement Filterable. JUnit's Filter.apply skips children that are not Filterable, so the filter kept the failing class but never narrowed its methods, and every method of the class reran (e.g. all 37 methods of WebAssetHelperIntegrationTest, all 10 of TagAPITest, reported as flakes). DotRunner now implements Filterable and delegates to the wrapped CustomDataProviderRunner, which already filters per method (including data-provider rows). Normal, unfiltered runs are unchanged. Evidence (temporary suite, not committed, one plain class and one DataProviderRunner class, each with a method failing on its first run): before the change the rerun pass executed 4 of 4 methods per class (14 tests total, 2 flakes); after, it executed only the failed method and the failed provider row (8 total, 2 flakes). A suite of SystemTableFactoryTest, ObjectMapperTest and TagAPITest ran 3, 2 and 45 tests, and TagAPITest run directly also ran 45. Refs #38308
|
Claude finished @swicken's task in 59s —— View job Code ReviewTask
VerdictNo blocking issues. The fix is correct and minimal. Analysis
The root cause is accurate: JUnit's The delegation chain checks out:
Normal, unfiltered runs never invoke
Notes (non-blocking)
No issues found. |
|
pipeline go burrrrrrr |
|
or not :P |
The test matrix cancelled every other suite as soon as one failed, unless a PR carried the "CI : No Fail Fast" label. That hides evidence: a single flake in one suite turned the other ~24 jobs into cancellations, which look like failures at a glance, and a push only ever showed the first failure. With Enterprise concurrency and free standard minutes on a public repo, the runner time fail-fast saved is no longer worth that. Fail-fast now applies only to merge_group runs, where a failing group should be ejected quickly so the groups behind it rebuild. Pull requests, trunk, nightly and LTS runs let every suite finish. Phased OpenSearch runs keep running to completion in every context, as before. The label is no longer needed. Refs #38308
Proposed Changes
When an integration test fails, failsafe retries it up to three times (
rerunFailingTestsCountindotcms-integration/pom.xml). The retry should repeat only the failed methods, but for tests in theMainSuite*suites it repeated every method of the failing class. For example, one failedWebAssetHelperIntegrationTestmethod reran all 37 of its methods in merge-queue run 40712603717. A failedTagAPITestmethod shows up as all ten of its methods "flaking".Request.aClass(<suite>).filterWith(<failed test descriptions>).MainBaseSuitewraps each class's runner inDotRunner, which extendedRunnerwithout implementingFilterable. JUnit'sFilter.applysilently skips children that are notFilterable, so the filter kept the failing class but never narrowed it to the failed methods.DotRunnernow implementsFilterableand passes the filter to the runner it wraps. That runner,CustomDataProviderRunner, already filters per method and per data-provider row. Runs without a filter are unchanged.Fixes #38308
Addendum: fail fast only in the merge queue (
.github/workflows/cicd_comp_test-phase.yml)The test matrix used to cancel every other suite as soon as one failed, unless the PR carried the
CI : No Fail Fastlabel. That hides evidence:With Enterprise concurrency, and free standard minutes on a public repo, the runner time fail-fast saved is no longer worth that.
merge_groupruns. A failing group should be ejected quickly so the groups behind it rebuild.Checklist
Additional Info
Verified locally with a throwaway suite, not committed, in the
MainBaseSuitestyle. It held one plain class and one data-provider class, each with a method that fails on its first run.SystemTableFactoryTest,ObjectMapperTestandTagAPITestran the same 3, 2 and 45 tests as before.The JUnit 5 suites (
Junit5Suite*) need no change. The JUnit Platform provider already retries by each failed test's unique ID, which was checked the same way (details in #38308).This changes only the cost of a retry, not whether retries happen. A test that passed its retry only because the rest of its class ran again will now fail. That means its methods depend on each other, which is worth seeing.
This PR fixes: #38308