1#!/usr/bin/env bash
2# Transaction functionality: restart single plugin and observe that only that plugin
3# gets callbacks
4# The test uses two backend plugins (main and nacm) that logs.
5# nacm is then restarted, not main
6
7# Magic line must be first in script (see README.md)
8s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
9
10APPNAME=example
11
12cfg=$dir/conf_yang.xml
13fyang=$dir/trans.yang
14flog=$dir/backend.log
15touch $flog
16
17# Used as a trigger for user-validittion errors, eg <a>$errnr</a> is invalid
18errnr=42
19
20cat <<EOF > $fyang
21module trans{
22   yang-version 1.1;
23   namespace "urn:example:clixon";
24   prefix ex;
25   /* Generic config data */
26   container table{
27      list parameter{
28         key name;
29	 leaf name{
30	    type string;
31	 }
32	 leaf value{
33	    type string;
34	 }
35      }
36   }
37}
38EOF
39
40cat <<EOF > $cfg
41<clixon-config xmlns="http://clicon.org/config">
42  <CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
43  <CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
44  <CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
45  <CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
46  <CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
47  <!--CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP-->
48  <CLICON_NETCONF_DIR>/usr/local/lib/$APPNAME/netconf</CLICON_NETCONF_DIR>
49  <CLICON_RESTCONF_DIR>/usr/local/lib/$APPNAME/restconf</CLICON_RESTCONF_DIR>
50  <CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
51  <CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
52  <CLICON_SOCK>$dir/$APPNAME.sock</CLICON_SOCK>
53  <CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
54  <CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
55</clixon-config>
56EOF
57
58# Check statements in log
59# arg1: a statement to look for
60# arg2: expected line number
61checklog(){
62    s=$1 # statement
63    l0=$2 # linenr
64    new "Check $s in log"
65#    echo "grep \"transaction_log $s line:$l0\"  $flog"
66    t=$(grep -n "transaction_log $s" $flog)
67
68    if [ -z "$t" ]; then
69	echo -e "\e[31m\nError in Test$testnr [$testname]:"
70	if [ $# -gt 0 ]; then
71	    echo "Not found in log"
72	    echo
73	fi
74	echo -e "\e[0m"
75	exit -1
76    fi
77    l1=$(echo "$t" | awk -F ":" '{print $1}')
78    if [ $l1 -ne $l0 ]; then
79	echo -e "\e[31m\nError in Test$testnr [$testname]:"
80	if [ $# -gt 0 ]; then
81	    echo "Expected match on line $l0, found on $l1"
82	    echo
83	fi
84	echo -e "\e[0m"
85	exit -1
86    fi
87}
88
89new "test params: -f $cfg -l f$flog -- -t" # Fail on this
90# Bring your own backend
91if [ $BE -ne 0 ]; then
92    # kill old backend (if any)
93    new "kill old backend"
94    sudo clixon_backend -zf $cfg
95    if [ $? -ne 0 ]; then
96	err
97    fi
98    new "start backend  -s init -f $cfg -l f$flog -- -t /foo"
99    start_backend -s init -f $cfg -l f$flog -- -t /foo # -t means transaction logging (foo is dummy)
100
101    new "waiting"
102    wait_backend
103fi
104
105let nr=0
106
107new "Basic transaction to add top-level x"
108expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><table xmlns='urn:example:clixon'><parameter><name>$nr</name></parameter></table></config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
109
110new "Commit base"
111expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
112
113let line=13 # Skipping basic transaction. Sanity check, find one last transaction
114xml="<table xmlns=\"urn:example:clixon\"><parameter><name>0</name></parameter></table>"
115checklog "$nr nacm_end add: $xml" $line
116
117new "Send restart nacm plugin"
118expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><restart-plugin xmlns=\"http://clicon.org/lib\"><plugin>example_backend_nacm</plugin></restart-plugin></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>"
119
120# Now analyze log:
121# all transactions come from nacm plugin only.
122let nr++
123let line=14
124
125for op in begin validate complete commit commit_done end; do
126    checklog "$nr nacm_$op add: $xml" $line
127    let line++
128done
129
130# Negative test: restart a plugin that does not exist
131new "Send restart to nonexistatn plugin expect fail"
132expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><restart-plugin xmlns=\"http://clicon.org/lib\"><plugin>xxx</plugin></restart-plugin></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>plugin</bad-element></error-info><error-severity>error</error-severity><error-message>No such plugin</error-message></rpc-error></rpc-reply>]]>]]>$"
133
134if [ $BE -eq 0 ]; then
135    exit # BE
136fi
137
138new "Kill backend"
139# Check if premature kill
140pid=$(pgrep -u root -f clixon_backend)
141if [ -z "$pid" ]; then
142    err "backend already dead"
143fi
144# kill backend
145stop_backend -f $cfg
146
147rm -rf $dir
148
149unset nr
150