#!/usr/bin/env bash # Transaction functionality # The test uses two backend plugins (main and nacm) that logs to a file and a # netconf client to push operation. The tests then look at the log. # The test assumes the two plugins recognize the -- -t argument which includes # that one of them fails at validation at one point # The tests are as follows (first five only callbacks per se; then data vector tests) # 1. Validate-only transaction # 2. Commit transaction # 3. Validate system-error (invalid type detected by system) # 4. Validate user-error (invalidation by user callback) # 5. Commit user-error (invalidation by user callback) # -- to here only basic callback tests (that they occur). Below transaction data # 6. Detailed transaction vector add/del/change tests # For the last test, the yang is a list with three members, so that you can do # add/delete/change in a single go. # The user-error uses a trick feature in the example nacm plugin which is started # with an "error-trigger" xpath which triggers an error. This also toggles between # validation and commit errors # 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_yang.xml fyang=$dir/trans.yang flog=$dir/backend.log touch $flog # Used as a trigger for user-validittion errors, eg $errnr = 42 is invalid errnr=42 cat < $fyang module trans{ yang-version 1.1; namespace "urn:example:clixon"; prefix ex; container x { list y { key "a"; leaf a { type int32; } leaf b { description "change this (also use to check invalid)"; type int32{ range "0..100"; } } leaf c { description "del this"; type int32; } leaf d { description "add this"; type int32; } } } } EOF cat < $cfg $cfg /usr/local/share/clixon $fyang /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/backend /usr/local/lib/$APPNAME/netconf /usr/local/lib/$APPNAME/restconf /usr/local/lib/$APPNAME/cli $APPNAME $dir/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME EOF # Check statements in log # arg1: a statement to look for # arg2: expected line number function checklog(){ s=$1 # statement l0=$2 # linenr new "Check $s in log" # echo "grep \"transaction_log $s line:$l0\" $flog" t=$(grep -n "transaction_log $s" $flog) if [ -z "$t" ]; then echo -e "\e[31m\nError in Test$testnr [$testname]:" if [ $# -gt 0 ]; then echo "Not found in log" echo fi echo -e "\e[0m" exit -1 fi l1=$(echo "$t" | awk -F ":" '{print $1}') if [ $l1 -ne $l0 ]; then echo -e "\e[31m\nError in Test$testnr [$testname]:" if [ $# -gt 0 ]; then echo "Expected match on line $l0, found on $l1" echo fi echo -e "\e[0m" exit -1 fi } new "test params: -f $cfg -l f$flog -- -t -v /x/y[a=$errnr]" # Fail on this # Bring your own backend if [ $BE -ne 0 ]; then # kill old backend (if any) new "kill old backend" sudo clixon_backend -zf $cfg if [ $? -ne 0 ]; then err fi new "start backend -s init -f $cfg -l f$flog -- -t -v /x/y[a=$errnr]" start_backend -s init -f $cfg -l f$flog -- -t -v /x/y[a=$errnr] # -t means transaction logging new "waiting" wait_backend fi let nr=0 new "Basic transaction to add top-level x" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$nr]]>]]>" "^]]>]]>$" new "Commit base" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" let line=14 # Skipping basic transaction # 1. validate(-only) transaction let nr++ let line new "1. Validate-only transaction" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$nr]]>]]>" "^]]>]]>$" new "Validate-only validate" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" xml="$nr" for op in begin validate complete end; do checklog "$nr main_$op add: $xml" $line let line++ checklog "$nr nacm_$op add: $xml" $line let line++ done new "Validate-only discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" # 2. Commit transaction let nr++ new "2. Commit transaction config" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$nr]]>]]>" "^]]>]]>$" new "Commit transaction: commit" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" xml="$nr" for op in begin validate complete commit commit_done end; do checklog "$nr main_$op add: $xml" $line let line++ checklog "$nr nacm_$op add: $xml" $line let line++ done # 3. Validate only system-error (invalid type detected by system) let nr++ new "3. Validate system-error config (9999 not in range)" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$nr9999]]>]]>" "^]]>]]>$" new "Validate system-error validate (should fail)" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationbad-elementberrorNumber 9999 out of range: 0 - 100]]>]]>$" new "Validate system-error discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" for op in begin abort; do checklog "$nr main_$op add: $nr9999" $line let line++ checklog "$nr nacm_$op add: $nr9999" $line let line++ done # 4. Validate only user-error (invalidation by user callback) let nr++ new "4. Validate user-error config ($errnr is invalid)" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$errnr]]>]]>" "^]]>]]>$" new "Validate user-error validate (should fail)" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationoperation-failederrorUser error]]>]]>$" new "Validate user-error discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" for op in begin validate; do checklog "$nr main_$op add: $errnr" $line let line++ checklog "$nr nacm_$op add: $errnr" $line let line++ done let line++ # error message for op in abort; do checklog "$nr main_$op add: $errnr" $line let line++ checklog "$nr nacm_$op add: $errnr" $line let line++ done # 5. Commit user-error (invalidation by user callback) # XXX Note Validate-only user-error must immediately preceede this due to toggling # in nacm/transaction example test module let nr++ new "5. Commit user-error ($errnr is invalid)" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$errnr]]>]]>" "^]]>]]>$" new "Commit user-error commit" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationoperation-failederrorUser error]]>]]>$" new "Commit user-error discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" for op in begin validate complete commit ; do checklog "$nr main_$op add: $errnr" $line let line++ checklog "$nr nacm_$op add: $errnr" $line let line++ done let line++ # error message checklog "$nr main_revert add: $errnr" $line let line++ for op in abort; do checklog "$nr main_$op add: $errnr" $line let line++ checklog "$nr nacm_$op add: $errnr" $line let line++ done # 6. Detailed transaction vector add/del/change tests let nr++ let base=nr new "Add base $base entry" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$base00]]>]]>" "^]]>]]>$" new "netconf commit base" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" #Ignore let line+=12 let nr++ new "6. netconf mixed change: change b, del c, add d" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$base420]]>]]>" "^]]>]]>$" new "netconf commit change" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" # Check complete transaction $nr: for op in begin validate complete commit commit_done; do checklog "$nr main_$op add: 0" $line let line++ checklog "$nr main_$op change: 042" $line let line++ checklog "$nr nacm_$op add: 0" $line let line++ checklog "$nr nacm_$op change: 042" $line let line++ done # End is special because change does not have old element checklog "$nr main_end add: 0" $line let line++ # This check does not work if MOVE_TRANS_END is set checklog "$nr main_end change: 42" $line let line+=3 # skip nacm let nr++ let base=nr new "Add base $base entry" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$base1]]>]]>" "^]]>]]>$" new "netconf commit base" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" let line+=12 # Variant check that only b,c let nr++ new "7. netconf insert b,c between end-points" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO$base11]]>]]>" "^]]>]]>$" new "netconf commit base" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" # check complete for op in begin validate complete commit commit_done end; do checklog "$nr main_$op add: 11" $line let line++ checklog "$nr nacm_$op add: 11" $line let line++ done 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 rm -rf $dir unset nr new "endtest" endtest