From 6fbb0128006471b255f411f8a60151f46ee32872 Mon Sep 17 00:00:00 2001 From: Kentaro Wakayama Date: Wed, 5 Aug 2026 02:25:28 +0200 Subject: [PATCH] test(import-map): stop racing wall time in preloader capacity tests `modules/import-map/preloader ... does not miss capacity released before a waiter observes its signal` failed five times today in `coverage shard 4/8`, each time with: RangeError: Import-map preloader load timed out It ejected veryfront-code#3365 from the merge queue and failed CI on #3364 and #3369. It passes on re-run every time, and 3/3 locally. `loadTimeoutMs` arms a real `setTimeout`, not the injected `now` clock. These tests deliberately hold a load unresolved across the whole test body to exercise capacity accounting, so a short timeout is racing wall time. Shard 4/8 runs 200+ files in parallel with coverage instrumentation and an 8GB heap, and the event loop can stall past the deadline. The timer then rejects a load the test never intended to time out. Give the three tests whose subject is not the timeout a delay far beyond any plausible stall, behind a named constant so the reason survives. Tests that do exercise timeout behavior keep their own small values. Verified the mechanism rather than assuming it: setting the constant to 1ms reproduces the exact CI failure, and restoring it passes 47 steps. Fixes veryfront-issue-inbox#364. --- src/modules/import-map/preloader.test.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/modules/import-map/preloader.test.ts b/src/modules/import-map/preloader.test.ts index 35d3c9cf9f..78625e91cc 100644 --- a/src/modules/import-map/preloader.test.ts +++ b/src/modules/import-map/preloader.test.ts @@ -18,6 +18,13 @@ import type { RuntimeAdapter } from "#veryfront/platform/adapters/base.ts"; import { MAX_TIMER_DELAY_MS } from "#veryfront/utils/constants/limits.ts"; import type { ImportMapConfig } from "./types.ts"; +/** + * `loadTimeoutMs` arms a real `setTimeout`, not the injected `now` clock, so + * tests holding a load unresolved race wall time and flake under CI load. Tests + * that do exercise timeout behavior keep their own small values. + */ +const TIMEOUT_NOT_UNDER_TEST_MS = 600_000; + function createMinimalAdapter(): RuntimeAdapter { return { fs: { @@ -1135,7 +1142,7 @@ describe("modules/import-map/preloader", () => { maxProjects: 2, maxVariantsPerProject: 1, ttlMs: 1_000, - loadTimeoutMs: 1_000, + loadTimeoutMs: TIMEOUT_NOT_UNDER_TEST_MS, loadImportMap: () => { const load = createDeferred(); loads.push(load); @@ -1223,7 +1230,7 @@ describe("modules/import-map/preloader", () => { maxProjects: 2, maxVariantsPerProject: 2, ttlMs: 1_000, - loadTimeoutMs: 1_000, + loadTimeoutMs: TIMEOUT_NOT_UNDER_TEST_MS, loadImportMap: () => { const load = createDeferred(); loads.push(load); @@ -1296,7 +1303,7 @@ describe("modules/import-map/preloader", () => { maxProjects: 1, maxVariantsPerProject: 2, ttlMs: 1_000, - loadTimeoutMs: 10_000, + loadTimeoutMs: TIMEOUT_NOT_UNDER_TEST_MS, now: () => { if (releaseDuringAdmission && admissionClockReads++ === 0) { loads[0]!.resolve({ imports: { source: "a" } });