[ -f ns1/named.stats ] || ret=1
cp ns1/named.stats ns1/named.stats.$n
# Check first 10 lines of Cache DB statistics. After prime queries, we expect
-# two active TXT one nxrrset TXT, and one NXDOMAIN.
+# two active TXT, one active Others, one nxrrset TXT, and one NXDOMAIN.
grep -A 10 "++ Cache DB RRsets ++" ns1/named.stats.$n > ns1/named.stats.$n.cachedb || ret=1
grep "1 Others" ns1/named.stats.$n.cachedb > /dev/null || ret=1
grep "2 TXT" ns1/named.stats.$n.cachedb > /dev/null || ret=1
[ -f ns1/named.stats ] || ret=1
cp ns1/named.stats ns1/named.stats.$n
# Check first 10 lines of Cache DB statistics. After prime queries, we expect
-# two active TXT RRsets, one nxrrset TXT, and one NXDOMAIN.
+# two active TXT RRsets, one active Others, one nxrrset TXT, and one NXDOMAIN.
grep -A 10 "++ Cache DB RRsets ++" ns1/named.stats.$n > ns1/named.stats.$n.cachedb || ret=1
grep "2 TXT" ns1/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 Others" ns1/named.stats.$n.cachedb > /dev/null || ret=1
[ -f ns3/named.stats ] || ret=1
cp ns3/named.stats ns3/named.stats.$n
# Check first 10 lines of Cache DB statistics. After prime queries, we expect
-# two active TXT RRsets, one nxrrset TXT, and one NXDOMAIN.
+# two active TXT RRsets, one active Others, one nxrrset TXT, and one NXDOMAIN.
grep -A 10 "++ Cache DB RRsets ++" ns3/named.stats.$n > ns3/named.stats.$n.cachedb || ret=1
grep "2 TXT" ns3/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 Others" ns3/named.stats.$n.cachedb > /dev/null || ret=1
[ -f ns4/named.stats ] || ret=1
cp ns4/named.stats ns4/named.stats.$n
# Check first 10 lines of Cache DB statistics. After prime queries, we expect
-# two active TXT RRsets, one nxrrset TXT, and one NXDOMAIN.
+# two active TXT RRsets, one active Others, one nxrrset TXT, and one NXDOMAIN.
grep -A 10 "++ Cache DB RRsets ++" ns4/named.stats.$n > ns4/named.stats.$n.cachedb || ret=1
grep "2 TXT" ns4/named.stats.$n.cachedb > /dev/null || ret=1
grep "1 Others" ns4/named.stats.$n.cachedb > /dev/null || ret=1
status=$((status+ret))
if [ $ret != 0 ]; then echo_i "failed"; fi
+#
+# Test the server with stale-cache disabled.
+#
+echo_i "test server with serve-stale cache disabled"
+
+n=$((n+1))
+echo_i "enable responses from authoritative server ($n)"
+ret=0
+$DIG -p ${PORT} @10.53.0.2 txt enable > dig.out.test$n
+grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
+grep "TXT.\"1\"" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "prime cache longttl.example (serve-stale cache disabled) ($n)"
+ret=0
+$DIG -p ${PORT} @10.53.0.5 longttl.example TXT > dig.out.test$n
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "prime cache data.example (serve-stale cache disabled) ($n)"
+ret=0
+$DIG -p ${PORT} @10.53.0.5 data.example TXT > dig.out.test$n
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
+grep "data\.example\..*2.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "prime cache othertype.example (serve-stale cache disabled) ($n)"
+ret=0
+$DIG -p ${PORT} @10.53.0.5 othertype.example CAA > dig.out.test$n
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
+grep "othertype\.example\..*2.*IN.*CAA.*0.*issue" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "prime cache nodata.example (serve-stale cache disabled) ($n)"
+ret=0
+$DIG -p ${PORT} @10.53.0.5 nodata.example TXT > dig.out.test$n
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
+grep "example\..*2.*IN.*SOA" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "prime cache nxdomain.example (serve-stale cache disabled) ($n)"
+ret=0
+$DIG -p ${PORT} @10.53.0.5 nxdomain.example TXT > dig.out.test$n
+grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
+grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
+grep "example\..*2.*IN.*SOA" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "verify prime cache statistics (serve-stale cache disabled) ($n)"
+ret=0
+rm -f ns5/named.stats
+$RNDCCMD 10.53.0.5 stats > /dev/null 2>&1
+[ -f ns5/named.stats ] || ret=1
+cp ns5/named.stats ns5/named.stats.$n
+# Check first 10 lines of Cache DB statistics. After serve-stale queries,
+# we expect two active TXT RRsets, one active Others, one nxrrset TXT, and
+# one NXDOMAIN.
+grep -A 10 "++ Cache DB RRsets ++" ns5/named.stats.$n > ns5/named.stats.$n.cachedb || ret=1
+grep "2 TXT" ns5/named.stats.$n.cachedb > /dev/null || ret=1
+grep "1 Others" ns5/named.stats.$n.cachedb > /dev/null || ret=1
+grep "1 !TXT" ns5/named.stats.$n.cachedb > /dev/null || ret=1
+grep "1 NXDOMAIN" ns5/named.stats.$n.cachedb > /dev/null || ret=1
+status=$((status+ret))
+if [ $ret != 0 ]; then echo_i "failed"; fi
+
+n=$((n+1))
+echo_i "disable responses from authoritative server ($n)"
+ret=0
+$DIG -p ${PORT} @10.53.0.2 txt disable > dig.out.test$n
+grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
+grep "TXT.\"0\"" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "check 'rndc serve-stale status' ($n)"
+ret=0
+$RNDCCMD 10.53.0.5 serve-stale status > rndc.out.test$n 2>&1 || ret=1
+grep "_default: off (not-cached)" rndc.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+sleep 2
+
+echo_i "sending queries for tests $((n+1))-$((n+4))..."
+$DIG -p ${PORT} @10.53.0.5 data.example TXT > dig.out.test$((n+1)) &
+$DIG -p ${PORT} @10.53.0.5 othertype.example CAA > dig.out.test$((n+2)) &
+$DIG -p ${PORT} @10.53.0.5 nodata.example TXT > dig.out.test$((n+3)) &
+$DIG -p ${PORT} @10.53.0.5 nxdomain.example TXT > dig.out.test$((n+4))
+
+# ensure all files have been written before proceeding
+waitfile dig.out.test$((n+1))
+waitfile dig.out.test$((n+2))
+waitfile dig.out.test$((n+3))
+waitfile dig.out.test$((n+4))
+
+n=$((n+1))
+echo_i "check fail of data.example (serve-stale cache disabled) ($n)"
+ret=0
+grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
+grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "check fail of othertype.example (serve-stale cache disabled) ($n)"
+ret=0
+grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
+grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "check fail of nodata.example (serve-stale cache disabled) ($n)"
+ret=0
+grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
+grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "check fail of nxdomain.example (serve-stale cache disabled) ($n)"
+ret=0
+grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
+grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "verify stale cache statistics (serve-stale cache disabled) ($n)"
+ret=0
+rm -f ns5/named.stats
+$RNDCCMD 10.53.0.5 stats > /dev/null 2>&1
+[ -f ns5/named.stats ] || ret=1
+cp ns5/named.stats ns5/named.stats.$n
+# Check first 10 lines of Cache DB statistics. After serve-stale queries,
+# we expect one active TXT (longttl) and the rest to be expired from cache.
+grep -A 10 "++ Cache DB RRsets ++" ns5/named.stats.$n > ns5/named.stats.$n.cachedb || ret=1
+grep -F "1 Others" ns5/named.stats.$n.cachedb > /dev/null || ret=1
+grep -F "2 TXT" ns5/named.stats.$n.cachedb > /dev/null || ret=1
+grep -F "1 !TXT" ns5/named.stats.$n.cachedb > /dev/null || ret=1
+grep -F "1 NXDOMAIN" ns5/named.stats.$n.cachedb > /dev/null || ret=1
+status=$((status+ret))
+if [ $ret != 0 ]; then echo_i "failed"; fi
+
+# Dump the cache.
+n=$((n+1))
+echo_i "dump the cache (serve-stale cache disabled) ($n)"
+ret=0
+$RNDCCMD 10.53.0.5 dumpdb -cache > rndc.out.test$n 2>&1 || ret=1
+done=0
+for i in 0 1 2 3 4 5 6 7 8 9; do
+ grep '^; Dump complete$' ns5/named_dump5.db > /dev/null 2>&1 && done=1
+ if [ $done != 1 ]; then sleep 1; fi
+done
+if [ $done != 1 ]; then ret=1; fi
+status=$((status+ret))
+if [ $ret != 0 ]; then echo_i "failed"; fi
+
+echo_i "stop ns5"
+$PERL ../stop.pl --use-rndc --port ${CONTROLPORT} serve-stale ns5
+
+# Load the cache as if it was five minutes (RBTDB_VIRTUAL) older.
+FIVEMINUTESAGO=`TZ=UTC perl -e 'my $now = time();
+ my $fiveMinutesAgo = 300;
+ my ($s, $m, $h, $d, $mo, $y) = (localtime($fiveMinutesAgo))[0, 1, 2, 3, 4, 5];
+ printf("%04d%02d%02d%02d%02d%02d", $y+1900, $mo+1, $d, $h, $m, $s);'`
+
+n=$((n+1))
+echo_i "mock the cache date to $FIVEMINUTESAGO (serve-stale cache disabled) ($n)"
+ret=0
+sed -E "s/DATE [0-9]{14}/DATE $FIVEMINUTESAGO/g" ns5/named_dump5.db > ns5/named_dumpdb5.db.out || ret=1
+cp ns5/named_dumpdb5.db.out ns5/named_dumpdb5.db
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+echo_i "start ns5"
+start_server --noclean --restart --port ${PORT} serve-stale ns5
+
+n=$((n+1))
+echo_i "verify ancient cache statistics (serve-stale cache disabled) ($n)"
+ret=0
+rm -f ns5/named.stats
+$RNDCCMD 10.53.0.5 stats #> /dev/null 2>&1
+[ -f ns5/named.stats ] || ret=1
+cp ns5/named.stats ns5/named.stats.$n
+# Check first 10 lines of Cache DB statistics. After last queries, we expect
+# everything to be removed or scheduled to be removed.
+grep -A 10 "++ Cache DB RRsets ++" ns5/named.stats.$n > ns5/named.stats.$n.cachedb || ret=1
+grep -F "#TXT" ns5/named.stats.$n.cachedb > /dev/null && ret=1
+grep -F "#Others" ns5/named.stats.$n.cachedb > /dev/null && ret=1
+grep -F "#!TXT" ns5/named.stats.$n.cachedb > /dev/null && ret=1
+grep -F "#NXDOMAIN" ns5/named.stats.$n.cachedb > /dev/null && ret=1
+status=$((status+ret))
+if [ $ret != 0 ]; then echo_i "failed"; fi
+
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1