Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/tests/net/ndp Make this test somewhat deterministic - far fe...



details:   https://anonhg.NetBSD.org/src/rev/2fe56b1e3e52
branches:  trunk
changeset: 828047:2fe56b1e3e52
user:      kre <kre%NetBSD.org@localhost>
date:      Sat Nov 25 07:58:47 2017 +0000

description:
Make this test somewhat deterministic - far fewer races, and most
of what are left are "race for the bus" type - if we lose, we just
wait for the next one ... slower but still reliable.

There are two exceptions ... when starting more than one rtadvd
(on different routers) we expect to receive an RA from each, but
all that we can check is that we received the (at least) right number
of RAs.  It is possible (though unlikely) that one router sent two
before another sent any, in which case we will not have the data we
expect, and a sub-test will fail.

Second, there is no way to know for sure that we have waited long
enough when we're waiting for data to expire - in systems with
correctly working clocks that actually measure time, this should not
be an issue, if data is due to expire in < 5 seconds, and we wait
5 seconds, and the data is still there, then that indicates a
failure, which should be detected.   Unfortunately with QEMU testing
time just isn't that reliable.  But fortunately, it is generally the
sleep which takes longer, while other timers run correctly, which is
the way that makes us happy...

While here lots of cleanups - everything from white space and
line wrapping, to removing superfluous quotes and adding some
(but probably not enough) that are not (though given the data is
all known here, lack of quotes will rarely hurt.)

Also take note of the fact that current rtadvd *cannot* delete its
pidfile, so waiting for that file to be removed is doomed to failure.
Do things in a way that works, rather than simply resorting to assassination.

Because we do a lot less "sleep and hope it is long enough" and more
"wait until it is observed to happen" the tests generally run in less
elapsed time than before (20% less has been observed.)  But because we
"wait until it is observed to happen" rather than just "sleep and hope
it is long enough" sometimes things take longer (and when that happens,
we no longer fail).  Up to 7% slower (overall) has been observed.
(Observations on an amd64 DomU, no idea yet as to what QEMU might observe.)

diffstat:

 tests/net/ndp/t_ra.sh |  319 ++++++++++++++++++++++++++-----------------------
 1 files changed, 167 insertions(+), 152 deletions(-)

diffs (truncated from 697 to 300 lines):

diff -r 499e7b8a19c0 -r 2fe56b1e3e52 tests/net/ndp/t_ra.sh
--- a/tests/net/ndp/t_ra.sh     Sat Nov 25 04:53:24 2017 +0000
+++ b/tests/net/ndp/t_ra.sh     Sat Nov 25 07:58:47 2017 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: t_ra.sh,v 1.31 2017/11/07 02:19:23 ozaki-r Exp $
+#      $NetBSD: t_ra.sh,v 1.32 2017/11/25 07:58:47 kre Exp $
 #
 # Copyright (c) 2015 Internet Initiative Japan Inc.
 # All rights reserved.
@@ -43,14 +43,16 @@
 PIDFILE3=./rump.rtadvd.pid3
 PIDFILE4=./rump.rtadvd.pid4
 CONFIG=./rtadvd.conf
-WAITTIME=2
 DEBUG=${DEBUG:-false}
 
+RUMP_PROGS="rump_server rump.rtadvd rump.ndp rump.ifconfig rump.netstat"
+
 init_server()
 {
 
        export RUMP_SERVER=$1
-       atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.forwarding=1
+       atf_check -s exit:0 -o match:'0.->.1' \
+               rump.sysctl -w net.inet6.ip6.forwarding=1
        export LD_PRELOAD=/usr/lib/librumphijack.so
        atf_check -s exit:0 mkdir -p /rump/var/chroot/rtadvd
        unset LD_PRELOAD
@@ -72,25 +74,17 @@
        $DEBUG && rump.ifconfig
 }
 
-wait_term()
-{
-       local PIDFILE=${1}
-       shift
-
-       while [ -f ${PIDFILE} ]
-       do
-               sleep 0.2
-       done
-
-       return 0
-}
-
 kill_rtadvd()
 {
-       local pidfile=$1
+       local pid=$(cat "$1")
 
-       kill -KILL `cat $pidfile`
-       rm -f $pidfile
+       test -n "$pid" && {
+               case "$pid" in
+               *[!0-9]*)       return 1;;
+               esac
+               test "$pid" -gt 1 && kill -s KILL "${pid}"
+       }
+       rm -f "$1"
 }
 
 terminate_rtadvd()
