#!/bin/bash # RPC tests # Validate parameters in restconf and netconf, check namespaces, etc # See rfc8040 3.6 # Use the example application that has one mandatory input arg, # At the end is an alternative Yang without mandatory arg for # valid empty input and output. # 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.xml # Use yang in example cat < $cfg $cfg /usr/local/share/clixon $IETFRFC clixon-example /usr/local/lib/$APPNAME/backend /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/cli $APPNAME false /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME 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 "kill old restconf daemon" sudo pkill -u www-data clixon_restconf new "start restconf daemon" start_restconf -f $cfg new "waiting" wait_backend wait_restconf new "rpc tests" # 1.First some positive tests vary media types # extra complex because pattern matching on return haders new "restconf empty rpc" ret=$(curl -is -X POST http://localhost/restconf/operations/clixon-example:empty) expect="204 No Content" match=`echo $ret | grep -EZo "$expect"` if [ -z "$match" ]; then err "$expect" "$ret" fi new "netconf empty rpc" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^]]>]]>$' new "restconf example rpc json/json default - no http media headers" expectpart "$(curl -is -X POST -H "Content-Type: application/yang-data+json" -d '{"clixon-example:input":{"x":0}}' http://localhost/restconf/operations/clixon-example:example)" 0 'HTTP/1.1 200 OK' 'Content-Type: application/yang-data+json' '{"clixon-example:output":{"x":"0","y":"42"}} ' new "restconf example rpc json/json change y default" expectpart "$(curl -is -X POST -H "Content-Type: application/yang-data+json" -d '{"clixon-example:input":{"x":"0","y":"99"}}' http://localhost/restconf/operations/clixon-example:example)" 0 'Content-Type: application/yang-data+json' '{"clixon-example:output":{"x":"0","y":"99"}} ' new "restconf example rpc json/json" # XXX example:input example:output expectpart "$(curl -is -X POST -H 'Content-Type: application/yang-data+json' -H 'Accept: application/yang-data+json' -d '{"clixon-example:input":{"x":"0"}}' http://localhost/restconf/operations/clixon-example:example)" 0 'Content-Type: application/yang-data+json' '{"clixon-example:output":{"x":"0","y":"42"}} ' new "restconf example rpc xml/json" expectpart "$(curl -is -X POST -H 'Content-Type: application/yang-data+xml' -H 'Accept: application/yang-data+json' -d '0' http://localhost/restconf/operations/clixon-example:example)" 0 'Content-Type: application/yang-data+json' '{"clixon-example:output":{"x":"0","y":"42"}} ' new "restconf example rpc json/xml" expectpart "$(curl -is -X POST -H 'Content-Type: application/yang-data+json' -H 'Accept: application/yang-data+xml' -d '{"clixon-example:input":{"x":"0"}}' http://localhost/restconf/operations/clixon-example:example)" 0 'Content-Type: application/yang-data+xml' '042 ' new "restconf example rpc xml/xml" expectpart "$(curl -is -X POST -H 'Content-Type: application/yang-data+xml' -H 'Accept: application/yang-data+xml' -d '0' http://localhost/restconf/operations/clixon-example:example)" 0 'Content-Type: application/yang-data+xml' '042 ' new "restconf example rpc xml in w json encoding (expect fail)" expectpart "$(curl -is -X POST -H 'Content-Type: application/yang-data+json' -H 'Accept: application/yang-data+xml' -d '0' http://localhost/restconf/operations/clixon-example:example)" 0 'HTTP/1.1 400 Bad Reques' "rpcmalformed-messageerror on line 1: syntax error at or before: '<' " new "restconf example rpc json in xml encoding (expect fail)" expectpart "$(curl -is -X POST -H 'Content-Type: application/yang-data+xml' -H 'Accept: application/yang-data+xml' -d '{"clixon-example:input":{"x":"0"}}' http://localhost/restconf/operations/clixon-example:example)" 0 'HTTP/1.1 400 Bad Reques' 'rpcmalformed-messageerrorxml_parse: line 0: syntax error: at or before: " ' new "netconf example rpc" expecteof "$clixon_netconf -qf $cfg" 0 '0]]>]]>' '^042]]>]]>$' # 2. Then error cases # new "restconf empty rpc with null input" ret=$(curl -is -X POST -H "Content-Type: application/yang-data+json" -d '{"clixon-example:input":null}' http://localhost/restconf/operations/clixon-example:empty) expect="204 No Content" match=`echo $ret | grep -EZo "$expect"` if [ -z "$match" ]; then err "$expect" "$ret" fi new "restconf empty rpc with input x" expectpart "$(curl -iss -X POST -H "Content-Type: application/yang-data+json" -d '{"clixon-example:input":{"x":0}}' http://localhost/restconf/operations/clixon-example:empty)" 0 'HTTP/1.1 400 Bad Request' '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"unknown-element","error-info":{"bad-element":"x"},"error-severity":"error"}}} ' # cornercase: optional has yang input/output sections but test without body new "restconf optional rpc with null input and output" ret=$(curl -is -X POST -H "Content-Type: application/yang-data+json" -d '{"clixon-example:input":null}' http://localhost/restconf/operations/clixon-example:optional) expect="204 No Content" match=`echo $ret | grep -EZo "$expect"` if [ -z "$match" ]; then err "$expect" "$ret" fi new "restconf omit mandatory" expectpart "$(curl -is -X POST -H "Content-Type: application/yang-data+json" -d '{"clixon-example:input":null}' http://localhost/restconf/operations/clixon-example:example)" 0 'HTTP/1.1 400 Bad Request' '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"missing-element","error-info":{"bad-element":"x"},"error-severity":"error","error-message":"Mandatory variable"}}} ' new "restconf add extra" expectpart "$(curl -is -X POST -H "Content-Type: application/yang-data+json" -d '{"clixon-example:input":{"x":"0","extra":"0"}}' http://localhost/restconf/operations/clixon-example:example)" 0 'HTTP/1.1 400 Bad Request' '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"unknown-element","error-info":{"bad-element":"extra"},"error-severity":"error"}}} ' new "restconf wrong method" expectpart "$(curl -is -X POST -H "Content-Type: application/yang-data+json" -d '{"clixon-example:input":{"x":"0"}}' http://localhost/restconf/operations/clixon-example:wrong)" 0 'HTTP/1.1 400 Bad Request' '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"missing-element","error-info":{"bad-element":"wrong"},"error-severity":"error","error-message":"RPC not defined"}}} ' new "restconf example missing input" expectpart "$(curl -is -X POST -H "Content-Type: application/yang-data+json" -d '{"clixon-example:input":null}' http://localhost/restconf/operations/ietf-netconf:edit-config)" 0 'HTTP/1.1 400 Bad Request' '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"missing-element","error-info":{"bad-element":"target"},"error-severity":"error","error-message":"Mandatory variable"}}} ' new "netconf kill-session missing session-id mandatory" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^applicationmissing-elementsession-iderrorMandatory variable]]>]]>$' new "netconf edit-config ok" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^]]>]]>$" new "netconf edit-config extra arg should fail" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^applicationunknown-elementextraerror]]>]]>$" new "netconf edit-config empty target should fail" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^applicationdata-missingmissing-choiceconfig-targeterror]]>]]>$' new "netconf edit-config missing target should fail" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^applicationmissing-elementtargeterrorMandatory variable]]>]]>$' new "netconf edit-config missing config should fail" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^applicationdata-missingmissing-choiceedit-contenterror]]>]]>$' 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