From a5a2e487c74d25294cb9a3935091611946ba66a1 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 13 Mar 2026 23:51:36 +0000 Subject: [PATCH] test: tighten transport ready coverage --- src/infra/transport-ready.test.ts | 66 ++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/src/infra/transport-ready.test.ts b/src/infra/transport-ready.test.ts index 318224cc78f..68a5406d254 100644 --- a/src/infra/transport-ready.test.ts +++ b/src/infra/transport-ready.test.ts @@ -4,11 +4,25 @@ import { waitForTransportReady } from "./transport-ready.js"; // Perf: `sleepWithAbort` uses `node:timers/promises` which isn't controlled by fake timers. // Route sleeps through global `setTimeout` so tests can advance time deterministically. vi.mock("./backoff.js", () => ({ - sleepWithAbort: async (ms: number) => { + sleepWithAbort: async (ms: number, signal?: AbortSignal) => { + if (signal?.aborted) { + throw new Error("aborted"); + } if (ms <= 0) { return; } - await new Promise((resolve) => setTimeout(resolve, ms)); + await new Promise((resolve, reject) => { + const timer = setTimeout(() => { + signal?.removeEventListener("abort", onAbort); + resolve(); + }, ms); + const onAbort = () => { + clearTimeout(timer); + signal?.removeEventListener("abort", onAbort); + reject(new Error("aborted")); + }; + signal?.addEventListener("abort", onAbort, { once: true }); + }); }, })); @@ -81,4 +95,52 @@ describe("waitForTransportReady", () => { }); expect(runtime.error).not.toHaveBeenCalled(); }); + + it("stops polling when aborted during the sleep interval", async () => { + const runtime = createRuntime(); + const controller = new AbortController(); + let attempts = 0; + + const waitPromise = waitForTransportReady({ + label: "test transport", + timeoutMs: 500, + pollIntervalMs: 50, + runtime, + abortSignal: controller.signal, + check: async () => { + attempts += 1; + setTimeout(() => controller.abort(), 10); + return { ok: false, error: "still down" }; + }, + }); + + await vi.advanceTimersByTimeAsync(100); + await waitPromise; + + expect(attempts).toBe(1); + expect(runtime.error).not.toHaveBeenCalled(); + }); + + it("logs repeated unknown-error retries and the final timeout message", async () => { + const runtime = createRuntime(); + const waitPromise = waitForTransportReady({ + label: "test transport", + timeoutMs: 120, + logAfterMs: 0, + logIntervalMs: 50, + pollIntervalMs: 50, + runtime, + check: async () => ({ ok: false, error: null }), + }); + + const asserted = expect(waitPromise).rejects.toThrow( + "test transport not ready (unknown error)", + ); + await vi.advanceTimersByTimeAsync(200); + await asserted; + + expect(runtime.error).toHaveBeenCalledTimes(2); + expect(runtime.error.mock.calls.at(0)?.[0]).toContain("unknown error"); + expect(runtime.error.mock.calls.at(-1)?.[0]).toContain("not ready after 120ms"); + }); });