From ab78e350ddfcd7e88c529f3be393245fc709be2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Thu, 8 Aug 2019 14:27:55 +0200 Subject: [PATCH 1/7] Implement a convenience function for "rndc dumpdb" Add a helper shell function, rndc_dumpdb(), which provides a convenient way to call "rndc dumpdb" for a given server with optional additional arguments. Since database dumping is an asynchronous process, the function waits until the dump is complete before returning, which prevents false positives in system tests caused by inspecting the dump before its preparation is finished. The function also renames the dump file before returning so that it does not get overwritten by subsequent calls; this retains forensic data in case of an unexpected test failure. --- bin/tests/system/conf.sh.common | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/bin/tests/system/conf.sh.common b/bin/tests/system/conf.sh.common index 921c349a57..613c0cd72b 100644 --- a/bin/tests/system/conf.sh.common +++ b/bin/tests/system/conf.sh.common @@ -343,6 +343,48 @@ rndc_reconfig() { done } +# rndc_dumpdb: call "rndc dumpdb [...]" and wait until it completes +# +# The first argument is the name server instance to send the command to, in the +# form of "nsX" (where "X" is the instance number), e.g. "ns5". The remaining +# arguments, if any, are appended to the rndc command line after "dumpdb". +# +# Control channel configuration for the name server instance to send the +# command to must match the contents of bin/tests/system/common/rndc.conf. +# +# rndc output is stored in a file called rndc.out.test${n}; the "n" variable is +# required to be set by the calling tests.sh script. +# +# Return 0 if the dump completes successfully; return 1 if rndc returns an exit +# code other than 0 or if the "; Dump complete" string does not appear in the +# dump within 10 seconds. +rndc_dumpdb() { + __ret=0 + __dump_complete=0 + __server="${1}" + __ip="10.53.0.$(echo "${__server}" | tr -c -d "0-9")" + + shift + ${RNDC} -c ../common/rndc.conf -p "${CONTROLPORT}" -s "${__ip}" dumpdb "$@" > "rndc.out.test${n}" 2>&1 || __ret=1 + + for _ in 0 1 2 3 4 5 6 7 8 9 + do + if grep '^; Dump complete$' "${__server}/named_dump.db" > /dev/null; then + mv "${__server}/named_dump.db" "${__server}/named_dump.db.test${n}" + __dump_complete=1 + break + fi + sleep 1 + done + + if [ ${__dump_complete} -eq 0 ]; then + echo_i "timed out waiting for 'rndc dumpdb' to finish" + __ret=1 + fi + + return ${__ret} +} + # get_dig_xfer_stats: extract transfer statistics from dig output stored # in $1, converting them to a format used by some system tests. get_dig_xfer_stats() { From 22d5355782785cc1da2370045f5347a845be8ec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Thu, 8 Aug 2019 14:27:55 +0200 Subject: [PATCH 2/7] Use rndc_dumpdb() in the "cacheclean" system test --- bin/tests/system/cacheclean/clean.sh | 1 + bin/tests/system/cacheclean/tests.sh | 24 +++++++++--------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/bin/tests/system/cacheclean/clean.sh b/bin/tests/system/cacheclean/clean.sh index 4cd319179e..52505a32dc 100644 --- a/bin/tests/system/cacheclean/clean.sh +++ b/bin/tests/system/cacheclean/clean.sh @@ -15,6 +15,7 @@ rm -f dig.out.ns2 rm -f dig.out.expire +rm -f rndc.out.* rm -f sed.out.* rm -f */named.memstats rm -f */named.run diff --git a/bin/tests/system/cacheclean/tests.sh b/bin/tests/system/cacheclean/tests.sh index fb9248ce2b..ed9707a511 100755 --- a/bin/tests/system/cacheclean/tests.sh +++ b/bin/tests/system/cacheclean/tests.sh @@ -57,13 +57,7 @@ EOF } dump_cache () { - $RNDC $RNDCOPTS dumpdb -cache _default - for i in 0 1 2 3 4 5 6 7 8 9 - do - grep '^; Dump complete$' ns2/named_dump.db > /dev/null && break - sleep 1 - done - mv ns2/named_dump.db ns2/named_dump.db.$n + rndc_dumpdb ns2 -cache _default } clear_cache () { @@ -113,7 +107,7 @@ echo_i "reset and check that records are correctly cached initially ($n)" ret=0 load_cache dump_cache -nrecords=`filter_tree flushtest.example ns2/named_dump.db.$n | egrep '(TXT|ANY)' | wc -l` +nrecords=`filter_tree flushtest.example ns2/named_dump.db.test$n | egrep '(TXT|ANY)' | wc -l` [ $nrecords -eq 18 ] || { ret=1; echo_i "found $nrecords records expected 18"; } if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -123,7 +117,7 @@ echo_i "check flushing of the full cache ($n)" ret=0 clear_cache dump_cache -nrecords=`filter_tree flushtest.example ns2/named_dump.db.$n | wc -l` +nrecords=`filter_tree flushtest.example ns2/named_dump.db.test$n | wc -l` [ $nrecords -eq 0 ] || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -207,7 +201,7 @@ n=`expr $n + 1` echo_i "check the number of cached records remaining ($n)" ret=0 dump_cache -nrecords=`filter_tree flushtest.example ns2/named_dump.db.$n | grep -v '^;' | egrep '(TXT|ANY)' | wc -l` +nrecords=`filter_tree flushtest.example ns2/named_dump.db.test$n | grep -v '^;' | egrep '(TXT|ANY)' | wc -l` [ $nrecords -eq 17 ] || { ret=1; echo_i "found $nrecords records expected 17"; } if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -225,7 +219,7 @@ n=`expr $n + 1` echo_i "check the number of cached records remaining ($n)" ret=0 dump_cache -nrecords=`filter_tree flushtest.example ns2/named_dump.db.$n | egrep '(TXT|ANY)' | wc -l` +nrecords=`filter_tree flushtest.example ns2/named_dump.db.test$n | egrep '(TXT|ANY)' | wc -l` [ $nrecords -eq 1 ] || { ret=1; echo_i "found $nrecords records expected 1"; } if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -235,17 +229,17 @@ echo_i "check flushtree clears adb correctly ($n)" ret=0 load_cache dump_cache -mv ns2/named_dump.db.$n ns2/named_dump.db.$n.a +mv ns2/named_dump.db.test$n ns2/named_dump.db.test$n.a sed -n '/plain success\/timeout/,/Unassociated entries/p' \ - ns2/named_dump.db.$n.a > sed.out.$n.a + ns2/named_dump.db.test$n.a > sed.out.$n.a grep 'plain success/timeout' sed.out.$n.a > /dev/null 2>&1 || ret=1 grep 'Unassociated entries' sed.out.$n.a > /dev/null 2>&1 || ret=1 grep 'ns.flushtest.example' sed.out.$n.a > /dev/null 2>&1 || ret=1 $RNDC $RNDCOPTS flushtree flushtest.example || ret=1 dump_cache -mv ns2/named_dump.db.$n ns2/named_dump.db.$n.b +mv ns2/named_dump.db.test$n ns2/named_dump.db.test$n.b sed -n '/plain success\/timeout/,/Unassociated entries/p' \ - ns2/named_dump.db.$n.b > sed.out.$n.b + ns2/named_dump.db.test$n.b > sed.out.$n.b grep 'plain success/timeout' sed.out.$n.b > /dev/null 2>&1 || ret=1 grep 'Unassociated entries' sed.out.$n.b > /dev/null 2>&1 || ret=1 grep 'ns.flushtest.example' sed.out.$n.b > /dev/null 2>&1 && ret=1 From cbf32b901b91b191c47feaf4c5f40f2d3c8ea885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Thu, 8 Aug 2019 14:27:55 +0200 Subject: [PATCH 3/7] Use rndc_dumpdb() in the "cookie" system test --- bin/tests/system/cookie/clean.sh | 3 ++- bin/tests/system/cookie/tests.sh | 9 ++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/bin/tests/system/cookie/clean.sh b/bin/tests/system/cookie/clean.sh index b5888d1f5b..3439fc64b2 100644 --- a/bin/tests/system/cookie/clean.sh +++ b/bin/tests/system/cookie/clean.sh @@ -9,7 +9,8 @@ rm -f ns*/named.conf rm -f dig.out.* -rm -f ns1/named_dump.db +rm -f rndc.out.* +rm -f ns1/named_dump.db* rm -f ns*/named.memstats rm -f ns*/named.run rm -f ns*/named.lock diff --git a/bin/tests/system/cookie/tests.sh b/bin/tests/system/cookie/tests.sh index f82bb00546..8e71103942 100755 --- a/bin/tests/system/cookie/tests.sh +++ b/bin/tests/system/cookie/tests.sh @@ -141,13 +141,8 @@ status=`expr $status + $ret` n=`expr $n + 1` echo_i "checking for COOKIE value in adb ($n)" ret=0 -$RNDCCMD 10.53.0.1 dumpdb -for i in 1 2 3 4 5 6 7 8 9 10 -do - sleep 1 - grep "10.53.0.2.*\[cookie=" ns1/named_dump.db > /dev/null && break -done -grep "10.53.0.2.*\[cookie=" ns1/named_dump.db > /dev/null || ret=1 +rndc_dumpdb ns1 +grep "10.53.0.2.*\[cookie=" ns1/named_dump.db.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` From 44c0cc881f6ab290a890e2581112842abf901f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Thu, 8 Aug 2019 14:27:55 +0200 Subject: [PATCH 4/7] Use rndc_dumpdb() in the "dnssec" system test --- bin/tests/system/dnssec/clean.sh | 2 +- bin/tests/system/dnssec/tests.sh | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/bin/tests/system/dnssec/clean.sh b/bin/tests/system/dnssec/clean.sh index c49ee9a1ac..bee3bbfd62 100644 --- a/bin/tests/system/dnssec/clean.sh +++ b/bin/tests/system/dnssec/clean.sh @@ -92,7 +92,7 @@ rm -f ./ns3/ttlpatch.example.db ./ns3/ttlpatch.example.db.signed rm -f ./ns3/ttlpatch.example.db.patched rm -f ./ns3/unsecure.example.db ./ns3/bogus.example.db ./ns3/keyless.example.db rm -f ./ns4/managed-keys.bind* -rm -f ./ns4/named_dump.db +rm -f ./ns4/named_dump.db* rm -f ./ns6/optout-tld.db rm -f ./ns7/multiple.example.bk ./ns7/nsec3.example.bk ./ns7/optout.example.bk rm -f ./ns7/split-rrsig.db ./ns7/split-rrsig.db.unsplit diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index a871bb7975..243b0a6426 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -3098,9 +3098,8 @@ status=$((status+ret)) echo_i "check that key id are logged when dumping the cache ($n)" ret=0 -rndccmd 10.53.0.4 dumpdb 2>&1 | sed 's/^/ns4 /' | cat_i -sleep 1 -grep "; key id = " ns4/named_dump.db > /dev/null || ret=1 +rndc_dumpdb ns4 +grep "; key id = " ns4/named_dump.db.test$n > /dev/null || ret=1 n=$((n+1)) test "$ret" -eq 0 || echo_i "failed" status=$((status+ret)) From 443449863b13bc4d757927e4e5244e417029be6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Thu, 8 Aug 2019 14:27:55 +0200 Subject: [PATCH 5/7] Use rndc_dumpdb() in the "rndc" system test --- bin/tests/system/rndc/clean.sh | 2 +- bin/tests/system/rndc/tests.sh | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/bin/tests/system/rndc/clean.sh b/bin/tests/system/rndc/clean.sh index 3472273c27..ddab2df8fe 100644 --- a/bin/tests/system/rndc/clean.sh +++ b/bin/tests/system/rndc/clean.sh @@ -16,7 +16,7 @@ rm -f ns*/named.run ns*/named.run.prev rm -f ns2/named.stats rm -f ns2/nil.db ns2/other.db ns2/static.db ns2/*.jnl rm -f ns2/session.key -rm -f ns3/named_dump.db +rm -f ns3/named_dump.db* rm -f ns4/*.nta rm -f ns4/key?.conf rm -f ns6/huge.zone.db diff --git a/bin/tests/system/rndc/tests.sh b/bin/tests/system/rndc/tests.sh index 3718e14318..2af855aa28 100644 --- a/bin/tests/system/rndc/tests.sh +++ b/bin/tests/system/rndc/tests.sh @@ -314,15 +314,7 @@ status=`expr $status + $ret` n=`expr $n + 1` echo_i "test 'rndc dumpdb' on a empty cache ($n)" ret=0 -$RNDCCMD 10.53.0.3 dumpdb > /dev/null || ret=1 -for i in 1 2 3 4 5 6 7 8 9 -do - tmp=0 - grep "Dump complete" ns3/named_dump.db > /dev/null || tmp=1 - [ $tmp -eq 0 ] && break - sleep 1 -done -[ $tmp -eq 1 ] && ret=1 +rndc_dumpdb ns3 || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` From 52beeed4442e81b6e1268ee7c001a00e52a3b37d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Thu, 8 Aug 2019 14:27:55 +0200 Subject: [PATCH 6/7] Use rndc_dumpdb() in the "serve-stale" system test --- bin/tests/system/serve-stale/ns1/named1.conf.in | 1 - bin/tests/system/serve-stale/ns1/named2.conf.in | 1 - bin/tests/system/serve-stale/tests.sh | 10 +++------- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/bin/tests/system/serve-stale/ns1/named1.conf.in b/bin/tests/system/serve-stale/ns1/named1.conf.in index 5e7caec3fe..be3551aae9 100644 --- a/bin/tests/system/serve-stale/ns1/named1.conf.in +++ b/bin/tests/system/serve-stale/ns1/named1.conf.in @@ -27,7 +27,6 @@ options { listen-on { 10.53.0.1; }; listen-on-v6 { none; }; recursion yes; - dump-file "named_dump1.db"; max-stale-ttl 3600; stale-answer-ttl 2; stale-answer-enable yes; diff --git a/bin/tests/system/serve-stale/ns1/named2.conf.in b/bin/tests/system/serve-stale/ns1/named2.conf.in index f330fd45cf..cdf1e9445d 100644 --- a/bin/tests/system/serve-stale/ns1/named2.conf.in +++ b/bin/tests/system/serve-stale/ns1/named2.conf.in @@ -26,7 +26,6 @@ options { pid-file "named.pid"; listen-on { 10.53.0.1; }; listen-on-v6 { none; }; - dump-file "named_dump1.db"; recursion yes; max-stale-ttl 7200; stale-answer-ttl 3; diff --git a/bin/tests/system/serve-stale/tests.sh b/bin/tests/system/serve-stale/tests.sh index a74b39efe0..01d3f210b6 100755 --- a/bin/tests/system/serve-stale/tests.sh +++ b/bin/tests/system/serve-stale/tests.sh @@ -96,15 +96,11 @@ grep "data\.example\..*2.*IN.*TXT.*A text record with a 1 second ttl" dig.out.te # Run rndc dumpdb, test whether the stale data has correct comment printed. # The max-stale-ttl is 3600 seconds, so the comment should say the data is # stale for somewhere between 3500-3599 seconds. -$RNDCCMD 10.53.0.1 dumpdb > rndc.out.test$n 2>&1 || ret=1 -for i in 0 1 2 3 4 5 6 7 8 9; do - grep '^; Dump complete$' ns1/named_dump1.db > /dev/null 2>&1 && break - sleep 1 -done -awk '/; stale/ { x=$0; getline; print x, $0}' ns1/named_dump1.db | +rndc_dumpdb ns1 || ret=1 +awk '/; stale/ { x=$0; getline; print x, $0}' ns1/named_dump.db.test$n | grep "; stale (will be retained for 35.. more seconds) data\.example.*A text record with a 1 second ttl" > /dev/null 2>&1 || ret=1 # Also make sure the not expired data does not have a stale comment. -awk '/; answer/ { x=$0; getline; print x, $0}' ns1/named_dump1.db | +awk '/; answer/ { x=$0; getline; print x, $0}' ns1/named_dump.db.test$n | grep "; answer longttl\.example.*A text record with a 600 second ttl" > /dev/null 2>&1 || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` From 4a8b3a8ac0642ce57eb450e5c6ab6111afa96aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Thu, 8 Aug 2019 14:27:55 +0200 Subject: [PATCH 7/7] Use rndc_dumpdb() in the "sfcache" system test --- bin/tests/system/sfcache/clean.sh | 4 +++- bin/tests/system/sfcache/tests.sh | 26 ++++++++++---------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/bin/tests/system/sfcache/clean.sh b/bin/tests/system/sfcache/clean.sh index 51939e98b0..75e55c18d8 100644 --- a/bin/tests/system/sfcache/clean.sh +++ b/bin/tests/system/sfcache/clean.sh @@ -17,7 +17,9 @@ rm -f ./*/named.memstats rm -f ./*/named.conf rm -f ./*/named.run ./*/named.run.prev rm -f ./dig.* +rm -f ./rndc.* rm -f ./sfcache.* +rm -f ./ns*/managed-keys.bind* rm -f ./ns*/named.lock rm -f ./ns5/named.run.part* -rm -f ./ns*/managed-keys.bind* +rm -f ./ns5/named_dump* diff --git a/bin/tests/system/sfcache/tests.sh b/bin/tests/system/sfcache/tests.sh index 19e34a724e..c512d6eea6 100644 --- a/bin/tests/system/sfcache/tests.sh +++ b/bin/tests/system/sfcache/tests.sh @@ -31,13 +31,8 @@ rndc_with_opts() { echo_i "checking DNSSEC SERVFAIL is cached ($n)" ret=0 dig_with_opts +dnssec foo.example. a @10.53.0.5 > dig.out.ns5.test$n || ret=1 -rndc_with_opts 10.53.0.5 dumpdb -all 2>&1 | sed 's/^/I:ns5 /' -# shellcheck disable=SC2034 -for i in 1 2 3 4 5 6 7 8 9 10; do - awk '/Zone/{out=0} { if (out) print } /SERVFAIL/{out=1}' ns5/named_dump.db > sfcache.$n - [ -s "sfcache.$n" ] && break - sleep 1 -done +rndc_dumpdb ns5 -all +awk '/Zone/{out=0} { if (out) print } /SERVFAIL/{out=1}' ns5/named_dump.db.test$n > sfcache.$n grep "^; foo.example/A" sfcache.$n > /dev/null || ret=1 n=$((n+1)) if [ $ret != 0 ]; then echo_i "failed"; fi @@ -62,17 +57,16 @@ status=$((status+ret)) echo_i "switching to non-dnssec SERVFAIL tests" ret=0 rndc_with_opts 10.53.0.5 flush 2>&1 | sed 's/^/I:ns5 /' -rndc_with_opts 10.53.0.5 dumpdb -all 2>&1 | sed 's/^/I:ns5 /' -awk '/SERVFAIL/ { next; out=1 } /Zone/ { out=0 } { if (out) print }' ns5/named_dump.db +rndc_dumpdb ns5 -all +mv ns5/named_dump.db.test$n ns5/named_dump.db.test$n.1 +awk '/SERVFAIL/ { next; out=1 } /Zone/ { out=0 } { if (out) print }' ns5/named_dump.db.test$n.1 > sfcache.$n.1 +[ -s "sfcache.$n.1" ] && ret=1 echo_i "checking SERVFAIL is cached ($n)" dig_with_opts bar.example2. a @10.53.0.5 > dig.out.ns5.test$n || ret=1 -for i in 1 2 3 4 5 6 7 8 9 10; do - rndc_with_opts 10.53.0.5 dumpdb -all 2>&1 | sed 's/^/I:ns5 /' - sleep 1 - awk '/Zone/{out=0} { if (out) print } /SERVFAIL/{out=1}' ns5/named_dump.db > sfcache.$n - [ -s "sfcache.$n" ] && break -done -grep "^; bar.example2/A" sfcache.$n > /dev/null || ret=1 +rndc_dumpdb ns5 -all +mv ns5/named_dump.db.test$n ns5/named_dump.db.test$n.2 +awk '/Zone/{out=0} { if (out) print } /SERVFAIL/{out=1}' ns5/named_dump.db.test$n.2 > sfcache.$n.2 +grep "^; bar.example2/A" sfcache.$n.2 > /dev/null || ret=1 n=$((n+1)) if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status+ret))