Repository navigation
Stop PumpUntil waits from destroying evidence later assertions need (#64) - #66
Merged
Merged
Conversation
…rtion needs
InteractiveAcceptGatesBothConnectionPackets is commented as "the load-bearing
assertion" -- neither peer may report a connection until the server answers
the session request -- but it could not detect that violation at all.
PumpUntil() deallocates every packet that is not the id it waits for, on the
waited-on peer as well as on alsoPump. The test's first action waits for
ID_SESSION_CONFIG_REQUEST on the server, so a connection packet produced
early is drained and freed there, before the negative assertion that looks
for it ever runs. Proved with a library mutant that reports the connection
instead of withholding it: the test passed 10/10, while the probe showed
PumpUntil(want=128) discarding id=19 from the waited-on peer.
The test also built its two negative assertions out of successive SawWithin()
probes, which swallow each other's evidence -- the hazard CollectIds()'s own
comment forbids.
Fixes both:
- PumpUntil() takes optional ledgers recording the ids it drains and discards,
from the waited-on peer and from alsoPump. Default-null, so no existing
call site changes.
- CollectIdsBoth() drains two peers in one loop, appending, so a paired
negative assertion cannot pass because the other probe consumed its packet.
- The gating test carries both ledgers across the wait and asserts over them.
An audit of the suite found exactly 2 at-risk negative assertions, both in
this test; every other one already uses the collect-once pattern.
Verified on macOS arm64. Against the withholding mutant the test now fails
5/5 deterministically in ~630 ms naming the side ("server reported a
connection before answering the session request"), where it previously passed
10/10. The payload-storing mutant is still caught. Clean library:
SessionConfigLive.* x10 green, full ctest 276/276.
Refs #64
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 30 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Partial fix for #64. Resolves the part that turned out to be an actually-blind test; the remaining static-mode item is called out below and left open.
The finding
InteractiveAcceptGatesBothConnectionPacketsis commented as "The load-bearing assertion" — neither peer may report a connection until the server answers the session request. It could not detect that violation at all.PumpUntil()deallocates every packet that is not the id it waits for — on the waited-on peer, not just onalsoPump:The test's first action waits for
ID_SESSION_CONFIG_REQUESTon the server. A connection packet produced early is drained and freed right there, before the negative assertion that looks for it ever runs.Proved with a library mutant that reports the connection instead of withholding it:
128=ID_SESSION_CONFIG_REQUEST,19=ID_NEW_INCOMING_CONNECTION. The gating contract was broken and the test said nothing, 10/10 runs.Second defect in the same test: its two negative assertions were successive
SawWithin()probes, which swallow each other's evidence — exactly the hazardCollectIds()'s own comment forbids.Fix
PumpUntil()takes two optional ledgers recording the ids it drains and discards, from the waited-on peer and fromalsoPump. Default-null, so none of the other call sites change.CollectIdsBoth()drains two peers in one loop, appending, so a paired negative assertion can't pass because the other probe ate its packet.No library change.
Scope
An audit found exactly 2 at-risk negative assertions, both in this one test; every other negative assertion in the suite already uses the collect-once pattern. So the helper hazard is real but the damage was contained — narrower than #64 implies, and I've noted that on the issue.
Verification (macOS arm64)
SessionConfigLive.*×10, clean libraryctestThe new failure message is specific:
server reported a connection before answering the session request.Still open on #64
A static-mode gating assertion. Static mode answers the session request the moment it arrives, so there is no window in which loopback can observe withholding — it needs control over message arrival order, i.e. the hermetic two-layer fake-socket harness per CLAUDE.md. Out of scope here; #64 stays open for it. Note the property is now covered deterministically by a test whose stated purpose is gating, rather than incidentally by two tests about rejection and client departure.