Problem
Several tests construct Zeroconf / AsyncZeroconf with InterfaceChoice.Default, which binds the host's real network interfaces and the wildcard 0.0.0.0:5353, and then perform real multicast I/O (announce / probe). When such a test runs in the same process as the registration/probing tests, it intermittently perturbs name-conflict probing and registration timing, producing flaky failures.
Observed once locally as 3 failures in the async_register_service / async_check_service path:
src/zeroconf/_core.py:387: in async_register_service
src/zeroconf/_core.py:388: in async_register_service
src/zeroconf/_core.py:623: in async_check_service
The run's debug output showed multiple live instances sharing the port, e.g.:
Listen socket <socket fd=19 ... 0.0.0.0:5353>, respond sockets [<... 127.0.0.1:5353>]
Sending to (224.0.0.251, 5353) via [socket 20 (('127.0.0.1', 5353))] ...
Reproduce
Intermittent (roughly 1 in 15–20 local runs on macOS):
SKIP_CYTHON=1 poetry run pytest \
tests/test_engine.py tests/test_interface_update.py tests/utils/test_net.py \
tests/test_core.py tests/test_asyncio.py -q
Most runs pass; occasionally 3 tests in the registration/probing path fail. It is not tied to a specific flag or to ordering (the repo does not install pytest-randomly).
Root cause
These tests are not network-isolated. Instances built with InterfaceChoice.Default join real multicast groups and send/receive on :5353, so concurrent instances in one process can answer or race each other's probes:
tests/test_core.py lines ~64, 72, 79, 83, 127, 140 (r.Zeroconf(interfaces=r.InterfaceChoice.Default ...))
tests/test_interface_update.py:216 (AsyncZeroconf(interfaces=InterfaceChoice.Default, ...))
async_check_service (probing for name uniqueness) is the sensitive path: a stray multicast answer or timing slip from another live instance can flip its result.
Suggested fixes (any of)
- Mock
zeroconf._utils.net.ifaddr.get_adapters in these tests so InterfaceChoice.Default resolves to loopback only (no real-interface binding), or
- Run the real-interface tests under the existing
run_isolated fixture (patches _MDNS_PORT to 5454) so they don't share :5353, or
- Bind these instances to an ephemeral/unique port and avoid real multicast where the test only needs socket bookkeeping.
I can put up a PR that isolates the InterfaceChoice.Default tests (mock the adapter enumeration) if that direction is agreeable.
Problem
Several tests construct
Zeroconf/AsyncZeroconfwithInterfaceChoice.Default, which binds the host's real network interfaces and the wildcard0.0.0.0:5353, and then perform real multicast I/O (announce / probe). When such a test runs in the same process as the registration/probing tests, it intermittently perturbs name-conflict probing and registration timing, producing flaky failures.Observed once locally as 3 failures in the
async_register_service/async_check_servicepath:The run's debug output showed multiple live instances sharing the port, e.g.:
Reproduce
Intermittent (roughly 1 in 15–20 local runs on macOS):
Most runs pass; occasionally 3 tests in the registration/probing path fail. It is not tied to a specific flag or to ordering (the repo does not install
pytest-randomly).Root cause
These tests are not network-isolated. Instances built with
InterfaceChoice.Defaultjoin real multicast groups and send/receive on:5353, so concurrent instances in one process can answer or race each other's probes:tests/test_core.pylines ~64, 72, 79, 83, 127, 140 (r.Zeroconf(interfaces=r.InterfaceChoice.Default ...))tests/test_interface_update.py:216(AsyncZeroconf(interfaces=InterfaceChoice.Default, ...))async_check_service(probing for name uniqueness) is the sensitive path: a stray multicast answer or timing slip from another live instance can flip its result.Suggested fixes (any of)
zeroconf._utils.net.ifaddr.get_adaptersin these tests soInterfaceChoice.Defaultresolves to loopback only (no real-interface binding), orrun_isolatedfixture (patches_MDNS_PORTto5454) so they don't share:5353, orI can put up a PR that isolates the
InterfaceChoice.Defaulttests (mock the adapter enumeration) if that direction is agreeable.