#!/usr/bin/env bash # Choice type and mandatory # Example from RFC7950 Sec 7.9.6 # Also test mandatory behaviour as in 7.6.5 # (XXX Would need default test in 7.6.4) # Use-case: The ietf-netconf edit-config has a shorthand version of choice w mandatory: # container { choice target { mandatory; leaf candidate; leaf running; }} # 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/choice.xml fyang=$dir/type.yang cat < $cfg $cfg $dir /usr/local/share/clixon $IETFRFC $fyang /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/cli $APPNAME /usr/local/var/$APPNAME/$APPNAME.sock false /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME EOF cat < $fyang module system{ yang-version 1.1; namespace "urn:example:config"; prefix ex; container system{ /* From RFC 7950 7.9.6 */ container protocol { presence true; choice name { case a { leaf udp { type empty; } } case b { leaf tcp { type empty; } } } } /* Same but shorthand */ container shorthand { presence true; choice name { leaf udp { type empty; } leaf tcp { type empty; } } } /* Same with mandatory true */ container mandatory { presence true; choice name { mandatory true; case a { leaf udp { type empty; } } case b { leaf tcp { type empty; } } } } /* Choice with multiple items */ choice mch { case first{ leaf-list ma { type int32; } leaf mb { type int32; } } case second{ leaf-list mc { type int32; } } } } } 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 sudo pkill -f clixon_backend # to be sure new "start backend -s init -f $cfg" start_backend -s init -f $cfg fi new "waiting" wait_backend new "kill old restconf daemon" sudo pkill -u $wwwuser -f clixon_restconf new "start restconf daemon" start_restconf -f $cfg new "waiting" wait_restconf # First vanilla (protocol) case new "netconf validate empty" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" new "netconf set protocol both udp and tcp" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^]]>]]>$" new "netconf validate both udp and tcp fail" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^applicationbad-elementudperrorElement in choice statement already exists]]>]]>$" new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" new "netconf set empty protocol" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^]]>]]>$" new "netconf validate protocol" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" new "netconf set protocol tcp" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^]]>]]>$" new "netconf get protocol tcp" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^]]>]]>$' new "netconf commit protocol tcp" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" new "netconf changing from TCP to UDP (RFC7950 7.9.6)" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^]]>]]>$' new "netconf get protocol udp" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^]]>]]>$' new "netconf commit protocol udp" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" #-- restconf new "restconf DELETE whole datastore" expectfn 'curl -s -X DELETE http://localhost/restconf/data' 0 "" new "restconf set protocol tcp+udp fail" expecteq "$(curl -s -X PUT -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/system:system/protocol -d '{"system:protocol":{"tcp": [null], "udp": [null]}}')" 0 '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"bad-element","error-info":{"bad-element":"udp"},"error-severity":"error","error-message":"Element in choice statement already exists"}}} ' new "restconf set protocol tcp" expecteq "$(curl -s -X PUT -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/system:system/protocol -d {\"system:protocol\":{\"tcp\":[null]}})" 0 "" new "restconf get protocol tcp" expecteq "$(curl -s -X GET http://localhost/restconf/data/system:system)" 0 '{"system:system":{"protocol":{"tcp":[null]}}} ' new "restconf set protocol tcp+udp fail" expecteq "$(curl -s -X PUT -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/system:system/protocol -d '{"system:protocol":{"tcp": [null], "udp": [null]}}')" 0 '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"bad-element","error-info":{"bad-element":"udp"},"error-severity":"error","error-message":"Element in choice statement already exists"}}} ' new "cli set protocol udp" expectfn "$clixon_cli -1 -f $cfg -l o set system protocol udp" 0 "^$" new "cli get protocol udp" expectfn "$clixon_cli -1 -f $cfg -l o show configuration cli " 0 "^system protocol udp$" new "cli change protocol to tcp" expectfn "$clixon_cli -1 -f $cfg -l o set system protocol tcp" 0 "^$" new "cli get protocol tcp" expectfn "$clixon_cli -1 -f $cfg -l o show configuration cli " 0 "^system protocol tcp$" new "cli delete all" expectfn "$clixon_cli -1 -f $cfg -l o delete all" 0 "^$" new "commit" expectfn "$clixon_cli -1 -f $cfg -l o commit" 0 "^$" # Second shorthand (no case) new "netconf set protocol both udp and tcp" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^]]>]]>$" new "netconf validate both udp and tcp fail" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^applicationbad-elementudperrorElement in choice statement already exists]]>]]>$" new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" new "netconf set shorthand tcp" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^]]>]]>$" new "netconf changing from TCP to UDP (RFC7950 7.9.6)" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^]]>]]>$' new "netconf get shorthand udp" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^]]>]]>$' new "netconf validate shorthand" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" # Third check mandatory new "netconf set empty mandatory" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^]]>]]>$" new "netconf get mandatory empty" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^]]>]]>$' new "netconf validate mandatory" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationdata-missingmissing-choicenameerror]]>]]>$' new "netconf set mandatory udp" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^]]>]]>$" new "netconf get mandatory udp" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^]]>]]>$' new "netconf validate mandatory" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" # Choice with multiple items new "netconf choice multiple items first" expecteof "$clixon_netconf -qf $cfg" 0 ' 0 1 2 ]]>]]>' "^]]>]]>$" new "netconf validate multiple ok" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" new "netconf choice multiple items second" expecteof "$clixon_netconf -qf $cfg" 0 ' 0 1 ]]>]]>' "^]]>]]>$" new "netconf validate multiple ok" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" new "netconf choice multiple items mix" expecteof "$clixon_netconf -qf $cfg" 0 ' 0 2 2 ]]>]]>' "^]]>]]>$" new "netconf validate multiple error" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementmcerrorElement in choice statement already exists]]>]]>$' 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