#!/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 # Define default restconfig config: RESTCONFIG RESTCONFIG=$(restconf_config none false) cat < $cfg $cfg clixon-restconf:allow-auth-none $dir /usr/local/share/clixon $IETFRFC $fyang /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/cli $APPNAME /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME $RESTCONFIG 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 if [ $RC -ne 0 ]; then new "kill old restconf daemon" stop_restconf_pre new "start restconf daemon" start_restconf -f $cfg new "waiting" wait_restconf fi # First vanilla (protocol) case new "netconf validate empty" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf set protocol both udp and tcp" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf validate both udp and tcp fail" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationbad-elementudperrorElement in choice statement already exists]]>]]>$" new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf set empty protocol" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf validate protocol" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf set protocol tcp" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf get protocol tcp" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^" new "netconf commit protocol tcp" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf changing from TCP to UDP (RFC7950 7.9.6)" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf get protocol udp" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^" new "netconf commit protocol udp" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" #-- restconf new "restconf DELETE whole datastore" expectpart "$(curl $CURLOPTS -X DELETE $RCPROTO://localhost/restconf/data)" 0 "HTTP/1.1 204 No Content" new "restconf set protocol tcp+udp fail" expectpart "$(curl $CURLOPTS -X PUT -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data/system:system/protocol -d '{"system:protocol":{"tcp": [null], "udp": [null]}}')" 0 "HTTP/1.1 400 Bad Request" '{"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" expectpart "$(curl $CURLOPTS -X PUT -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data/system:system/protocol -d {\"system:protocol\":{\"tcp\":[null]}})" 0 "HTTP/1.1 201 Created" new "restconf get protocol tcp" expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/system:system)" 0 "HTTP/1.1 200 OK" '{"system:system":{"protocol":{"tcp":\[null\]}}}' new "restconf set protocol tcp+udp fail again" expectpart "$(curl $CURLOPTS -X PUT -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data/system:system/protocol -d '{"system:protocol":{"tcp": [null], "udp": [null]}}')" 0 "HTTP/1.1 400 Bad Request" '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"bad-element","error-info":{"bad-element":"tcp"},"error-severity":"error","error-message":"Element in choice statement already exists"}}}' new "cli set protocol udp" expectpart "$($clixon_cli -1 -f $cfg -l o set system protocol udp)" 0 "^$" new "cli get protocol udp" expectpart "$($clixon_cli -1 -f $cfg -l o show configuration cli)" 0 "set system protocol" "set system protocol udp" new "cli change protocol to tcp" expectpart "$($clixon_cli -1 -f $cfg -l o set system protocol tcp)" 0 "^$" new "cli get protocol tcp" expectpart "$($clixon_cli -1 -f $cfg -l o show configuration cli)" 0 "set system protocol" "set system protocol tcp" new "cli delete all" expectpart "$($clixon_cli -1 -f $cfg -l o delete all)" 0 "^$" new "commit" expectpart "$($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 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf validate both udp and tcp fail" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationbad-elementudperrorElement in choice statement already exists]]>]]>$" new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf set shorthand tcp" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf changing from TCP to UDP (RFC7950 7.9.6)" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf get shorthand udp" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf validate shorthand" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" # Third check mandatory new "netconf set empty mandatory" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf get mandatory empty" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf validate mandatory" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationdata-missingmissing-choicenameerror]]>]]>$" new "netconf set mandatory udp" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf get mandatory udp" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf validate mandatory" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" # Choice with multiple items new "netconf choice multiple items first" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO 0 1 2 ]]>]]>" "^]]>]]>$" new "netconf validate multiple ok" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf choice multiple items second" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO 0 1 ]]>]]>" "^]]>]]>$" new "netconf validate multiple ok" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" new "netconf choice multiple items mix" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO 0 2 2 ]]>]]>" "^]]>]]>$" new "netconf validate multiple error" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^applicationbad-elementmcerrorElement in choice statement already exists]]>]]>$" if [ $RC -ne 0 ]; then new "Kill restconf daemon" stop_restconf fi 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 # Set by restconf_config unset RESTCONFIG rm -rf $dir new "endtest" endtest