Skip to content

Commit 9b4db62

Browse files
bluetoothbotbdraco
andauthored
test: widen scheduling buffer in flaky get_info suppression test (#1698)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
1 parent d2058d9 commit 9b4db62

4 files changed

Lines changed: 39 additions & 52 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
build/
22
*.pyc
33
*.pyo
4+
.coverage
5+
coverage.xml
6+
htmlcov/
47
Thumbs.db
58
.DS_Store
69
.project

tests/services/test_info.py

Lines changed: 31 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -436,12 +436,29 @@ def get_service_info_helper(zc, type, name):
436436
service_info_event.set()
437437

438438
try:
439+
# Seed TXT/A/AAAA with a far-future `than` before the
440+
# helper thread starts. The first (QU) query bypasses
441+
# suppression so phase 1 still observes 4 questions; the
442+
# second (QM) query fires ~220-320ms after the first, too
443+
# tight a window to seed reliably from the test thread on
444+
# slow runners. async_expire only removes entries where
445+
# now - than > _DUPLICATE_QUESTION_INTERVAL, so future-
446+
# dated entries persist for the duration of the test.
447+
seed_history_questions = (
448+
r.DNSQuestion(service_name, const._TYPE_A, const._CLASS_IN),
449+
r.DNSQuestion(service_name, const._TYPE_AAAA, const._CLASS_IN),
450+
r.DNSQuestion(service_name, const._TYPE_TXT, const._CLASS_IN),
451+
)
452+
far_future = r.current_time_millis() + 60_000
453+
for question in seed_history_questions:
454+
zc.question_history.add_question_at_time(question, far_future, set())
455+
439456
helper_thread = threading.Thread(
440457
target=get_service_info_helper,
441458
args=(zc, service_type, service_name),
442459
)
443460
helper_thread.start()
444-
wait_time = (const._LISTENER_TIME + info._AVOID_SYNC_DELAY_RANDOM_INTERVAL[1] + 5) / 1000
461+
wait_time = (const._LISTENER_TIME + info._AVOID_SYNC_DELAY_RANDOM_INTERVAL[1] + 500) / 1000
445462

446463
# Expect query for SRV, TXT, A, AAAA
447464
send_event.wait(wait_time)
@@ -457,64 +474,29 @@ def get_service_info_helper(zc, type, name):
457474
# by the question history
458475
last_sent = None
459476
send_event.clear()
460-
for _ in range(3):
461-
send_event.wait(
462-
wait_time * 0.25
463-
) # Wait long enough to be inside the question history window
464-
now = r.current_time_millis()
465-
zc.question_history.add_question_at_time(
466-
r.DNSQuestion(service_name, const._TYPE_A, const._CLASS_IN),
467-
now,
468-
set(),
469-
)
470-
zc.question_history.add_question_at_time(
471-
r.DNSQuestion(service_name, const._TYPE_AAAA, const._CLASS_IN),
472-
now,
473-
set(),
474-
)
475-
zc.question_history.add_question_at_time(
476-
r.DNSQuestion(service_name, const._TYPE_TXT, const._CLASS_IN),
477-
now,
478-
set(),
479-
)
480-
send_event.wait(wait_time * 0.25)
477+
send_event.wait(wait_time)
481478
assert last_sent is not None
482479
assert len(last_sent.questions) == 1 # type: ignore[unreachable]
483480
assert r.DNSQuestion(service_name, const._TYPE_SRV, const._CLASS_IN) in last_sent.questions
484481
assert service_info is None
485482

483+
# Future-date SRV too: the SRV entry added by the previous
484+
# QM query has `than = now`, so it expires after
485+
# _DUPLICATE_QUESTION_INTERVAL — before the next scheduled
486+
# QM query (~1s + jitter later).
487+
zc.question_history.add_question_at_time(
488+
r.DNSQuestion(service_name, const._TYPE_SRV, const._CLASS_IN),
489+
r.current_time_millis() + 60_000,
490+
set(),
491+
)
492+
486493
wait_time = (
487-
const._DUPLICATE_QUESTION_INTERVAL + info._AVOID_SYNC_DELAY_RANDOM_INTERVAL[1] + 5
494+
const._DUPLICATE_QUESTION_INTERVAL + info._AVOID_SYNC_DELAY_RANDOM_INTERVAL[1] + 500
488495
) / 1000
489496
# Expect no queries as all are suppressed by the question history
490497
last_sent = None
491498
send_event.clear()
492-
for _ in range(3):
493-
send_event.wait(
494-
wait_time * 0.25
495-
) # Wait long enough to be inside the question history window
496-
now = r.current_time_millis()
497-
zc.question_history.add_question_at_time(
498-
r.DNSQuestion(service_name, const._TYPE_A, const._CLASS_IN),
499-
now,
500-
set(),
501-
)
502-
zc.question_history.add_question_at_time(
503-
r.DNSQuestion(service_name, const._TYPE_AAAA, const._CLASS_IN),
504-
now,
505-
set(),
506-
)
507-
zc.question_history.add_question_at_time(
508-
r.DNSQuestion(service_name, const._TYPE_TXT, const._CLASS_IN),
509-
now,
510-
set(),
511-
)
512-
zc.question_history.add_question_at_time(
513-
r.DNSQuestion(service_name, const._TYPE_SRV, const._CLASS_IN),
514-
now,
515-
set(),
516-
)
517-
send_event.wait(wait_time * 0.25)
499+
send_event.wait(wait_time)
518500
# All questions are suppressed so no query should be sent
519501
assert last_sent is None
520502
assert service_info is None

tests/test_asyncio.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ async def test_service_info_async_request(quick_timing: None) -> None:
710710
# Generating the race condition is almost impossible
711711
# without patching since its a TOCTOU race
712712
with patch("zeroconf.asyncio.AsyncServiceInfo._is_complete", False):
713-
await aiosinfo.async_request(aiozc.zeroconf, 500)
713+
await aiosinfo.async_request(aiozc.zeroconf, 3000)
714714
assert aiosinfo is not None
715715
assert aiosinfo.addresses == [socket.inet_aton("10.0.1.3")]
716716

tests/test_core.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,10 @@ def test_get_service_info_failure_path():
496496
zc.close()
497497

498498

499+
@pytest.mark.skipif(
500+
sys.platform == "win32",
501+
reason="multicast loopback on the 127.0.0.1-only socket is unreliable on GH Actions Windows runners",
502+
)
499503
def test_sending_unicast():
500504
"""Test sending unicast response."""
501505
zc = Zeroconf(interfaces=["127.0.0.1"])
@@ -517,8 +521,6 @@ def test_sending_unicast():
517521
assert zc.cache.get(entry) is None
518522

519523
zc.send(generated)
520-
521-
# Handle slow github CI runners on windows
522524
for _ in range(10):
523525
time.sleep(0.05)
524526
if zc.cache.get(entry) is not None:

0 commit comments

Comments
 (0)