Merge branch 'modules-state'
This commit is contained in:
commit
2394c6f46e
43 changed files with 1755 additions and 587 deletions
|
|
@ -10,6 +10,7 @@ fi
|
|||
err=0
|
||||
testnr=0
|
||||
for test in test*.sh; do
|
||||
if [ $testnr != 0 ]; then echo; fi
|
||||
testfile=$test
|
||||
. ./$test
|
||||
errcode=$?
|
||||
|
|
|
|||
13
test/lib.sh
13
test/lib.sh
|
|
@ -59,6 +59,10 @@ testname=
|
|||
# If set to 0, override starting of clixon_backend in test (you bring your own)
|
||||
: ${BE:=1}
|
||||
|
||||
# If BE is set, some tests have a user timeout to show which params to set
|
||||
# for starting a backend
|
||||
: ${BETIMEOUT:=10}
|
||||
|
||||
# If set, enable debugging (of backend)
|
||||
: ${DBG:=0}
|
||||
|
||||
|
|
@ -95,7 +99,12 @@ dir=/var/tmp/$0
|
|||
if [ ! -d $dir ]; then
|
||||
mkdir $dir
|
||||
fi
|
||||
rm -rf $dir/*
|
||||
# If we bring our own backend BE=0 (it is already started),the backend may
|
||||
# have created some files (eg unix socket) in $dir and therefore cannot
|
||||
# be deleted
|
||||
if [ $BE -ne 0 ]; then
|
||||
rm -rf $dir/*
|
||||
fi
|
||||
|
||||
# error and exit,
|
||||
# arg1: expected
|
||||
|
|
@ -179,7 +188,7 @@ new(){
|
|||
fi
|
||||
testnr=`expr $testnr + 1`
|
||||
testname=$1
|
||||
>&2 echo "Test$testnr [$1]"
|
||||
>&2 echo "Test $testnr [$1]"
|
||||
}
|
||||
|
||||
# clixon command tester.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#!/bin/bash
|
||||
# Test of backward compatibility
|
||||
# 1) Load <3.9 startup/running/extra files without namespaces - ensure it returns namespaces
|
||||
# Test of backward compatibility, from last release to newer.
|
||||
#
|
||||
|
||||
# Magic line must be first in script (see README.md)
|
||||
|
|
@ -35,82 +34,6 @@ cat <<EOF > $cfg
|
|||
|
||||
EOF
|
||||
|
||||
testrun(){
|
||||
mode=$1
|
||||
expect=$2
|
||||
|
||||
dbdir=$dir/db
|
||||
cat <<EOF > $dbdir
|
||||
<config>
|
||||
<interfaces>
|
||||
<interface>
|
||||
<name>run</name>
|
||||
<type>ex:eth</type>
|
||||
</interface>
|
||||
</interfaces>
|
||||
</config>
|
||||
EOF
|
||||
sudo mv $dbdir /usr/local/var/$APPNAME/running_db
|
||||
|
||||
cat <<EOF > $dbdir
|
||||
<config>
|
||||
<interfaces>
|
||||
<interface>
|
||||
<name>startup</name>
|
||||
<type>ex:eth</type>
|
||||
</interface>
|
||||
</interfaces>
|
||||
</config>
|
||||
EOF
|
||||
sudo mv $dbdir /usr/local/var/$APPNAME/startup_db
|
||||
|
||||
cat <<EOF > $dir/config
|
||||
<config>
|
||||
<interfaces>
|
||||
<interface>
|
||||
<name>extra</name>
|
||||
<type>ex:eth</type>
|
||||
</interface>
|
||||
</interfaces>
|
||||
</config>
|
||||
EOF
|
||||
|
||||
new "test params: -f $cfg -s $mode -c $dir/config"
|
||||
|
||||
if [ $BE -ne 0 ]; then
|
||||
new "kill old backend"
|
||||
sudo clixon_backend -zf $cfg
|
||||
if [ $? -ne 0 ]; then
|
||||
err
|
||||
fi
|
||||
|
||||
new "start backend -f $cfg -s $mode -c $dir/config"
|
||||
start_backend -f $cfg -s $mode -c $dir/config
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
|
||||
fi
|
||||
|
||||
new "Check $mode"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' "^<rpc-reply>$expect</rpc-reply>]]>]]>$"
|
||||
|
||||
if [ $BE -eq 0 ]; then
|
||||
return # 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
|
||||
} # testrun
|
||||
|
||||
testrun running '<data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>extra</name><type>ex:eth</type><enabled>true</enabled></interface><interface><name>lo</name><type>ex:loopback</type><enabled>true</enabled></interface><interface><name>run</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data>'
|
||||
|
||||
testrun startup '<data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>extra</name><type>ex:eth</type><enabled>true</enabled></interface><interface><name>lo</name><type>ex:loopback</type><enabled>true</enabled></interface><interface><name>startup</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data>'
|
||||
# Nothing
|
||||
|
||||
rm -rf $dir
|
||||
|
|
|
|||
178
test/test_copy_config.sh
Executable file
178
test/test_copy_config.sh
Executable file
|
|
@ -0,0 +1,178 @@
|
|||
#!/bin/bash
|
||||
# RFC 6241:
|
||||
# 7.3 - Even if it advertises the :writable-running capability, a device
|
||||
# MAY choose not to support the <running/> configuration datastore
|
||||
# as the <target> parameter of a <copy-config> operation.
|
||||
# - If the <source> and <target> parameters identify the same URL or
|
||||
# configuration datastore, an error MUST be returned with an error-
|
||||
# tag containing "invalid-value".
|
||||
# 8.3.5.1 The candidate configuration can be used as a source or target
|
||||
# 8.4.1 If :startup capability is advertized, <copy-config> from running to
|
||||
# startup is also necessary
|
||||
# 8.8.5.2 :url capability <copy-config> accepts <url> element as value of
|
||||
# the <source> and the <target> parameters.
|
||||
#
|
||||
# The test checks that these are allowed:
|
||||
# running->startup
|
||||
# running->candidate
|
||||
# candidate->startup
|
||||
# startup->candidate
|
||||
# And checks that copying to running is not allowed
|
||||
|
||||
# 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
|
||||
# include err() and new() functions and creates $dir
|
||||
. ./lib.sh
|
||||
|
||||
cfg=$dir/conf_yang.xml
|
||||
|
||||
# Use yang in example
|
||||
|
||||
cat <<EOF > $cfg
|
||||
<config>
|
||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||
<CLICON_MODULE_SET_ID>42</CLICON_MODULE_SET_ID>
|
||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_MODULE_MAIN>clixon-example</CLICON_YANG_MODULE_MAIN>
|
||||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
||||
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
|
||||
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>
|
||||
<CLICON_NETCONF_DIR>/usr/local/lib/$APPNAME/netconf</CLICON_NETCONF_DIR>
|
||||
<CLICON_RESTCONF_DIR>/usr/local/lib/$APPNAME/restconf</CLICON_RESTCONF_DIR>
|
||||
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
||||
<CLICON_SOCK>$dir/$APPNAME.sock</CLICON_SOCK>
|
||||
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
|
||||
<CLICON_CLI_GENMODEL_COMPLETION>1</CLICON_CLI_GENMODEL_COMPLETION>
|
||||
<CLICON_XMLDB_DIR>$dir</CLICON_XMLDB_DIR>
|
||||
<CLICON_XMLDB_PLUGIN>/usr/local/lib/xmldb/text.so</CLICON_XMLDB_PLUGIN>
|
||||
</config>
|
||||
EOF
|
||||
|
||||
# Create empty startup
|
||||
cat <<EOF > $dir/startup_db
|
||||
<config/>
|
||||
EOF
|
||||
|
||||
# rm candidate and running
|
||||
rm -f $dir/running_db
|
||||
rm -f $dir/candidate_db
|
||||
|
||||
new "test params: -f $cfg"
|
||||
# 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"
|
||||
# start new backend
|
||||
echo "sudo $clixon_backend -s init -f $cfg -D $DBG"
|
||||
sudo $clixon_backend -s init -f $cfg -D $DBG
|
||||
if [ $? -ne 0 ]; then
|
||||
err
|
||||
fi
|
||||
fi
|
||||
|
||||
new "Add config to candidate"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="create"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf commit to running"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "Delete candidate"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="delete"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||
|
||||
# Here startup and candidate are empty, only running has content
|
||||
# test running->startup and running->candidate
|
||||
new "Check candidate empty"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
||||
|
||||
new "Check startup empty"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><startup/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
||||
|
||||
new "copy running->startup"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><copy-config><target><startup/></target><source><running/></source></copy-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "copy running->candidate"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><copy-config><target><candidate/></target><source><running/></source></copy-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
# Here startup and candidate have content
|
||||
new "Check candidate content"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$'
|
||||
|
||||
new "Check startup content"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><startup/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$'
|
||||
|
||||
new "Delete startup"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><delete-config><target><startup/></target></delete-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
# Here startup is empty and candidate has content
|
||||
# test candidate->startup
|
||||
new "Check startup empty"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><startup/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
||||
|
||||
new "copy candidate->startup"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><copy-config><target><startup/></target><source><candidate/></source></copy-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "Check startup content"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><startup/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$'
|
||||
|
||||
new "Delete candidate"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="delete"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||
|
||||
# Here candidate is empty and startup has content
|
||||
# test startup->candidate
|
||||
new "Check candidate empty"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
||||
|
||||
new "copy startup->candidate"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><copy-config><target><candidate/></target><source><startup/></source></copy-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "Check candidate content"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$'
|
||||
|
||||
# Negative test: check copying to running is not allowed
|
||||
new "Delete candidate"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="delete"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||
|
||||
new "netconf commit to running"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
# Here running is empty
|
||||
new "Check running empty"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><running/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
||||
|
||||
# Add to candidate
|
||||
new "copy startup->candidate"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><copy-config><target><candidate/></target><source><startup/></source></copy-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "copy startup->running not allowed"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><copy-config><target><running/></target><source><startup/></source></copy-config></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>unknown-element</error-tag><error-info><bad-element>running</bad-element></error-info><error-severity>error</error-severity></rpc-error></rpc-reply>]]>]]>$"
|
||||
|
||||
# Here running is empty
|
||||
new "Check running empty"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><running/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
||||
|
||||
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
|
||||
sudo clixon_backend -z -f $cfg
|
||||
if [ $? -ne 0 ]; then
|
||||
err "kill backend"
|
||||
fi
|
||||
|
||||
rm -rf $dir
|
||||
|
|
@ -155,7 +155,7 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "$(cat $tmp)" '<rpc-reply><data
|
|||
|
||||
# Check as file
|
||||
new "verify running from start, should be: c,l,y0,y1,y2,y3; y1 and y3 sorted."
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><c xmlns="urn:example:order"><d>hej</d></c><l xmlns="urn:example:order">hopp</l><y0 xmlns="urn:example:order">d</y0><y0 xmlns="urn:example:order">b</y0><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">a</y0><y1 xmlns="urn:example:order">a</y1><y1 xmlns="urn:example:order">b</y1><y1 xmlns="urn:example:order">c</y1><y1 xmlns="urn:example:order">d</y1><y2 xmlns="urn:example:order"><k>d</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>a</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>bar</a></y2><y3 xmlns="urn:example:order"><k>a</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>b</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>c</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>d</k><a>bar</a></y3><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>lo</name><type>ex:loopback</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><c xmlns="urn:example:order"><d>hej</d></c><l xmlns="urn:example:order">hopp</l><y0 xmlns="urn:example:order">d</y0><y0 xmlns="urn:example:order">b</y0><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">a</y0><y1 xmlns="urn:example:order">a</y1><y1 xmlns="urn:example:order">b</y1><y1 xmlns="urn:example:order">c</y1><y1 xmlns="urn:example:order">d</y1><y2 xmlns="urn:example:order"><k>d</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>a</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>bar</a></y2><y3 xmlns="urn:example:order"><k>a</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>b</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>c</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>d</k><a>bar</a></y3></data></rpc-reply>]]>]]>$'
|
||||
|
||||
new "get each ordered-by user leaf-list"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k='a']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>a</k><a>bar</a></y2></data></rpc-reply>]]>]]>$'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/bin/bash
|
||||
# Startup test: Start clicon daemon in the (four) different startup modes
|
||||
# and the dbs and files are setup as follows:
|
||||
# (init, none, running, or startup)
|
||||
# The dbs and files are setup as follows:
|
||||
# - The example reset_state callback adds "lo" interface
|
||||
# - An extra xml configuration file starts with an "extra" interface
|
||||
# - running db starts with a "run" interface
|
||||
|
|
@ -27,8 +28,7 @@ cat <<EOF > $cfg
|
|||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
||||
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
|
||||
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
|
||||
<CLICON_CLI_GENMODEL_COMPLETION>1</CLICON_CLI_GENMODEL_COMPLETION>
|
||||
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
|
||||
<CLICON_XMLDB_DIR>$dir</CLICON_XMLDB_DIR>
|
||||
<CLICON_XMLDB_PLUGIN>/usr/local/lib/xmldb/text.so</CLICON_XMLDB_PLUGIN>
|
||||
<CLICON_CLI_LINESCROLLING>0</CLICON_CLI_LINESCROLLING>
|
||||
<CLICON_STARTUP_MODE>init</CLICON_STARTUP_MODE>
|
||||
|
|
@ -36,12 +36,17 @@ cat <<EOF > $cfg
|
|||
|
||||
EOF
|
||||
|
||||
# Create a pre-set running, startup and (extra) config.
|
||||
# The configs are identified by an interface called run, startup, extra.
|
||||
# Depending on startup mode (init, none, running, or startup)
|
||||
# expect different output of an initial get-config
|
||||
testrun(){
|
||||
mode=$1
|
||||
expect=$2
|
||||
|
||||
dbdir=$dir/db
|
||||
cat <<EOF > $dbdir
|
||||
# Create running-db containin the interface "run"
|
||||
sudo rm -f $dir/running_db
|
||||
cat <<EOF > $dir/running_db
|
||||
<config>
|
||||
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
|
||||
<interface>
|
||||
|
|
@ -51,9 +56,10 @@ testrun(){
|
|||
</interfaces>
|
||||
</config>
|
||||
EOF
|
||||
sudo mv $dbdir /usr/local/var/$APPNAME/running_db
|
||||
|
||||
cat <<EOF > $dbdir
|
||||
# Create startup-db containin the interface "startup"
|
||||
sudo rm -f $dir/startup_db
|
||||
cat <<EOF > $dir/startup_db
|
||||
<config>
|
||||
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
|
||||
<interface>
|
||||
|
|
@ -63,8 +69,9 @@ EOF
|
|||
</interfaces>
|
||||
</config>
|
||||
EOF
|
||||
sudo mv $dbdir /usr/local/var/$APPNAME/startup_db
|
||||
|
||||
# Create extra xml containin the interface "extra"
|
||||
sudo rm -f $dir/config
|
||||
cat <<EOF > $dir/config
|
||||
<config>
|
||||
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
|
||||
|
|
@ -76,20 +83,23 @@ EOF
|
|||
</config>
|
||||
EOF
|
||||
|
||||
# kill old backend (if any)
|
||||
new "kill old backend"
|
||||
sudo clixon_backend -zf $cfg
|
||||
if [ $? -ne 0 ]; then
|
||||
err
|
||||
if [ $BE -ne 0 ]; then # Bring your own backend
|
||||
# kill old backend (if any)
|
||||
new "kill old backend"
|
||||
sudo clixon_backend -zf $cfg
|
||||
if [ $? -ne 0 ]; then
|
||||
err
|
||||
fi
|
||||
new "start backend -f $cfg -s $mode -c $dir/config"
|
||||
start_backend -s $mode -f $cfg -c $dir/config
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
else
|
||||
new "Restart backend as eg follows: -Ff $cfg -s $mode -c $dir/config # $BETIMEOUT s"
|
||||
sleep $BETIMEOUT
|
||||
fi
|
||||
|
||||
new "start backend -f $cfg -s $mode -c $dir/config"
|
||||
start_backend -s $mode -f $cfg -c $dir/config
|
||||
|
||||
new "waiting"
|
||||
sleep $RCWAIT
|
||||
|
||||
new "Check $mode"
|
||||
new "Startup test for init mode: $mode"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' "^<rpc-reply>$expect</rpc-reply>]]>]]>$"
|
||||
|
||||
new "Kill backend"
|
||||
|
|
@ -102,12 +112,12 @@ EOF
|
|||
stop_backend -f $cfg
|
||||
} # testrun
|
||||
|
||||
testrun init '<data/>'
|
||||
testrun init '<data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>extra</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data>'
|
||||
|
||||
testrun none '<data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>run</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data>'
|
||||
|
||||
testrun running '<data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>extra</name><type>ex:eth</type><enabled>true</enabled></interface><interface><name>lo</name><type>ex:loopback</type><enabled>true</enabled></interface><interface><name>run</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data>'
|
||||
testrun running '<data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>extra</name><type>ex:eth</type><enabled>true</enabled></interface><interface><name>run</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data>'
|
||||
|
||||
testrun startup '<data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>extra</name><type>ex:eth</type><enabled>true</enabled></interface><interface><name>lo</name><type>ex:loopback</type><enabled>true</enabled></interface><interface><name>startup</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data>'
|
||||
testrun startup '<data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>extra</name><type>ex:eth</type><enabled>true</enabled></interface><interface><name>startup</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data>'
|
||||
|
||||
rm -rf $dir
|
||||
|
|
|
|||
333
test/test_upgrade.sh
Executable file
333
test/test_upgrade.sh
Executable file
|
|
@ -0,0 +1,333 @@
|
|||
#!/bin/bash
|
||||
# Starting clixon with outdated (or not) modules
|
||||
# This relieas on storing RFC7895 YANG Module Library modules-state info
|
||||
# in the datastore (or XML files?)
|
||||
# There is also a: Factory default Setting:
|
||||
# draft-wu-netconf-restconf-factory-restore-03
|
||||
# And: A YANG Data Model for module revision management:
|
||||
# draft-wang-netmod-module-revision-management-01
|
||||
# The test is made with three Yang models A, B and C as follows:
|
||||
# Yang module A has revisions "814-01-28" and "2019-01-01"
|
||||
# Yang module B has only revision "2019-01-01"
|
||||
# Yang module C has only revision "2019-01-01"
|
||||
# The system is started YANG modules:
|
||||
# A revision "2019-01-01"
|
||||
# B revision "2019-01-01"
|
||||
# The (startup) configuration XML file has:
|
||||
# A revision "814-01-28";
|
||||
# B revision "2019-01-01"
|
||||
# C revision "2019-01-01"
|
||||
# Which means the following:
|
||||
# A has an obsolete version
|
||||
# containing a0 which has been removed, and a1 which is OK
|
||||
# B has a compatible version
|
||||
# C is not present in the system
|
||||
|
||||
APPNAME=example
|
||||
|
||||
# include err() and new() functions and creates $dir
|
||||
. ./lib.sh
|
||||
|
||||
cfg=$dir/conf_yang.xml
|
||||
fyangA0=$dir/A@814-01-28.yang
|
||||
fyangA1=$dir/A@2019-01-01.yang
|
||||
fyangB=$dir/B@2019-01-01.yang
|
||||
|
||||
# Yang module A revision "814-01-28"
|
||||
# Note that this Yang model will exist in the DIR but will not be loaded
|
||||
# by the system. Just here for reference
|
||||
# XXX: Maybe it should be loaded and used in draft-wu?
|
||||
cat <<EOF > $fyangA0
|
||||
module A{
|
||||
prefix a;
|
||||
revision 814-01-28;
|
||||
namespace "urn:example:a";
|
||||
leaf a0{
|
||||
type string;
|
||||
}
|
||||
leaf a1{
|
||||
type string;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Yang module A revision "2019-01-01"
|
||||
cat <<EOF > $fyangA1
|
||||
module A{
|
||||
prefix a;
|
||||
revision 2019-01-01;
|
||||
revision 814-01-28;
|
||||
namespace "urn:example:a";
|
||||
/* leaf a0 has been removed */
|
||||
leaf a1{
|
||||
description "exists in both versions";
|
||||
type string;
|
||||
}
|
||||
leaf a2{
|
||||
description "has been added";
|
||||
type string;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Yang module B revision "2019-01-01"
|
||||
cat <<EOF > $fyangB
|
||||
module B{
|
||||
prefix b;
|
||||
revision 2019-01-01;
|
||||
namespace "urn:example:b";
|
||||
leaf b{
|
||||
type string;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Yang module C revision "2019-01-01" (note not written to yang dir)
|
||||
cat <<EOF > /dev/null
|
||||
module C{
|
||||
prefix c;
|
||||
revision 2019-01-01;
|
||||
namespace "urn:example:c";
|
||||
leaf c{
|
||||
type string;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Create configuration
|
||||
cat <<EOF > $cfg
|
||||
<config>
|
||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_MAIN_DIR>$dir</CLICON_YANG_MAIN_DIR>
|
||||
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
|
||||
<CLICON_BACKEND_DIR>/usr/local/lib/example/backend</CLICON_BACKEND_DIR>
|
||||
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
|
||||
<CLICON_XMLDB_DIR>$dir</CLICON_XMLDB_DIR>
|
||||
<CLICON_XMLDB_PLUGIN>/usr/local/lib/xmldb/text.so</CLICON_XMLDB_PLUGIN>
|
||||
<CLICON_XMLDB_MODSTATE>true</CLICON_XMLDB_MODSTATE>
|
||||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
||||
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
||||
</config>
|
||||
EOF
|
||||
|
||||
# Create failsafe db
|
||||
cat <<EOF > $dir/failsafe_db
|
||||
<config>
|
||||
<a1 xmlns="urn:example:a">always work</a1>
|
||||
</config>
|
||||
EOF
|
||||
|
||||
# Create compatible startup db
|
||||
# startup config XML with following
|
||||
cat <<EOF > $dir/compat-valid.xml
|
||||
<config>
|
||||
<modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
|
||||
<module-set-id>42</module-set-id>
|
||||
<module>
|
||||
<name>A</name>
|
||||
<revision>2019-01-01</revision>
|
||||
<namespace>urn:example:a</namespace>
|
||||
</module>
|
||||
<module>
|
||||
<name>B</name>
|
||||
<revision>2019-01-01</revision>
|
||||
<namespace>urn:example:b</namespace>
|
||||
</module>
|
||||
</modules-state>
|
||||
<a1 xmlns="urn:example:a">always work</a1>
|
||||
<b xmlns="urn:example:b">other text</b>
|
||||
</config>
|
||||
EOF
|
||||
|
||||
# Create compatiblae startup db
|
||||
# startup config XML with following
|
||||
cat <<EOF > $dir/compat-invalid.xml
|
||||
<config>
|
||||
<modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
|
||||
<module-set-id>42</module-set-id>
|
||||
<module>
|
||||
<name>A</name>
|
||||
<revision>2019-01-01</revision>
|
||||
<namespace>urn:example:a</namespace>
|
||||
</module>
|
||||
<module>
|
||||
<name>B</name>
|
||||
<revision>2019-01-01</revision>
|
||||
<namespace>urn:example:b</namespace>
|
||||
</module>
|
||||
</modules-state>
|
||||
<a0 xmlns="urn:example:a">old version</a0>
|
||||
<a1 xmlns="urn:example:a">always work</a1>
|
||||
<b xmlns="urn:example:b">other text</b>
|
||||
<c xmlns="urn:example:c">bla bla</c>
|
||||
</config>
|
||||
EOF
|
||||
|
||||
|
||||
# Create non-compat valid startup db
|
||||
# startup config XML with following (A obsolete, B OK, C lacking)
|
||||
# But XML is OK
|
||||
cat <<EOF > $dir/non-compat-valid.xml
|
||||
<config>
|
||||
<modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
|
||||
<module-set-id>42</module-set-id>
|
||||
<module>
|
||||
<name>A</name>
|
||||
<revision>814-01-28</revision>
|
||||
<namespace>urn:example:a</namespace>
|
||||
</module>
|
||||
<module>
|
||||
<name>B</name>
|
||||
<revision>2019-01-01</revision>
|
||||
<namespace>urn:example:b</namespace>
|
||||
</module>
|
||||
<module>
|
||||
<name>C</name>
|
||||
<revision>2019-01-01</revision>
|
||||
<namespace>urn:example:c</namespace>
|
||||
</module>
|
||||
</modules-state>
|
||||
<a1 xmlns="urn:example:a">always work</a1>
|
||||
<b xmlns="urn:example:b">other text</b>
|
||||
</config>
|
||||
EOF
|
||||
|
||||
# Create non-compat startup db
|
||||
# startup config XML with following (A obsolete, B OK, C lacking)
|
||||
cat <<EOF > $dir/non-compat-invalid.xml
|
||||
<config>
|
||||
<modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
|
||||
<module-set-id>42</module-set-id>
|
||||
<module>
|
||||
<name>A</name>
|
||||
<revision>814-01-28</revision>
|
||||
<namespace>urn:example:a</namespace>
|
||||
</module>
|
||||
<module>
|
||||
<name>B</name>
|
||||
<revision>2019-01-01</revision>
|
||||
<namespace>urn:example:b</namespace>
|
||||
</module>
|
||||
<module>
|
||||
<name>C</name>
|
||||
<revision>2019-01-01</revision>
|
||||
<namespace>urn:example:c</namespace>
|
||||
</module>
|
||||
</modules-state>
|
||||
<a0 xmlns="urn:example:a">old version</a0>
|
||||
<a1 xmlns="urn:example:a">always work</a1>
|
||||
<b xmlns="urn:example:b">other text</b>
|
||||
<c xmlns="urn:example:c">bla bla</c>
|
||||
</config>
|
||||
EOF
|
||||
|
||||
# Compatible startup with syntax errors
|
||||
cat <<EOF > $dir/compat-err.xml
|
||||
<config>
|
||||
<modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
|
||||
<module-set-id>42</module-set-id>
|
||||
<module>
|
||||
<name>A</name>
|
||||
<revision>2019-01-01</revision>
|
||||
<namespace>urn:example:a</namespace>
|
||||
</module>
|
||||
<module>
|
||||
<name>B</name>
|
||||
<revision>2019-01-01</revision>
|
||||
<namespace>urn:example:b</namespace>
|
||||
</module>
|
||||
</modules-state>
|
||||
<<a3 xmlns="urn:example:a">always work</a2>
|
||||
<b xmlns="urn:example:b">other text
|
||||
</config>
|
||||
EOF
|
||||
|
||||
# Start system in $mode with existing (old) configuration in $db
|
||||
# mode is one of: init, none, running, or startup
|
||||
# db is one of: running_db or startup_db
|
||||
runtest(){
|
||||
mode=$1
|
||||
expect=$2
|
||||
startup=$3
|
||||
|
||||
new "test params: -f $cfg"
|
||||
# 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 $mode -f $cfg"
|
||||
# start new backend
|
||||
sudo $clixon_backend -s $mode -f $cfg -D $DBG
|
||||
if [ $? -ne 0 ]; then
|
||||
err
|
||||
fi
|
||||
else
|
||||
new "Restart backend as eg follows: -Ff $cfg -s $mode ($BETIMEOUT s)"
|
||||
sleep $BETIMEOUT
|
||||
fi
|
||||
|
||||
new "Get running"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' "^<rpc-reply>$expect</rpc-reply>]]>]]>$"
|
||||
|
||||
new "Get startup"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><startup/></source></get-config></rpc>]]>]]>' "^<rpc-reply>$startup</rpc-reply>]]>]]>$"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
# Compatible == all yang modules match
|
||||
# runtest <mode> <expected running> <expected startup>
|
||||
|
||||
new "1. Load compatible valid startup (all OK)"
|
||||
(cd $dir; rm -f tmp_db candidate_db running_db startup_db) # remove databases
|
||||
(cd $dir; cp compat-valid.xml startup_db)
|
||||
runtest startup '<data><a1 xmlns="urn:example:a">always work</a1><b xmlns="urn:example:b">other text</b></data>' '<data><a1 xmlns="urn:example:a">always work</a1><b xmlns="urn:example:b">other text</b></data>'
|
||||
|
||||
new "2. Load compatible running valid running (rest of tests are startup)"
|
||||
(cd $dir; rm -f tmp_db candidate_db running_db startup_db) # remove databases
|
||||
(cd $dir; cp compat-valid.xml running_db)
|
||||
runtest running '<data><a1 xmlns="urn:example:a">always work</a1><b xmlns="urn:example:b">other text</b></data>' '<data><a1 xmlns="urn:example:a">always work</a1><b xmlns="urn:example:b">other text</b></data>'
|
||||
|
||||
new "3. Load non-compat valid startup"
|
||||
(cd $dir; rm -f tmp_db candidate_db running_db startup_db) # remove databases
|
||||
(cd $dir; cp non-compat-valid.xml startup_db)
|
||||
runtest startup '<data><a1 xmlns="urn:example:a">always work</a1><b xmlns="urn:example:b">other text</b></data>' '<data><a1 xmlns="urn:example:a">always work</a1><b xmlns="urn:example:b">other text</b></data>'
|
||||
|
||||
new "4. Load non-compat invalid startup. Enter failsafe, startup invalid."
|
||||
(cd $dir; rm -f tmp_db candidate_db running_db startup_db) # remove databases
|
||||
(cd $dir; cp non-compat-invalid.xml startup_db)
|
||||
runtest startup '<data><a1 xmlns="urn:example:a">always work</a1></data>' '<data><a1 xmlns="urn:example:a">always work</a1><b xmlns="urn:example:b">other text</b><a0 xmlns="urn:example:a">old version</a0><c xmlns="urn:example:c">bla bla</c></data>'
|
||||
|
||||
new "5. Load non-compat invalid running. Enter failsafe, startup invalid."
|
||||
(cd $dir; rm -f tmp_db candidate_db running_db startup_db) # remove databases
|
||||
(cd $dir; cp non-compat-invalid.xml running_db)
|
||||
runtest running '<data><a1 xmlns="urn:example:a">always work</a1></data>' '<data><a1 xmlns="urn:example:a">always work</a1><b xmlns="urn:example:b">other text</b><a0 xmlns="urn:example:a">old version</a0><c xmlns="urn:example:c">bla bla</c></data>'
|
||||
|
||||
new "6. Load compatible invalid startup."
|
||||
(cd $dir; rm -f tmp_db candidate_db running_db startup_db) # remove databases
|
||||
(cd $dir; cp compat-invalid.xml startup_db)
|
||||
runtest startup '<data><a1 xmlns="urn:example:a">always work</a1></data>' '<data><a1 xmlns="urn:example:a">always work</a1><b xmlns="urn:example:b">other text</b><a0 xmlns="urn:example:a">old version</a0><c xmlns="urn:example:c">bla bla</c></data>'
|
||||
|
||||
new "7. Load non-compat startup. Syntax fail, enter failsafe, startup invalid"
|
||||
(cd $dir; rm -f tmp_db candidate_db running_db startup_db) # remove databases
|
||||
(cd $dir; cp compat-err.xml startup_db)
|
||||
runtest startup '<data><a1 xmlns="urn:example:a">always work</a1></data>' '<rpc-error><error-type>application</error-type><error-tag>operation-failed</error-tag><error-severity>error</error-severity><error-message>read registry</error-message></rpc-error>'
|
||||
|
||||
if [ $BE -ne 0 ]; then
|
||||
rm -rf $dir
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue