From 1b0c71d96363e96409e38ad6047ebc1ae1089dc7 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 23 Sep 2026 19:32:43 +0200 Subject: [PATCH] Bound P8's race so a regression fails by assertion, not a file-wide hang MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without sendOnStream's disposed guard, the queued send never settles (no event or sweep is left to reject it), so a bare assert.rejects(send, ...) would hang the whole file instead of failing this one test. Race the send against a 3s timeout that rejects with a different message, so the mutant is a loud assertion mismatch either way the native layer happens to fail first. Verified by hand: reverted sendOnStream's `if (this.disposed)` guard to `if (false)` locally, rebuilt, and ran P8 alone — it died by assertion in 81ms (a native stream-send error on the already-shut-down connection, still not matching /disposed/i), not a timeout. Restored the guard before committing. Also hand-verified fix 1 the same way: commenting out the `clearTimeout(handshakeTimer)` on CONNECTED reproduces the original handshake-timer eviction, and the new fix-1 test dies by assertion (0 !== 1) rather than a hang. Full Windows pass on Starfire after restoring: 158/158 cultmesh-ts tests and all 5 QUIC interop tests (including the native-connector and late-join lanes), msquic.dll confirmed as the pinned build (4,181,856 bytes, SHA-256 C17C6581...). Co-Authored-By: Claude Sonnet 5 --- .../cultmesh-ts/test/realtime-quic-consumer.test.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/cultmesh-ts/test/realtime-quic-consumer.test.ts b/packages/cultmesh-ts/test/realtime-quic-consumer.test.ts index 97be7891..8a2063fe 100644 --- a/packages/cultmesh-ts/test/realtime-quic-consumer.test.ts +++ b/packages/cultmesh-ts/test/realtime-quic-consumer.test.ts @@ -1053,7 +1053,18 @@ test("P8: a reliable send still queued behind reliableSendTail rejects instead o // ran too. const send = transport.sendFrame(testFrame({ delivery: "reliable-ordered", sequence: 2n })); transport.dispose(); - await assert.rejects(send, /disposed/i); + // Bounded: without the guard, `send` never settles (nothing left to + // reject it), so a bare `assert.rejects(send, ...)` would hang this + // whole file instead of failing this one test by assertion. Racing + // against a timeout that rejects with a different message turns a + // regression into a prompt, loud assertion mismatch. + const bounded = Promise.race([ + send, + new Promise((_, reject) => + setTimeout(() => reject(new Error("P8 guard timed out instead of rejecting")), 3_000), + ), + ]); + await assert.rejects(bounded, /disposed/i); } finally { transport.dispose(); }