FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

chore: adopt the zc fixture across the remaining simple tests (#1876) · python-zeroconf/python-zeroconf@9ddeffb · GitHub

Repository navigation

Commit 9ddeffb

Browse files
authored
chore: adopt the zc fixture across the remaining simple tests (#1876)
1 parent a1a61e9 commit 9ddeffb

5 files changed

Lines changed: 32 additions & 105 deletions

File tree

‎tests/conftest.py‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,15 @@ def verify_threads_ended():
105105

106106

107107
@pytest.fixture
108-
def zc() -> Generator[Zeroconf]:
108+
def zc(verify_threads_ended: None) -> Generator[Zeroconf]:
109109
"""Yield a loopback `Zeroconf` and close it on teardown.
110110
111111
Replaces the inline `zc = Zeroconf(interfaces=["127.0.0.1"])` +
112112
explicit `zc.close()` pattern duplicated across the suite. Calling
113113
`zc.close()` inside a test is still safe — `close()` is idempotent.
114+
115+
Depends on `verify_threads_ended` so the instance is torn down before
116+
the thread check runs.
114117
"""
115118
zc = Zeroconf(interfaces=["127.0.0.1"])
116119
try:
@@ -120,7 +123,7 @@ def zc() -> Generator[Zeroconf]:
120123

121124

122125
@pytest_asyncio.fixture
123-
async def aiozc() -> AsyncGenerator[AsyncZeroconf]:
126+
async def aiozc(verify_threads_ended: None) -> AsyncGenerator[AsyncZeroconf]:
124127
"""Yield a loopback `AsyncZeroconf` and close it on teardown.
125128
126129
Replaces the inline `aiozc = AsyncZeroconf(interfaces=["127.0.0.1"])`

‎tests/services/test_browser.py‎

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,10 @@ def teardown_module():
5454
log.setLevel(original_logging_level)
5555

5656

57-
def test_service_browser_cancel_multiple_times():
57+
def test_service_browser_cancel_multiple_times(zc: Zeroconf) -> None:
5858
"""Test we can cancel a ServiceBrowser multiple times before close."""
5959

6060
# instantiate a zeroconf instance
61-
zc = Zeroconf(interfaces=["127.0.0.1"])
6261
# start a browser
6362
type_ = "_hap._tcp.local."
6463

@@ -73,14 +72,11 @@ class MyServiceListener(r.ServiceListener):
7372
browser.cancel()
7473
browser.cancel()
7574

76-
zc.close()
77-
7875

79-
def test_service_browser_cancel_context_manager():
76+
def test_service_browser_cancel_context_manager(zc: Zeroconf) -> None:
8077
"""Test we can cancel a ServiceBrowser with it being used as a context manager."""
8178

8279
# instantiate a zeroconf instance
83-
zc = Zeroconf(interfaces=["127.0.0.1"])
8480
# start a browser
8581
type_ = "_hap._tcp.local."
8682

@@ -102,8 +98,6 @@ class MyServiceListener(r.ServiceListener):
10298

10399
assert cast(bool, browser.done) is True
104100

105-
zc.close()
106-
107101

108102
def test_service_browser_cancel_multiple_times_after_close():
109103
"""Test we can cancel a ServiceBrowser multiple times after close."""
@@ -834,12 +828,10 @@ def on_service_state_change(zeroconf, service_type, state_change, name):
834828
await aiozc.async_close()
835829

836830

837-
def test_legacy_record_update_listener(quick_timing: None) -> None:
831+
def test_legacy_record_update_listener(zc: Zeroconf, quick_timing: None) -> None:
838832
"""Test a RecordUpdateListener that does not implement update_records."""
839833

840834
# instantiate a zeroconf instance
841-
zc = Zeroconf(interfaces=["127.0.0.1"])
842-
843835
with pytest.raises(RuntimeError):
844836
r.RecordUpdateListener().update_record(
845837
zc,
@@ -892,14 +884,11 @@ def on_service_state_change(zeroconf, service_type, state_change, name):
892884
# Removing a second time should not throw
893885
zc.remove_listener(listener)
894886

895-
zc.close()
896-
897887

898-
def test_service_browser_is_aware_of_port_changes():
888+
def test_service_browser_is_aware_of_port_changes(zc: Zeroconf) -> None:
899889
"""Test that the ServiceBrowser is aware of port changes."""
900890

901891
# instantiate a zeroconf instance
902-
zc = Zeroconf(interfaces=["127.0.0.1"])
903892
# start a browser
904893
type_ = "_hap._tcp.local."
905894
registration_name = f"xxxyyy.{type_}"
@@ -955,14 +944,11 @@ def on_service_state_change(zeroconf, service_type, state_change, name):
955944
assert service_info.port == 400
956945
browser.cancel()
957946

958-
zc.close()
959-
960947

961-
def test_service_browser_listeners_update_service():
948+
def test_service_browser_listeners_update_service(zc: Zeroconf) -> None:
962949
"""Test that the ServiceBrowser ServiceListener that implements update_service."""
963950

964951
# instantiate a zeroconf instance
965-
zc = Zeroconf(interfaces=["127.0.0.1"])
966952
# start a browser
967953
type_ = "_hap._tcp.local."
968954
registration_name = f"xxxyyy.{type_}"
@@ -1017,14 +1003,11 @@ def update_service(self, zc, type_, name) -> None: # type: ignore[no-untyped-de
10171003
]
10181004
browser.cancel()
10191005

1020-
zc.close()
1021-
10221006

1023-
def test_service_browser_listeners_no_update_service():
1007+
def test_service_browser_listeners_no_update_service(zc: Zeroconf) -> None:
10241008
"""A listener that ignores update events records only add/remove callbacks."""
10251009

10261010
# instantiate a zeroconf instance
1027-
zc = Zeroconf(interfaces=["127.0.0.1"])
10281011
# start a browser
10291012
type_ = "_hap._tcp.local."
10301013
registration_name = f"xxxyyy.{type_}"
@@ -1077,12 +1060,9 @@ def update_service(self, zc, type_, name) -> None: # type: ignore[no-untyped-de
10771060
]
10781061
browser.cancel()
10791062

1080-
zc.close()
1081-
10821063

1083-
def test_service_browser_nsec_record_does_not_trigger_update():
1064+
def test_service_browser_nsec_record_does_not_trigger_update(zc: Zeroconf) -> None:
10841065
"""NSEC records assert non-existence and must not fire ServiceStateChange.Updated."""
1085-
zc = Zeroconf(interfaces=["127.0.0.1"])
10861066
type_ = "_hap._tcp.local."
10871067
registration_name = f"xxxyyy.{type_}"
10881068
callbacks: list[tuple[str, str, str]] = []
@@ -1144,24 +1124,21 @@ def update_service(self, zc, type_, name) -> None: # type: ignore[no-untyped-de
11441124
assert callbacks == [("add", type_, registration_name)]
11451125
finally:
11461126
browser.cancel()
1147-
zc.close()
11481127

11491128

1150-
def test_service_browser_uses_non_strict_names():
1129+
def test_service_browser_uses_non_strict_names(zc: Zeroconf) -> None:
11511130
"""Verify we can look for technically invalid names as we cannot change what others do."""
11521131

11531132
# dummy service callback
11541133
def on_service_state_change(zeroconf, service_type, state_change, name):
11551134
pass
11561135

1157-
zc = r.Zeroconf(interfaces=["127.0.0.1"])
11581136
browser = ServiceBrowser(zc, ["_tivo-videostream._tcp.local."], [on_service_state_change])
11591137
browser.cancel()
11601138

11611139
# Still fail on completely invalid
11621140
with pytest.raises(r.BadTypeInNameException):
11631141
browser = ServiceBrowser(zc, ["tivo-videostream._tcp.local."], [on_service_state_change])
1164-
zc.close()
11651142

11661143

11671144
def test_group_ptr_queries_with_known_answers():
@@ -1408,11 +1385,10 @@ def send(out, addr=const._MDNS_ADDR, port=const._MDNS_PORT, v6_flow_scope=()):
14081385
await aiozc.async_close()
14091386

14101387

1411-
def test_service_browser_matching():
1388+
def test_service_browser_matching(zc: Zeroconf) -> None:
14121389
"""Test that the ServiceBrowser matching does not match partial names."""
14131390

14141391
# instantiate a zeroconf instance
1415-
zc = Zeroconf(interfaces=["127.0.0.1"])
14161392
# start a browser
14171393
type_ = "_http._tcp.local."
14181394
registration_name = f"xxxyyy.{type_}"
@@ -1495,8 +1471,6 @@ def update_service(self, zc, type_, name) -> None: # type: ignore[no-untyped-de
14951471
]
14961472
browser.cancel()
14971473

1498-
zc.close()
1499-
15001474

15011475
@patch.object(_engine, "_CACHE_CLEANUP_INTERVAL", 0.01)
15021476
def test_service_browser_expire_callbacks():

‎tests/test_core.py‎

Lines changed: 13 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,9 @@ def test_use_asyncio_true_requires_running_loop():
181181
r.Zeroconf(interfaces=["127.0.0.1"], use_asyncio=True)
182182

183183

184-
def test_use_asyncio_default_starts_thread_without_loop():
184+
def test_use_asyncio_default_starts_thread_without_loop(zc: Zeroconf) -> None:
185185
"""use_asyncio=None (default) keeps the historic auto-detect behavior."""
186-
zc = r.Zeroconf(interfaces=["127.0.0.1"])
187-
try:
188-
assert zc._loop_thread is not None
189-
finally:
190-
zc.close()
186+
assert zc._loop_thread is not None
191187

192188

193189
def test_async_updates_from_response():
@@ -396,9 +392,8 @@ def test_invalid_packets_ignored_and_does_not_cause_loop_exception():
396392
assert zc.cache.get(entry) is not None
397393

398394

399-
def test_goodbye_all_services():
395+
def test_goodbye_all_services(zc: Zeroconf) -> None:
400396
"""Verify generating the goodbye query does not change with time."""
401-
zc = Zeroconf(interfaces=["127.0.0.1"])
402397
out = zc.generate_unregister_all_services()
403398
assert out is None
404399
type_ = "_http._tcp.local."
@@ -429,15 +424,11 @@ def test_goodbye_all_services():
429424
assert out3 is None
430425
assert zc.registry.async_get_service_infos() == []
431426

432-
zc.close()
433427

434-
435-
def test_register_service_with_custom_ttl(quick_timing: None) -> None:
428+
def test_register_service_with_custom_ttl(zc: Zeroconf, quick_timing: None) -> None:
436429
"""Test a registering a service with a custom ttl."""
437430

438431
# instantiate a zeroconf instance
439-
zc = Zeroconf(interfaces=["127.0.0.1"])
440-
441432
# start a browser
442433
type_ = "_homeassistant._tcp.local."
443434
name = "MyTestHome"
@@ -456,15 +447,12 @@ def test_register_service_with_custom_ttl(quick_timing: None) -> None:
456447
record = zc.cache.get(info_service.dns_pointer())
457448
assert record is not None
458449
assert record.ttl == 3000
459-
zc.close()
460450

461451

462-
def test_logging_packets(caplog: pytest.LogCaptureFixture, quick_timing: None) -> None:
452+
def test_logging_packets(zc: Zeroconf, caplog: pytest.LogCaptureFixture, quick_timing: None) -> None:
463453
"""Test packets are only logged with debug logging."""
464454

465455
# instantiate a zeroconf instance
466-
zc = Zeroconf(interfaces=["127.0.0.1"])
467-
468456
# start a browser
469457
type_ = "_logging._tcp.local."
470458
name = "TLD"
@@ -492,23 +480,18 @@ def test_logging_packets(caplog: pytest.LogCaptureFixture, quick_timing: None) -
492480
assert "Sending to" not in caplog.text
493481
logging.getLogger("zeroconf").setLevel(logging.DEBUG)
494482

495-
zc.close()
496-
497483

498-
def test_get_service_info_failure_path():
484+
def test_get_service_info_failure_path(zc: Zeroconf) -> None:
499485
"""Verify get_service_info return None when the underlying call returns False."""
500-
zc = Zeroconf(interfaces=["127.0.0.1"])
501486
assert zc.get_service_info("_neverused._tcp.local.", "xneverused._neverused._tcp.local.", 10) is None
502-
zc.close()
503487

504488

505489
@pytest.mark.skipif(
506490
sys.platform == "win32",
507491
reason="multicast loopback on the 127.0.0.1-only socket is unreliable on GH Actions Windows runners",
508492
)
509-
def test_sending_unicast():
493+
def test_sending_unicast(zc: Zeroconf) -> None:
510494
"""Test sending unicast response."""
511-
zc = Zeroconf(interfaces=["127.0.0.1"])
512495
generated = r.DNSOutgoing(const._FLAGS_QR_RESPONSE)
513496
entry = r.DNSText(
514497
"didnotcrashincoming._crash._tcp.local.",
@@ -534,11 +517,8 @@ def test_sending_unicast():
534517

535518
assert zc.cache.get(entry) is not None
536519

537-
zc.close()
538520

539-
540-
def test_tc_bit_defers():
541-
zc = Zeroconf(interfaces=["127.0.0.1"])
521+
def test_tc_bit_defers(zc: Zeroconf) -> None:
542522
_wait_for_start(zc)
543523
type_ = "_tcbitdefer._tcp.local."
544524
name = "knownname"
@@ -634,11 +614,9 @@ def test_tc_bit_defers():
634614

635615
# unregister
636616
zc.unregister_service(info)
637-
zc.close()
638617

639618

640-
def test_tc_bit_defers_last_response_missing():
641-
zc = Zeroconf(interfaces=["127.0.0.1"])
619+
def test_tc_bit_defers_last_response_missing(zc: Zeroconf) -> None:
642620
_wait_for_start(zc)
643621
type_ = "_knowndefer._tcp.local."
644622
name = "knownname"
@@ -751,12 +729,10 @@ def test_tc_bit_defers_last_response_missing():
751729

752730
# unregister
753731
zc.registry.async_remove(info)
754-
zc.close()
755732

756733

757-
def test_tc_bit_defer_window_is_bounded():
734+
def test_tc_bit_defer_window_is_bounded(zc: Zeroconf) -> None:
758735
"""TC-deferral assembly window must not slide past first_arrival + max delay."""
759-
zc = Zeroconf(interfaces=["127.0.0.1"])
760736
_wait_for_start(zc)
761737
type_ = "_boundeddefer._tcp.local."
762738
registration_name = f"knownname.{type_}"
@@ -797,7 +773,6 @@ def test_tc_bit_defer_window_is_bounded():
797773
assert protocol._timers[source_ip].when() <= first_when
798774

799775
zc.registry.async_remove(info)
800-
zc.close()
801776

802777

803778
def _make_distinct_tc_packets(count: int, name_prefix: str = "q") -> list[bytes]:
@@ -819,9 +794,8 @@ def _synthetic_source_ip(i: int) -> str:
819794
return f"192.0.2.{i - 512}"
820795

821796

822-
def test_tc_bit_per_addr_queue_is_bounded(quick_timing: None) -> None:
797+
def test_tc_bit_per_addr_queue_is_bounded(zc: Zeroconf, quick_timing: None) -> None:
823798
"""Per-addr deferred queue must not grow past ``_MAX_DEFERRED_PER_ADDR``."""
824-
zc = Zeroconf(interfaces=["127.0.0.1"])
825799
_wait_for_start(zc)
826800
protocol = zc.engine.protocols[0]
827801
source_ip = "203.0.113.21"
@@ -841,12 +815,9 @@ def test_tc_bit_per_addr_queue_is_bounded(quick_timing: None) -> None:
841815
retained = [incoming.data for incoming in protocol._deferred[source_ip]]
842816
assert retained == packets[: const._MAX_DEFERRED_PER_ADDR]
843817

844-
zc.close()
845-
846818

847-
def test_tc_bit_total_addrs_is_bounded(quick_timing: None) -> None:
819+
def test_tc_bit_total_addrs_is_bounded(zc: Zeroconf, quick_timing: None) -> None:
848820
"""Distinct addrs with deferred state must not exceed ``_MAX_DEFERRED_ADDRS``."""
849-
zc = Zeroconf(interfaces=["127.0.0.1"])
850821
_wait_for_start(zc)
851822
protocol = zc.engine.protocols[0]
852823

@@ -865,12 +836,9 @@ def test_tc_bit_total_addrs_is_bounded(quick_timing: None) -> None:
865836
assert len(protocol._deferred) == const._MAX_DEFERRED_ADDRS
866837
assert len(protocol._timers) == const._MAX_DEFERRED_ADDRS
867838

868-
zc.close()
869-
870839

871-
def test_tc_bit_eviction_drops_oldest_addr(quick_timing: None) -> None:
840+
def test_tc_bit_eviction_drops_oldest_addr(zc: Zeroconf, quick_timing: None) -> None:
872841
"""Adding a new addr at capacity drops the oldest insertion (FIFO)."""
873-
zc = Zeroconf(interfaces=["127.0.0.1"])
874842
_wait_for_start(zc)
875843
protocol = zc.engine.protocols[0]
876844

@@ -892,8 +860,6 @@ def test_tc_bit_eviction_drops_oldest_addr(quick_timing: None) -> None:
892860
assert new_addr in protocol._deferred
893861
assert len(protocol._deferred) == const._MAX_DEFERRED_ADDRS
894862

895-
zc.close()
896-
897863

898864
@pytest.mark.asyncio
899865
async def test_open_close_twice_from_async() -> None:

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL