1 1.1 christos #!/bin/sh 2 1.1.1.5 christos 3 1.1 christos # Copyright (C) Internet Systems Consortium, Inc. ("ISC") 4 1.1 christos # 5 1.1.1.5 christos # SPDX-License-Identifier: MPL-2.0 6 1.1.1.5 christos # 7 1.1 christos # This Source Code Form is subject to the terms of the Mozilla Public 8 1.1.1.5 christos # License, v. 2.0. If a copy of the MPL was not distributed with this 9 1.1.1.4 christos # file, you can obtain one at https://mozilla.org/MPL/2.0/. 10 1.1 christos # 11 1.1 christos # See the COPYRIGHT file distributed with this work for additional 12 1.1 christos # information regarding copyright ownership. 13 1.1 christos 14 1.1.1.7 christos set -e 15 1.1.1.7 christos 16 1.1.1.7 christos . ../conf.sh 17 1.1 christos 18 1.1 christos status=0 19 1.1 christos n=0 20 1.1 christos 21 1.1.1.7 christos RNDCOPTS="-c ../_common/rndc.conf -s 10.53.0.2 -p ${CONTROLPORT}" 22 1.1 christos DIGOPTS="+nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm \ 23 1.1 christos +nostat @10.53.0.2 -p ${PORT}" 24 1.1 christos 25 1.1 christos # fill the cache with nodes from flushtest.example zone 26 1.1.1.7 christos load_cache() { 27 1.1.1.7 christos # empty all existing cache data 28 1.1.1.7 christos $RNDC $RNDCOPTS flush 29 1.1 christos 30 1.1.1.7 christos # load the positive cache entries 31 1.1.1.7 christos $DIG $DIGOPTS -f - <<EOF >/dev/null 2>&1 32 1.1 christos txt top1.flushtest.example 33 1.1 christos txt second1.top1.flushtest.example 34 1.1 christos txt third1.second1.top1.flushtest.example 35 1.1 christos txt third2.second1.top1.flushtest.example 36 1.1 christos txt second2.top1.flushtest.example 37 1.1 christos txt second3.top1.flushtest.example 38 1.1 christos txt second1.top2.flushtest.example 39 1.1 christos txt second2.top2.flushtest.example 40 1.1 christos txt second3.top2.flushtest.example 41 1.1 christos txt top3.flushtest.example 42 1.1 christos txt second1.top3.flushtest.example 43 1.1 christos txt third1.second1.top3.flushtest.example 44 1.1 christos txt third2.second1.top3.flushtest.example 45 1.1 christos txt third1.second2.top3.flushtest.example 46 1.1 christos txt third2.second2.top3.flushtest.example 47 1.1 christos txt second3.top3.flushtest.example 48 1.1 christos EOF 49 1.1 christos 50 1.1.1.7 christos # load the negative cache entries 51 1.1.1.7 christos # nxrrset: 52 1.1.1.7 christos $DIG $DIGOPTS a third1.second1.top1.flushtest.example >/dev/null 53 1.1.1.7 christos # nxdomain: 54 1.1.1.7 christos $DIG $DIGOPTS txt top4.flushtest.example >/dev/null 55 1.1.1.7 christos # empty nonterminal: 56 1.1.1.7 christos $DIG $DIGOPTS txt second2.top3.flushtest.example >/dev/null 57 1.1.1.7 christos 58 1.1.1.7 christos # sleep 2 seconds ensure the TTLs will be lower on cached data 59 1.1.1.7 christos sleep 2 60 1.1.1.7 christos } 61 1.1.1.7 christos 62 1.1.1.7 christos dump_cache() { 63 1.1.1.7 christos rndc_dumpdb ns2 -cache _default 64 1.1.1.7 christos } 65 1.1.1.7 christos 66 1.1.1.7 christos clear_cache() { 67 1.1.1.7 christos $RNDC $RNDCOPTS flush 68 1.1.1.7 christos } 69 1.1.1.7 christos 70 1.1.1.7 christos in_cache() { 71 1.1.1.7 christos ttl=$($DIG $DIGOPTS "$@" | awk '{print $2}') 72 1.1.1.7 christos [ -z "$ttl" ] && { 73 1.1.1.7 christos ttl=$($DIG $DIGOPTS +noanswer +auth "$@" | awk '{print $2}') 74 1.1.1.7 christos [ "$ttl" -ge 3599 ] && return 1 75 1.1.1.7 christos return 0 76 1.1.1.7 christos } 77 1.1.1.7 christos [ "$ttl" -ge 3599 ] && return 1 78 1.1.1.7 christos return 0 79 1.1 christos } 80 1.1 christos 81 1.1.1.2 christos # Extract records at and below name "$1" from the cache dump in file "$2". 82 1.1.1.7 christos filter_tree() { 83 1.1.1.7 christos tree="$1" 84 1.1.1.7 christos file="$2" 85 1.1.1.7 christos perl -n -e ' 86 1.1.1.2 christos next if /^;/; 87 1.1.1.2 christos if (/'"$tree"'/ || (/^\t/ && $print)) { 88 1.1.1.2 christos $print = 1; 89 1.1.1.2 christos } else { 90 1.1.1.2 christos $print = 0; 91 1.1.1.2 christos } 92 1.1.1.2 christos print if $print; 93 1.1.1.2 christos ' "$file" 94 1.1.1.2 christos } 95 1.1.1.2 christos 96 1.1.1.7 christos n=$((n + 1)) 97 1.1 christos echo_i "check correctness of routine cache cleaning ($n)" 98 1.1.1.7 christos $DIG $DIGOPTS +tcp +keepopen -b 10.53.0.7 -f dig.batch >dig.out.ns2 || status=1 99 1.1 christos 100 1.1 christos digcomp --lc dig.out.ns2 knowngood.dig.out || status=1 101 1.1 christos 102 1.1.1.7 christos n=$((n + 1)) 103 1.1 christos echo_i "only one tcp socket was used ($n)" 104 1.1.1.7 christos tcpclients=$(awk '$3 == "client" && $5 ~ /10.53.0.7#[0-9]*:/ {print $5}' ns2/named.run | sort | uniq -c | wc -l) 105 1.1 christos 106 1.1.1.7 christos test $tcpclients -eq 1 || { 107 1.1.1.7 christos status=1 108 1.1.1.7 christos echo_i "failed" 109 1.1.1.7 christos } 110 1.1 christos 111 1.1.1.7 christos n=$((n + 1)) 112 1.1 christos echo_i "reset and check that records are correctly cached initially ($n)" 113 1.1 christos ret=0 114 1.1 christos load_cache 115 1.1 christos dump_cache 116 1.1.1.7 christos nrecords=$(filter_tree flushtest.example ns2/named_dump.db.test$n | grep -E '(TXT|ANY)' | wc -l) 117 1.1.1.7 christos [ $nrecords -eq 18 ] || { 118 1.1.1.7 christos ret=1 119 1.1.1.7 christos echo_i "found $nrecords records expected 18" 120 1.1.1.7 christos } 121 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 122 1.1.1.7 christos status=$((status + ret)) 123 1.1 christos 124 1.1.1.7 christos n=$((n + 1)) 125 1.1 christos echo_i "check flushing of the full cache ($n)" 126 1.1 christos ret=0 127 1.1 christos clear_cache 128 1.1 christos dump_cache 129 1.1.1.7 christos nrecords=$(filter_tree flushtest.example ns2/named_dump.db.test$n | wc -l) 130 1.1 christos [ $nrecords -eq 0 ] || ret=1 131 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 132 1.1.1.7 christos status=$((status + ret)) 133 1.1 christos 134 1.1.1.7 christos n=$((n + 1)) 135 1.1 christos echo_i "check flushing of individual nodes (interior node) ($n)" 136 1.1 christos ret=0 137 1.1 christos clear_cache 138 1.1 christos load_cache 139 1.1 christos # interior node 140 1.1 christos in_cache txt top1.flushtest.example || ret=1 141 1.1 christos $RNDC $RNDCOPTS flushname top1.flushtest.example 142 1.1 christos in_cache txt top1.flushtest.example && ret=1 143 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 144 1.1.1.7 christos status=$((status + ret)) 145 1.1 christos 146 1.1.1.7 christos n=$((n + 1)) 147 1.1 christos echo_i "check flushing of individual nodes (leaf node, under the interior node) ($n)" 148 1.1 christos ret=0 149 1.1 christos # leaf node, under the interior node (should still exist) 150 1.1 christos in_cache txt third2.second1.top1.flushtest.example || ret=1 151 1.1 christos $RNDC $RNDCOPTS flushname third2.second1.top1.flushtest.example 152 1.1 christos in_cache txt third2.second1.top1.flushtest.example && ret=1 153 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 154 1.1.1.7 christos status=$((status + ret)) 155 1.1 christos 156 1.1.1.7 christos n=$((n + 1)) 157 1.1 christos echo_i "check flushing of individual nodes (another leaf node, with both positive and negative cache entries) ($n)" 158 1.1 christos ret=0 159 1.1 christos # another leaf node, with both positive and negative cache entries 160 1.1 christos in_cache a third1.second1.top1.flushtest.example || ret=1 161 1.1 christos in_cache txt third1.second1.top1.flushtest.example || ret=1 162 1.1 christos $RNDC $RNDCOPTS flushname third1.second1.top1.flushtest.example 163 1.1 christos in_cache a third1.second1.top1.flushtest.example && ret=1 164 1.1 christos in_cache txt third1.second1.top1.flushtest.example && ret=1 165 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 166 1.1.1.7 christos status=$((status + ret)) 167 1.1 christos 168 1.1.1.7 christos n=$((n + 1)) 169 1.1 christos echo_i "check flushing a nonexistent name ($n)" 170 1.1 christos ret=0 171 1.1 christos $RNDC $RNDCOPTS flushname fake.flushtest.example || ret=1 172 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 173 1.1.1.7 christos status=$((status + ret)) 174 1.1 christos 175 1.1.1.7 christos n=$((n + 1)) 176 1.1 christos echo_i "check flushing of namespaces ($n)" 177 1.1 christos ret=0 178 1.1 christos clear_cache 179 1.1 christos load_cache 180 1.1 christos # flushing leaf node should leave the interior node: 181 1.1 christos in_cache txt third1.second1.top1.flushtest.example || ret=1 182 1.1 christos in_cache txt top1.flushtest.example || ret=1 183 1.1 christos $RNDC $RNDCOPTS flushtree third1.second1.top1.flushtest.example 184 1.1 christos in_cache txt third1.second1.top1.flushtest.example && ret=1 185 1.1 christos in_cache txt top1.flushtest.example || ret=1 186 1.1 christos in_cache txt second1.top1.flushtest.example || ret=1 187 1.1 christos in_cache txt third2.second1.top1.flushtest.example || ret=1 188 1.1 christos $RNDC $RNDCOPTS flushtree second1.top1.flushtest.example 189 1.1 christos in_cache txt top1.flushtest.example || ret=1 190 1.1 christos in_cache txt second1.top1.flushtest.example && ret=1 191 1.1 christos in_cache txt third2.second1.top1.flushtest.example && ret=1 192 1.1 christos 193 1.1 christos # flushing from an empty node should still remove all its children 194 1.1 christos in_cache txt second1.top2.flushtest.example || ret=1 195 1.1 christos $RNDC $RNDCOPTS flushtree top2.flushtest.example 196 1.1 christos in_cache txt second1.top2.flushtest.example && ret=1 197 1.1 christos in_cache txt second2.top2.flushtest.example && ret=1 198 1.1 christos in_cache txt second3.top2.flushtest.example && ret=1 199 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 200 1.1.1.7 christos status=$((status + ret)) 201 1.1 christos 202 1.1.1.7 christos n=$((n + 1)) 203 1.1 christos echo_i "check flushing a nonexistent namespace ($n)" 204 1.1 christos ret=0 205 1.1 christos $RNDC $RNDCOPTS flushtree fake.flushtest.example || ret=1 206 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 207 1.1.1.7 christos status=$((status + ret)) 208 1.1 christos 209 1.1.1.7 christos n=$((n + 1)) 210 1.1 christos echo_i "check the number of cached records remaining ($n)" 211 1.1 christos ret=0 212 1.1 christos dump_cache 213 1.1.1.7 christos nrecords=$(filter_tree flushtest.example ns2/named_dump.db.test$n | grep -v '^;' | grep -E '(TXT|ANY)' | wc -l) 214 1.1.1.7 christos [ $nrecords -eq 17 ] || { 215 1.1.1.7 christos ret=1 216 1.1.1.7 christos echo_i "found $nrecords records expected 17" 217 1.1.1.7 christos } 218 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 219 1.1.1.7 christos status=$((status + ret)) 220 1.1 christos 221 1.1.1.7 christos n=$((n + 1)) 222 1.1 christos echo_i "check the check that flushname of a partial match works ($n)" 223 1.1 christos ret=0 224 1.1 christos in_cache txt second2.top1.flushtest.example || ret=1 225 1.1 christos $RNDC $RNDCOPTS flushtree example 226 1.1 christos in_cache txt second2.top1.flushtest.example && ret=1 227 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 228 1.1.1.7 christos status=$((status + ret)) 229 1.1 christos 230 1.1.1.7 christos n=$((n + 1)) 231 1.1 christos echo_i "check the number of cached records remaining ($n)" 232 1.1 christos ret=0 233 1.1 christos dump_cache 234 1.1.1.7 christos nrecords=$(filter_tree flushtest.example ns2/named_dump.db.test$n | grep -E '(TXT|ANY)' | wc -l) 235 1.1.1.7 christos [ $nrecords -eq 1 ] || { 236 1.1.1.7 christos ret=1 237 1.1.1.7 christos echo_i "found $nrecords records expected 1" 238 1.1.1.7 christos } 239 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 240 1.1.1.7 christos status=$((status + ret)) 241 1.1 christos 242 1.1.1.7 christos n=$((n + 1)) 243 1.1 christos echo_i "check flushtree clears adb correctly ($n)" 244 1.1 christos ret=0 245 1.1 christos load_cache 246 1.1 christos dump_cache 247 1.1.1.3 christos mv ns2/named_dump.db.test$n ns2/named_dump.db.test$n.a 248 1.1 christos sed -n '/plain success\/timeout/,/Unassociated entries/p' \ 249 1.1.1.7 christos ns2/named_dump.db.test$n.a >sed.out.$n.a 250 1.1.1.7 christos grep 'plain success/timeout' sed.out.$n.a >/dev/null 2>&1 || ret=1 251 1.1.1.7 christos grep 'ns.flushtest.example' sed.out.$n.a >/dev/null 2>&1 || ret=1 252 1.1 christos $RNDC $RNDCOPTS flushtree flushtest.example || ret=1 253 1.1 christos dump_cache 254 1.1.1.3 christos mv ns2/named_dump.db.test$n ns2/named_dump.db.test$n.b 255 1.1 christos sed -n '/plain success\/timeout/,/Unassociated entries/p' \ 256 1.1.1.7 christos ns2/named_dump.db.test$n.b >sed.out.$n.b 257 1.1.1.7 christos grep 'plain success/timeout' sed.out.$n.b >/dev/null 2>&1 || ret=1 258 1.1.1.7 christos grep 'ns.flushtest.example' sed.out.$n.b >/dev/null 2>&1 && ret=1 259 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 260 1.1.1.7 christos status=$((status + ret)) 261 1.1 christos 262 1.1.1.7 christos n=$((n + 1)) 263 1.1.1.4 christos echo_i "check expire option returned from primary zone ($n)" 264 1.1 christos ret=0 265 1.1.1.7 christos $DIG @10.53.0.1 -p ${PORT} +expire soa expire-test >dig.out.expire || ret=1 266 1.1.1.7 christos grep EXPIRE: dig.out.expire >/dev/null || ret=1 267 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 268 1.1.1.7 christos status=$((status + ret)) 269 1.1 christos 270 1.1.1.7 christos n=$((n + 1)) 271 1.1.1.4 christos echo_i "check expire option returned from secondary zone ($n)" 272 1.1 christos ret=0 273 1.1.1.7 christos $DIG @10.53.0.2 -p ${PORT} +expire soa expire-test >dig.out.expire || ret=1 274 1.1.1.7 christos grep EXPIRE: dig.out.expire >/dev/null || ret=1 275 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 276 1.1.1.7 christos status=$((status + ret)) 277 1.1 christos 278 1.1 christos echo_i "exit status: $status" 279 1.1 christos [ $status -eq 0 ] || exit 1 280