test: wait for ledger-wrapped sends in drain assertions

Two consumer tests assumed a send completes synchronously within the
handler turn: the continuation-drain test polled on handler-call count
then immediately asserted on adapter.sent, and the split-brain heal
test drained with bare zero-delay yields. With ledger calls hopping to
worker threads around each send, the reply can land microseconds after
those checks. Poll for the actual sends with a bounded 2s window —
same invariants, scheduling-robust.
This commit is contained in:
kshitijk4poor 2026-08-03 10:48:46 +05:30 committed by kshitij
parent 5b36d64583
commit 5633764733
2 changed files with 11 additions and 4 deletions

View File

@ -120,7 +120,10 @@ async def test_fifo_enqueued_continuation_is_drained_without_new_user_message():
await adapter._process_message_background(event, key)
# The in-band drain hands off to a fresh task (#17758); let it run.
for _ in range(40):
if len(handled) >= 2:
# Wait for the SENDS, not just the handler calls: the delivery
# ledger hops to worker threads around each send, so the handler
# can return while reply-2's send is still in flight.
if len(adapter.sent) >= 2:
break
await asyncio.sleep(0.05)

View File

@ -198,9 +198,13 @@ class TestStaleSessionLockSelfHeal:
# An ordinary message should heal the stale lock, then fall through
# to normal dispatch. User gets a reply instead of a busy ack.
await adapter.handle_message(_make_event("hello"))
# Drain any spawned background tasks.
for _ in range(5):
await asyncio.sleep(0)
# Drain any spawned background tasks. Real sleeps, not bare yields:
# the delivery ledger hops to worker threads around the send, so a
# zero-delay yield loop can finish before the reply lands.
for _ in range(40):
if any("handled:text" in r for r in adapter.sent_responses):
break
await asyncio.sleep(0.05)
assert any("handled:text" in r for r in adapter.sent_responses), (
"stale lock trapped a normal message — split-brain not healed"