Skip to content

test(fallback): fix flaky cooldown-window timing assertion - #53940

Closed
teknium1 wants to merge 2 commits into
mainfrom
fix/flaky-fallback-cooldown-timing
Closed

teknium1 wants to merge 2 commits into
mainfrom
fix/flaky-fallback-cooldown-timing

Conversation

@teknium1

Copy link
Copy Markdown
Collaborator

Summary

test_non_retryable_exhaustion_arms_cooldown is a freshly-merged flaky test (added in #53909) that fails reliably on loaded CI workers. It captured before = time.monotonic() ahead of three _try_activate_fallback() calls, then asserted the armed cooldown was <= before + 5.0 + 1.0. The cooldown is set relative to the final call, and the activation work (agent init, resolve_provider_client) takes >1s under load — so the before-anchored bound overshoots and fails.

Anchoring the upper bound to after (captured once the cooldown is armed) makes the assertion immune to activation latency without weakening what it verifies.

Changes

  • tests/run_agent/test_24996_fallback_exhaustion_cooldown.py: capture after = time.monotonic() after the activation block; assert cooldown <= after + _FALLBACK_EXHAUSTED_COOLDOWN_S + 1.0.

Root cause

cooldown == final_call_time + 5.0, and after >= final_call_time, so cooldown <= after + 5.0 + 1.0 holds regardless of how slow the three activation calls are. The old before-anchored bound did not — any activation latency >1s leaked straight into the slack.

Validation

Before After
CI slice 8/8 assert 230.21 <= 229.73 FAIL (observed twice; also 905.80 <= 905.31) bound tracks after, no drift
Local pytest (file) — 4 passed
Local stress (target test ×5) — 5/5 pass

Still proves the short 5s window vs the 60s rate-limit one — far below the +50s discriminator the sibling test_rate_limit_exhaustion_keeps_60s_cooldown relies on. Test-only, +7/-1, no logic change.

Infographic

infographic

teknium1 added 2 commits June 27, 2026 19:49
test_non_retryable_exhaustion_arms_cooldown captured `before` ahead of three
_try_activate_fallback() calls, then asserted the armed cooldown was
<= before + 5.0 + 1.0. The cooldown is set relative to the *final* call, and
the activation work (agent init, resolve_provider_client) can take >1s on a
loaded CI worker — so `before`-anchored upper bound overshot by ~0.5s and
failed reliably (slice 8/8, observed twice: 230.21 vs 229.73 bound,
905.80 vs 905.31 bound).

Anchor the upper bound to `after = time.monotonic()` captured once the
cooldown is armed. cooldown is final_call_time + 5.0 and after >= final_call_time,
so cooldown <= after + 5.0 + 1.0 holds regardless of activation latency. Still
proves the short 5s window vs the 60s rate-limit one (well under the +50s
discriminator in the sibling test). Test added in #53909.
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: fix/flaky-fallback-cooldown-timing vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 11602 on HEAD, 11604 on base (✅ -2)

🆕 New issues (1):

Rule Count
invalid-assignment 1
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to attribute `_credits_session_start_micros` of type `int`

✅ Fixed issues (2):

Rule Count
unresolved-attribute 2
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`
run_agent.py:3014: [unresolved-attribute] unresolved-attribute: Object of type `Self@get_credits_spent_micros` has no attribute `_credits_session_start_micros`

Unchanged: 6087 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/test Test coverage or test infrastructure comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have labels Jun 28, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Approved

Clean test fix. Anchoring the upper bound to after (captured once the cooldown has actually been armed) rather than before eliminates the wall-clock jitter that caused CI flakes. The rationale in the comment is clear. Note: this PR also includes an infographic PNG, which is fine.


Reviewed by Hermes Agent

@teknium1

Copy link
Copy Markdown
Collaborator Author

Superseded by 88b3d86 (test: de-flake SIGKILL-tree, compression-tip resume, and fallback-cooldown tests), which landed on main and fixes the same flake in the same test via a wider +30s slack. Same root cause we diagnosed here (tight +1.0s upper slack false-failing on loaded CI runners). Closing as redundant — the test is no longer flaky on main.

@teknium1 teknium1 closed this Jun 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have type/test Test coverage or test infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants