# #-- 09-unbound-control.test --# # source the master var file when it's there [ -f ../.tpkg.var.master ] && source ../.tpkg.var.master # use .tpkg.var.test for in test variable passing [ -f .tpkg.var.test ] && source .tpkg.var.test PRE="../.." . ../common.sh # End the test # $1: exit value end () { echo "> cat logfiles" cat fwd.log cat unbound.log exit $1 } # Expect a given exit value of the previous command # $1: the expected exit value # $2: optional text to print when failing expect_exit_value () { if test $? -ne $1; then if test -z "$2"; then if test $1 -eq 1; then msg="on error" else msg="after success" fi else msg="$2" fi echo "wrong exit value $msg" end 1 fi } # Helper function for quering # $@: at least the domain name to query and optional dig arguments query () { echo "> dig $@" dig @127.0.0.1 -p $UNBOUND_PORT $@ | tee outfile } # Expect something in the answer # $1: expected regular expression expect_answer () { echo "> check answer for \"$1\"" if grep "$1" outfile; then echo "OK" else echo "Not OK" end 1 fi } # Fail the test for unexpected answers # $1: unexpected regular expression fail_answer () { echo "> \"$1\" should not be in answer" if grep "$1" outfile; then echo "Not OK" end 1 else echo "OK" fi } # Issue an unbound-control command # $@: command arguments control_command() { echo "$PRE/unbound-control $@" $PRE/unbound-control $@ > outfile exitstatus=$? cat outfile return $exitstatus } # Reload the server and check the reload has finished processing # when a lot of debug is enabled, a lot of log needs to be printed. control_reload () { prelines=`wc -l unbound.log | awk '{print $1;}'` cmd="$1" if test -z "$cmd"; then cmd="reload"; fi control_command -c ub.conf $cmd expect_exit_value 0 # see if the reload has completed. lines1=`wc -l unbound.log | awk '{print $1;}'` count=0 lines2=`wc -l unbound.log | awk '{print $1;}'` # See if the log finishes up without sleeping too long. while test "$lines1" -ne "$lines2"; do lines1=`wc -l unbound.log | awk '{print $1;}'` # There is no sleep here. The add and compare are a # brief wait. count=`expr "$count" + 1` if test "$count" -gt 30; then break; fi lines2=`wc -l unbound.log | awk '{print $1;}'` done if test "$lines1" -ne "$lines2"; then count=0 while test "$lines1" -ne "$lines2"; do tail -1 unbound.log lines1=`wc -l unbound.log | awk '{print $1;}'` sleep 1 count=`expr "$count" + 1` if test "$count" -gt 30; then echo "reload is taking too long" exit 1 fi lines2=`wc -l unbound.log | awk '{print $1;}'` done if test "$count" -ne "0"; then echo "reload done with $count sec" fi fi } # Reload the server for a clean state clean_reload () { echo "> Reloading the server for a clean state" cp main.conf ub.conf control_reload } # Reload the server for a clean state and populate the cache clean_reload_and_fill_cache () { clean_reload echo "> Populating the cache" query www.example.com expect_answer "10.20.30.40" if test "$have_threads" = "no"; then # Try to get the answer in all processes' cache. for (( try=0 ; try < num_threads * 2 * 2 ; try++ )) ; do query www.example.com expect_answer "10.20.30.40" done fi } # Dump the cache contents # $@: optional options to unbound-control cache_dump () { echo "$PRE/unbound-control $@ dump_cache > cache.dump" $PRE/unbound-control $@ dump_cache > cache.dump } # Load cache contents # $@: optional options to unbound-control cache_load () { echo "$PRE/unbound-control $@ load_cache < cache.dump" $PRE/unbound-control $@ load_cache < cache.dump } # Expect an entry in the cache dump # $1: expected regular expression expect_in_cache_dump () { echo "> check cache dump for \"$1\"" if grep "$1" cache.dump; then echo "OK cache dump" else echo "Not OK cache dump" end 1 fi } # Fail the test for unexpected entry in the cache dump # $1: unexpected regular expression fail_in_cache_dump () { echo "> \"$1\" should not be in cache dump" if grep "$1" cache.dump; then echo "Not OK cache dump" end 1 else echo "OK cache dump" fi } # Check if multi-threading or multi-process environment have_threads="no" if grep "define HAVE_PTHREAD 1" $PRE/config.h; then have_threads="yes"; fi if grep "define HAVE_SOLARIS_THREADS 1" $PRE/config.h; then have_threads="yes"; fi if grep "define HAVE_WINDOWS_THREADS 1" $PRE/config.h; then have_threads="yes"; fi # start the test; keep the original conf file around cp ub.conf orig.conf # START - thread configuration # Do both single thread/process and multi thread/process runs. # The number of threads can only go up from the initial configuration between # reloads so starting with 1. for num_threads in 1 4; do cp orig.conf ub.conf echo "> setting num-threads: $num_threads" echo "server: num-threads: $num_threads" >> ub.conf cp ub.conf main.conf clean_reload teststep "exit value is 1 on usage" control_command -h expect_exit_value 1 "for usage" # use lock-verify if possible teststep "test if the server is up" query www.example.com. expect_answer "10.20.30.40" teststep "exit value is 1 when a bad command is given" control_command -c ub.conf blablargh expect_exit_value 1 # reload the server. test if the server came up by putting a new # local-data element in the server. teststep "reload the server" echo "server: local-data: 'afterreload. IN A 5.6.7.8'" >> ub.conf control_reload query afterreload. expect_answer "5.6.7.8" teststep "must have had at least 1 query since reload" control_command -c ub.conf stats expect_exit_value 0 expect_answer "^total.num.queries=[1-9][0-9]*$" teststep "check verbosity" control_command -c ub.conf verbosity 2 expect_exit_value 0 teststep "check syntax error in parse" control_command -c ub.conf verbosity jkdf expect_exit_value 1 teststep "check bad credentials" cp ub.conf bad.conf cat conf.bad_credentials >> bad.conf control_command -c bad.conf verbosity 2 expect_exit_value 1 teststep "check spoofed client credentials" rm -f bad.conf cp ub.conf bad.conf cat conf.spoofed_credentials >> bad.conf control_command -c bad.conf verbosity 2 expect_exit_value 1 teststep "clean reload" clean_reload # The flush negative only works if the server is either on 1 thread, # or there is threading enabled. Multiple processes does not work for the # test, since the printout does not have the stats of a global cache. if test $num_threads -le 1 -o "$have_threads" = "yes"; then teststep "Check negative flushing" query always.empty. expect_answer "SERVFAIL" query always.empty. DNSKEY expect_answer "SERVFAIL" control_command -c ub.conf flush_negative expect_exit_value 0 expect_answer "^ok removed .*, 3 messages and 1 key entries" control_command -c ub.conf flush_negative expect_exit_value 0 expect_answer "^ok removed .*, 0 messages and 0 key entries" else echo "> skip Check negative flushing, because no threads" fi teststep "create a new local zone" control_command -c ub.conf local_zone example.net static expect_exit_value 0 control_command -c ub.conf local_data www.example.net A 192.0.2.1 expect_exit_value 0 teststep "check that www.example.net exists" query www.example.net. expect_answer "192.0.2.1" teststep "check that mail.example.net has nxdomain" query mail.example.net. expect_answer "NXDOMAIN" teststep "remove www.example.net - check it gets nxdomain" control_command -c ub.conf local_data_remove www.example.net expect_exit_value 0 query www.example.net. expect_answer "NXDOMAIN" teststep "remove nonexistent name - check bug#287(segfault) does not happen" control_command -c ub.conf local_data_remove test.example.net # if crash then then we get: error: could not SSL_read from unbound-control expect_exit_value 0 teststep "remove example.net - check its gone" control_command -c ub.conf local_zone_remove example.net expect_exit_value 0 query www.example.net. expect_answer "SERVFAIL" teststep "load local-zones from file" control_command -c ub.conf local_zones < local_zones expect_exit_value 0 query localzonefromfile expect_answer "REFUSED" if test "$have_threads" = "no"; then # Try to see if a process other than the first one # has updated data from stdin. for (( try=0 ; try < num_threads * 2 ; try++ )) ; do query localzonefromfile expect_answer "REFUSED" done fi teststep "load local-data from file" control_command -c ub.conf local_datas < local_data expect_exit_value 0 query -t txt localdatafromfile expect_answer "local data from file OK" if test "$have_threads" = "no"; then # Try to see if a process other than the first one # has updated data from stdin. for (( try=0 ; try < num_threads * 2 ; try++ )) ; do query -t txt localdatafromfile expect_answer "local data from file OK" done fi teststep "load view-local-data from file" control_command -c ub.conf view_local_datas testview < view_local_data expect_exit_value 0 control_command -c ub.conf view_list_local_zones testview query -t txt viewlocaldatafromfile expect_answer "view local data from file OK" if test "$have_threads" = "no"; then # Try to see if a process other than the first one # has updated data from stdin. for (( try=0 ; try < num_threads * 2 ; try++ )) ; do query -t txt viewlocaldatafromfile expect_answer "view local data from file OK" done fi teststep "remove local-zone, local-data and view-local-data from file" control_command -c ub.conf local_zones_remove < local_zones_remove expect_exit_value 0 control_command -c ub.conf local_datas_remove < local_data_remove expect_exit_value 0 control_command -c ub.conf view_local_datas_remove testview < view_local_data_remove expect_exit_value 0 control_command -c ub.conf list_local_zones fail_answer "localzonefromfile" fail_answer "local data from file OK" expect_answer "otherlocalzone" control_command -c ub.conf view_list_local_data testview fail_answer "viewlocaldatafromfile" teststep "flushing" control_command -c ub.conf flush www.example.net expect_exit_value 0 control_command -c ub.conf flush_type www.example.net TXT expect_exit_value 0 control_command -c ub.conf flush_zone example.net expect_exit_value 0 # START - single thread/process tests only if test $num_threads -le 1; then clean_reload_and_fill_cache teststep "dump the cache" query www.example.com. cache_dump -c ub.conf expect_exit_value 0 cat cache.dump expect_in_cache_dump "10.20.30.40" control_command -c ub.conf lookup www.example.com expect_exit_value 0 # answer to lookup is meaningless because of use a forwarder, oh well. teststep "load the cache dump" cache_load -c ub.conf expect_exit_value 0 query www.example.com. +nordflag expect_answer "10.20.30.40" else echo "" echo "> skip test parts that need single thread/process" fi # END - single thread/process tests only clean_reload_and_fill_cache teststep "reload and check cache - should be empty" control_reload query www.example.com +nordflag fail_answer "10.20.30.40" clean_reload_and_fill_cache teststep "reload_keep_cache and check cache - should not be empty" control_reload reload_keep_cache query www.example.com +nordflag expect_answer "10.20.30.40" clean_reload_and_fill_cache teststep "change msg-cache-size and reload_keep_cache - should be empty" echo "server: msg-cache-size: 2m" >> ub.conf control_reload reload_keep_cache query www.example.com +nordflag fail_answer "10.20.30.40" clean_reload_and_fill_cache teststep "change rrset-cache-size and reload_keep_cache - should be empty" echo "server: rrset-cache-size: 2m" >> ub.conf control_reload reload_keep_cache query www.example.com +nordflag fail_answer "10.20.30.40" # START - have_threads tests # This part of the test needs threads for combined output. if test "$have_threads" = "yes"; then clean_reload_and_fill_cache teststep "change num-threads and reload_keep_cache - should be empty" echo "server: num-threads: 2" >> ub.conf control_reload reload_keep_cache query www.example.com +nordflag fail_answer "10.20.30.40" clean_reload_and_fill_cache teststep "change minimal-responses and reload_keep_cache - should not be empty" echo "server: minimal-responses: no" >> ub.conf control_reload reload_keep_cache query www.example.com +nordflag expect_answer "10.20.30.40" else echo "" echo "> skip test parts that need threads, have_threads=no" fi # END - have_threads tests done # END - thread configuration teststep "now stop the server" control_command -c ub.conf stop expect_exit_value 0 teststep "see if the server has really exited" TRY_MAX=20 for (( try=0 ; try <= $TRY_MAX ; try++ )) ; do if kill -0 $UNBOUND_PID 2>&1 | tee tmp.$$; then echo "not stopped yet, waiting" sleep 1 else echo "stopped OK; break" break; fi if grep "No such process" tmp.$$; then echo "stopped OK; break" break; fi done if kill -0 $UNBOUND_PID; then echo "still up!" echo "not stopped, failure" end 1 else echo "stopped OK" if test -f ublocktrace.0; then if $PRE/lock-verify ublocktrace.*; then echo "lock-verify test worked." else echo "lock-verify test failed." end 1 fi fi fi end 0