Skip to content

Commit 36f20b0

Browse files
committed
test: speed up slow loopback tests via quick_timing fixture and shorter timeouts
Cuts ~28s from the top-20 durations sum (was 70s, now 42s) without changing what the tests assert. - Add quick_timing fixture (introduced for the same purpose in conftest) to register/announce-heavy tests in test_asyncio.py, test_services.py, test_handlers.py, and test_init.py. The fixture shortens _CHECK_TIME/_REGISTER_TIME/_UNREGISTER_TIME to 10ms on loopback so the probe/announce/goodbye cycle no longer pays the RFC 6762 production budget. - Drop ZeroconfServiceTypes.find timeouts from 2s to 0.5s in test_types.py and test_async_zeroconf_service_types — find() sleeps the full timeout, and on loopback the response arrives in milliseconds. - Tighten the explicit TOCTOU wait in test_service_info_async_request from 3000ms to 500ms; _is_complete=False forces the request to run out the full timeout regardless. - Cut the 'allow multicast timers to expire' sleep in test_integration_with_listener_class from 3s to 0.5s now that quick_timing makes the preceding broadcasts settle in <100ms. - Shorten the duplicate-update negative-assertion wait in TestServiceBrowser.test_update_record from wait_time=3 to 0.3s — the listener is asserted NOT to fire, so the wait always times out.
1 parent dfa4e00 commit 36f20b0

6 files changed

Lines changed: 27 additions & 19 deletions

File tree

tests/services/test_browser.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,9 @@ def mock_record_update_incoming_msg(
331331
service_updated_event.clear()
332332
service_text = b"path=/~matt2/"
333333
_inject_response(zeroconf, mock_record_update_incoming_msg(r.ServiceStateChange.Updated))
334-
service_updated_event.wait(wait_time)
334+
# Negative assertion: a duplicate update must NOT fire the listener. The wait
335+
# always times out, so keep the budget short rather than reusing wait_time.
336+
service_updated_event.wait(0.3)
335337
assert service_added_count == 1
336338
assert service_updated_count == 2
337339
assert service_removed_count == 0

tests/services/test_types.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ def test_integration_with_listener(disable_duplicate_packet_suppression):
4747
)
4848
zeroconf_registrar.registry.async_add(info)
4949
try:
50-
service_types = ZeroconfServiceTypes.find(interfaces=["127.0.0.1"], timeout=2)
50+
service_types = ZeroconfServiceTypes.find(interfaces=["127.0.0.1"], timeout=0.5)
5151
assert type_ in service_types
5252
_clear_cache(zeroconf_registrar)
53-
service_types = ZeroconfServiceTypes.find(zc=zeroconf_registrar, timeout=2)
53+
service_types = ZeroconfServiceTypes.find(zc=zeroconf_registrar, timeout=0.5)
5454
assert type_ in service_types
5555

5656
finally:
@@ -79,10 +79,10 @@ def test_integration_with_listener_v6_records(disable_duplicate_packet_suppressi
7979
)
8080
zeroconf_registrar.registry.async_add(info)
8181
try:
82-
service_types = ZeroconfServiceTypes.find(interfaces=["127.0.0.1"], timeout=2)
82+
service_types = ZeroconfServiceTypes.find(interfaces=["127.0.0.1"], timeout=0.5)
8383
assert type_ in service_types
8484
_clear_cache(zeroconf_registrar)
85-
service_types = ZeroconfServiceTypes.find(zc=zeroconf_registrar, timeout=2)
85+
service_types = ZeroconfServiceTypes.find(zc=zeroconf_registrar, timeout=0.5)
8686
assert type_ in service_types
8787

8888
finally:
@@ -115,10 +115,10 @@ def test_integration_with_listener_ipv6(disable_duplicate_packet_suppression):
115115
)
116116
zeroconf_registrar.registry.async_add(info)
117117
try:
118-
service_types = ZeroconfServiceTypes.find(ip_version=r.IPVersion.V6Only, timeout=2)
118+
service_types = ZeroconfServiceTypes.find(ip_version=r.IPVersion.V6Only, timeout=0.5)
119119
assert type_ in service_types
120120
_clear_cache(zeroconf_registrar)
121-
service_types = ZeroconfServiceTypes.find(zc=zeroconf_registrar, timeout=2)
121+
service_types = ZeroconfServiceTypes.find(zc=zeroconf_registrar, timeout=0.5)
122122
assert type_ in service_types
123123

124124
finally:
@@ -147,10 +147,10 @@ def test_integration_with_subtype_and_listener(disable_duplicate_packet_suppress
147147
)
148148
zeroconf_registrar.registry.async_add(info)
149149
try:
150-
service_types = ZeroconfServiceTypes.find(interfaces=["127.0.0.1"], timeout=2)
150+
service_types = ZeroconfServiceTypes.find(interfaces=["127.0.0.1"], timeout=0.5)
151151
assert discovery_type in service_types
152152
_clear_cache(zeroconf_registrar)
153-
service_types = ZeroconfServiceTypes.find(zc=zeroconf_registrar, timeout=2)
153+
service_types = ZeroconfServiceTypes.find(zc=zeroconf_registrar, timeout=0.5)
154154
assert discovery_type in service_types
155155

156156
finally:

tests/test_asyncio.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def sync_code():
126126

127127

128128
@pytest.mark.asyncio
129-
async def test_async_service_registration() -> None:
129+
async def test_async_service_registration(quick_timing: None) -> None:
130130
"""Test registering services broadcasts the registration by default."""
131131
aiozc = AsyncZeroconf(interfaces=["127.0.0.1"])
132132
type_ = "_test1-srvc-type._tcp.local."
@@ -193,7 +193,7 @@ def update_service(self, zeroconf: Zeroconf, type: str, name: str) -> None:
193193

