Bound P8's race so a regression fails by assertion, not a file-wide hang

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 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-23 19:32:43 +02:00
commit 1b0c71d963

View file

@ -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();
}