#!/usr/bin/env bash # test xpath functions in YANG conditionals # XPATH base https://www.w3.org/TR/xpath-10/ # YANG XPATH functions: https://tools.ietf.org/html/rfc7950 # Tests: # - Contains # 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/$APPNAME.yang cat < $cfg $cfg ${YANG_INSTALLDIR} $dir $fyang /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/cli /usr/local/lib/$APPNAME/netconf /usr/local/lib/$APPNAME/backend $APPNAME /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME false EOF cat < $fyang module $APPNAME{ yang-version 1.1; prefix ex; namespace "urn:example:clixon"; identity interface-type; identity atm { base interface-type; } identity ethernet { base interface-type; } identity fast-ethernet { base ethernet; } identity gigabit-ethernet { base ethernet; } container top{ leaf class { /* contains */ type string; } list mylist{ /* contains */ key id; leaf id { type string; } leaf site { /* If the XPath expression is defined in a substatement to a data * node that represents configuration, the accessible tree is the * data in the datastore where the context node exists. * The "when" statement makes its parent data definition statement conditional. */ when "contains(../../class,'foo') or contains(../../class,'bar')"; type int32; } } } list interface { /* derived-from */ key name; leaf name{ type string; } leaf type { type identityref { base interface-type; } } leaf flags { description "See RFC 7950 Sec 10.6.1"; type bits{ bit UP; bit PROMISCUOUS; bit DISABLED; } } } augment "/ex:interface" { when 'derived-from(type, "ex:ethernet")'; leaf mtu { type uint32; } } augment "/ex:interface" { when 'derived-from-or-self(type, "ex:ethernet")'; leaf crc { type uint32; } } } 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" start_backend -s init -f $cfg fi new "wait backend" wait_backend # contains new "contains: Set site to foo that validates site OK" expecteof "$clixon_netconf -qf $cfg -D $DBG" 0 "$DEFAULTHELLOfoo1242]]>]]>" "^]]>]]>" new "netconf validate OK" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "Set site to fie which invalidates the when contains" expecteof "$clixon_netconf -qf $cfg -D $DBG" 0 "$DEFAULTHELLOfie]]>]]>" "^]]>]]>" new "netconf validate not OK" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationoperation-failederrorFailed WHEN condition of site in module example (WHEN xpath is contains(../../class,'foo') or contains(../../class,'bar'))]]>]]>$" new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" # derived-from new "derived-from: Set mtu to interface OK on GE" expecteof "$clixon_netconf -qf $cfg -D $DBG" 0 "$DEFAULTHELLOe0fast-ethernet1500]]>]]>" "^]]>]]>" new "netconf validate OK" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "Change type to atm" expecteof "$clixon_netconf -qf $cfg -D $DBG" 0 "$DEFAULTHELLOe0atm]]>]]>" "^]]>]]>" new "netconf validate not OK (mtu not allowed)" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationoperation-failederrorFailed WHEN condition of mtu in module example (WHEN xpath is derived-from(type, \"ex:ethernet\"))]]>]]>$" new "Change type to ethernet (self)" expecteof "$clixon_netconf -qf $cfg -D $DBG" 0 "$DEFAULTHELLOe0ethernet]]>]]>" "^]]>]]>" new "netconf validate not OK (mtu not allowed on self)" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationoperation-failederrorFailed WHEN condition of mtu in module example (WHEN xpath is derived-from(type, \"ex:ethernet\"))]]>]]>$" new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" # derived-from-or-self new "derived-from-or-self: Set crc to interface OK on GE" expecteof "$clixon_netconf -qf $cfg -D $DBG" 0 "$DEFAULTHELLOe0fast-ethernet42]]>]]>" "^]]>]]>" new "netconf validate OK" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "Change type to atm" expecteof "$clixon_netconf -qf $cfg -D $DBG" 0 "$DEFAULTHELLOe0atm]]>]]>" "^]]>]]>" new "netconf validate not OK (crc not allowed)" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationoperation-failederrorFailed WHEN condition of crc in module example (WHEN xpath is derived-from-or-self(type, \"ex:ethernet\"))]]>]]>$" new "Change type to ethernet (self)" expecteof "$clixon_netconf -qf $cfg -D $DBG" 0 "$DEFAULTHELLOe0ethernet]]>]]>" "^]]>]]>" new "netconf validate OK (self)" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" # bit-is-set new "Add interfaces with different flags" expecteof "$clixon_netconf -qf $cfg -D $DBG" 0 "$DEFAULTHELLOe0UPe1UP PROMISCUOUSe2PROMISCUOUS]]>]]>" "^]]>]]>" new "netconf bit-is-set" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^e1UP PROMISCUOUSe2PROMISCUOUS]]>]]>$" 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 sudo pkill -u root -f clixon_backend fi rm -rf $dir new "endtest" endtest