]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Avoid rndc loadkeys race in checkds system test 12150/head
authorNicki Křížek <nicki@isc.org>
Thu, 28 May 2026 16:13:20 +0000 (16:13 +0000)
committerNicki Křížek <nicki@isc.org>
Mon, 1 Jun 2026 13:48:46 +0000 (15:48 +0200)
The wait loop in test_checkds() called "rndc loadkeys" once per
second while polling ns9.log for expected parental-agent response
lines. Under load (notably the rbt CI job), responses to one query
batch could land after a subsequent loadkeys had already reset the
per-key DSPUBCOUNT counter in lib/dns/zone.c without cancelling the
in-flight requests. Stragglers from the earlier round then bumped the
new round's counter to parentalscnt and BIND finalized DSPublish for
zones where one parental-agent legitimately serves no DS, spuriously
failing the !DSPublish keystate assertion.

Trigger at most one loadkeys per test case and wait passively via
watch_log_from_start() / wait_for_all().  Watching from the start
of the log preserves the original implicit semantics for zones
whose DS state was already finalized by BIND's automatic checkds
polling at zone-load time -- the expected lines are already
present and the watcher returns immediately.

Assisted-by: Claude:claude-opus-4-7
(cherry picked from commit 02b6239489549e44daac123f556f851dd9949b27)

bin/tests/system/checkds/tests_checkds.py

index c0f834c42ba27783853c54a66b1f7c01210dfedb..2b081f420ca3d2aed358de1d0701932b17de584d 100755 (executable)
@@ -435,16 +435,14 @@ def test_checkds(ns2, ns9, params):
     # Wait until the provided zone is signed and then verify its DNSSEC data.
     zone_check(ns9, params.zone)
 
-    # Wait up to 10 seconds until all the expected log lines are found in the
-    # log file for the provided server.  Rekey every second if necessary.
-    time_remaining = 10
-    for log_string in params.logs_to_wait_for:
-        line = f"zone {params.zone}/IN (signed): checkds: {log_string}"
-        while line not in ns9.log:
-            ns9.rndc(f"loadkeys {params.zone}")
-            time_remaining -= 1
-            assert time_remaining, f'Timed out waiting for "{log_string}" to be logged'
-            time.sleep(1)
+    # Trigger a single checkds round and wait for all expected parental-
+    # agent response lines.
+    patterns = [
+        f"zone {params.zone}/IN (signed): checkds: {s}" for s in params.logs_to_wait_for
+    ]
+    with ns9.watch_log_from_start() as watcher:
+        ns9.rndc(f"loadkeys {params.zone}")
+        watcher.wait_for_all(patterns)
 
     # Check whether key states on the parent server provided match
     # expectations.