test(cli): stabilize flaky install-lock wait-notice test with fake timers

Adopt the fake-timer pattern the sibling "recovers when a crashed reclaimer
leaves both lock directories" test in the same file already uses. Without
fake timers, if the dynamic `import("./manager.js")` beat between
`installFsMocks({ initialMtimeMs: Date.now() })` and the `withInstallLock`
call exceeds `staleMs` (50 ms on a busy shared runner with `vi.resetModules()`
per beforeEach), the new immediate-stale short-circuit added in #2328 fires
on iteration 1, breaks out before `waitedMs` reaches `waitNoticeMs=20`, and
no "Waiting for another hyperframes process" warn ever emits — the assertion
at `manager.test.ts:428` (`expected false to be true`) then fails.

Under fake timers, `Date.now()` is frozen at the mtime seed, so the lock
stays non-stale across the dynamic import and the wait-notice branch
observes real polling; `vi.advanceTimersByTimeAsync(staleMs + pollMs * 5)`
then drives the loop past both the wait-notice threshold and the stale
deadline so the reclaim + acquisition still resolves.

Test-only change; no production-code diff. Verified 27/27 in
`packages/cli/src/browser/manager.test.ts` under `vitest run`.
This commit is contained in:
Vance Ingalls
2026-07-13 21:30:44 +00:00
parent 3df59fc0a4
commit e47af77c5a
+16 -1
View File
@@ -411,6 +411,12 @@ describe("findBrowser — cache resolution", () => {
});
it("withInstallLock reports progress while waiting instead of staying silent", async () => {
// Fake timers freeze Date.now() so the lock mtime stays non-stale across
// the dynamic import that follows — without them, a slow import beat could
// push wall-clock past staleMs before `withInstallLock` even starts polling,
// firing the immediate-stale short-circuit and skipping the wait-notice
// branch this test exists to observe.
vi.useFakeTimers();
const paths = installFsMocks({
existing: new Set([CACHE_ROOT, HF_LOCK]),
initialMtimeMs: Date.now(),
@@ -418,8 +424,17 @@ describe("findBrowser — cache resolution", () => {
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
const { withInstallLock } = await import("./manager.js");
await withInstallLock(async () => "done", { ...TEST_LOCK_TIMINGS, waitNoticeMs: 20 });
const acquisition = withInstallLock(async () => "done", {
...TEST_LOCK_TIMINGS,
waitNoticeMs: 20,
});
// Advance past waitNoticeMs (fires the "Waiting for…" warn), then past
// staleMs (lets `reclaimStaleInstallLock` clear the held lock so the
// acquisition resolves).
await vi.advanceTimersByTimeAsync(TEST_LOCK_TIMINGS.staleMs + TEST_LOCK_TIMINGS.pollMs * 5);
await expect(acquisition).resolves.toBe("done");
expect(paths.has(HF_LOCK)).toBe(false);
expect(
warnSpy.mock.calls.some(([msg]) =>