Skip to content

Commit 1bef356

Browse files
committed
fix(test): force the stub server's sockets shut so a stalled request cannot wedge the suite
CI's server `test` job was cancelled at its 15-minute limit having produced only 22 seconds of output. That shape is not slowness — `node --test` buffers each file's TAP until the file finishes and then waits for every file, so one file that never completes looks exactly like this: the others report, and then silence until the job is killed. The file that never completed is the one that asks the stub to accept an upload and never answer it (`mediaStall`, added with the media-upload timeout test). `server.close()` stops accepting connections but *waits* for the ones still open, and that request is deliberately still open — so `stub.close()` never resolved. It passed locally because macOS tears the socket down on the client's `req.destroy()`; on Linux the server-side socket lingers, which is why only CI hung. `closeAllConnections()` before `close()` makes teardown unconditional, so a test may leave a request unanswered — which is the point of `mediaStall` — without the failure mode being an unreadable timeout fifteen minutes later. Verified on Node 22 (CI's version, since the local default is 26): the five stub-heavy CLI files 56/56, and the full suite 1622/1623 — the one failure is a pre-existing git-worktree test that passes twice in isolation and had been starved to a 233-second runtime by local load, not by this change.
1 parent eeb24f8 commit 1bef356

1 file changed

Lines changed: 7 additions & 0 deletions

File tree

server/test/support/stub_wss.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,13 @@ export async function startStubWss(opts: StubWssOpts = {}): Promise<StubWss> {
178178
close: () =>
179179
new Promise<void>((resolve) => {
180180
for (const ws of live) ws.terminate();
181+
// `server.close()` stops accepting but WAITS for connections that are still
182+
// open, and a test may deliberately leave a request unanswered — that is
183+
// exactly what `mediaStall` is for. Without forcing the sockets shut, such
184+
// a test wedges teardown, and because the whole file then never finishes,
185+
// the symptom is a suite that goes silent until CI's job timeout kills it
186+
// rather than a failing assertion anyone can read.
187+
https.closeAllConnections();
181188
wss.close(() => https.close(() => resolve()));
182189
}),
183190
};

0 commit comments

Comments
 (0)