fix(test): keep readiness probes within the startup deadline (#150559)

This commit is contained in:
Peter Steinberger 2026-09-16 21:08:27 -07:00 • committed by GitHub
parent 1adc86b88c
commit 5d3a73dd4b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 71 additions and 2 deletions

View file

@ -331,9 +331,12 @@ async function waitForGatewayReady(
throw exitedBeforeReadinessError();
}
const remainingMs = timeoutMs - (Date.now() - startedAt);
const attemptTimeoutMs = Math.min(1_000, Math.max(1, remainingMs));
const attemptStartedAt = Date.now();
const remainingMs = timeoutMs - (attemptStartedAt - startedAt);
if (remainingMs <= 0) {
break;
}
const attemptTimeoutMs = Math.min(1_000, Math.max(1, remainingMs));
const probe: ReadinessProbe = { attempt: ++attempts, phase: "headers", elapsedMs: 0 };
const probeAbort = new AbortController();
const abortProbe = () => probeAbort.abort(signal?.reason);

View file

@ -115,6 +115,72 @@ describe("desktop readiness evidence", () => {
expect(failure.errors[1]).toBe(cleanup);
});
it("keeps the probe deadline within the startup budget as the clock advances", async () => {
const diagnostics: GatewayReadinessDiagnostic[] = [];
const fetchImpl = vi
.fn<typeof fetch>()
.mockResolvedValue(new Response('{"ready":true,"failing":[]}', { status: 200 }));
let now = 1_000;
const clock = vi.spyOn(Date, "now").mockImplementation(() => now++);
try {
await testing.waitForGatewayReady(
processState(),
[],
[],
12345,
25,
fetchImpl,
undefined,
(entry) => diagnostics.push(entry),
);
} finally {
clock.mockRestore();
}
const artifact = await publicArtifact(diagnostics);
const entries = artifact.files[0]!.assertions[0]!.gatewayReadiness!;
expect(entries).toHaveLength(1);
const entry = entries[0]!;
expect(entry).toMatchObject({ outcome: "ready", attempts: 1 });
expect(entry.deadlineMs - entry.startedAtMs).toBe(25);
expect(entry.probes[0]!.deadlineMs).toBe(entry.deadlineMs);
});
it("does not start a probe when the startup budget expires before admission", async () => {
const diagnostics: GatewayReadinessDiagnostic[] = [];
const fetchImpl = vi
.fn<typeof fetch>()
.mockResolvedValue(new Response('{"ready":true,"failing":[]}', { status: 200 }));
const clock = vi
.spyOn(Date, "now")
.mockReturnValueOnce(1_000)
.mockReturnValueOnce(1_024)
.mockReturnValue(1_026);
let failure: unknown;
try {
failure = await testing
.waitForGatewayReady(processState(), [], [], 12345, 25, fetchImpl, undefined, (entry) =>
diagnostics.push(entry),
)
.catch((error: unknown) => error);
} finally {
clock.mockRestore();
}
expect(fetchImpl).not.toHaveBeenCalled();
expect(failure).toBeInstanceOf(Error);
expect(String(failure)).toContain("timeout waiting for gateway readiness");
const artifact = await publicArtifact(diagnostics, failure);
const entries = artifact.files[0]!.assertions[0]!.gatewayReadiness!;
expect(entries).toHaveLength(1);
expect(entries[0]).toMatchObject({
outcome: "timeout",
startedAtMs: 1_000,
deadlineMs: 1_025,
attempts: 0,
probes: [],
omittedProbes: 0,
});
});
it("records every completed probe and one success timing line", async () => {
const diagnostics: GatewayReadinessDiagnostic[] = [];
const fetchImpl = vi