Skip to content

test(draft): de-flake fork-readiness retry test (fake only setTimeout + flush real async) - #1057

Merged
JSONbored merged 1 commit into
mainfrom
fix/flaky-draft-test
Jun 22, 2026
Merged

test(draft): de-flake fork-readiness retry test (fake only setTimeout + flush real async)#1057
JSONbored merged 1 commit into
mainfrom
fix/flaky-draft-test

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Why

draft.test.ts > processSubmitDraft — fork-readiness retry loop (fake timers) flaked only in CI under test:coverage --shard=1/2 (passed locally + on re-run), repeatedly blocking the validate gate on #1050, #1051, #1052, #1056.

Root cause

The flow interleaves real async — WebCrypto token-decrypt (crypto.subtle, a real macrotask) + the async D1/fetch mocks — with one fake setTimeout(sleep 3000). The old driver pumped await vi.advanceTimersByTimeAsync(3000) in a fixed 50-iteration loop, which only flushes microtasks. Under coverage-instrumented slowness the crypto macrotask lagged, so the sleep wasn't scheduled before the loop exhausted its iterations → await done hung → CI timeout.

Fix

  • Fake only setTimeout/clearTimeout (the sleep) via useFakeTimers({ toFake: [...] }), so every other async — crypto, D1, fetch — runs on the real event loop.
  • Drive deterministically: flush a real setImmediate macrotask tick (lets the real chain complete + schedule its next sleep), then fire the one pending fake sleep, repeating until the flow settles.

No weakened assertions, no real 3s wait. Verified stable across 8 consecutive runs (5 plain + 3 under coverage).

@dosubot dosubot Bot added the size:XS label Jun 22, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@ghost

ghost commented Jun 22, 2026

Copy link
Copy Markdown

Note

🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦

💡 Gittensory review — advisory only

0 files · no blockers · readiness 0/100

💡 Advisory only — no action taken

Signal Result Evidence
Code review ✅ No blockers synthesized
Gate result ⚠️ Skipped #1057 is no longer open.

💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

@ghost ghost 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.

Gittensory approves — the gate is satisfied.

@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.39%. Comparing base (ac7429e) to head (e6e7226).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff             @@
##             main    #1057       +/-   ##
===========================================
+ Coverage   70.27%   95.39%   +25.11%     
===========================================
  Files         148      148               
  Lines       17864    17864               
  Branches     6473     6473               
===========================================
+ Hits        12554    17041     +4487     
+ Misses       4118      359     -3759     
+ Partials     1192      464      -728     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…ke timers)

The test drove an async flow — real WebCrypto token-decrypt + async D1/fetch interleaved with one setTimeout(sleep 3000) — via a fake-timer pump loop. Under CI full-shard coverage load the real macrotask lagged the microtask flush the pump relied on, so the scheduled sleep was never fired and the test HUNG → 15s timeout (the CI-only flake that blocked #1050/#1051/#1052/#1056).

Fix: drop fake timers entirely. Mock setTimeout so the sleep(3000) backoff fires on a real 0ms tick, then await processSubmitDraft directly — the flow runs to completion on the real event loop (probe 404 → instant backoff → probe 200 → open PR) with no pump, no race, no real 3s wait, no weakened assertions. Verified stable across 6+ consecutive plain + coverage runs locally.
@JSONbored
JSONbored force-pushed the fix/flaky-draft-test branch from c3c8f1a to e6e7226 Compare June 22, 2026 19:48

@ghost ghost 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.

Gittensory approves — the gate is satisfied.

@JSONbored
JSONbored merged commit 6402c50 into main Jun 22, 2026
19 checks passed
@JSONbored
JSONbored deleted the fix/flaky-draft-test branch June 22, 2026 19:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant