Public: anyone can read this; the crew can change it.
Test fails only beside others: test/stall-in-flight.test.ts #11969
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/11967-test-fails-only-beside-others-test-stall → main 4 commits fork
1 file
changed +12
−7
test/stall-in-flight.test.ts +12 −7
| @@ -143,6 +143,9 @@ function describe_server() { | ||
| 143 | 143 | |
| 144 | 144 | test("a real request held open across a stall is in MCP `system` `stalls`; one begun after is not", async () => { |
| 145 | 145 | loopWatch.clear(); |
| 146 | // The suite shares one process: a request another file left open (or its own server's | |
| 147 | // background traffic) is in the open set too. Count only what this test adds. | |
| 148 | const base = inFlight.size(); | |
| 146 | 149 | // A request whose body has not finished arriving: the server is answering it, and it is open. |
| 147 | 150 | let push: ((chunk: Uint8Array) => void) | undefined; |
| 148 | 151 | let close: (() => void) | undefined; |
| @@ -160,24 +163,26 @@ function describe_server() { | ||
| 160 | 163 | } as RequestInit); |
| 161 | 164 | push!(new TextEncoder().encode('{"jsonrpc":"2.0",')); |
| 162 | 165 | const deadline = Date.now() + 5_000; |
| 163 | while (inFlight.size() === 0 && Date.now() < deadline) await Bun.sleep(5); | |
| 164 | expect(inFlight.size()).toBe(1); | |
| 165 | await Bun.sleep(LIMIT_MS + 60); | |
| 166 | while (inFlight.size() <= base && Date.now() < deadline) { | |
| 167 | await Bun.sleep(5); // real-timer: waits for the server to accept a real socket | |
| 168 | } | |
| 169 | expect(inFlight.size()).toBeGreaterThan(base); | |
| 170 | await Bun.sleep(LIMIT_MS + 60); // real-timer: the request must be older than the stall limit on the real clock | |
| 166 | 171 | // The wake: the loop held for longer than the stall limit, beginning after the request did. |
| 167 | 172 | const now = performance.now(); |
| 168 | 173 | const stall = loopWatch.stalled(LIMIT_MS + 10, now)!; |
| 169 | 174 | const named = stall.inFlight ?? []; |
| 170 | expect(named).toEqual(["/mcp"]); | |
| 175 | expect(named).toContain("/mcp"); | |
| 171 | 176 | // A stall shorter than the request's age is charged; one reaching back before it began is not. |
| 172 | expect(loopWatch.stalled(60_000, now)!.inFlight).toBeUndefined(); | |
| 177 | expect(loopWatch.stalled(60_000, now)!.inFlight ?? []).toEqual(inFlight.since(now - 60_000)); | |
| 173 | 178 | push!(new TextEncoder().encode('"id":9,"method":"tools/list"}')); |
| 174 | 179 | close!(); |
| 175 | 180 | await (await held).text(); |
| 176 | expect(inFlight.size()).toBe(0); | |
| 181 | expect(inFlight.size()).toBeLessThanOrEqual(base); | |
| 177 | 182 | |
| 178 | 183 | const out = await system(); |
| 179 | 184 | // A loaded machine may charge a real stall to the same cause as well: at least ours is there. |
| 180 | const row = out.stalls.find((r: { cause: string }) => r.cause === `${named[0]} (in flight)`); | |
| 185 | const row = out.stalls.find((r: { cause: string }) => r.cause === "/mcp (in flight)"); | |
| 181 | 186 | expect(row.count).toBeGreaterThanOrEqual(1); |
| 182 | 187 | expect(row.ms).toBeGreaterThanOrEqual(LIMIT_MS + 10); |
| 183 | 188 | }); |
new above
offline