Skip to content

Commit aaf120e

Browse files
committed
test: drop pending multicast responses before TOCTOU assertion
`test_service_info_async_request` patches `_is_complete` to False to keep `async_request` looping. With `quick_timing`, the earlier `async_get_service_info` queries leave multicast responses pending in `out_queue` / `out_delay_queue` that snapshot the records as they were *before* `async_update_service` swapped the registry to `new_info`. When those stale answers flush after `_clear_cache` they re-cache `xxxyyy._test1-srvc-type._tcp.local. -> ash-1.local. -> 10.0.1.2` and point `aiosinfo.server` at `ash-1.local.`. The patched loop then keeps asking for an A record nobody answers, so the final state stays on `10.0.1.2`: AssertionError: assert [b'\\n\\x00\\x01\\x02'] == [b'\\n\\x00\\x01\\x03'] Drop the pending entries from both queues before clearing the cache. The already-scheduled `loop.call_at` for each queue fires on the empty deque and is a no-op, so this is deterministic and adds no wall-clock delay.
1 parent dd341a3 commit aaf120e

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

tests/test_asyncio.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,16 @@ async def test_service_info_async_request(quick_timing: None) -> None:
695695
assert aiosinfos[1] is not None
696696
assert aiosinfos[1].addresses == [socket.inet_aton("10.0.1.5")]
697697

698+
# Drop pending multicast responses queued under the original
699+
# `info` / `info2` registrations. Their snapshots predate the
700+
# `async_update_service` swap, so if they flushed after
701+
# `_clear_cache` below they would poison `aiosinfo.server`
702+
# with `ash-1.local.` and the `_is_complete=False` loop would
703+
# then keep asking for an A record nobody answers. The pending
704+
# `loop.call_at` for each queue fires harmlessly on the empty
705+
# deque.
706+
aiozc.zeroconf.out_queue.queue.clear()
707+
aiozc.zeroconf.out_delay_queue.queue.clear()
698708
aiosinfo = AsyncServiceInfo(type_, registration_name)
699709
_clear_cache(aiozc.zeroconf)
700710
# Generating the race condition is almost impossible

0 commit comments

Comments
 (0)