194194

195195
@pytest.mark.asyncio
196-
async def test_async_service_registration_with_server_missing() -> None:
196+
async def test_async_service_registration_with_server_missing(quick_timing: None) -> None:
197197
"""Test registering a service with the server not specified.
198198
199199
For backwards compatibility, the server should be set to the
@@ -394,7 +394,7 @@ def update_service(self, zeroconf: Zeroconf, type: str, name: str) -> None:
394394

395395

396396
@pytest.mark.asyncio
397-
async def test_async_service_registration_name_conflict() -> None:
397+
async def test_async_service_registration_name_conflict(quick_timing: None) -> None:
398398
"""Test registering services throws on name conflict."""
399399
aiozc = AsyncZeroconf(interfaces=["127.0.0.1"])
400400
type_ = "_test-srvc2-type._tcp.local."
@@ -503,7 +503,7 @@ async def test_async_service_registration_name_strict_check(quick_timing: None)
503503

504504

505505
@pytest.mark.asyncio
506-
async def test_async_tasks() -> None:
506+
async def test_async_tasks(quick_timing: None) -> None:
507507
"""Test awaiting broadcast tasks"""
508508

509509
aiozc = AsyncZeroconf(interfaces=["127.0.0.1"])
@@ -605,7 +605,7 @@ async def test_async_wait_unblocks_on_update() -> None:
605605

606606

607607
@pytest.mark.asyncio
608-
async def test_service_info_async_request() -> None:
608+
async def test_service_info_async_request(quick_timing: None) -> None:
609609
"""Test registering services broadcasts and query with AsyncServceInfo.async_request."""
610610
if not has_working_ipv6() or os.environ.get("SKIP_IPV6"):
611611
pytest.skip("Requires IPv6")
@@ -700,7 +700,7 @@ async def test_service_info_async_request() -> None:
700700
# Generating the race condition is almost impossible
701701
# without patching since its a TOCTOU race
702702
with patch("zeroconf.asyncio.AsyncServiceInfo._is_complete", False):
703-
await aiosinfo.async_request(aiozc.zeroconf, 3000)
703+
await aiosinfo.async_request(aiozc.zeroconf, 500)
704704
assert aiosinfo is not None
705705
assert aiosinfo.addresses == [socket.inet_aton("10.0.1.3")]
706706

@@ -714,7 +714,7 @@ async def test_service_info_async_request() -> None:
714714

715715

716716
@pytest.mark.asyncio
717-
async def test_async_service_browser() -> None:
717+
async def test_async_service_browser(quick_timing: None) -> None:
718718
"""Test AsyncServiceBrowser."""
719719
aiozc = AsyncZeroconf(interfaces=["127.0.0.1"])
720720
type_ = "_test9-srvc-type._tcp.local."
@@ -906,10 +906,10 @@ async def test_async_zeroconf_service_types(quick_timing: None) -> None:
906906
await asyncio.sleep(0.2)
907907
_clear_cache(zeroconf_registrar.zeroconf)
908908
try:
909-
service_types = await AsyncZeroconfServiceTypes.async_find(interfaces=["127.0.0.1"], timeout=2)
909+
service_types = await AsyncZeroconfServiceTypes.async_find(interfaces=["127.0.0.1"], timeout=0.5)
910910
assert type_ in service_types
911911
_clear_cache(zeroconf_registrar.zeroconf)
912-
service_types = await AsyncZeroconfServiceTypes.async_find(aiozc=zeroconf_registrar, timeout=2)
912+
service_types = await AsyncZeroconfServiceTypes.async_find(aiozc=zeroconf_registrar, timeout=0.5)
913913
assert type_ in service_types
914914

915915
finally:

tests/test_handlers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ def _process_outgoing_packet(out):
160160
nbr_answers = nbr_additionals = nbr_authorities = 0
161161
zc.close()
162162

163+
@pytest.mark.usefixtures("quick_timing")
163164
def test_name_conflicts(self):
164165
# instantiate a zeroconf instance
165166
zc = Zeroconf(interfaces=["127.0.0.1"])
@@ -189,6 +190,7 @@ def test_name_conflicts(self):
189190
zc.register_service(conflicting_info)
190191
zc.close()
191192

193+
@pytest.mark.usefixtures("quick_timing")
192194
def test_register_and_lookup_type_by_uppercase_name(self):
193195
# instantiate a zeroconf instance
194196
zc = Zeroconf(interfaces=["127.0.0.1"])

tests/test_init.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import unittest.mock
99
from unittest.mock import patch
1010

11+
import pytest
12+
1113
import zeroconf as r
1214
from zeroconf import ServiceInfo, Zeroconf, const
1315

@@ -68,6 +70,7 @@ def test_same_name(self):
6870
generated.add_question(question)
6971
r.DNSIncoming(generated.packets()[0])
7072

73+
@pytest.mark.usefixtures("quick_timing")
7174
def test_verify_name_change_with_lots_of_names(self):
7275
# instantiate a zeroconf instance
7376
zc = Zeroconf(interfaces=["127.0.0.1"])

tests/test_services.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def teardown_module():
3434

3535

3636
class ListenerTest(unittest.TestCase):
37+
@pytest.mark.usefixtures("quick_timing")
3738
def test_integration_with_listener_class(self):
3839
sub_service_added = Event()
3940
service_added = Event()
@@ -113,7 +114,7 @@ def update_service(self, zeroconf, type, name):
113114
assert service_added.is_set()
114115

115116
# short pause to allow multicast timers to expire
116-
time.sleep(3)
117+
time.sleep(0.5)
117118

118119
zeroconf_browser.add_service_listener(type_, DuplicateListener())
119120
duplicate_service_added.wait(

0 commit comments

Comments
 (0)