diff --git a/src/daemon/main.test.ts b/src/daemon/main.test.ts index 628dbcf44..ffbb04761 100644 --- a/src/daemon/main.test.ts +++ b/src/daemon/main.test.ts @@ -530,8 +530,10 @@ describe("startDaemon wires core and leasing together", () => { readonly device: { readonly id: string }; }; - /** Lets real I/O that a mutated daemon would still be doing finish, so "nothing happened" is - * a statement about the daemon and not about how early the test looked. */ + /** Lets the work a mutated daemon would still be doing finish, so "nothing happened" is a + * statement about the daemon and not about how early the test looked. Only sound when that + * work is all in memory: a timer fires after it however loaded the machine is, but real I/O + * (a process spawn, a real file) can outlast it. */ const settleRealTime = async () => new Promise((resolve) => setTimeout(resolve, 25)); async function leasedIos(options: ConstructorParameters[0]) { @@ -634,11 +636,18 @@ describe("startDaemon wires core and leasing together", () => { const writeHeld = new Promise((resolve) => { releaseWrite = resolve; }); + let reachWrite: () => void = () => undefined; + const writeReached = new Promise((resolve) => { + reachWrite = resolve; + }); class HoldingFilesystem extends MemoryFilesystem { async writeFileAtomic( ...arguments_: Parameters ): Promise { - if (holdWrites && arguments_[0] === statePath) await writeHeld; + if (holdWrites && arguments_[0] === statePath) { + reachWrite(); + await writeHeld; + } return super.writeFileAtomic(...arguments_); } } @@ -655,7 +664,6 @@ describe("startDaemon wires core and leasing together", () => { }) as StartDaemonOptions; const failing = new FakeDriver({ availableOsVersions: ["26.5"], clock, platform: "ios" }); failing.failOn("reclaim", 1, new DriverCrashError("purge exploded")); - // The previous process: a device left quarantined, and one request still open. const first = await startDaemon(options(failing)); const grant = (await first.dispatch("lease.request", ios, agent)) as Grant; await first.dispatch("lease.release", { leaseId: grant.lease.id }, agent); @@ -672,20 +680,19 @@ describe("startDaemon wires core and leasing together", () => { request: ios, requesterId: "agent-1", }); - // Leasing's startup settles the open request by writing the registry; hold that write. holdWrites = true; const starting = startDaemon( options(new FakeDriver({ availableOsVersions: ["26.5"], clock, platform: "ios" })), ); - await settleRealTime(); + // Waits on the write itself, not on real time: how long startup takes to reach it depends on + // the machine's load. The race lets a startup that never writes fail on the count below. + await Promise.race([writeReached, starting]); const timersWhileLeasingStartupPending = clock.pendingTimerCount; releaseWrite(); runningDaemons.push(await starting); const timersAfterStartup = clock.pendingTimerCount; - // One timer is startup's own (nothing to do with devices). The quarantined device's retry - // timer is armed by core's convergence, which must not have begun. expect(timersWhileLeasingStartupPending).toBe(1); expect(timersAfterStartup).toBeGreaterThan(timersWhileLeasingStartupPending); }); @@ -700,11 +707,18 @@ describe("startDaemon wires core and leasing together", () => { const writeHeld = new Promise((resolve) => { releaseWrite = resolve; }); + let reachWrite: () => void = () => undefined; + const writeReached = new Promise((resolve) => { + reachWrite = resolve; + }); class HoldingFilesystem extends MemoryFilesystem { async writeFileAtomic( ...arguments_: Parameters ): Promise { - if (holdWrites && arguments_[0] === statePath) await writeHeld; + if (holdWrites && arguments_[0] === statePath) { + reachWrite(); + await writeHeld; + } return super.writeFileAtomic(...arguments_); } } @@ -723,7 +737,6 @@ describe("startDaemon wires core and leasing together", () => { const grant = (await first.dispatch("lease.request", ios, agent)) as Grant; await first.stop("test"); // The restarted process's driver knows no device, so the leased one is gone from its platform. - // Ending that lease writes the registry; hold that write. holdWrites = true; let started = false; @@ -731,7 +744,11 @@ describe("startDaemon wires core and leasing together", () => { started = true; return daemon; }); - await settleRealTime(); + // Waits on the write, not on real time: the steps before it include real I/O, so under load + // they outlast any fixed sleep. From the write on, a startup that did not wait for it only + // has in-memory work left, which finishes before the next macrotask. + await Promise.race([writeReached, starting]); + await new Promise((resolve) => setImmediate(resolve)); const startedWhileEndingPending = started; releaseWrite(); const daemon = await starting;