@@ -98,102 +92,131 @@
        local pidfile=$1
        local n=5
 
-       if [ ! -f $pidfile ]; then
+       if ! [ -f "$pidfile" ]; then
                return
        fi
 
-       kill -TERM `cat $pidfile`
-       while [ -f $pidfile ]; do
+       local pid=$(cat "$pidfile")
+
+       test -n "${pid}" && kill -s TERM "${pid}"
+
+       # Note, rtadvd cannot remove its own pidfile, it chroots after
+       # creating it (and if it chroot'd first, we would not be able to
+       # control where it puts the thing, and so it would be useless.)
+       # However, it does truncate it... so watch for that.
+       while [ -s "$pidfile" ]; do
                n=$((n - 1))
-               if [ $n = 0 ]; then
-                       kill_rtadvd $pidfile
-                       break
+               if [ "$n" = 0 ]; then
+                       kill_rtadvd "$pidfile"
+                       return
                fi
                sleep 0.2
        done
+       # and finally complete the cleanup that rtadvd did not do.
+       rm -f "$pidfile"
 }
 
 create_rtadvdconfig()
 {
-
        cat << _EOF > ${CONFIG}
-shmif0:\
+shmif0:\\
        :mtu#1300:maxinterval#4:mininterval#3:
 _EOF
 }
 
 create_rtadvdconfig_rltime()
 {
-       local time=$1
-
        cat << _EOF > ${CONFIG}
-shmif0:\
-       :mtu#1300:maxinterval#4:mininterval#3:rltime#$time:
+shmif0:\\
+       :mtu#1300:maxinterval#4:mininterval#3:rltime#$1:
 _EOF
        $DEBUG && cat ${CONFIG}
 }
 
 create_rtadvdconfig_vltime()
 {
-       local addr=$1
-       local time=$2
-
        cat << _EOF > ${CONFIG}
-shmif0:\
-       :mtu#1300:maxinterval#4:mininterval#3:addr="$addr":vltime#$time:
+shmif0:\\
+       :mtu#1300:maxinterval#4:mininterval#3:addr="$1":vltime#$2:
 _EOF
        $DEBUG && cat ${CONFIG}
 }
 
+RA_count()
+{
+       RUMP_SERVER="$1" rump.netstat -p icmp6 | sed -n '
+               $ {
+                       s/^.*$/0/p
+                       q
+               }
+               /router advertisement:/!d
+               s/.*router advertisement: *//
+               s/[     ]*$//
+               s/^$/0/
+               p
+               q
+       '
+}
+
+await_RA()
+{
+       local N=$(RA_count "$1")
+       while [ "$(RA_count "$1")" -le "$N" ]; do
+               sleep 0.2
+       done
+}
+
 start_rtadvd()
 {
-       local sock=$1
-       local pidfile=$2
+       local RUMP_SERVER="$1"
+       export RUMP_SERVER
 
-       export RUMP_SERVER=$sock
        atf_check -s exit:0 -e ignore \
-           rump.rtadvd -D -c ${CONFIG} -p $pidfile shmif0
-       while [ ! -f $pidfile ]; do
-               sleep 0.2
-       done
-       unset RUMP_SERVER
+           rump.rtadvd -D -c ${CONFIG} -p "$2" shmif0
+
+       # don't wait for the pid file to appear and get a pid in it.
+       # we look for receiving RAs instead, must more reliable
+       # extra delay here increases possibility of RA arriving before
+       # we start looking (which means we then wait for the next .. boring!)
 }
 
 check_entries()
 {
-       local cli=$1
+       local RUMP_SERVER="$1"
        local srv=$2
        local addr_prefix=$3
        local mac_srv= ll_srv=
+       export RUMP_SERVER
 
-       ll_srv=$(get_linklocal_addr $srv shmif0)
-       mac_srv=$(get_macaddr $srv shmif0)
+       ll_srv=$(get_linklocal_addr "$srv" shmif0)
+       mac_srv=$(get_macaddr "$srv" shmif0)
 
-       export RUMP_SERVER=$cli
        $DEBUG && dump_entries
-       atf_check -s exit:0 -o match:'if=shmif0' rump.ndp -r
-       atf_check -s exit:0 -o match:'advertised' rump.ndp -p
-       atf_check -s exit:0 -o match:"${ll_srv}%shmif0 \(reachable\)" rump.ndp -p
-       atf_check -s exit:0 -o match:'linkmtu=1300' rump.ndp -n -i shmif0
+       atf_check -s exit:0 -o match:if=shmif0 rump.ndp -r
+       atf_check -s exit:0 -o match:advertised  \
+           -o match:"${ll_srv}%shmif0 \(reachable\)" \
+               rump.ndp -p
+       atf_check -s exit:0 -o match:linkmtu=1300 rump.ndp -n -i shmif0
        atf_check -s exit:0 \
            -o match:"$ll_srv%shmif0 +$mac_srv +shmif0 +$ONEDAYISH S R" \
-           rump.ndp -n -a
-       atf_check -s exit:0 -o not-match:$addr_prefix rump.ndp -n -a
+           -o not-match:"$addr_prefix"  \
+                   rump.ndp -n -a
        atf_check -s exit:0 \
            -o match:"$addr_prefix.+<(TENTATIVE,)?AUTOCONF>" \
            rump.ifconfig shmif0 inet6
-       unset RUMP_SERVER
 }
 
 dump_entries()
 {
+       local marker="+-+-+-+-+-+-+-+-+"
 
-       echo ndp -n -a
+       printf '%s %s\n' "$marker" 'ndp -n -a'
        rump.ndp -n -a
-       echo ndp -p
+       printf '%s %s\n' "$marker" 'ndp -p'
        rump.ndp -p
-       echo ndp -r
+       printf '%s %s\n' "$marker" 'ndp -r'
        rump.ndp -r
+       printf '%s\n' "$marker"
 }
 
 atf_test_case ra_basic cleanup
