Fix CancelOnLossSend test race by arming loss helper before send#6079
Open
guhetier wants to merge 3 commits into
Open
Fix CancelOnLossSend test race by arming loss helper before send#6079guhetier wants to merge 3 commits into
guhetier wants to merge 3 commits into
Conversation
The Misc/WithCancelOnLossArgs.CancelOnLossSend/1 test was racy: it called LossHelper.DropPackets(1) AFTER MsQuicStream::Send(QUIC_SEND_FLAG_CANCEL_ON_LOSS) had already queued the data to the worker thread. On a fast loopback datapath (e.g. UseXdp + UseQtip), the worker can transmit the stream data and the server can dispatch QUIC_STREAM_EVENT_RECEIVE before the test thread arms the drop. The test then observes SuccessExitCode (42) instead of the expected ErrorExitCode (24) coming from QUIC_STREAM_EVENT_CANCEL_ON_LOSS. Arm the loss helper before Send so the next packet on the server receive path (the stream data) is the one dropped, which triggers loss detection on the client and fires CANCEL_ON_LOSS as intended. Fixes #6065 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6079 +/- ##
==========================================
+ Coverage 85.32% 85.62% +0.29%
==========================================
Files 60 60
Lines 18798 18841 +43
==========================================
+ Hits 16040 16132 +92
+ Misses 2758 2709 -49 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
guhetier
commented
Jun 9, 2026
There was a problem hiding this comment.
Pull request overview
This PR fixes a race in the Misc/WithCancelOnLossArgs.CancelOnLossSend/1 test by ensuring the selective packet-drop hook is armed before calling MsQuicStream::Send(..., QUIC_SEND_FLAG_CANCEL_ON_LOSS), so the stream data packet is reliably the one dropped on fast loopback datapaths.
Changes:
- Move
LossHelper.DropPackets(1)to occur beforeSend(...)in theDropPackets: truevariant to eliminate a timing window. - Expand the in-test comment explaining why arming after
Sendis racy.
mtfriesen
reviewed
Jun 10, 2026
mtfriesen
previously approved these changes
Jun 10, 2026
guhetier
commented
Jun 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The
Misc/WithCancelOnLossArgs.CancelOnLossSend/1test (theDropPackets: truevariant) was racy. It armed the loss helper after callingMsQuicStream::Send(QUIC_SEND_FLAG_CANCEL_ON_LOSS):Sendis asynchronous: it queues the data to an MsQuic worker thread. On a fast loopback datapath (this manifested in theUseXdp + UseQtipBVT configuration), the worker can transmit the stream data and the server can dispatchQUIC_STREAM_EVENT_RECEIVEbefore the test thread executesDropPackets(1). The server callback then setsExitCode = SuccessExitCode (42)and signalsSendPhaseEndedEvent; the main test thread wakes and asserts42 != ErrorExitCode (24).Trace from the failing run (
quic.loglines, same TID 2784.2064):22:28:27.381556QUIC_STREAM_EVENT_RECEIVE [23 bytes](server)22:28:27.407382[test][hook] Selective packet drop(26 ms too late)22:28:27.468536QUIC_STREAM_EVENT_PEER_SEND_ABORTED (0x18)(server)The fix moves the
DropPackets(1)call to beforeSend, so the very next packet hitting the server receive path (the stream data) is the one dropped. This causes the client to detect loss and fireQUIC_STREAM_EVENT_CANCEL_ON_LOSSas intended, which in turn deliversPEER_SEND_ABORTEDto the server withErrorExitCode.Fixes #6065
Testing
Existing test
Misc/WithCancelOnLossArgs.CancelOnLossSend/*covers this change. Ran the parameterized test 20 times locally with the Debug + schannel build — 20/20 passed (previously intermittent in CI).Documentation
No documentation impact.