#!/bin/bash # Scaling/ performance tests # Config + state data, only get # Restconf/Netconf/CLI # Use mixed ietf-interfaces config+state # Magic line must be first in script (see README.md) s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi # Which format to use as datastore format internally : ${format:=xml} # Number of list/leaf-list entries in file (cant be less than 2) : ${perfnr:=1000} # Number of requests made get/put : ${perfreq:=100} APPNAME=example cfg=$dir/config.xml fconfig=$dir/large.xml cat < $cfg $cfg $dir /usr/local/share/clixon clixon-example /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/example/$APPNAME.pidfile /usr/local/lib/$APPNAME/backend example_backend.so$ false $dir false $format example /usr/local/lib/example/cli /usr/local/lib/example/clispec 1 VARS 0 ietf-netconf:startup EOF new "test params: -f $cfg" if [ $BE -ne 0 ]; then new "kill old backend" sudo clixon_backend -zf $cfg if [ $? -ne 0 ]; then err fi new "start backend -s init -f $cfg -- -s" start_backend -s init -f $cfg -- -s fi new "kill old restconf daemon" sudo pkill -u www-data -f "/www-data/clixon_restconf" new "start restconf daemon" start_restconf -f $cfg new "waiting" wait_backend wait_restconf new "generate 'large' config with $perfnr list entries" echo -n "" > $fconfig for (( i=0; i<$perfnr; i++ )); do echo -n "e$iex:eth" >> $fconfig done echo "]]>]]>" >> $fconfig # Now take large config file and write it via netconf to candidate new "netconf write large config" expecteof_file "/usr/bin/time -f %e $clixon_netconf -qf $cfg" "$fconfig" "^]]>]]>$" # Now commit it from candidate to running new "netconf commit large config" expecteof "/usr/bin/time -f %e $clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" # START actual tests # Having a large db, get single entries many times # NETCONF get new "netconf get test single req" sel="/ietf-interfaces:interfaces/interface[name='e1']" msg="]]>]]>" expecteof "$clixon_netconf -qf $cfg" 0 "$msg" '^e1ex:ethtrueup]]>]]>$' new "netconf get $perfreq single reqs" { time -p for (( i=0; i<$perfreq; i++ )); do rnd=$(( ( RANDOM % $perfnr ) )) sel="/ietf-interfaces:interfaces/interface[name='e$rnd']" echo "]]>]]>" done | $clixon_netconf -qf $cfg > /dev/null; } 2>&1 | awk '/real/ {print $2}' # RESTCONF get new "restconf get test single req" expecteq "$(curl -s -X GET http://localhost/restconf/data/ietf-interfaces:interfaces/interface=e1)" 0 '{"ietf-interfaces:interface": [{"name": "e1","type": "ex:eth","enabled": true,"oper-status": "up"}]} ' new "restconf get $perfreq single reqs" #echo "curl -sG http://localhost/restconf/data/ietf-interfaces:interfaces/interface=e0" #curl -sG http://localhost/restconf/data/ietf-interfaces:interfaces/interface=e67 { time -p for (( i=0; i<$perfreq; i++ )); do rnd=$(( ( RANDOM % $perfnr ) )) curl -sG http://localhost/restconf/data/ietf-interfaces:interfaces/interface=e$rnd > /dev/null done } 2>&1 | awk '/real/ {print $2}' # CLI get new "cli get test single req" expectfn "$clixon_cli -1 -1f $cfg -l o show state xml interfaces interface e1" 0 '^ e1 ex:eth true up $' new "cli get $perfreq single reqs" { time -p for (( i=0; i<$perfreq; i++ )); do rnd=$(( ( RANDOM % $perfnr ) )) $clixon_cli -1 -f $cfg show state xml interfaces interface e$rnd > /dev/null done } 2>&1 | awk '/real/ {print $2}' # Get config in one large get new "netconf get large config" /usr/bin/time -f %e echo " ]]>]]>" | $clixon_netconf -qf $cfg > /tmp/netconf new "restconf get large config" /usr/bin/time -f %e curl -sG http://localhost/restconf/data/ietf-interfaces:interfaces | wc new "cli get large config" /usr/bin/time -f %e $clixon_cli -1f $cfg show state xml interfaces | wc new "Kill restconf daemon" stop_restconf if [ $BE -eq 0 ]; then exit # BE fi 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 rm -rf $dir