From aa1a546a2298bce39f7929dedb3b8d1f6cf69d4d Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Mon, 7 Sep 2026 17:02:05 -0700 Subject: [PATCH] test: make desktop orphan-reap deadline checks deterministic --- apps/desktop/electron/backend-ownership.test.ts | 15 ++++++++++----- evals/desktop-reap-clock-pressure.cjs | 12 ++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 evals/desktop-reap-clock-pressure.cjs diff --git a/apps/desktop/electron/backend-ownership.test.ts b/apps/desktop/electron/backend-ownership.test.ts index 77a6e46e2e..54baa74420 100644 --- a/apps/desktop/electron/backend-ownership.test.ts +++ b/apps/desktop/electron/backend-ownership.test.ts @@ -178,16 +178,19 @@ test('startup reap preserves failed stops for the next launch', async () => { assert.deepEqual(parseBackendOwnership(store.value()), [entry]) }) -test('startup reap stops at the deadline and preserves the unprocessed records', async () => { +test('startup reap stops at the deadline and preserves the unprocessed records', async ({ onTestFinished }) => { + // Advance only when the first probe completes, never with runner scheduling. + const now = vi.spyOn(Date, 'now').mockReturnValue(0) + onTestFinished(() => now.mockRestore()) const first = ownershipEntry({ pid: 60 }) const second = ownershipEntry({ pid: 61 }) const store = memoryStore(stored([first, second])) const stop = vi.fn() const ownership = createOwnership(store, { - // Each probe is slow enough to blow a 1ms budget after the first entry. + // Exhaust the budget exactly at the boundary after processing one entry. matchesIdentity: async () => { - await new Promise(resolve => setTimeout(resolve, 10)) + now.mockReturnValue(1) return false }, @@ -201,7 +204,9 @@ test('startup reap stops at the deadline and preserves the unprocessed records', assert.deepEqual(parseBackendOwnership(store.value()), [second]) }) -test('startup reap preserves would-be-reaped records when the budget runs out', async () => { +test('startup reap preserves would-be-reaped records when the budget runs out', async ({ onTestFinished }) => { + const now = vi.spyOn(Date, 'now').mockReturnValue(0) + onTestFinished(() => now.mockRestore()) const first = ownershipEntry({ pid: 62 }) const second = ownershipEntry({ pid: 63 }) const store = memoryStore(stored([first, second])) @@ -209,7 +214,7 @@ test('startup reap preserves would-be-reaped records when the budget runs out', const ownership = createOwnership(store, { matchesIdentity: async () => { - await new Promise(resolve => setTimeout(resolve, 10)) + now.mockReturnValue(1) return true }, diff --git a/evals/desktop-reap-clock-pressure.cjs b/evals/desktop-reap-clock-pressure.cjs new file mode 100644 index 0000000000..09dc6b436b --- /dev/null +++ b/evals/desktop-reap-clock-pressure.cjs @@ -0,0 +1,12 @@ +// Replay scheduling pressure without changing Date.now() results: +// NODE_OPTIONS="--require=$PWD/evals/desktop-reap-clock-pressure.cjs" \ +// npm run test:desktop:platforms -w apps/desktop -- electron/backend-ownership.test.ts +// The old 1ms fixtures can expire before their first record is processed. +const now = Date.now.bind(Date) +const gate = new Int32Array(new SharedArrayBuffer(4)) +Date.now = function () { + if (new Error().stack.includes('/electron/backend-ownership.ts:')) { + Atomics.wait(gate, 0, 0, 5) + } + return now() +}