fix(test): guard YAMCS event subscription teardown against websocket race - #515
fix(test): guard YAMCS event subscription teardown against websocket race#515Mikefly123 wants to merge 1 commit into
Conversation
…race
test_noop_round_trip failed intermittently in integration-uart with:
AttributeError: 'NoneType' object has no attribute 'close_frame'
websocket/_app.py:211
The round trip itself was healthy in every failing run (both failures
completed in ~1s, well inside the 180s budget, i.e. the NoOpReceived
event was observed and the test returned). The failure came entirely
from `subscription.cancel()` in the `finally` block.
websocket-client's WebSocketApp.close() has a check-then-use race on
self.sock: it tests the attribute for truthiness, calls self.sock.close()
- which wakes the reader thread, and that thread sets self.sock = None -
then dereferences self.sock again to capture close_frame. The race is
still present in websocket-client 1.9.1, so bumping the dependency does
not fix it.
Swallow and log teardown errors so they cannot replace the test's real
result (a pass, or the AssertionError raised above) with a misleading
traceback.
Closes #514
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WBD3NFb2h8TxkuxrfSRyhS
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughSummary by CodeRabbit
WalkthroughThe YAMCS noop test now logs exceptions from subscription cancellation during teardown. This prevents cancellation errors from replacing the test result. ChangesYAMCS teardown handling
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This change prevents a websocket teardown race from masking the completed integration-test result without affecting production behavior. No actionable merge-blocking risk remains after normal checks and review. Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Full details: Description checkExplanation The description is detailed and directly explains the issue, root cause, correction, evidence, and scope. It references issue ✨ Finishing Touches📝 Generate docstrings
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 |
Fixes the recurring
integration-uartfailure tracked in #514.Root cause
The round-trip test was passing and then failing in teardown. In both failing runs the whole test completed in about a second (
1 failed in 0.97s,1 failed in 1.03s) — far inside the 180 s budget — meaning theNoOpReceivedevent was observed and the test returned normally. The only exception came fromsubscription.cancel()in thefinallyblock:WebSocketApp.close()has a check-then-use race onself.sock:The race is still present in
websocket-client1.9.1, so bumping the dependency does not help.Corrections to the analysis in #514
create_event_subscriptionblocks onsubscription.reply(timeout=60), so a failed handshake raises at subscription time rather than yielding a silently empty queue. No readiness check is needed.AssertionErrorwas the real failure, masked by teardown" — inverted. TheAssertionErrorwas never raised; pytest was only echoing the test's source in the traceback context. Teardown was the sole failure.yamcs-client1.12.1" — wrong layer, and the bug is unpatched upstream anyway.Only the "guard the teardown" suggestion from the issue holds, and it is the complete fix.
Change
Wrap
subscription.cancel()in try/except and log at warning level, so a teardown error can never replace the test's real result.Evidence
Attempt-1 logs of runs 33270707473 and 33325337362: identical traceback, both sub-second, both raised through
finally: subscription.cancel().Out of scope
mainhas been red onintegration-uartsince the F Prime 4.3.0 upgrade, but that failure occurs at the UART pytest step, before YAMCS starts — a different signature, not addressed here.🤖 Generated with Claude Code
https://claude.ai/code/session_01WBD3NFb2h8TxkuxrfSRyhS