]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
system test for rndc dumpdb -cache and reload
authorColin Vidal <colin@isc.org>
Tue, 24 Mar 2026 13:37:00 +0000 (14:37 +0100)
committerColin Vidal <colin@isc.org>
Mon, 30 Mar 2026 18:41:13 +0000 (20:41 +0200)
Add system test which check the behavior of `rndc dumpdb -cache` as well
as the preservation of the delegation cache on server reload.

bin/tests/system/cacheclean/ns1/bar.com.db
bin/tests/system/cacheclean/tests_cacheclean_deleg.py [new file with mode: 0644]

index 7bd7b4a5a03856f602aa64ca0121bebe0e82d6b4..4a720ed1d1df93413993896eb166e3314599147a 100644 (file)
@@ -20,3 +20,4 @@ bar.com.             IN SOA  hostmaster.nominum.com. a.root-servers.nil. (
                        IN      NS      ns
 ns                     IN      A       10.53.0.1
 foo                    IN      NS      ns.somehost.com.
+lame-and-expired-soon 1 IN     NS      ns.somehost.com.
diff --git a/bin/tests/system/cacheclean/tests_cacheclean_deleg.py b/bin/tests/system/cacheclean/tests_cacheclean_deleg.py
new file mode 100644 (file)
index 0000000..9b80cd4
--- /dev/null
@@ -0,0 +1,116 @@
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0.  If a copy of the MPL was not distributed with this
+# file, you can obtain one at https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+from re import compile as Re
+
+import time
+
+import isctest
+
+DUMP_FILE_NAME = "ns2/named_dump.db"
+
+
+def warmup_cache(ns):
+    # Let's flush all caches first so we're sure the query will fully run into the resolver.
+    flush_caches(ns, "flush", "", "flushing caches in all views succeeded")
+    msg = isctest.query.create("gee.foo.bar.com.", "A")
+    res = isctest.query.udp(msg, ns.ip)
+    isctest.check.noerror(res)
+    msg = isctest.query.create("whatever.lame-and-expired-soon.bar.com.", "A")
+    # This will fail, we don't care, this is just to have the entry in the cache
+    isctest.query.udp(msg, ns.ip)
+    assert len(res.answer) == 1
+
+
+def check_cache_expired(ns):
+    time.sleep(2)
+    with ns.watch_log_from_here() as watcher:
+        ns.rndc("dumpdb -expired")
+        watcher.wait_for_line("dumpdb complete")
+    with isctest.log.WatchLogFromStart(DUMP_FILE_NAME) as watcher:
+        patterns = [
+            Re("lame-and-expired-soon.bar.com. 0 DELEG server-name=ns.somehost.com."),
+            Re("foo.bar.com. 99999[5-9] DELEG server-name=ns.somehost.com."),
+        ]
+        watcher.wait_for_all(patterns)
+
+
+def check_cache(ns, hit):
+    with ns.watch_log_from_here() as watcher:
+        ns.rndc("dumpdb -deleg")
+        watcher.wait_for_line("dumpdb complete")
+    with isctest.log.WatchLogFromStart(DUMP_FILE_NAME) as watcher:
+        if hit:
+            pattern = Re("foo.bar.com. 99999[5-9] DELEG server-name=ns.somehost.com.")
+            watcher.wait_for_line(pattern)
+        else:
+            seq = ["; Delegation cache", ";", ";", "; Start view _bind"]
+            watcher.wait_for_sequence(seq)
+
+
+def reload_server(ns):
+    with ns.watch_log_from_here() as watcher:
+        ns.rndc("reload")
+        watcher.wait_for_line("running")
+    with ns.watch_log_from_here() as watcher:
+        ns.rndc("reconfig")
+        watcher.wait_for_line("running")
+
+
+def flush_caches(ns, flushcmd, flusharg, confirm):
+    with ns.watch_log_from_here() as watcher:
+        ns.rndc(f"{flushcmd} {flusharg}")
+        watcher.wait_for_line(confirm)
+
+
+def test_cacheclean_deleg(ns2):
+    # Make sure the delegation cache has foo.bar.com.
+    warmup_cache(ns2)
+
+    # Flushing the cache
+    check_cache(ns2, True)
+
+    # Reloading the server keeps the cache hot
+    reload_server(ns2)
+
+    # The cache is still hot
+    check_cache(ns2, True)
+
+    # Flush the cache, and its now cold
+    flush_caches(ns2, "flush", "", "flushing caches in all views succeeded")
+    check_cache(ns2, False)
+
+    # Flush just the name foo.bar.com.
+    warmup_cache(ns2)
+    check_cache(ns2, True)
+    flush_caches(
+        ns2,
+        "flushname",
+        "foo.bar.com.",
+        "flushing name 'foo.bar.com.' in delegation cache for all views succeeded",
+    )
+    check_cache(ns2, False)
+
+    # Flush the whole .com. tree (need to flush
+    warmup_cache(ns2)
+    check_cache(ns2, True)
+    flush_caches(
+        ns2,
+        "flushtree",
+        "com.",
+        "flushing tree 'com.' in DNS cache for all views succeeded",
+    )
+    check_cache(ns2, False)
+
+    # Check -expired
+    warmup_cache(ns2)
+    check_cache(ns2, True)
+    check_cache_expired(ns2)