Repository navigation
tests/run-tests.py: Add automatic retry for known-flaky tests. - #18861
Conversation
|
Code size report: |
projectgus
left a comment
There was a problem hiding this comment.
Thanks for putting this together, @andrewleech!
It looks fine to me, although the implementation feels like yet another way that run-tests.py is due for a refactor as the simple script-y style is starting to buckle under the load of features added to it!
However that's a problem for another day, and having a flaky test retry mechanism seems pretty valuable.
Only one thing I'm worried about: the Checks list seems to not include any of the Unix port checks running? Do you know what that might be? I was going to go and mash "retry" on them a few times to see how the flaky check works in practice.
Would also add, there is another possible alternative approach here which is to improve these flaky tests until they are no longer flaky. I think we should keep this as an eventual goal, but the fact they've been flaky for some years now suggests it's not a viable short-term goal.
|
Thanks @projectgus I've got a few minor cleanups to make still based on feedback in andrewleech#6 ...
I'm not quite sure what you mean by Checks list here?
Oh yes that's absolutely preferential, ideally even with this flaky retry handling the tests should get fixed to eventually empty the list here. I believe it's not just the tests that are flaky though... threads in particular I think have a/some bugs on unix port at least that the tests correctly detect, some kind of intermittent race condition that's hard to track down. I've tried to look into this in the past but not got to the bottom of it. The other tests, not sure, but the AI investigation into these failing tests did purpose some theories (in the report in a gist linked from my discussion post) that I haven't reviewed yet. |
Oh for sure, I should have said to "fix whatever is making the tests fail".
Sorry, wasn't clear: I meant that if I click the Checks tab in this PR then I can't see the workflow run for the unix port in the list of workflows... It's like it somehow hasn't run it? As it happens, though, I spoke with @dpgeorge about this just now and he prefers if we ignore failures on these tests instead of retrying. He made the reasonable point that most bugs will be masked in either case, so we may as well do it the simpler way. Do you want to update this PR? If not then I'm happy to throw up a quick one to add some more ignore logic. |
Should we create issues for each of these flaky test, or just keep them as a TODO comment in the test or test runner? I'd prefer explicit issues for sake of visibility and possible connections to real-world occurrences. |
5571e56 to
cbc5529
Compare
|
Updated to ignore failures instead of retrying, as suggested. The The @Josverl yeah creating individual issues for each is a good idea, it'd make it easier to track and reference from the Force pushed, old version backed up at |
| @@ -93,6 +93,7 @@ jobs: | |||
| (cd ports/unix && gcov -o build-coverage/py ../../py/*.c || true) | |||
| (cd ports/unix && gcov -o build-coverage/extmod ../../extmod/*.c || true) | |||
| - name: Upload coverage to Codecov | |||
| if: ${{ secrets.CODECOV_TOKEN != '' }} | |||
There was a problem hiding this comment.
Ah, this is why the unix port checks aren't running in this PR:
https://github.com/micropython/micropython/actions/runs/22411608686
Invalid workflow file: .github/workflows/ports_unix.yml#L1
(Line: 96, Col: 11): Unrecognized named-value: 'secrets'. Located at position 1 within expression: secrets.CODECOV_TOKEN != ''
There was a problem hiding this comment.
Ah, whoops. I'll have to figure out a better way to fix this (or leave it for another PR).
Basically this step always fails if you run actions on a fork, so I'm hoping to gate it cleanly so forks can properly test things before submitting a pr
cbc5529 to
36ae4eb
Compare
9cfef37 to
032aa59
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #18861 +/- ##
=======================================
Coverage 98.45% 98.45%
=======================================
Files 175 175
Lines 22635 22635
=======================================
Hits 22286 22286
Misses 349 349 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
5ed226e to
06ba55a
Compare
06ba55a to
56d2d12
Compare
Reclassify failures of tests listed in flaky_tests_to_ignore as "ignored" instead of retrying them. Ignored tests still run and their output is reported, but they don't affect the exit code. The ci.sh --exclude lists for these tests are removed so they run normally. Signed-off-by: Andrew Leech <[email protected]>
56d2d12 to
4319927
Compare
Summary
The unix port CI workflow on master fails ~18% of the time due to a handful of intermittent test failures (mostly thread-related). This has normalised red CI to the point where contributors ignore it, masking real regressions.
I added a flaky-test allowlist and retry-until-pass mechanism to
run-tests.py. When a listed test fails, it's re-run up to 2 more times and passes on the first success. The 8 tests on the list account for essentially all spurious CI failures on master.tools/ci.shis updated to remove--excludepatterns for tests now handled by the retry logic, so they get actual coverage again.thread/stress_aes.pystays excluded on RISC-V QEMU where it runs close to the 200s timeout and retries would burn excessive CI time.Retries are on by default;
--no-retrydisables them. The end-of-run summary reports tests that passed via retry separately from clean passes.Testing
Full CI passed on fork (all workflows green). The codecov upload step is also gated on
CODECOV_TOKENbeing available so it skips cleanly on forks.Trade-offs and Alternatives
Retry-until-pass can mask a test that has become intermittently broken. The allowlist is deliberately small and each entry documents a reason and optional platform restriction. An alternative would be to mark these tests as expected-fail, but that removes coverage entirely which is worse than the current situation.
The test result status strings (
"pass","fail","skip") are bare string literals throughoutrun-tests.py— the retry code follows this existing convention. Worth considering a follow-up to consolidate these into constants for the whole file.Generative AI
I used generative AI tools when creating this PR, but a human has checked the code and is responsible for the description above.