test: shave register/shutdown/TC waits on loopback#1711
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1711 +/- ##
=======================================
Coverage 99.76% 99.76%
=======================================
Files 33 33
Lines 3426 3427 +1
Branches 471 471
=======================================
+ Hits 3418 3419 +1
Misses 5 5
Partials 3 3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
all the windows TC tests fail with this pr try harder |
PR Review — test: shave register/shutdown/TC waits on loopbackThe The blocker is 🔴 Blocking1. Cleanup poll timeout halved — too tight for Windows (`tests/test_core.py`, L734-736)The cleanup poll budget was reduced from 8×100ms=800ms to 20×20ms=400ms — a 50% cut. Combined with the patched Two Windows-specific problems compound here:
Suggested fix: either keep the original 800ms cleanup budget (use 🟡 Important1. Patched interval is below practical Windows asyncio timer resolution (`tests/test_core.py`, L634)
A value like Checklist
SummaryThe The blocker is Automated review by Kōanca16a07 |
The Windows failure is almost certainly the combination of two compounding factors in
Two options to fix:
I'd lean toward the second — it preserves the speedup intent of the PR without making the cleanup poll do double duty as a slack budget for scheduler jitter. |
`async_check_service` paid an inline `random.randint(150, 250)` ms wait on every `register_service` — RFC 6762 §8.1 thundering-herd avoidance for real networks, pure overhead on 127.0.0.1. Extracted as a module constant `_REGISTER_RANDOM_INTERVAL` and patched in the `quick_timing` fixture to (1, 5)ms alongside the existing _CHECK_TIME / _REGISTER_TIME / _UNREGISTER_TIME shaves. Also: - `test_shutdown_loop`: drop `.result(1)` → `.result(0.1)` and patch `_TASK_AWAIT_TIMEOUT` to 0.1s. The 1s waits were `shutdown_loop`'s outer timeout on a never-completing `asyncio.sleep(5)` — the test only needs the loop to be stoppable while a task is pending. - `test_tc_bit_defers_last_response_missing`: patch `_TC_DELAY_RANDOM_INTERVAL` (400-500ms, RFC 6762 §7.2 TC-bit deferral) to (10, 20)ms and tighten the cleanup poll loop. - `test_integration`: wait for the browser's first startup query to fire (with empty cache) before registering. Previously the test relied on the register's 150-250ms random wait being longer than the browser's 20-120ms first-query delay; with the new fast register that race flipped and the first query started seeing the known PTR via §7.1 known-answer suppression. Speedups on loopback (CPython 3.12): | test | before | after | | ----------------------------------------------------- | ------ | ----- | | test_shutdown_loop | 1.16s | 0.26s | | test_tc_bit_defers_last_response_missing | 0.79s | 0.32s | | test_async_service_registration_name_conflict | 0.72s | 0.10s | | test_name_conflicts | 0.50s | 0.10s | Plus a smaller transparent shave on every other `quick_timing` register-based test. Full suite: 338 passed, 2 skipped. No production behavior change — `_REGISTER_RANDOM_INTERVAL` still defaults to the RFC 6762 §8.1 value on real networks.
…ot fire the timer mid-assertion
Rebase with requested adjustmentsBranch Changes applied
StatsActions performed
CI statusCI will be checked asynchronously. Automated by Kōan |
ca16a07 to
6b84b72
Compare
What
Speed up four slow tests by extracting one production constant (
_REGISTER_RANDOM_INTERVAL, the RFC 6762 §8.1 random pre-probe wait inasync_check_service) and patching it throughquick_timingon loopback, plus three localised test-only patches.Part of #1707.
Why
async_check_servicewaits a random 150-250ms before probing — RFC 6762 §8.1 thundering-herd avoidance for real networks, pure overhead on 127.0.0.1. Tests that usequick_timingalready get probe/announce/goodbye intervals shrunk, but the inlinerandom.randinton this path is opaque to patching. Three of the slowest tests in #1707 without an in-flight PR (test_async_service_registration_name_conflict,test_name_conflicts, and everything that registers a service) pay this for nothing.test_shutdown_loopandtest_tc_bit_defers_last_response_missingcarry similar dead waits — a 1s outer timeout inshutdown_loopagainst a never-completing pending task, and an 800ms cleanup poll against a 400-500ms RFC 6762 §7.2 TC-bit defer timer.How
_REGISTER_RANDOM_INTERVAL = (150, 250)as a module-level constant in_core.pyand patch it inquick_timingalongside the other loopback shaves. No production change — default still matches the RFC value.test_shutdown_loop: patch_TASK_AWAIT_TIMEOUTto 0.1s and drop.result(1)→.result(0.1). Both were just upper bounds on a never-completing pending task.test_tc_bit_defers_last_response_missing: patch_TC_DELAY_RANDOM_INTERVALto (10, 20)ms and tighten the cleanup poll loop.test_integration: wait for the browser's first startup query to fire (cache empty) before registering. The original test relied on the 150-250ms register-random-wait being longer than the browser's 20-120ms first-query delay; with the new fast register that race flipped and the first query started picking up the known PTR via §7.1 known-answer suppression.Speedups (CPython 3.12, loopback)
test_shutdown_looptest_tc_bit_defers_last_response_missingtest_async_service_registration_name_conflicttest_name_conflictsPlus a smaller transparent shave on every other
quick_timing-using test that registers a service.Test plan
tests/suite passes (338 passed, 2 skipped, ~47s wall)Quality Report
Changes: 6 files changed, 31 insertions(+), 12 deletions(-)
Code scan: clean
Tests: passed (4 PASSED)
Branch hygiene: clean
Generated by Kōan post-mission quality pipeline