fix(e2e): retry a Pass-expected scenario once on transient failure (#124) #125
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/124-e2e-flaky-retry"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Retry a Pass-expected e2e scenario once on a transient failure before recording it.
KnownFailscenarios never retry; aSkipstays terminal.Why (#124 root cause)
The nightly
e2e.ymlsuite has been red since ~07-11. I root-caused it with clean-tree builds (git archive, per the #123 rule) on a quiet runner:guild_footprint()for #94). 48/48 hermetic puppet-allocation tests pass on master.steal_release_repromotion,multi_bridge_isolation,external_disconnect_recovery,recovery_no_spareall green in isolation.--allrun while infra is flapping. In a full run I captured 23 pass / 3 fail / 2 known-fail, where the 3 fails were:audio_d2m_encandsteal_release_repromotion— a phantom's Matrix membership-heartbeat dropped mid-run (bridge log shows Carol/Alice memberships vanishing ~3 s after join, collapsing the multi-actor choreography). nether.im was returning intermittent 502s during the run (they also caused both#104known-fails).multi_bridge_isolation— the bridge released its puppet and left voice on time (per its log), but the harness listener never observed the leave within 60 s → Discord voice-state propagation lag at the tail of a 30-scenario suite on 3 shared bots.audio_d2m_encre-ran with a different ncc (0.253 → 0.500) — non-deterministic, i.e. flaky, not a hard bug.So the cluster is infra-induced flakiness in a live triage suite, not a code fault. A single retry (each scenario re-sweeps memberships on entry, so it starts clean) turns a transient blip green while a real regression still fails both attempts.
Change
run_scenarios: per-scenario attempt loop, max 2 attempts forPass, 1 forKnownFail; 5 s backoff between attempts; last attempt's artifacts are kept.crates/e2e/Cargo.toml: dev-deptokiotest-utilso the unit tests virtualize the backoff under a paused clock.retry_turns_a_transient_failure_green_and_spares_knownfail(flaky-then-pass →passin 2 runs;KnownFailruns exactly once).Related (separate)
nvb-watch(polls the Actions API, alerts the ops room on a new failing/stale scheduled run). Not in this PR (ops repo).mgmt_dm_pending_reap: keep asKnownFail— it known-failed on a 502 this run, so it is not reliably unexpected-passing.🤖 Generated with Claude Code
Validation
ci.yml#278 on this branch is success — the hermetic gate (cargo test --workspace) includes the newretry_turns_a_transient_failure_green_and_spares_knownfailunit test.--allon the runner,audio_d2m_unencfailed its first attempt and the harness loggedattempt 1 failed — retrying once (transient-infra tolerance, #124).Caveat on live
--allevidenceI could not get a clean green live
--allbecause, mid-run, a concurrent Forgejo CIcargo test --workspacelanded on the shared host and drove load to 17 — the audio scenarios then failed at ncc≈0.0 on both attempts (total non-crossing = CPU starvation of the audio pipeline), and the prod bridge was at 128% CPU. I SIGINT/killed my manual run to protect prod.This is not a regression in the fix — it's a live reproduction of the shared-host contention that is one arm of #124. Note the real nightly is serialized against CI via the
live-hostconcurrency group, so it does not see CI contention; a manual run isn't serialized. The retry helps single-blip flakes (membership drop, voice-state lag) but by design cannot beat sustained starvation — that needs #90 (offload builds to a dedicated runner). Recommend merging on CI-green + the next real serialized nightly, not on a manual contended run.