From 6beed9a883500fb7de88ca2e8ea5e38b021496bc Mon Sep 17 00:00:00 2001 From: Dudu-0223 Date: Mon, 6 Jul 2026 19:55:46 +0800 Subject: [PATCH] test: make the timeout-wins race deterministic under fake timers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI (node 24/26) failed on the exact-boundary construction: advanceTimersByTime(100) then an immediate upstream.abort() let the manual abort win the race on some runtimes, so timeoutOf returned undefined. Advance unambiguously past the deadline and assert the timeout classification before firing the late abort — that late abort is now asserted as a no-op, which is the real first-cause-wins invariant. --- packages/util/timeout/tests/timeout.spec.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/util/timeout/tests/timeout.spec.ts b/packages/util/timeout/tests/timeout.spec.ts index 57066a4f54..588317f48d 100644 --- a/packages/util/timeout/tests/timeout.spec.ts +++ b/packages/util/timeout/tests/timeout.spec.ts @@ -99,7 +99,11 @@ describe('deadline — fuse with upstream', () => { try { const upstream = new AbortController() using d = deadline(upstream.signal, 100, 'WEB_FETCH_TIMEOUT') - vi.advanceTimersByTime(100) // timer fires first + vi.advanceTimersByTime(150) // past the 100ms deadline: the timer fires first + expect(d.signal.aborted).toBe(true) + expect(timeoutOf(d.signal)?.code).toBe('WEB_FETCH_TIMEOUT') + // A later upstream abort is a no-op on the already-aborted fused signal: + // AbortSignal.any keeps the FIRST cause, so the timeout classification stands. upstream.abort('too late') expect(timeoutOf(d.signal)?.code).toBe('WEB_FETCH_TIMEOUT') } finally {