Home | History | Annotate | Line # | Download | only in dnstap
      1 #!/bin/sh
      2 
      3 # Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      4 #
      5 # SPDX-License-Identifier: MPL-2.0
      6 #
      7 # This Source Code Form is subject to the terms of the Mozilla Public
      8 # License, v. 2.0.  If a copy of the MPL was not distributed with this
      9 # file, you can obtain one at https://mozilla.org/MPL/2.0/.
     10 #
     11 # See the COPYRIGHT file distributed with this work for additional
     12 # information regarding copyright ownership.
     13 
     14 set -e
     15 
     16 . ../conf.sh
     17 
     18 DIGOPTS="+short -p ${PORT}"
     19 RNDCCMD="$RNDC -p ${CONTROLPORT} -c ../_common/rndc.conf"
     20 
     21 status=0
     22 
     23 # dnstap_data_ready <fstrm_capture_PID> <capture_file> <min_file_size>
     24 # Flushes capture_file and checks wheter its size is >= min_file_size.
     25 dnstap_data_ready() {
     26   # Process id of running fstrm_capture.
     27   fstrm_capture_pid=$1
     28   # Output file provided to fstrm_capture via -w switch.
     29   capture_file=$2
     30   # Minimum expected file size.
     31   min_size_expected=$3
     32 
     33   kill -HUP $fstrm_capture_pid
     34   file_size=$(wc -c <"$capture_file" | tr -d ' ')
     35   if [ $file_size -lt $min_size_expected ]; then
     36     return 1
     37   fi
     38 }
     39 
     40 for bad in bad-*.conf; do
     41   ret=0
     42   echo_i "checking that named-checkconf detects error in $bad"
     43   {
     44     $CHECKCONF $bad >/dev/null 2>&1
     45     rc=$?
     46   } || true
     47   if [ $rc != 1 ]; then
     48     echo_i "failed"
     49     ret=1
     50   fi
     51   status=$((status + ret))
     52 done
     53 
     54 for good in good-*.conf; do
     55   ret=0
     56   echo_i "checking that named-checkconf detects no error in $good"
     57   {
     58     $CHECKCONF $good >/dev/null 2>&1
     59     rc=$?
     60   } || true
     61   if [ $rc != 0 ]; then
     62     echo_i "failed"
     63     ret=1
     64   fi
     65   status=$((status + ret))
     66 done
     67 
     68 echo_i "wait for servers to finish loading"
     69 ret=0
     70 wait_for_log 20 "all zones loaded" ns1/named.run || ret=1
     71 wait_for_log 20 "all zones loaded" ns2/named.run || ret=1
     72 wait_for_log 20 "all zones loaded" ns3/named.run || ret=1
     73 wait_for_log 20 "all zones loaded" ns4/named.run || ret=1
     74 if [ $ret != 0 ]; then echo_i "failed"; fi
     75 status=$((status + ret))
     76 
     77 # both the 'a.example/A' lookup and the './NS' lookup to ns1
     78 # need to complete before reopening/rolling for the counts to
     79 # be correct.
     80 
     81 echo_i "prime cache"
     82 ret=0
     83 $DIG $DIGOPTS @10.53.0.3 a.example >dig.out || true
     84 wait_for_log 20 "(.): reset client" ns1/named.run || true
     85 if [ $ret != 0 ]; then echo_i "failed"; fi
     86 status=$((status + ret))
     87 
     88 # check three different dnstap reopen/roll methods:
     89 # ns1: dnstap-reopen; ns2: dnstap -reopen; ns3: dnstap -roll
     90 mv ns1/dnstap.out ns1/dnstap.out.save
     91 mv ns2/dnstap.out ns2/dnstap.out.save
     92 
     93 if [ -n "$FSTRM_CAPTURE" ]; then
     94   ret=0
     95   echo_i "starting fstrm_capture"
     96   $FSTRM_CAPTURE -t protobuf:dnstap.Dnstap -u ns4/dnstap.out \
     97     -w dnstap.out >fstrm_capture.out.1 2>&1 &
     98   fstrm_capture_pid=$!
     99   wait_for_log 10 "socket path ns4/dnstap.out" fstrm_capture.out.1 || ret=1
    100   if [ $ret != 0 ]; then echo_i "failed"; fi
    101   status=$((status + ret))
    102 fi
    103 
    104 echo_i "reopen/roll capture streams"
    105 ret=0
    106 $RNDCCMD -s 10.53.0.1 dnstap-reopen | sed 's/^/ns1 /' | cat_i
    107 $RNDCCMD -s 10.53.0.2 dnstap -reopen | sed 's/^/ns2 /' | cat_i
    108 $RNDCCMD -s 10.53.0.3 dnstap -roll | sed 's/^/ns3 /' | cat_i
    109 $RNDCCMD -s 10.53.0.4 dnstap -reopen | sed 's/^/ns4 /' | cat_i
    110 
    111 echo_i "send test traffic"
    112 ret=0
    113 $DIG $DIGOPTS @10.53.0.3 a.example >dig.out || ret=1
    114 
    115 # send an UPDATE to ns2
    116 $NSUPDATE <<-EOF
    117 server 10.53.0.2 ${PORT}
    118 zone example
    119 update add b.example 3600 in a 10.10.10.10
    120 send
    121 EOF
    122 
    123 # XXX: file output should be flushed once a second according
    124 # to the libfstrm source, but it doesn't seem to happen until
    125 # enough data has accumulated. to get all the output, we stop
    126 # the name servers, forcing a flush on shutdown. it would be
    127 # nice to find a better way to do this.
    128 $RNDCCMD -s 10.53.0.1 stop | sed 's/^/ns1 /' | cat_i
    129 $RNDCCMD -s 10.53.0.2 stop | sed 's/^/ns2 /' | cat_i
    130 $RNDCCMD -s 10.53.0.3 stop | sed 's/^/ns3 /' | cat_i
    131 
    132 sleep 1
    133 
    134 echo_i "checking initial message counts"
    135 
    136 udp1=$($DNSTAPREAD ns1/dnstap.out.save | grep "UDP " | wc -l)
    137 tcp1=$($DNSTAPREAD ns1/dnstap.out.save | grep "TCP " | wc -l)
    138 aq1=$($DNSTAPREAD ns1/dnstap.out.save | grep "AQ " | wc -l)
    139 ar1=$($DNSTAPREAD ns1/dnstap.out.save | grep "AR " | wc -l)
    140 cq1=$($DNSTAPREAD ns1/dnstap.out.save | grep "CQ " | wc -l)
    141 cr1=$($DNSTAPREAD ns1/dnstap.out.save | grep "CR " | wc -l)
    142 rq1=$($DNSTAPREAD ns1/dnstap.out.save | grep "RQ " | wc -l)
    143 rr1=$($DNSTAPREAD ns1/dnstap.out.save | grep "RR " | wc -l)
    144 uq1=$($DNSTAPREAD ns1/dnstap.out.save | grep "UQ " | wc -l)
    145 ur1=$($DNSTAPREAD ns1/dnstap.out.save | grep "UR " | wc -l)
    146 
    147 udp2=$($DNSTAPREAD ns2/dnstap.out.save | grep "UDP " | wc -l)
    148 tcp2=$($DNSTAPREAD ns2/dnstap.out.save | grep "TCP " | wc -l)
    149 aq2=$($DNSTAPREAD ns2/dnstap.out.save | grep "AQ " | wc -l)
    150 ar2=$($DNSTAPREAD ns2/dnstap.out.save | grep "AR " | wc -l)
    151 cq2=$($DNSTAPREAD ns2/dnstap.out.save | grep "CQ " | wc -l)
    152 cr2=$($DNSTAPREAD ns2/dnstap.out.save | grep "CR " | wc -l)
    153 rq2=$($DNSTAPREAD ns2/dnstap.out.save | grep "RQ " | wc -l)
    154 rr2=$($DNSTAPREAD ns2/dnstap.out.save | grep "RR " | wc -l)
    155 uq2=$($DNSTAPREAD ns2/dnstap.out.save | grep "UQ " | wc -l)
    156 ur2=$($DNSTAPREAD ns2/dnstap.out.save | grep "UR " | wc -l)
    157 
    158 mv ns3/dnstap.out.0 ns3/dnstap.out.save
    159 udp3=$($DNSTAPREAD ns3/dnstap.out.save | grep "UDP " | wc -l)
    160 tcp3=$($DNSTAPREAD ns3/dnstap.out.save | grep "TCP " | wc -l)
    161 aq3=$($DNSTAPREAD ns3/dnstap.out.save | grep "AQ " | wc -l)
    162 ar3=$($DNSTAPREAD ns3/dnstap.out.save | grep "AR " | wc -l)
    163 cq3=$($DNSTAPREAD ns3/dnstap.out.save | grep "CQ " | wc -l)
    164 cr3=$($DNSTAPREAD ns3/dnstap.out.save | grep "CR " | wc -l)
    165 rq3=$($DNSTAPREAD ns3/dnstap.out.save | grep "RQ " | wc -l)
    166 rr3=$($DNSTAPREAD ns3/dnstap.out.save | grep "RR " | wc -l)
    167 uq3=$($DNSTAPREAD ns3/dnstap.out.save | grep "UQ " | wc -l)
    168 ur3=$($DNSTAPREAD ns3/dnstap.out.save | grep "UR " | wc -l)
    169 
    170 echo_i "checking UDP message counts"
    171 ret=0
    172 [ $udp1 -eq 0 ] || {
    173   echo_i "ns1 $udp1 expected 0"
    174   ret=1
    175 }
    176 [ $udp2 -eq 2 ] || {
    177   echo_i "ns2 $udp2 expected 2"
    178   ret=1
    179 }
    180 [ $udp3 -eq 4 ] || {
    181   echo_i "ns3 $udp3 expected 4"
    182   ret=1
    183 }
    184 if [ $ret != 0 ]; then echo_i "failed"; fi
    185 status=$((status + ret))
    186 
    187 echo_i "checking TCP message counts"
    188 ret=0
    189 [ $tcp1 -eq 6 ] || {
    190   echo_i "ns1 $tcp1 expected 6"
    191   ret=1
    192 }
    193 [ $tcp2 -eq 2 ] || {
    194   echo_i "ns2 $tcp2 expected 2"
    195   ret=1
    196 }
    197 [ $tcp3 -eq 6 ] || {
    198   echo_i "ns3 $tcp3 expected 6"
    199   ret=1
    200 }
    201 if [ $ret != 0 ]; then echo_i "failed"; fi
    202 status=$((status + ret))
    203 
    204 echo_i "checking AUTH_QUERY message counts"
    205 ret=0
    206 [ $aq1 -eq 3 ] || {
    207   echo_i "ns1 $aq1 exepcted 3"
    208   ret=1
    209 }
    210 [ $aq2 -eq 2 ] || {
    211   echo_i "ns2 $aq2 expected 2"
    212   ret=1
    213 }
    214 [ $aq3 -eq 1 ] || {
    215   echo_i "ns3 $aq3 expected 1"
    216   ret=1
    217 }
    218 if [ $ret != 0 ]; then echo_i "failed"; fi
    219 status=$((status + ret))
    220 
    221 echo_i "checking AUTH_RESPONSE message counts"
    222 ret=0
    223 [ $ar1 -eq 2 ] || {
    224   echo_i "ns1 $ar1 expected 2"
    225   ret=1
    226 }
    227 [ $ar2 -eq 1 ] || {
    228   echo_i "ns2 $ar2 expected 1"
    229   ret=1
    230 }
    231 [ $ar3 -eq 0 ] || {
    232   echo_i "ns3 $ar3 expected 0"
    233   ret=1
    234 }
    235 if [ $ret != 0 ]; then echo_i "failed"; fi
    236 status=$((status + ret))
    237 
    238 echo_i "checking CLIENT_QUERY message counts"
    239 ret=0
    240 [ $cq1 -eq 0 ] || {
    241   echo_i "ns1 $cq1 expected 0"
    242   ret=1
    243 }
    244 [ $cq2 -eq 0 ] || {
    245   echo_i "ns2 $cq2 expected 0"
    246   ret=1
    247 }
    248 [ $cq3 -eq 1 ] || {
    249   echo_i "ns3 $cq3 expected 1"
    250   ret=1
    251 }
    252 if [ $ret != 0 ]; then echo_i "failed"; fi
    253 status=$((status + ret))
    254 
    255 echo_i "checking CLIENT_RESPONSE message counts"
    256 ret=0
    257 [ $cr1 -eq 1 ] || {
    258   echo_i "ns1 $cr1 expected 1"
    259   ret=1
    260 }
    261 [ $cr2 -eq 1 ] || {
    262   echo_i "ns2 $cr2 expected 1"
    263   ret=1
    264 }
    265 [ $cr3 -eq 2 ] || {
    266   echo_i "ns3 $cr3 expected 2"
    267   ret=1
    268 }
    269 if [ $ret != 0 ]; then echo_i "failed"; fi
    270 status=$((status + ret))
    271 
    272 echo_i "checking RESOLVER_QUERY message counts"
    273 ret=0
    274 [ $rq1 -eq 0 ] || {
    275   echo_i "ns1 $rq1 expected 0"
    276   ret=1
    277 }
    278 [ $rq2 -eq 0 ] || {
    279   echo_i "ns2 $rq2 expected 0"
    280   ret=1
    281 }
    282 [ $rq3 -eq 3 ] || {
    283   echo_i "ns3 $rq3 expected 3"
    284   ret=1
    285 }
    286 if [ $ret != 0 ]; then echo_i "failed"; fi
    287 status=$((status + ret))
    288 
    289 echo_i "checking RESOLVER_RESPONSE message counts"
    290 ret=0
    291 [ $rr1 -eq 0 ] || {
    292   echo_i "ns1 $rr1 expected 0"
    293   ret=1
    294 }
    295 [ $rr2 -eq 0 ] || {
    296   echo_i "ns2 $rr2 expected 0"
    297   ret=1
    298 }
    299 [ $rr3 -eq 3 ] || {
    300   echo_i "ns3 $rr3 expected 3"
    301   ret=1
    302 }
    303 if [ $ret != 0 ]; then echo_i "failed"; fi
    304 status=$((status + ret))
    305 
    306 echo_i "checking UPDATE_QUERY message counts"
    307 ret=0
    308 [ $uq1 -eq 0 ] || {
    309   echo_i "ns1 $uq1 expected 0"
    310   ret=1
    311 }
    312 [ $uq2 -eq 0 ] || {
    313   echo_i "ns2 $uq2 expected 0"
    314   ret=1
    315 }
    316 [ $uq3 -eq 0 ] || {
    317   echo_i "ns3 $uq3 expected 0"
    318   ret=1
    319 }
    320 if [ $ret != 0 ]; then echo_i "failed"; fi
    321 status=$((status + ret))
    322 
    323 echo_i "checking UPDATE_RESPONSE message counts"
    324 ret=0
    325 [ $ur1 -eq 0 ] || {
    326   echo_i "ns1 $ur1 expected 0"
    327   ret=1
    328 }
    329 [ $ur2 -eq 0 ] || {
    330   echo_i "ns2 $ur2 expected 0"
    331   ret=1
    332 }
    333 [ $ur3 -eq 0 ] || {
    334   echo_i "ns3 $ur3 expected 0"
    335   ret=1
    336 }
    337 if [ $ret != 0 ]; then echo_i "failed"; fi
    338 status=$((status + ret))
    339 
    340 echo_i "checking reopened message counts"
    341 
    342 udp1=$($DNSTAPREAD ns1/dnstap.out | grep "UDP " | wc -l)
    343 tcp1=$($DNSTAPREAD ns1/dnstap.out | grep "TCP " | wc -l)
    344 aq1=$($DNSTAPREAD ns1/dnstap.out | grep "AQ " | wc -l)
    345 ar1=$($DNSTAPREAD ns1/dnstap.out | grep "AR " | wc -l)
    346 cq1=$($DNSTAPREAD ns1/dnstap.out | grep "CQ " | wc -l)
    347 cr1=$($DNSTAPREAD ns1/dnstap.out | grep "CR " | wc -l)
    348 rq1=$($DNSTAPREAD ns1/dnstap.out | grep "RQ " | wc -l)
    349 rr1=$($DNSTAPREAD ns1/dnstap.out | grep "RR " | wc -l)
    350 uq1=$($DNSTAPREAD ns1/dnstap.out | grep "UQ " | wc -l)
    351 ur1=$($DNSTAPREAD ns1/dnstap.out | grep "UR " | wc -l)
    352 
    353 udp2=$($DNSTAPREAD ns2/dnstap.out | grep "UDP " | wc -l)
    354 tcp2=$($DNSTAPREAD ns2/dnstap.out | grep "TCP " | wc -l)
    355 aq2=$($DNSTAPREAD ns2/dnstap.out | grep "AQ " | wc -l)
    356 ar2=$($DNSTAPREAD ns2/dnstap.out | grep "AR " | wc -l)
    357 cq2=$($DNSTAPREAD ns2/dnstap.out | grep "CQ " | wc -l)
    358 cr2=$($DNSTAPREAD ns2/dnstap.out | grep "CR " | wc -l)
    359 rq2=$($DNSTAPREAD ns2/dnstap.out | grep "RQ " | wc -l)
    360 rr2=$($DNSTAPREAD ns2/dnstap.out | grep "RR " | wc -l)
    361 uq2=$($DNSTAPREAD ns2/dnstap.out | grep "UQ " | wc -l)
    362 ur2=$($DNSTAPREAD ns2/dnstap.out | grep "UR " | wc -l)
    363 
    364 udp3=$($DNSTAPREAD ns3/dnstap.out | grep "UDP " | wc -l)
    365 tcp3=$($DNSTAPREAD ns3/dnstap.out | grep "TCP " | wc -l)
    366 aq3=$($DNSTAPREAD ns3/dnstap.out | grep "AQ " | wc -l)
    367 ar3=$($DNSTAPREAD ns3/dnstap.out | grep "AR " | wc -l)
    368 cq3=$($DNSTAPREAD ns3/dnstap.out | grep "CQ " | wc -l)
    369 cr3=$($DNSTAPREAD ns3/dnstap.out | grep "CR " | wc -l)
    370 rq3=$($DNSTAPREAD ns3/dnstap.out | grep "RQ " | wc -l)
    371 rr3=$($DNSTAPREAD ns3/dnstap.out | grep "RR " | wc -l)
    372 uq3=$($DNSTAPREAD ns3/dnstap.out | grep "UQ " | wc -l)
    373 ur3=$($DNSTAPREAD ns3/dnstap.out | grep "UR " | wc -l)
    374 
    375 echo_i "checking UDP message counts"
    376 ret=0
    377 [ $udp1 -eq 0 ] || {
    378   echo_i "ns1 $udp1 expected 0"
    379   ret=1
    380 }
    381 [ $udp2 -eq 2 ] || {
    382   echo_i "ns2 $udp2 expected 2"
    383   ret=1
    384 }
    385 [ $udp3 -eq 2 ] || {
    386   echo_i "ns3 $udp3 expected 2"
    387   ret=1
    388 }
    389 if [ $ret != 0 ]; then echo_i "failed"; fi
    390 status=$((status + ret))
    391 
    392 echo_i "checking TCP message counts"
    393 ret=0
    394 [ $tcp1 -eq 0 ] || {
    395   echo_i "ns1 $tcp1 expected 0"
    396   ret=1
    397 }
    398 [ $tcp2 -eq 0 ] || {
    399   echo_i "ns2 $tcp2 expected 0"
    400   ret=1
    401 }
    402 [ $tcp3 -eq 0 ] || {
    403   echo_i "ns3 $tcp3 expected 0"
    404   ret=1
    405 }
    406 if [ $ret != 0 ]; then echo_i "failed"; fi
    407 status=$((status + ret))
    408 
    409 echo_i "checking AUTH_QUERY message counts"
    410 ret=0
    411 [ $aq1 -eq 0 ] || {
    412   echo_i "ns1 $aq1 exepcted 0"
    413   ret=1
    414 }
    415 [ $aq2 -eq 0 ] || {
    416   echo_i "ns2 $aq2 expected 0"
    417   ret=1
    418 }
    419 [ $aq3 -eq 0 ] || {
    420   echo_i "ns3 $aq3 expected 0"
    421   ret=1
    422 }
    423 if [ $ret != 0 ]; then echo_i "failed"; fi
    424 status=$((status + ret))
    425 
    426 echo_i "checking AUTH_RESPONSE message counts"
    427 ret=0
    428 [ $ar1 -eq 0 ] || {
    429   echo_i "ns1 $ar1 expected 0"
    430   ret=1
    431 }
    432 [ $ar2 -eq 0 ] || {
    433   echo_i "ns2 $ar2 expected 0"
    434   ret=1
    435 }
    436 [ $ar3 -eq 0 ] || {
    437   echo_i "ns3 $ar3 expected 0"
    438   ret=1
    439 }
    440 if [ $ret != 0 ]; then echo_i "failed"; fi
    441 status=$((status + ret))
    442 
    443 echo_i "checking CLIENT_QUERY message counts"
    444 ret=0
    445 [ $cq1 -eq 0 ] || {
    446   echo_i "ns1 $cq1 expected 0"
    447   ret=1
    448 }
    449 [ $cq2 -eq 0 ] || {
    450   echo_i "ns2 $cq2 expected 0"
    451   ret=1
    452 }
    453 [ $cq3 -eq 1 ] || {
    454   echo_i "ns3 $cq3 expected 1"
    455   ret=1
    456 }
    457 if [ $ret != 0 ]; then echo_i "failed"; fi
    458 status=$((status + ret))
    459 
    460 echo_i "checking CLIENT_RESPONSE message counts"
    461 ret=0
    462 [ $cr1 -eq 0 ] || {
    463   echo_i "ns1 $cr1 expected 0"
    464   ret=1
    465 }
    466 [ $cr2 -eq 0 ] || {
    467   echo_i "ns2 $cr2 expected 0"
    468   ret=1
    469 }
    470 [ $cr3 -eq 1 ] || {
    471   echo_i "ns3 $cr3 expected 1"
    472   ret=1
    473 }
    474 if [ $ret != 0 ]; then echo_i "failed"; fi
    475 status=$((status + ret))
    476 
    477 echo_i "checking RESOLVER_QUERY message counts"
    478 ret=0
    479 [ $rq1 -eq 0 ] || {
    480   echo_i "ns1 $rq1 expected 0"
    481   ret=1
    482 }
    483 [ $rq2 -eq 0 ] || {
    484   echo_i "ns2 $rq2 expected 0"
    485   ret=1
    486 }
    487 [ $rq3 -eq 0 ] || {
    488   echo_i "ns3 $rq3 expected 0"
    489   ret=1
    490 }
    491 if [ $ret != 0 ]; then echo_i "failed"; fi
    492 status=$((status + ret))
    493 
    494 echo_i "checking RESOLVER_RESPONSE message counts"
    495 ret=0
    496 [ $rr1 -eq 0 ] || {
    497   echo_i "ns1 $rr1 expected 0"
    498   ret=1
    499 }
    500 [ $rr2 -eq 0 ] || {
    501   echo_i "ns2 $rr2 expected 0"
    502   ret=1
    503 }
    504 [ $rr3 -eq 0 ] || {
    505   echo_i "ns3 $rr3 expected 0"
    506   ret=1
    507 }
    508 if [ $ret != 0 ]; then echo_i "failed"; fi
    509 status=$((status + ret))
    510 
    511 echo_i "checking UPDATE_QUERY message counts"
    512 ret=0
    513 [ $uq1 -eq 0 ] || {
    514   echo_i "ns1 $uq1 expected 0"
    515   ret=1
    516 }
    517 [ $uq2 -eq 1 ] || {
    518   echo_i "ns2 $uq2 expected 1"
    519   ret=1
    520 }
    521 [ $uq3 -eq 0 ] || {
    522   echo_i "ns3 $uq3 expected 0"
    523   ret=1
    524 }
    525 if [ $ret != 0 ]; then echo_i "failed"; fi
    526 status=$((status + ret))
    527 
    528 echo_i "checking UPDATE_RESPONSE message counts"
    529 ret=0
    530 [ $ur1 -eq 0 ] || {
    531   echo_i "ns1 $ur1 expected 0"
    532   ret=1
    533 }
    534 [ $ur2 -eq 1 ] || {
    535   echo_i "ns2 $ur2 expected 1"
    536   ret=1
    537 }
    538 [ $ur3 -eq 0 ] || {
    539   echo_i "ns3 $ur3 expected 0"
    540   ret=1
    541 }
    542 if [ $ret != 0 ]; then echo_i "failed"; fi
    543 status=$((status + ret))
    544 
    545 echo_i "checking whether destination UDP port is logged for client queries"
    546 ret=0
    547 $DNSTAPREAD ns3/dnstap.out.save | grep -Eq "CQ [0-9:.]+ -> 10.53.0.3:${PORT} UDP" || ret=1
    548 if [ $ret != 0 ]; then echo_i "failed"; fi
    549 status=$((status + ret))
    550 
    551 HAS_PYYAML=0
    552 $PYTHON -c "import yaml" 2>/dev/null && HAS_PYYAML=1
    553 
    554 if [ $HAS_PYYAML -ne 0 ]; then
    555   echo_i "checking dnstap-read YAML output"
    556   ret=0
    557   {
    558     $PYTHON ydump.py "$DNSTAPREAD" "ns3/dnstap.out.save" >ydump.out || ret=1
    559   } | cat_i
    560   if [ $ret != 0 ]; then echo_i "failed"; fi
    561   status=$((status + ret))
    562 fi
    563 
    564 echo_i "checking dnstap-read hex output"
    565 ret=0
    566 hex=$($DNSTAPREAD -x ns3/dnstap.out | tail -1)
    567 echo $hex | $WIRETEST >dnstap.hex
    568 grep 'status: NOERROR' dnstap.hex >/dev/null 2>&1 || ret=1
    569 grep 'ANSWER: 3, AUTHORITY: 1' dnstap.hex >/dev/null 2>&1 || ret=1
    570 if [ $ret != 0 ]; then echo_i "failed"; fi
    571 status=$((status + ret))
    572 
    573 if [ -n "$FSTRM_CAPTURE" ]; then
    574   $DIG $DIGOPTS @10.53.0.4 a.example >dig.out || ret=1
    575 
    576   # send an UPDATE to ns4
    577   $NSUPDATE <<-EOF >nsupdate.out 2>&1 && ret=1
    578 	server 10.53.0.4 ${PORT}
    579 	zone example
    580 	update add b.example 3600 in a 10.10.10.10
    581 	send
    582 EOF
    583   grep "update failed: NOTAUTH" nsupdate.out >/dev/null || ret=1
    584 
    585   echo_i "checking unix socket message counts"
    586   sleep 2
    587   retry_quiet 5 dnstap_data_ready $fstrm_capture_pid dnstap.out 450 || {
    588     echo_i "dnstap output file smaller than expected"
    589     ret=1
    590   }
    591   if [ $ret != 0 ]; then echo_i "failed"; fi
    592   status=$((status + ret))
    593   kill $fstrm_capture_pid
    594   wait
    595   udp4=$($DNSTAPREAD dnstap.out | grep "UDP " | wc -l)
    596   tcp4=$($DNSTAPREAD dnstap.out | grep "TCP " | wc -l)
    597   aq4=$($DNSTAPREAD dnstap.out | grep "AQ " | wc -l)
    598   ar4=$($DNSTAPREAD dnstap.out | grep "AR " | wc -l)
    599   cq4=$($DNSTAPREAD dnstap.out | grep "CQ " | wc -l)
    600   cr4=$($DNSTAPREAD dnstap.out | grep "CR " | wc -l)
    601   rq4=$($DNSTAPREAD dnstap.out | grep "RQ " | wc -l)
    602   rr4=$($DNSTAPREAD dnstap.out | grep "RR " | wc -l)
    603   uq4=$($DNSTAPREAD dnstap.out | grep "UQ " | wc -l)
    604   ur4=$($DNSTAPREAD dnstap.out | grep "UR " | wc -l)
    605 
    606   echo_i "checking UDP message counts"
    607   ret=0
    608   [ $udp4 -eq 4 ] || {
    609     echo_i "ns4 $udp4 expected 4"
    610     ret=1
    611   }
    612   if [ $ret != 0 ]; then echo_i "failed"; fi
    613   status=$((status + ret))
    614 
    615   echo_i "checking TCP message counts"
    616   ret=0
    617   [ $tcp4 -eq 0 ] || {
    618     echo_i "ns4 $tcp4 expected 0"
    619     ret=1
    620   }
    621   if [ $ret != 0 ]; then echo_i "failed"; fi
    622   status=$((status + ret))
    623 
    624   echo_i "checking AUTH_QUERY message counts"
    625   ret=0
    626   [ $aq4 -eq 0 ] || {
    627     echo_i "ns4 $aq4 expected 0"
    628     ret=1
    629   }
    630   if [ $ret != 0 ]; then echo_i "failed"; fi
    631   status=$((status + ret))
    632 
    633   echo_i "checking AUTH_RESPONSE message counts"
    634   ret=0
    635   [ $ar4 -eq 0 ] || {
    636     echo_i "ns4 $ar4 expected 0"
    637     ret=1
    638   }
    639   if [ $ret != 0 ]; then echo_i "failed"; fi
    640   status=$((status + ret))
    641 
    642   echo_i "checking CLIENT_QUERY message counts"
    643   ret=0
    644   [ $cq4 -eq 1 ] || {
    645     echo_i "ns4 $cq4 expected 1"
    646     ret=1
    647   }
    648   if [ $ret != 0 ]; then echo_i "failed"; fi
    649   status=$((status + ret))
    650 
    651   echo_i "checking CLIENT_RESPONSE message counts"
    652   ret=0
    653   [ $cr4 -eq 1 ] || {
    654     echo_i "ns4 $cr4 expected 1"
    655     ret=1
    656   }
    657   if [ $ret != 0 ]; then echo_i "failed"; fi
    658   status=$((status + ret))
    659 
    660   echo_i "checking RESOLVER_QUERY message counts"
    661   ret=0
    662   [ $rq4 -eq 0 ] || {
    663     echo_i "ns4 $rq4 expected 0"
    664     ret=1
    665   }
    666   if [ $ret != 0 ]; then echo_i "failed"; fi
    667   status=$((status + ret))
    668 
    669   echo_i "checking RESOLVER_RESPONSE message counts"
    670   ret=0
    671   [ $rr4 -eq 0 ] || {
    672     echo_i "ns4 $rr4 expected 0"
    673     ret=1
    674   }
    675 
    676   echo_i "checking UPDATE_QUERY message counts"
    677   ret=0
    678   [ $uq4 -eq 1 ] || {
    679     echo_i "ns4 $uq4 expected 1"
    680     ret=1
    681   }
    682   if [ $ret != 0 ]; then echo_i "failed"; fi
    683   status=$((status + ret))
    684 
    685   echo_i "checking UPDATE_RESPONSE message counts"
    686   ret=0
    687   [ $ur4 -eq 1 ] || {
    688     echo_i "ns4 $ur4 expected 1"
    689     ret=1
    690   }
    691   if [ $ret != 0 ]; then echo_i "failed"; fi
    692   status=$((status + ret))
    693 
    694   mv dnstap.out dnstap.out.save
    695 
    696   echo_i "restarting fstrm_capture"
    697   $FSTRM_CAPTURE -t protobuf:dnstap.Dnstap -u ns4/dnstap.out \
    698     -w dnstap.out >fstrm_capture.out.2 2>&1 &
    699   fstrm_capture_pid=$!
    700   wait_for_log 10 "socket path ns4/dnstap.out" fstrm_capture.out.2 || {
    701     echo_i "failed"
    702     ret=1
    703   }
    704   $RNDCCMD -s 10.53.0.4 dnstap -reopen | sed 's/^/ns4 /' | cat_i
    705   $DIG $DIGOPTS @10.53.0.4 a.example >dig.out || ret=1
    706 
    707   echo_i "checking reopened unix socket message counts"
    708   sleep 2
    709   retry_quiet 5 dnstap_data_ready $fstrm_capture_pid dnstap.out 270 || {
    710     echo_i "dnstap output file smaller than expected"
    711     ret=1
    712   }
    713   if [ $ret != 0 ]; then echo_i "failed"; fi
    714   status=$((status + ret))
    715   kill $fstrm_capture_pid
    716   wait
    717   udp4=$($DNSTAPREAD dnstap.out | grep "UDP " | wc -l)
    718   tcp4=$($DNSTAPREAD dnstap.out | grep "TCP " | wc -l)
    719   aq4=$($DNSTAPREAD dnstap.out | grep "AQ " | wc -l)
    720   ar4=$($DNSTAPREAD dnstap.out | grep "AR " | wc -l)
    721   cq4=$($DNSTAPREAD dnstap.out | grep "CQ " | wc -l)
    722   cr4=$($DNSTAPREAD dnstap.out | grep "CR " | wc -l)
    723   rq4=$($DNSTAPREAD dnstap.out | grep "RQ " | wc -l)
    724   rr4=$($DNSTAPREAD dnstap.out | grep "RR " | wc -l)
    725   uq4=$($DNSTAPREAD dnstap.out | grep "UQ " | wc -l)
    726   ur4=$($DNSTAPREAD dnstap.out | grep "UR " | wc -l)
    727 
    728   echo_i "checking UDP message counts"
    729   ret=0
    730   [ $udp4 -eq 2 ] || {
    731     echo_i "ns4 $udp4 expected 2"
    732     ret=1
    733   }
    734   if [ $ret != 0 ]; then echo_i "failed"; fi
    735   status=$((status + ret))
    736 
    737   echo_i "checking TCP message counts"
    738   ret=0
    739   [ $tcp4 -eq 0 ] || {
    740     echo_i "ns4 $tcp4 expected 0"
    741     ret=1
    742   }
    743   if [ $ret != 0 ]; then echo_i "failed"; fi
    744   status=$((status + ret))
    745 
    746   echo_i "checking AUTH_QUERY message counts"
    747   ret=0
    748   [ $aq4 -eq 0 ] || {
    749     echo_i "ns4 $aq4 expected 0"
    750     ret=1
    751   }
    752   if [ $ret != 0 ]; then echo_i "failed"; fi
    753   status=$((status + ret))
    754 
    755   echo_i "checking AUTH_RESPONSE message counts"
    756   ret=0
    757   [ $ar4 -eq 0 ] || {
    758     echo_i "ns4 $ar4 expected 0"
    759     ret=1
    760   }
    761   if [ $ret != 0 ]; then echo_i "failed"; fi
    762   status=$((status + ret))
    763 
    764   echo_i "checking CLIENT_QUERY message counts"
    765   ret=0
    766   [ $cq4 -eq 1 ] || {
    767     echo_i "ns4 $cq4 expected 1"
    768     ret=1
    769   }
    770   if [ $ret != 0 ]; then echo_i "failed"; fi
    771   status=$((status + ret))
    772 
    773   echo_i "checking CLIENT_RESPONSE message counts"
    774   ret=0
    775   [ $cr4 -eq 1 ] || {
    776     echo_i "ns4 $cr4 expected 1"
    777     ret=1
    778   }
    779   if [ $ret != 0 ]; then echo_i "failed"; fi
    780   status=$((status + ret))
    781 
    782   echo_i "checking RESOLVER_QUERY message counts"
    783   ret=0
    784   [ $rq4 -eq 0 ] || {
    785     echo_i "ns4 $rq4 expected 0"
    786     ret=1
    787   }
    788   if [ $ret != 0 ]; then echo_i "failed"; fi
    789   status=$((status + ret))
    790 
    791   echo_i "checking RESOLVER_RESPONSE message counts"
    792   ret=0
    793   [ $rr4 -eq 0 ] || {
    794     echo_i "ns4 $rr4 expected 0"
    795     ret=1
    796   }
    797 
    798   echo_i "checking UPDATE_QUERY message counts"
    799   ret=0
    800   [ $uq4 -eq 0 ] || {
    801     echo_i "ns4 $uq4 expected 0"
    802     ret=1
    803   }
    804   if [ $ret != 0 ]; then echo_i "failed"; fi
    805   status=$((status + ret))
    806 
    807   echo_i "checking UPDATE_RESPONSE message counts"
    808   ret=0
    809   [ $ur4 -eq 0 ] || {
    810     echo_i "ns4 $ur4 expected 0"
    811     ret=1
    812   }
    813   if [ $ret != 0 ]; then echo_i "failed"; fi
    814   status=$((status + ret))
    815 fi
    816 
    817 echo_i "checking large packet printing"
    818 ret=0
    819 # Expect one occurrence of "opcode: QUERY" below "reponse_message_data" and
    820 # another one below "response_message".
    821 lines=$($DNSTAPREAD -y large-answer.fstrm | grep -c "opcode: QUERY")
    822 [ $lines -eq 2 ] || ret=1
    823 if [ $ret != 0 ]; then echo_i "failed"; fi
    824 status=$((status + ret))
    825 
    826 _test_dnstap_roll() (
    827   ip="$1"
    828   ns="$2"
    829   n="$3"
    830 
    831   $RNDCCMD -s "${ip}" dnstap -roll "${n}" | sed "s/^/${ns} /" | cat_i \
    832     && files=$(find "$ns" -name "dnstap.out.[0-9]" | wc -l) \
    833     && test "$files" -eq "${n}" && test "$files" -ge "1" || return 1
    834 )
    835 
    836 test_dnstap_roll() {
    837   echo_i "checking 'rndc -roll $4' ($1)"
    838   ret=0
    839 
    840   try=0
    841   while test $try -lt 12; do
    842     touch "$3/dnstap.out.$try"
    843     try=$((try + 1))
    844   done
    845 
    846   _repeat 10 _test_dnstap_roll $2 $3 $4 || ret=1
    847   if [ $ret != 0 ]; then echo_i "failed"; fi
    848   status=$((status + ret))
    849 }
    850 
    851 start_server --noclean --restart --port "${PORT}" ns3
    852 test_dnstap_roll "no versions" 10.53.0.3 ns3 6
    853 test_dnstap_roll "no versions" 10.53.0.3 ns3 3
    854 test_dnstap_roll "no versions" 10.53.0.3 ns3 1
    855 
    856 start_server --noclean --restart --port "${PORT}" ns2
    857 test_dnstap_roll "versions" 10.53.0.2 ns2 6
    858 test_dnstap_roll "versions" 10.53.0.2 ns2 3
    859 test_dnstap_roll "versions" 10.53.0.2 ns2 1
    860 
    861 echo_i "exit status: $status"
    862 [ "$status" -eq 0 ] || exit 1
    863