test(device): a raw-capture test was failing on CI for a reason that had nothing to do with the PR under review - #517
Conversation
The hammer sent for as long as the raw capture held the device, then the test waited for HAMMER-0 to reach the wire. But the deferred-send backlog is capped at 1024 and overflows drop-OLDEST, so once the hammer parked more than the cap HAMMER-0 was the first thing evicted — and the test failed with "HAMMER-0 never reached the wire". That only happened when the capture window ran long, which is why it passed locally (~130 ms) and reddened unrelated PRs on loaded runners (6-12 s), twice in a row on #515. The hammer now fires a fixed budget derived from the cap itself (DefaultMaxDeferredSends / 8), so nothing can be evicted however long the window stays open, and the capture holds the stream until the hammer is done, so every one of those sends is issued inside the window by construction rather than by timing. DroppedDeferredSendCount == 0 is asserted alongside, so if the budget and the cap ever drift apart the test says so instead of failing on HAMMER-0. Verified by mutation: serving the payload one byte at a time (a ~10 s window, the loaded-runner shape) fails the old test with the exact CI message and passes the new one 3/3; capping the backlog at 16 trips the new dropped-count assertion; disabling TryDeferSend still fails the test, now catching all 128 sends rather than a timing-dependent subset. closes #516 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
/agentic_review |
PR Summary by QodoFix RawCapture send-hammer CI flake by budgeting deferred sends
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewTip of the day💡 Did you know, you can type 'qodo, fix this' on a finding and the fix lands right on your PR |
|
Qodo-clean, CI green — ready for review. (1 round on head |
What was wrong. One of the raw-capture tests (
RawCapture_UnderASendHammer_...) would go red on GitHub Actions on pull requests that had not touched any of the code it covers — it failed twice in a row on #515, a branch that only changes Windows discovery. The test fires a stream ofSend()calls at a device while a raw capture holds it, then checks that the very first of those messages (HAMMER-0) was parked and replayed rather than thrown away. ButSend()'s hold-back backlog is capped, and when it overflows it discards its oldest entry — soHAMMER-0is by definition the first casualty. The hammer ran for as long as the capture window stayed open, so on a fast machine it parked a couple of hundred messages and passed, and on a loaded CI runner it parked thousands, evicted the message the test was waiting for, and failed. Nothing was wrong with the library; the test was asserting something the design does not promise.How it was fixed. The hammer now sends a fixed number of messages instead of running until told to stop, and that number is derived from the backlog cap (
DefaultMaxDeferredSends / 8) rather than picked by hand, so the two cannot drift apart silently. To keep the test as strong as it was, the capture now holds the stream until the hammer has finished, which makes "every one of those sends happened while the capture owned the device" true by construction rather than by hoping the window outlasts the sender. ADroppedDeferredSendCount == 0assertion sits next to the original wait, so if anyone does raise the budget past the cap the failure says "112 messages were dropped" instead of the misleading "HAMMER-0 never reached the wire". No production code changed.The one thing worth pushing back on: the capture task now waits on the hammer, which is a dependency the old version did not have. It is signalled from a
finally, so a hammer that throws surfaces as its own failure rather than hanging the capture.Verified. Simulating a loaded runner by serving the capture payload one byte at a time (a ~10 s window) reproduces the CI failure on the old test with the exact same message, and the new test passes 3/3 under those same conditions. Two more mutations confirm the assertions are real catchers: shrinking the backlog cap to 16 trips the new dropped-count assertion, and disabling send deferral entirely still fails the test — now catching all 128 sends instead of a timing-dependent subset. Full suite green on net9.0 (3045 Core + 86 Mcp) and net10.0 (3045), 0 warnings. Bench health check on the Nq1 (fw 3.7.2,
/dev/cu.usbmodem1101), non-destructive: discovery, 3 s @ 500 Hz on channels 0-2 → 1186 samples (this unit's usual ratio), SD storage 7.80 GB, clean disconnect — unchanged, as expected for a test-only change.closes #516
Not merging — opened for your review.