#!/usr/bin/env bash # Send restconf rpc:s when starting from backend # Two specific usecases that have been problematic are tested here # In comparison test_restconf_rpc.sh: # - uses externally started restconf, here started by backend # - generic tests, here specific # The first usecases is: empty status message # 1. Start a minimal restconf # 2. Kill it externally (or it exits) # 3. Start a server # 4. Query status (Error message is returned) # The second usecase is: zombie process on exit # 1. Start server with bad address # 2. Zombie process appears # The third usecase is: restconf not removed # 1. Start server # 2. Remove server # 3. Check status (Error: still up) # Magic line must be first in script (see README.md) s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi APPNAME=example cfg=$dir/conf.xml startupdb=$dir/startup_db # Restconf debug RESTCONFDBG=0 RCPROTO=http # no ssl here cat < $cfg $cfg ietf-netconf:startup clixon-restconf:allow-auth-none /usr/local/share/clixon $IETFRFC $dir /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/backend example_backend.so$ /usr/local/lib/$APPNAME/restconf /usr/local/lib/$APPNAME/cli $APPNAME /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile $dir true true EOF cat < $dir/example.yang module example { namespace "urn:example:clixon"; prefix ex; revision 2021-03-05; leaf val{ type string; } } EOF function testrpc() { operation=$1 expectret=$2 sleep $DEMSLEEP new "send rpc $operation" ret=$($clixon_netconf -qf $cfg< restconf $operation ]]>]]> EOF ) # >&2 echo "ret:$ret" # debug expect1="[0-9]*" match=$(echo "$ret" | grep --null -Go "$expect1") # >&2 echo "match:$match" # debug if [ -z "$match" ]; then pid=0 else pid=$(echo "$match" | awk -F'[<>]' '{print $3}') fi # >&2 echo "pid:$pid" # debug if [ -z "$pid" ]; then err "Running process" "$ret" fi new "check restconf retvalue" if [ $operation = "status" ]; then if [ $expectret -eq 0 ]; then if [ $pid -ne 0 ]; then err "No process" "$pid" fi else if [ $pid -eq 0 ]; then err "Running process" fi fi echo "$pid" # cant use return that only uses 0-255 fi sleep $DEMSLEEP } # FIRST usecase new "1. Empty status message" new "kill old restconf" stop_restconf_pre new "test params: -f $cfg" if [ $BE -ne 0 ]; then new "kill old backend" sudo clixon_backend -z -f $cfg if [ $? -ne 0 ]; then err fi new "start backend -s init -f $cfg" start_backend -s init -f $cfg fi new "wait backend" wait_backend RESTCONFIG1=$(cat < true $RESTCONFDBG EOF ) LIBNS='xmlns="http://clicon.org/lib"' new "get status 1" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLOrestconfstatus]]>]]>" "^falseClixon RESTCONF process/www-data/clixon_restconf -f $cfg -D $RESTCONFDBG]]>]]>$" new "enable minimal restconf, no server" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$RESTCONFIG1]]>]]>" "^]]>]]>$" new "netconf commit" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" # Get pid2 new "get pid" pid2=$(testrpc status 1) echo "pid2:$pid2" new "get status 2" ret=$($clixon_netconf -qf $cfg< restconf status ]]>]]> EOF ) expect="^trueClixon RESTCONF process$pid2/www-data/clixon_restconf -f $cfg -D $RESTCONFDBG20[0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\.[0-9]*Z" match=$(echo "$ret" | grep --null -Go "$expect") if [ -z "$match" ]; then err "$expect" "$ret" fi # Kill it new "kill $pid2" sudo kill $pid2 sleep $DEMSLEEP # Why kill it twice? # I should really debug this,... it happens in docker somethimes but its not the aim of the test new "kill $pid2 again" sudo kill $pid2 sleep $DEMSLEEP new "Check killed" # Ensure no pid testrpc status 0 > /dev/null RESTCONFIG2=$(cat < default
0.0.0.0
80false
EOF ) new "create a server" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$RESTCONFIG2]]>]]>" "^]]>]]>$" new "netconf commit" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" # 3. get status new "get status 3" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLOrestconfstatus]]>]]>" "^trueClixon RESTCONF process" if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi # kill backend stop_backend -f $cfg fi # SECOND usecase new "2. zombie process on exit" new "kill old restconf" stop_restconf_pre new "test params: -f $cfg" if [ $BE -ne 0 ]; then new "kill old backend" sudo clixon_backend -z -f $cfg if [ $? -ne 0 ]; then err fi new "start backend -s init -f $cfg" start_backend -s init -f $cfg fi new "wait backend" wait_backend new "get status 1" testrpc status 0 > /dev/null RESTCONFIG1=$(cat < true $RESTCONFDBG none false default
221.0.0.1
80false
EOF ) new "Create server with invalid address" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$RESTCONFIG1]]>]]>" "^]]>]]>$" new "netconf commit" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" sleep $DEMSLEEP new "Check zombies" # NOTE unsure where zombies actually appear ret=$(ps aux| grep clixon | grep defunc | grep -v grep) if [ -n "$ret" ]; then err "No zombie process" "$ret" fi if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi # kill backend stop_backend -f $cfg fi sleep $DEMSLEEP new "Check zombies again" # NOTE unsure where zombies actually appear ret=$(ps aux| grep clixon | grep defunc | grep -v grep) if [ -n "$ret" ]; then err "No zombie process" "$ret" fi new "3. restconf not removed" new "kill old restconf" stop_restconf_pre new "test params: -f $cfg" if [ $BE -ne 0 ]; then new "kill old backend" sudo clixon_backend -z -f $cfg if [ $? -ne 0 ]; then err fi new "start backend -s init -f $cfg" start_backend -s init -f $cfg fi new "wait backend" wait_backend new "get status 1" testrpc status 0 > /dev/null RESTCONFIG1=$(cat < true $RESTCONFDBG none false default
0.0.0.0
80false
EOF ) new "Create server" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$RESTCONFIG1]]>]]>" "^]]>]]>$" new "commit create" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" # pid pid1=$(testrpc status 1) sleep $DEMSLEEP new "Get restconf config 1" expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+xml' $RCPROTO://localhost/restconf/data/clixon-restconf:restconf)" 0 "HTTP/1.1 200 OK" "truenone0falsedefault
0.0.0.0
80false
" # remove it new "Delete server" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLOnonedefault
0.0.0.0
80
]]>]]>" "^]]>]]>$" new "commit delete" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "Get restconf config 2" expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+xml' $RCPROTO://localhost/restconf/data/clixon-restconf:restconf)" 0 "HTTP/1.1 200 OK" "truenone0false" pid2=$(testrpc status 1) if [ $pid1 -ne $pid2 ]; then err "Same pid:$pid1" "$pid2" fi if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi # kill backend stop_backend -f $cfg fi new "endtest" endtest # Set by restconf_config unset RESTCONFIG1 unset RESTCONFIG2 unset RESTCONFDBG unset RCPROTO rm -rf $dir