@@ -201,7 +224,7 @@
 {
 
        atf_set "descr" "Tests for basic functions of router advaertisement(RA)"
-       atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig"
+       atf_set "require.progs" "${RUMP_PROGS}"
 }
 
 ra_basic_body()
@@ -216,30 +239,30 @@
        setup_shmif0 ${RUMPCLI} ${IP6CLI}
        export RUMP_SERVER=${RUMPCLI}
        $DEBUG && rump.ndp -n -a
-       atf_check -s exit:0 -o match:'= 0' rump.sysctl net.inet6.ip6.accept_rtadv
+       atf_check -s exit:0 -o match:'= 0' \
+               rump.sysctl net.inet6.ip6.accept_rtadv
        unset RUMP_SERVER
 
        create_rtadvdconfig
        start_rtadvd $RUMPSRV $PIDFILE
-       sleep $WAITTIME
+       await_RA "${RUMPCLI}"
 
        export RUMP_SERVER=${RUMPCLI}
        atf_check -s exit:0 -o empty rump.ndp -r
-       atf_check -s exit:0 -o not-match:'advertised' rump.ndp -p
-       atf_check -s exit:0 -o match:'linkmtu=0' rump.ndp -n -i shmif0
-       atf_check -s exit:0 -o not-match:'S R' rump.ndp -n -a
-       atf_check -s exit:0 -o not-match:'fc00:1:' rump.ndp -n -a
-       atf_check -s exit:0 -o not-match:'fc00:1:' rump.ifconfig shmif0 inet6
+       atf_check -s exit:0 -o not-match:advertised rump.ndp -p
+       atf_check -s exit:0 -o match:linkmtu=0 rump.ndp -n -i shmif0
+       atf_check -s exit:0 -o not-match:'S R' -o not-match:fc00:1: \
+               rump.ndp -n -a
+       atf_check -s exit:0 -o not-match:fc00:1: rump.ifconfig shmif0 inet6
        unset RUMP_SERVER
 
        terminate_rtadvd $PIDFILE
 
-       export RUMP_SERVER=${RUMPCLI}
-       atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1
-       unset RUMP_SERVER
+       RUMP_SERVER=${RUMPCLI} atf_check -s exit:0 -o match:'0 -> 1' \
+               rump.sysctl -w net.inet6.ip6.accept_rtadv=1
 
        start_rtadvd $RUMPSRV $PIDFILE
-       sleep $WAITTIME
+       await_RA "${RUMPCLI}"
 
        check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
 
@@ -261,7 +284,7 @@
 {
 
        atf_set "descr" "Tests for flushing prefixes (ndp -P)"
-       atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig"
+       atf_set "require.progs" "${RUMP_PROGS}"
 }
 
 ra_flush_prefix_entries_body()
@@ -278,29 +301,29 @@
        create_rtadvdconfig
 
        export RUMP_SERVER=${RUMPCLI}
-       atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1
+       atf_check -s exit:0 -o match:'0 -> 1' \
+               rump.sysctl -w net.inet6.ip6.accept_rtadv=1



Home | Main Index | Thread Index | Old Index