# 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)