From c1b5a2beb7342567e4ce71fc459b30d79df3f000 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 2 Nov 2026 07:33:07 +0000 Subject: [PATCH] test(producer): the stall tests wait out a slow cold start before moving fake time runFor shared one 1 s real-time budget between the render's start and every step. When the cold start alone spent it, fake time jumped before the stalled attempt opened, so the 400 s window ran out with no retry: "expected [] to deeply equal [2]" on the first test, four merge-group failures since 10-30. The first hold now gets its own 4 s budget. Reproduced by holding the compile stage mock for 1.5 s of real time; it fails before and passes after. Co-Authored-By: Claude Opus 5.5 --- .../producer/src/services/renderOrchestrator.stall.test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/producer/src/services/renderOrchestrator.stall.test.ts b/packages/producer/src/services/renderOrchestrator.stall.test.ts index cac8f7de97f..8f7dc5c401d 100644 --- a/packages/producer/src/services/renderOrchestrator.stall.test.ts +++ b/packages/producer/src/services/renderOrchestrator.stall.test.ts @@ -233,6 +233,9 @@ const PENDING = Symbol("pending"); const dirs: string[] = []; // A test over SLOW_TEST_MS prints where its real time went, so a slow CI run names the step. const SLOW_TEST_MS = 2_000; +// A render's cold start (module loads, temp dirs) can take over a second on a loaded CI runner. Fake time that +// moves before the first attempt is held spends the test's window early. Kept under vitest's 5 s test timeout. +const START_BUDGET_MS = 4_000; const spent = new Map(); let testStarted = 0; let budgetRanOut = 0; @@ -332,8 +335,8 @@ async function untilHeld(outcome: () => unknown, budget: { ms: number }): Promis /** Jumps fake time to the next timer while the scripted attempt waits, with real IO between steps. */ async function runFor(ms: number, outcome: () => unknown): Promise { + await timed("wait for held", () => untilHeld(outcome, { ms: START_BUDGET_MS })); const budget = { ms: 1_000 }; - await timed("wait for held", () => untilHeld(outcome, budget)); for (let elapsed = 0; elapsed < ms && outcome() === PENDING; ) { await timed("io turns", ioTurns); await timed("wait for held", () => untilHeld(outcome, budget));