Merge branch 'master' into filter-and-xml-encoding-fixes
This commit is contained in:
commit
3c5f956805
97 changed files with 2861 additions and 1480 deletions
|
|
@ -32,6 +32,7 @@ for test in $pattern; do
|
|||
testfile=$test
|
||||
. ./$test
|
||||
errcode=$?
|
||||
endsuite
|
||||
if [ $errcode -ne 0 ]; then
|
||||
allerr=1
|
||||
echo -e "\e[31mError in $test errcode=$errcode"
|
||||
|
|
|
|||
32
test/lib.sh
32
test/lib.sh
|
|
@ -127,7 +127,12 @@ DEMSLEEP=.2
|
|||
let DEMLOOP=5*DEMWAIT
|
||||
|
||||
# RESTCONF protocol, eg http or https
|
||||
: ${RCPROTO:=https}
|
||||
|
||||
if [ "${WITH_RESTCONF}" = "fcgi" ]; then
|
||||
: ${RCPROTO:=http}
|
||||
else
|
||||
: ${RCPROTO:=https}
|
||||
fi
|
||||
|
||||
# www user (on linux typically www-data, freebsd www)
|
||||
# Start restconf user, can be root which is dropped to wwwuser
|
||||
|
|
@ -221,6 +226,7 @@ fi
|
|||
# 1: auth-type (one of none, client-cert, user)
|
||||
# 2: pretty (if true pretty-print restconf return values)
|
||||
# Note, if AUTH=none then FEATURE clixon-restconf:allow-auth-none must be enabled
|
||||
# Note if https, check if server cert/key exists, if not generate them
|
||||
function restconf_config()
|
||||
{
|
||||
AUTH=$1
|
||||
|
|
@ -229,11 +235,21 @@ function restconf_config()
|
|||
if [ $RCPROTO = http ]; then
|
||||
echo "<restconf><enable>true</enable><auth-type>$AUTH</auth-type><pretty>$PRETTY</pretty><debug>$DBG</debug><socket><namespace>default</namespace><address>0.0.0.0</address><port>80</port><ssl>false</ssl></socket></restconf>"
|
||||
else
|
||||
echo "<restconf><enable>true</enable><auth-type>$AUTH</auth-type><pretty>$PRETTY</pretty><server-cert-path>/etc/ssl/certs/clixon-server-crt.pem</server-cert-path><server-key-path>/etc/ssl/private/clixon-server-key.pem</server-key-path><server-ca-cert-path>/etc/ssl/certs/clixon-ca-crt.pem</server-ca-cert-path><debug>$DBG</debug><socket><namespace>default</namespace><address>0.0.0.0</address><port>443</port><ssl>true</ssl></socket></restconf>"
|
||||
certdir=$dir/certs
|
||||
if [ ! -f ${dir}/clixon-server-crt.pem ]; then
|
||||
certdir=$dir/certs
|
||||
test -d $certdir || mkdir $certdir
|
||||
srvcert=${certdir}/clixon-server-crt.pem
|
||||
srvkey=${certdir}/clixon-server-key.pem
|
||||
cacert=${certdir}/clixon-ca-crt.pem
|
||||
cakey=${certdir}/clixon-ca-key.pem
|
||||
cacerts $cakey $cacert
|
||||
servercerts $cakey $cacert $srvkey $srvcert
|
||||
fi
|
||||
echo "<restconf><enable>true</enable><auth-type>$AUTH</auth-type><pretty>$PRETTY</pretty><server-cert-path>${certdir}/clixon-server-crt.pem</server-cert-path><server-key-path>${certdir}/clixon-server-key.pem</server-key-path><server-ca-cert-path>${certdir}/clixon-ca-crt.pem</server-ca-cert-path><debug>$DBG</debug><socket><namespace>default</namespace><address>0.0.0.0</address><port>443</port><ssl>true</ssl></socket></restconf>"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Some tests may set owner of testdir to something strange and quit, need
|
||||
# to reset to me
|
||||
if [ ! -G $dir ]; then
|
||||
|
|
@ -366,9 +382,10 @@ function stop_restconf_pre(){
|
|||
}
|
||||
|
||||
# Stop restconf daemon after test
|
||||
# Two caveats in pkill:
|
||||
# Some problems with pkill:
|
||||
# 1) Dont use $clixon_restconf (dont work in valgrind)
|
||||
# 2) Dont use -u $WWWUSER since clixon_restconf may drop privileges.
|
||||
# 3) After fork, it seems to take some time before name is right
|
||||
function stop_restconf(){
|
||||
sudo pkill -f clixon_restconf
|
||||
if [ $valgrindtest -eq 3 ]; then
|
||||
|
|
@ -432,6 +449,7 @@ function wait_restconf_stopped(){
|
|||
}
|
||||
|
||||
# End of test, final tests before normal exit of test
|
||||
# Note this is a single test started by new, not a total test suite
|
||||
function endtest()
|
||||
{
|
||||
if [ $valgrindtest -eq 1 ]; then
|
||||
|
|
@ -448,6 +466,12 @@ function new(){
|
|||
>&2 echo "Test $testi($testnr) [$1]"
|
||||
}
|
||||
|
||||
# End of complete test-suite, eg a test file
|
||||
function endsuite()
|
||||
{
|
||||
unset CURLOPTS
|
||||
}
|
||||
|
||||
# Evaluate and return
|
||||
# Example: expectpart $(fn arg) 0 "my return" -- "foo"
|
||||
# - evaluated expression
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ function memonce(){
|
|||
sudo chmod 660 $valgrindfile
|
||||
sudo chown www-data $valgrindfile
|
||||
: ${DEMWAIT:=15} # valgrind backend needs some time to get up
|
||||
clixon_restconf="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile clixon_restconf"
|
||||
clixon_restconf="/usr/bin/valgrind --num-callers=50 --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile clixon_restconf"
|
||||
|
||||
;;
|
||||
*)
|
||||
|
|
@ -58,6 +58,7 @@ function memonce(){
|
|||
testfile=$test
|
||||
. ./$test
|
||||
errcode=$?
|
||||
endsuite
|
||||
if [ $errcode -ne 0 ]; then
|
||||
memerr=1
|
||||
echo -e "\e[31mError in $test errcode=$errcode"
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ cat <<EOF > $fyang2
|
|||
module ietf-interfaces {
|
||||
yang-version 1.1;
|
||||
namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
|
||||
revision "2019-03-04";
|
||||
prefix if;
|
||||
revision "2019-03-04";
|
||||
identity interface-type {
|
||||
description
|
||||
"Base identity from which specific interface types are
|
||||
|
|
@ -110,10 +110,10 @@ module example-augment {
|
|||
yang-version 1.1;
|
||||
namespace "urn:example:augment";
|
||||
prefix mymod;
|
||||
revision "2019-03-04";
|
||||
import ietf-interfaces {
|
||||
prefix if;
|
||||
}
|
||||
revision "2019-03-04";
|
||||
identity some-new-iftype {
|
||||
base if:interface-type;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ cat <<EOF > $fyang2
|
|||
module example-lib {
|
||||
yang-version 1.1;
|
||||
namespace "urn:example:lib";
|
||||
revision "2019-03-04";
|
||||
prefix lib;
|
||||
revision "2019-03-04";
|
||||
container global-state {
|
||||
config false;
|
||||
leaf gbds{
|
||||
|
|
@ -81,10 +81,10 @@ module example-augment {
|
|||
yang-version 1.1;
|
||||
namespace "urn:example:augment";
|
||||
prefix aug;
|
||||
revision "2020-09-25";
|
||||
import example-lib {
|
||||
prefix lib;
|
||||
}
|
||||
revision "2020-09-25";
|
||||
/* Augments global state */
|
||||
augment "/lib:global-state" {
|
||||
leaf gads{
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ cat <<EOF > $fyang
|
|||
module example-lib {
|
||||
yang-version 1.1;
|
||||
namespace "urn:example:lib";
|
||||
revision "2019-03-04";
|
||||
prefix lib;
|
||||
revision "2019-03-04";
|
||||
container base-config {
|
||||
}
|
||||
/* No prefix */
|
||||
|
|
@ -61,10 +61,10 @@ module example-augment1 {
|
|||
yang-version 1.1;
|
||||
namespace "urn:example:augment1";
|
||||
prefix aug1;
|
||||
revision "2020-09-25";
|
||||
import example-lib {
|
||||
prefix lib;
|
||||
}
|
||||
revision "2020-09-25";
|
||||
/* Augments config */
|
||||
augment "/lib:base-config/lib:parameter" {
|
||||
container aug1{
|
||||
|
|
@ -80,13 +80,13 @@ module example-augment2 {
|
|||
yang-version 1.1;
|
||||
namespace "urn:example:augment2";
|
||||
prefix aug2;
|
||||
revision "2020-09-25";
|
||||
import example-lib {
|
||||
prefix lib;
|
||||
}
|
||||
import example-augment1 {
|
||||
prefix aug1;
|
||||
}
|
||||
revision "2020-09-25";
|
||||
/* Augments config */
|
||||
augment "/lib:base-config/lib:parameter/aug1:aug1" {
|
||||
/* when 'lib:name="foobar" and aug:aug1="foobar"'; */
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ new "wait backend"
|
|||
wait_backend
|
||||
|
||||
new "Netconf runtime test"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><example xmlns=\"urn:example:clixon\"><x>0</x></example></rpc>]]>]]>" '^<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><x xmlns="urn:example:clixon">0</x><y xmlns="urn:example:clixon">42</y></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><example xmlns=\"urn:example:clixon\"><x>0</x></example></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><x xmlns=\"urn:example:clixon\">0</x><y xmlns=\"urn:example:clixon\">42</y></rpc-reply>]]>]]>$"
|
||||
|
||||
if [ $BE -ne 0 ]; then
|
||||
new "Kill backend"
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ main(int argc,
|
|||
/* Provide a clixon config-file, get a clixon handle */
|
||||
if ((h = clixon_client_init("$cfg")) == NULL)
|
||||
return -1;
|
||||
/* Make a conenction over netconf or ssh/netconf */
|
||||
/* Make a connection over netconf or ssh/netconf */
|
||||
if ((ch = clixon_client_connect(h, CLIXON_CLIENT_NETCONF)) == NULL)
|
||||
return -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ EOF
|
|||
cat <<EOF > $fyangA
|
||||
module A{
|
||||
prefix a;
|
||||
revision 2020-02-11;
|
||||
namespace "urn:example:a";
|
||||
revision 2020-02-11;
|
||||
container x {
|
||||
container y {
|
||||
}
|
||||
|
|
@ -56,11 +56,11 @@ EOF
|
|||
cat <<EOF > $fyangB
|
||||
module B{
|
||||
prefix b;
|
||||
revision 2020-02-11;
|
||||
namespace "urn:example:b";
|
||||
import A {
|
||||
prefix "a";
|
||||
}
|
||||
revision 2020-02-11;
|
||||
augment "/a:x/a:y" {
|
||||
container z {
|
||||
leaf w {
|
||||
|
|
|
|||
|
|
@ -105,6 +105,9 @@ expectpart "$($clixon_cli -1 -f $cfg -l o debug restconf 1)" 0 "^$"
|
|||
new "get and put config using restconf"
|
||||
expectpart "$(curl $CURLOPTS -H "Accept: application/yang-data+xml" -X GET $RCPROTO://localhost/restconf/data?content=config --next $CURLOPTS -H "Content-Type: application/yang-data+json" -X POST $RCPROTO://localhost/restconf/data -d '{"example:table":{"parameter":{"name":"local0","value":"foo"}}}')" 0 "HTTP/$HVER 200" '<data>' "HTTP/$HVER 201"
|
||||
|
||||
# In freebsd, backend dies in stop_restconf below unless sleep
|
||||
sleep $DEMSLEEP
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
new "Kill restconf daemon"
|
||||
stop_restconf
|
||||
|
|
@ -115,7 +118,7 @@ if [ $BE -ne 0 ]; then
|
|||
# Check if premature kill
|
||||
pid=$(pgrep -u root -f clixon_backend)
|
||||
if [ -z "$pid" ]; then
|
||||
err "backend already dead"
|
||||
err1 "backend pid !=0" 0
|
||||
fi
|
||||
# kill backend
|
||||
stop_backend -f $cfg
|
||||
|
|
|
|||
|
|
@ -46,10 +46,10 @@ cat <<EOF > $fyang
|
|||
module nacm-example{
|
||||
yang-version 1.1;
|
||||
namespace "urn:example:nacm";
|
||||
prefix nacm;
|
||||
import clixon-example {
|
||||
prefix ex;
|
||||
}
|
||||
prefix nacm;
|
||||
container authentication {
|
||||
presence "To keep this from auto-expanding";
|
||||
description "Example code for enabling www basic auth and some example
|
||||
|
|
|
|||
|
|
@ -232,13 +232,13 @@ new "limit rpc ok"
|
|||
expectpart "$(curl -u wilma:bar $CURLOPTS -X POST $RCPROTO://localhost/restconf/operations/clixon-example:example -H "Content-Type: application/yang-data+json" -d '{"clixon-example:input":{"x":42}}' )" 0 "HTTP/$HVER 200" '{"clixon-example:output":{"x":"42","y":"42"}}'
|
||||
|
||||
new "limit rpc netconf ok"
|
||||
expecteof "$clixon_netconf -U wilma -qf $cfg" 0 "$DEFAULTHELLO<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><example xmlns=\"urn:example:clixon\"><x>0</x></example></rpc>]]>]]>" '^<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><x xmlns="urn:example:clixon">0</x><y xmlns="urn:example:clixon">42</y></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -U wilma -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><example xmlns=\"urn:example:clixon\"><x>0</x></example></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><x xmlns=\"urn:example:clixon\">0</x><y xmlns=\"urn:example:clixon\">42</y></rpc-reply>]]>]]>$"
|
||||
|
||||
new "guest rpc fail"
|
||||
expectpart "$(curl -u guest:bar $CURLOPTS -X POST $RCPROTO://localhost/restconf/operations/clixon-example:example -H "Content-Type: application/yang-data+json" -d '{"clixon-example:input":{"x":42}}' )" 0 "HTTP/$HVER 403" '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"access-denied","error-severity":"error","error-message":"access denied"}}}'
|
||||
|
||||
new "guest rpc netconf fail"
|
||||
expecteof "$clixon_netconf -U guest -qf $cfg" 0 "$DEFAULTHELLO<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><example xmlns=\"urn:example:clixon\"><x>0</x></example></rpc>]]>]]>" '^<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><rpc-error><error-type>application</error-type><error-tag>access-denied</error-tag><error-severity>error</error-severity><error-message>access denied</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -U guest -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><example xmlns=\"urn:example:clixon\"><x>0</x></example></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>access-denied</error-tag><error-severity>error</error-severity><error-message>access denied</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||
|
||||
#------------------ Set read-default permit
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ cat <<EOF > $cfg
|
|||
<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_NETCONF_MESSAGE_ID_OPTIONAL>false</CLICON_NETCONF_MESSAGE_ID_OPTIONAL>
|
||||
<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>
|
||||
|
|
@ -67,6 +68,9 @@ expecteof "$clixon_netconf -qf $cfg" 0 "<hello $DEFAULTNS><capabilities><capabil
|
|||
new "Frame with unknown message"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<xxx $DEFAULTNS></xxx>]]>]]>" "^<rpc-reply $DEFAULTNS><rpc-error><error-type>protocol</error-type><error-tag>unknown-element</error-tag><error-info><bad-element>xxx</bad-element></error-info><error-severity>error</error-severity><error-message>Unrecognized netconf operation</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||
|
||||
new "Frame without message-id attribute"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTONLY><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTONLY><rpc-error><error-type>rpc</error-type><error-tag>missing-attribute</error-tag><error-info><bad-attribute>message-id</bad-attribute></error-info><error-severity>error</error-severity><error-message>Incoming rpc</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf rcv hello, disable RFC7895/ietf-yang-library"
|
||||
expecteof "$clixon_netconf -f $cfg -o CLICON_MODULE_LIBRARY_RFC7895=0" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<hello $DEFAULTNS><capabilities><capability>urn:ietf:params:netconf:base:1.1</capability><capability>urn:ietf:params:netconf:base:1.0</capability><capability>urn:ietf:params:netconf:capability:candidate:1.0</capability><capability>urn:ietf:params:netconf:capability:validate:1.1</capability><capability>urn:ietf:params:netconf:capability:startup:1.0</capability><capability>urn:ietf:params:netconf:capability:xpath:1.0</capability><capability>urn:ietf:params:netconf:capability:notification:1.0</capability></capabilities><session-id>[0-9]*</session-id></hello>]]>]]><rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ for f in $files; do
|
|||
fi
|
||||
done
|
||||
|
||||
new "Openconfig test: $clixon_cli -1f $cfg -y $f show version ($m modules)"
|
||||
new "Openconfig test: $clixon_cli -1f $cfg show version ($m modules)"
|
||||
for f in $files; do
|
||||
if [ -n "$(head -1 $f|grep '^module')" ]; then
|
||||
new "$clixon_cli -D $DBG -1f $cfg -y $f show version"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
# Run a system around openconfig interface, ie: openconfig-if-ethernet
|
||||
# Note first variant uses ietf-interfaces, maybe remove this?
|
||||
|
||||
# Magic line must be first in script (see README.md)
|
||||
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
||||
|
|
@ -22,13 +23,11 @@ cat <<EOF > $cfg
|
|||
<clixon-config xmlns="http://clicon.org/config">
|
||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||
<CLICON_FEATURE>ietf-netconf:startup</CLICON_FEATURE>
|
||||
<CLICON_YANG_DIR>$OPENCONFIG/third_party/ietf/</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_DIR>$OCDIR</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_DIR>$OCDIR</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_DIR>$OCDIR/interfaces</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_DIR>$OCDIR/types</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_DIR>$OCDIR/wifi</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_DIR>$OCDIR/vlan</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
||||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
||||
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||
|
|
@ -42,6 +41,7 @@ cat <<EOF > $cfg
|
|||
</clixon-config>
|
||||
EOF
|
||||
|
||||
# First using ietf-interfaces (not openconfig-interfaces)
|
||||
# Example yang
|
||||
cat <<EOF > $fyang
|
||||
module clixon-example{
|
||||
|
|
@ -99,7 +99,7 @@ fi
|
|||
new "wait backend"
|
||||
wait_backend
|
||||
|
||||
new "$clixon_cli -D $DBG -1f $cfg -y $f show version"
|
||||
new "$clixon_cli -D $DBG -1f $cfg show version"
|
||||
expectpart "$($clixon_cli -D $DBG -1f $cfg show version)" 0 "${CLIXON_VERSION}"
|
||||
|
||||
new "$clixon_netconf -qf $cfg"
|
||||
|
|
@ -126,6 +126,76 @@ if [ $BE -ne 0 ]; then
|
|||
stop_backend -f $cfg
|
||||
fi
|
||||
|
||||
# Second using openconfig-interfaces instead
|
||||
# Example yang
|
||||
cat <<EOF > $fyang
|
||||
module clixon-example{
|
||||
yang-version 1.1;
|
||||
namespace "urn:example:example";
|
||||
prefix ex;
|
||||
|
||||
import openconfig-vlan {
|
||||
prefix oc-vlan;
|
||||
}
|
||||
import openconfig-if-ethernet {
|
||||
prefix oc-eth;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Example system
|
||||
cat <<EOF > $dir/startup_db
|
||||
<config>
|
||||
<interfaces xmlns="http://openconfig.net/yang/interfaces">
|
||||
<interface>
|
||||
<name>eth1</name>
|
||||
<config>
|
||||
<name>eth1</name>
|
||||
<type>ianaift:ethernetCsmacd</type>
|
||||
<mtu>9206</mtu>
|
||||
<enabled>true</enabled>
|
||||
<oc-vlan:tpid xmlns:oc-vlan="http://openconfig.net/yang/vlan">oc-vlan-types:TPID_0X8100</oc-vlan:tpid>
|
||||
</config>
|
||||
<oc-eth:ethernet xmlns:oc-eth="http://openconfig.net/yang/interfaces/ethernet">
|
||||
<oc-eth:config>
|
||||
<oc-eth:mac-address>2c:53:4a:09:59:73</oc-eth:mac-address>
|
||||
</oc-eth:config>
|
||||
</oc-eth:ethernet>
|
||||
</interface>
|
||||
</interfaces>
|
||||
</config>
|
||||
EOF
|
||||
|
||||
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 startup -f $cfg"
|
||||
start_backend -s startup -f $cfg
|
||||
fi
|
||||
|
||||
new "wait backend"
|
||||
wait_backend
|
||||
|
||||
new "$clixon_cli -D $DBG -1f $cfg show version"
|
||||
expectpart "$($clixon_cli -D $DBG -1f $cfg show version)" 0 "${CLIXON_VERSION}"
|
||||
|
||||
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
|
||||
|
||||
|
||||
rm -rf $dir
|
||||
|
||||
new "endtest"
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ ftest=$dir/test.xml
|
|||
fconfig=$dir/large.xml
|
||||
fconfig2=$dir/large2.xml # leaf-list
|
||||
foutput=$dir/output.xml
|
||||
foutput2=$dir/output2.xml
|
||||
|
||||
cat <<EOF > $fyang
|
||||
module scaling{
|
||||
|
|
@ -132,15 +133,20 @@ expecteof "time -p $clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><co
|
|||
|
||||
new "Check running-db contents"
|
||||
curl $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data?content=config > $foutput
|
||||
r=$?
|
||||
if [ $r -ne 0 ]; then
|
||||
err1 "retval 0" $r
|
||||
fi
|
||||
|
||||
# Remove Content-Length line (depends on size)
|
||||
sed -i '/Content-Length:/d' $foutput
|
||||
sed -i '/content-length:/d' $foutput
|
||||
# Note: do not use sed -i since it is not portable between gnu and bsd
|
||||
sed '/Content-Length:/d' $foutput > $foutput2 && mv $foutput2 $foutput
|
||||
sed '/content-length:/d' $foutput > $foutput2 && mv $foutput2 $foutput
|
||||
# Remove (nginx) web-server specific lines
|
||||
sed -i '/Server:/d' $foutput
|
||||
sed -i '/Date:/d' $foutput
|
||||
sed -i '/Transfer-Encoding:/d' $foutput
|
||||
sed -i '/Connection:/d' $foutput
|
||||
sed '/Server:/d' $foutput > $foutput2 && mv $foutput2 $foutput
|
||||
sed '/Date:/d' $foutput > $foutput2 && mv $foutput2 $foutput
|
||||
sed '/Transfer-Encoding:/d' $foutput > $foutput2 && mv $foutput2 $foutput
|
||||
sed '/Connection:/d' $foutput > $foutput2 && mv $foutput2 $foutput
|
||||
|
||||
# Create a file to compare with
|
||||
if ${HAVE_LIBNGHTTP2}; then
|
||||
|
|
@ -165,7 +171,7 @@ echo "</data>
" >> $ftest
|
|||
|
||||
ret=$(diff -i $ftest $foutput)
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "$ret"
|
||||
echo "diff -i $ftest $foutput"
|
||||
err1 "Matching running-db with $fconfigonly"
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -172,37 +172,86 @@ function testrun()
|
|||
echo "curl $CURLOPTS -X GET $proto://$addr/.well-known/host-meta"
|
||||
expectpart "$(curl $CURLOPTS -X GET $proto://$addr/.well-known/host-meta)" 0 "HTTP/$HVER 200" "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
|
||||
|
||||
if ! ${HAVE_LIBNGHTTP2}; then # http/2
|
||||
if [ ${HAVE_LIBNGHTTP2} = true -a ${HAVE_LIBEVHTP} = false ]; then
|
||||
echo "native + http/2 only"
|
||||
# Important here is robustness of restconf daemon, not a meaningful reply
|
||||
if [ $proto = http ]; then # see (2) https to http port in restconf_main_native.c
|
||||
# http protocol mismatch can just close the socket if assumed its http/2
|
||||
# everything else would guess it is http/1 which is really wrong here
|
||||
# The tr statement replaces null char to get rid of annoying message:
|
||||
# ./test_restconf.sh: line 180: warning: command substitution: ignored null byte in input
|
||||
new "restconf GET http/1.0 - close"
|
||||
expectpart "$(curl $CURLOPTS --http1.0 -X GET $proto://$addr/.well-known/host-meta | tr '\0' '\n')" 0 "" --not-- 'HTTP'
|
||||
else
|
||||
new "restconf GET https/1.0 - close"
|
||||
expectpart "$(curl $CURLOPTS --http1.0 -X GET $proto://$addr/.well-known/host-meta)" 52 "" --not-- 'HTTP'
|
||||
|
||||
if [ "${WITH_RESTCONF}" = "native" ]; then # XXX does not work with nginx
|
||||
new "restconf GET http/1.0 - returns 1.0"
|
||||
expectpart "$(curl $CURLOPTS --http1.0 -X GET $proto://$addr/.well-known/host-meta)" 0 'HTTP/1.0 200 OK' "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
|
||||
fi
|
||||
new "restconf GET http/1.1"
|
||||
expectpart "$(curl $CURLOPTS --http1.1 -X GET $proto://$addr/.well-known/host-meta)" 0 'HTTP/1.1 200 OK' "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
|
||||
fi
|
||||
|
||||
# Try http/2 - go back to http/1.1
|
||||
new "restconf GET http/2"
|
||||
expectpart "$(curl $CURLOPTS --http2 -X GET $proto://$addr/.well-known/host-meta)" 0 "HTTP/1.1 200 OK" "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
|
||||
if [ $proto = http ]; then
|
||||
new "restconf GET http/1.1 - close"
|
||||
expectpart "$(curl $CURLOPTS --http1.1 -X GET $proto://$addr/.well-known/host-meta | tr '\0' '\n')" 0 --not-- 'HTTP'
|
||||
else
|
||||
new "restconf GET https/1.1 - close"
|
||||
expectpart "$(curl $CURLOPTS --http1.1 -X GET $proto://$addr/.well-known/host-meta)" 52 --not-- 'HTTP'
|
||||
fi
|
||||
|
||||
if [ $proto = http ]; then
|
||||
new "restconf GET http/2 switch protocol"
|
||||
expectpart "$(curl $CURLOPTS --http2 -X GET $proto://$addr/.well-known/host-meta | tr '\0' '\n')" 0 --not-- 'HTTP'
|
||||
else
|
||||
new "restconf GET https/2 alpn protocol"
|
||||
expectpart "$(curl $CURLOPTS --http2 -X GET $proto://$addr/.well-known/host-meta)" 0 "HTTP/$HVER 200" "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
|
||||
fi
|
||||
|
||||
if [ $proto = http ]; then # see (2) https to http port in restconf_main_native.c
|
||||
new "restconf GET http/2 prior-knowledge (http)"
|
||||
expectpart "$(curl $CURLOPTS --http2-prior-knowledge -X GET $proto://$addr/.well-known/host-meta 2>&1)" "16 52 55" # "Error in the HTTP2 framing layer" "Connection reset by peer"
|
||||
# Wrong protocol http when https or vice versa
|
||||
if [ $proto = http ]; then # see (2) https to http port in restconf_main_native.c
|
||||
new "Wrong proto=https on http port, expect err 35 wrong version number"
|
||||
expectpart "$(curl $CURLOPTS -X GET https://$addr:80/.well-known/host-meta 2>&1)" 35 #"wrong version number" # dependent on curl version
|
||||
else # see (1) http to https port in restconf_main_native.c
|
||||
new "Wrong proto=http on https port, expect bad request"
|
||||
expectpart "$(curl $CURLOPTS -X GET http://$addr:443/.well-known/host-meta)" "16 52 55" --not-- 'HTTP'
|
||||
fi
|
||||
else
|
||||
new "restconf GET http/2 prior-knowledge(http2)"
|
||||
expectpart "$(curl $CURLOPTS --http2-prior-knowledge -X GET $proto://$addr/.well-known/host-meta)" 0 'HTTP/1.1 200 OK' "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
|
||||
fi
|
||||
echo "fcgi or native+http/1 or native+http/1+http/2"
|
||||
if [ "${WITH_RESTCONF}" = "native" ]; then # XXX does not work with nginx
|
||||
new "restconf GET http/1.0 - returns 1.0"
|
||||
expectpart "$(curl $CURLOPTS --http1.0 -X GET $proto://$addr/.well-known/host-meta)" 0 'HTTP/1.0 200 OK' "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
|
||||
fi
|
||||
new "restconf GET http/1.1"
|
||||
expectpart "$(curl $CURLOPTS --http1.1 -X GET $proto://$addr/.well-known/host-meta)" 0 'HTTP/1.1 200 OK' "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
|
||||
|
||||
# Negative test GET datastore
|
||||
if [ $proto = http ]; then # see (2) https to http port in restconf_main_native.c
|
||||
new "Wrong proto=https on http port, expect err 35 wrong version number"
|
||||
expectpart "$(curl $CURLOPTS -X GET https://$addr:80/.well-known/host-meta 2>&1)" 35 #"wrong version number" # dependent on curl version
|
||||
else # see (1) http to https port in restconf_main_native.c
|
||||
new "Wrong proto=http on https port, expect bad request"
|
||||
expectpart "$(curl $CURLOPTS -X GET http://$addr:443/.well-known/host-meta)" 0 "HTTP/$HVER 400"
|
||||
# expectpart "$(curl $CURLOPTS -X GET http://$addr:443/.well-known/host-meta 2>&1)" 56 "Connection reset by peer"
|
||||
fi
|
||||
if ${HAVE_LIBNGHTTP2}; then
|
||||
# http/1 + http/2
|
||||
|
||||
new "restconf GET http/2 switch protocol"
|
||||
expectpart "$(curl $CURLOPTS --http2 -X GET $proto://$addr/.well-known/host-meta)" 0 "" "HTTP/2 200" "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>" # Only if http: HTTP/1.1 101 Switching Protocols
|
||||
else
|
||||
# http/1 only Try http/2 - go back to http/1.1
|
||||
new "restconf GET http/2 switch protocol"
|
||||
expectpart "$(curl $CURLOPTS --http2 -X GET $proto://$addr/.well-known/host-meta)" 0 "HTTP/1.1 200 OK" "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
|
||||
fi
|
||||
|
||||
# http2-prior knowledge
|
||||
if [ $proto = http ]; then # see (2) https to http port in restconf_main_native.c
|
||||
new "restconf GET http/2 prior-knowledge (http)"
|
||||
expectpart "$(curl $CURLOPTS --http2-prior-knowledge -X GET $proto://$addr/.well-known/host-meta 2>&1)" "16 52 55" # "Error in the HTTP2 framing layer" "Connection reset by peer"
|
||||
else
|
||||
new "restconf GET https/2 prior-knowledge"
|
||||
expectpart "$(curl $CURLOPTS --http2-prior-knowledge -X GET $proto://$addr/.well-known/host-meta)" 0 "HTTP/$HVER 200" "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
|
||||
fi
|
||||
|
||||
# Wrong protocol http when https or vice versa
|
||||
if [ $proto = http ]; then # see (2) https to http port in restconf_main_native.c
|
||||
new "Wrong proto=https on http port, expect err 35 wrong version number"
|
||||
expectpart "$(curl $CURLOPTS -X GET https://$addr:80/.well-known/host-meta 2>&1)" 35 #"wrong version number" # dependent on curl version
|
||||
else # see (1) http to https port in restconf_main_native.c
|
||||
new "Wrong proto=http on https port, expect bad request"
|
||||
expectpart "$(curl $CURLOPTS -X GET http://$addr:443/.well-known/host-meta)" 0 "HTTP/" "400"
|
||||
# expectpart "$(curl $CURLOPTS -X GET http://$addr:443/.well-known/host-meta 2>&1)" 56 "Connection reset by peer"
|
||||
fi
|
||||
fi # HTTP/2
|
||||
|
||||
# Exact match
|
||||
new "restconf get restconf resource. RFC 8040 3.3 (json)"
|
||||
expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+json" $proto://$addr/restconf)" 0 "HTTP/$HVER 200" '{"ietf-restconf:restconf":{"data":{},"operations":{},"yang-library-version":"2019-01-04"}}'
|
||||
|
|
@ -341,7 +390,7 @@ function testrun()
|
|||
new "restconf Check eth/0/0 GET augmented state level 2"
|
||||
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+json' $proto://$addr/restconf/data/ietf-interfaces:interfaces/interface=eth%2f0%2f0/clixon-example:my-status)" 0 "HTTP/$HVER 200" '{"clixon-example:my-status":{"int":42,"str":"foo"}}'
|
||||
|
||||
new "restconf Check eth/0/0 added state XXXXXXX"
|
||||
new "restconf Check eth/0/0 added state"
|
||||
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+json' $proto://$addr/restconf/data/clixon-example:state)" 0 "HTTP/$HVER 200" '{"clixon-example:state":{"op":\["41","42","43"\]}}'
|
||||
|
||||
new "restconf Re-post eth/0/0 which should generate error"
|
||||
|
|
@ -393,7 +442,7 @@ function testrun()
|
|||
|
||||
new "restconf rpc using POST xml"
|
||||
ret=$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" -H "Accept: application/yang-data+xml" -d '{"clixon-example:input":{"x":42}}' $proto://$addr/restconf/operations/clixon-example:example)
|
||||
expect='<output xmlns="urn:example:clixon"><x>42</x><y>42</y></output>'
|
||||
expect='<output message-id="42" xmlns="urn:example:clixon"><x>42</x><y>42</y></output>'
|
||||
match=`echo $ret | grep --null -Eo "$expect"`
|
||||
if [ -z "$match" ]; then
|
||||
err "$expect" "$ret"
|
||||
|
|
|
|||
|
|
@ -275,10 +275,8 @@ if [ $pid0 -eq $pid3 ]; then
|
|||
err1 "A different pid" "same pid: $pid3"
|
||||
fi
|
||||
|
||||
new "kill restconf using kill"
|
||||
stop_restconf_pre
|
||||
|
||||
sleep $DEMSLEEP
|
||||
new "kill restconf"
|
||||
sudo kill $pid3
|
||||
|
||||
new "Wait for restconf to stop"
|
||||
wait_restconf_stopped
|
||||
|
|
@ -378,6 +376,7 @@ cat<<EOF > $startupdb
|
|||
EOF
|
||||
|
||||
new "kill old restconf"
|
||||
sleep $DEMSLEEP
|
||||
stop_restconf_pre
|
||||
|
||||
new "test params: -f $cfg"
|
||||
|
|
@ -485,10 +484,9 @@ fi
|
|||
#Start backend -s none should start
|
||||
|
||||
new "kill restconf"
|
||||
sleep $DEMSLEEP
|
||||
stop_restconf
|
||||
|
||||
sleep $DEMSLEEP # Lots of processes need to die before next test
|
||||
|
||||
new "endtest"
|
||||
endtest
|
||||
|
||||
|
|
|
|||
|
|
@ -116,12 +116,7 @@ fi
|
|||
new "wait backend"
|
||||
wait_backend
|
||||
|
||||
#new "netconf edit config"
|
||||
#expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config>$RESTCONFIG</config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
#new "netconf commit"
|
||||
#expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
# Explicit start of restconf for easier debugging
|
||||
if [ $RC -ne 0 ]; then
|
||||
new "kill old restconf daemon"
|
||||
stop_restconf_pre
|
||||
|
|
|
|||
|
|
@ -204,7 +204,6 @@ new "restconf DELETE whole datastore"
|
|||
expectpart "$(curl $CURLOPTS -X DELETE $RCPROTO://localhost/restconf/data)" 0 "HTTP/$HVER 204"
|
||||
|
||||
#--------------- Multiple request in single TCP tests
|
||||
|
||||
expectpart "$(curl $CURLOPTS -H "Accept: application/yang-data+xml" -X GET $RCPROTO://localhost/restconf/data?content=config --next $CURLOPTS -H "Content-Type: application/yang-data+json" -X POST $RCPROTO://localhost/restconf/data -d '{"example:cont1":{"interface":{"name":"local0","type":"regular"}}}')" 0 "HTTP/$HVER 200" '<data/>' "HTTP/$HVER 201"
|
||||
|
||||
#--------------- json type tests
|
||||
|
|
|
|||
|
|
@ -91,6 +91,9 @@ cat <<EOF > $dir/example-system.yang
|
|||
leaf enable-jukebox-streaming {
|
||||
type boolean;
|
||||
}
|
||||
leaf extraleaf {
|
||||
type string;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
|
@ -250,6 +253,16 @@ expectpart "$(curl -u andy:bar $CURLOPTS -X PATCH -H "Content-Type: application
|
|||
new "GET check" # XXX: "data" should probably be namespaced?
|
||||
expectpart "$(curl -u andy:bar $CURLOPTS -X GET $RCPROTO://localhost/restconf/data?content=config -H 'Accept: application/yang-data+xml')" 0 "HTTP/$HVER 200" '<extra xmlns="http://example.com/ns/example-jukebox">c</extra>' '<data>'
|
||||
|
||||
new "Add empty leaf"
|
||||
expectpart "$(curl -u andy:bar $CURLOPTS -X POST $RCPROTO://localhost/restconf/data -H 'Content-Type: application/yang-data+json' -d '{"example-system:system":{"extraleaf":""}}')" 0 "HTTP/$HVER 201"
|
||||
|
||||
new "Add entry with PATCH"
|
||||
expectpart "$(curl -u andy:bar $CURLOPTS -X PATCH $RCPROTO://localhost/restconf/data/example-system:system -H 'Content-Type: application/yang-data+json' -d '{"example-system:system":{"extraleaf":"something"}}')" 0 "HTTP/$HVER 204"
|
||||
|
||||
new "GET check"
|
||||
expectpart "$(curl -u andy:bar $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/example-system:system -H 'Accept: application/yang-data+xml')" 0 "HTTP/$HVER 200" '<system xmlns="http://example.com/ns/example-system"><extraleaf>something</extraleaf></system>'
|
||||
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
new "Kill restconf daemon"
|
||||
stop_restconf
|
||||
|
|
|
|||
|
|
@ -288,10 +288,10 @@ EOF
|
|||
|
||||
|
||||
new "limited invalid cert"
|
||||
expectpart "$(curl $CURLOPTS --key $certdir/limited.key --cert $certdir/limited.crt -X GET $RCPROTO://localhost/restconf/data/example:x 2>&1)" "35 55 56" # 55 "certificate expired"
|
||||
expectpart "$(curl $CURLOPTS --key $certdir/limited.key --cert $certdir/limited.crt -X GET $RCPROTO://localhost/restconf/data/example:x 2>&1)" "16 35 55 56" # 55 "certificate expired"
|
||||
|
||||
new "too weak cert (sign w md5)"
|
||||
expectpart "$(curl $CURLOPTS --key $certdir/mymd5.key --cert $certdir/mymd5.crt -X GET $RCPROTO://localhost/restconf/data/example:x 2>&1)" 58 "md too weak"
|
||||
expectpart "$(curl $CURLOPTS --key $certdir/mymd5.key --cert $certdir/mymd5.crt -X GET $RCPROTO://localhost/restconf/data/example:x 2>&1)" "35 58" # "md too weak"
|
||||
|
||||
# Havent been able to generate "wrong CA"
|
||||
# new "invalid cert from wrong CA"
|
||||
|
|
|
|||
205
test/test_restconf_yang_patch.sh
Executable file
205
test/test_restconf_yang_patch.sh
Executable file
|
|
@ -0,0 +1,205 @@
|
|||
#!/usr/bin/env bash
|
||||
# Restconf RFC8072 yang patch
|
||||
# XXX enable YANG_PACTH in include/clixon_custom.h to run this test
|
||||
# Use nacm module in example/main/example_restconf.c hardcoded to
|
||||
# andy:bar and wilma:bar
|
||||
|
||||
# Magic line must be first in script (see README.md)
|
||||
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
||||
|
||||
echo "...skipped: YANG_PATCH NYI"
|
||||
if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
||||
|
||||
APPNAME=example
|
||||
|
||||
cfg=$dir/conf.xml
|
||||
startupdb=$dir/startup_db
|
||||
fjukebox=$dir/example-jukebox.yang
|
||||
|
||||
# Define default restconfig config: RESTCONFIG
|
||||
RESTCONFIG=$(restconf_config user false)
|
||||
|
||||
cat <<EOF > $cfg
|
||||
<clixon-config xmlns="http://clicon.org/config">
|
||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_MAIN_DIR>$dir</CLICON_YANG_MAIN_DIR>
|
||||
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
|
||||
<CLICON_FEATURE>ietf-netconf:startup</CLICON_FEATURE>
|
||||
<CLICON_RESTCONF_DIR>/usr/local/lib/$APPNAME/restconf</CLICON_RESTCONF_DIR>
|
||||
<CLICON_BACKEND_PIDFILE>$dir/restconf.pidfile</CLICON_BACKEND_PIDFILE>
|
||||
<CLICON_XMLDB_DIR>$dir</CLICON_XMLDB_DIR>
|
||||
<CLICON_NACM_MODE>internal</CLICON_NACM_MODE>
|
||||
<CLICON_NACM_DISABLED_ON_EMPTY>true</CLICON_NACM_DISABLED_ON_EMPTY>
|
||||
$RESTCONFIG
|
||||
</clixon-config>
|
||||
EOF
|
||||
|
||||
NACM0="<nacm xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-acm\">
|
||||
<enable-nacm>true</enable-nacm>
|
||||
<read-default>deny</read-default>
|
||||
<write-default>deny</write-default>
|
||||
<exec-default>permit</exec-default>
|
||||
<groups>
|
||||
<group>
|
||||
<name>admin</name>
|
||||
<user-name>andy</user-name>
|
||||
</group>
|
||||
<group>
|
||||
<name>limited</name>
|
||||
<user-name>wilma</user-name>
|
||||
</group>
|
||||
</groups>
|
||||
<rule-list>
|
||||
<name>admin</name>
|
||||
<group>admin</group>
|
||||
<rule>
|
||||
<name>permit-all</name>
|
||||
<module-name>*</module-name>
|
||||
<access-operations>*</access-operations>
|
||||
<action>permit</action>
|
||||
<comment>
|
||||
Allow the 'admin' group complete access to all operations and data.
|
||||
</comment>
|
||||
</rule>
|
||||
</rule-list>
|
||||
<rule-list>
|
||||
<name>limited</name>
|
||||
<group>limited</group>
|
||||
<rule>
|
||||
<name>limit-jukebox</name>
|
||||
<module-name>jukebox-example</module-name>
|
||||
<access-operations>read create delete</access-operations>
|
||||
<action>deny</action>
|
||||
</rule>
|
||||
</rule-list>
|
||||
</nacm>
|
||||
"
|
||||
|
||||
cat<<EOF > $startupdb
|
||||
<${DATASTORE_TOP}>
|
||||
$NACM0
|
||||
</${DATASTORE_TOP}>
|
||||
EOF
|
||||
|
||||
# An extra testmodule that includes nacm
|
||||
cat <<EOF > $dir/example-system.yang
|
||||
module example-system {
|
||||
namespace "http://example.com/ns/example-system";
|
||||
prefix "ex";
|
||||
import ietf-netconf-acm {
|
||||
prefix nacm;
|
||||
}
|
||||
container system {
|
||||
leaf enable-jukebox-streaming {
|
||||
type boolean;
|
||||
}
|
||||
leaf extraleaf {
|
||||
type string;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Common Jukebox spec (fjukebox must be set)
|
||||
. ./jukebox.sh
|
||||
|
||||
new "test params: -s startup -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 startup -f $cfg"
|
||||
start_backend -s startup -f $cfg
|
||||
fi
|
||||
|
||||
new "wait backend"
|
||||
wait_backend
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
new "kill old restconf daemon"
|
||||
stop_restconf_pre
|
||||
|
||||
new "start restconf daemon"
|
||||
start_restconf -f $cfg
|
||||
fi
|
||||
|
||||
new "wait restconf"
|
||||
wait_restconf
|
||||
|
||||
# RFC 8072 A.1.1
|
||||
REQ='<yang-patch xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-patch">
|
||||
<patch-id>add-songs-patch</patch-id>
|
||||
<edit>
|
||||
<edit-id>edit1</edit-id>
|
||||
<operation>create</operation>
|
||||
<target>/song=Bridge%20Burning</target>
|
||||
<value>
|
||||
<song xmlns="http://example.com/ns/example-jukebox">
|
||||
<name>Bridge Burning</name>
|
||||
<location>/media/bridge_burning.mp3</location>
|
||||
<format>MP3</format>
|
||||
<length>288</length>
|
||||
</song>
|
||||
</value>
|
||||
</edit>
|
||||
<edit>
|
||||
<edit-id>edit2</edit-id>
|
||||
<operation>create</operation>
|
||||
<target>/song=Rope</target>
|
||||
<value>
|
||||
<song xmlns="http://example.com/ns/example-jukebox">
|
||||
<name>Rope</name>
|
||||
<location>/media/rope.mp3</location>
|
||||
<format>MP3</format>
|
||||
<length>259</length>
|
||||
</song>
|
||||
</value>
|
||||
</edit>
|
||||
<edit>
|
||||
<edit-id>edit3</edit-id>
|
||||
<operation>create</operation>
|
||||
<target>/song=Dear%20Rosemary</target>
|
||||
<value>
|
||||
<song xmlns="http://example.com/ns/example-jukebox">
|
||||
<name>Dear Rosemary</name>
|
||||
<location>/media/dear_rosemary.mp3</location>
|
||||
<format>MP3</format>
|
||||
<length>269</length>
|
||||
</song>
|
||||
</value>
|
||||
</edit>
|
||||
</yang-patch>'
|
||||
|
||||
new "RFC 8072 A.1.1 Add resources: Error."
|
||||
expectpart "$(curl -u andy:bar $CURLOPTS -X PATCH -H 'Content-Type: application/yang-patch+xml' -H 'Accept: application/yang-data+xml' $RCPROTO://localhost/restconf/data/example-jukebox:jukebox/library/artist=Foo%20Fighters/album=Wasting%20Light -d "$REQ")" 0 "HTTP/$HVER 409"
|
||||
|
||||
|
||||
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
|
||||
|
|
@ -89,10 +89,10 @@ new "restconf example rpc xml/json"
|
|||
expectpart "$(curl $CURLOPTS -X POST -H 'Content-Type: application/yang-data+xml' -H 'Accept: application/yang-data+json' -d '<input xmlns="urn:example:clixon"><x>0</x></input>' $RCPROTO://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 $CURLOPTS -X POST -H 'Content-Type: application/yang-data+json' -H 'Accept: application/yang-data+xml' -d '{"clixon-example:input":{"x":"0"}}' $RCPROTO://localhost/restconf/operations/clixon-example:example)" 0 'Content-Type: application/yang-data+xml' '<output xmlns="urn:example:clixon"><x>0</x><y>42</y></output>'
|
||||
expectpart "$(curl $CURLOPTS -X POST -H 'Content-Type: application/yang-data+json' -H 'Accept: application/yang-data+xml' -d '{"clixon-example:input":{"x":"0"}}' $RCPROTO://localhost/restconf/operations/clixon-example:example)" 0 'Content-Type: application/yang-data+xml' '<output message-id="42" xmlns="urn:example:clixon"><x>0</x><y>42</y></output>'
|
||||
|
||||
new "restconf example rpc xml/xml"
|
||||
expectpart "$(curl $CURLOPTS -X POST -H 'Content-Type: application/yang-data+xml' -H 'Accept: application/yang-data+xml' -d '<input xmlns="urn:example:clixon"><x>0</x></input>' $RCPROTO://localhost/restconf/operations/clixon-example:example)" 0 'Content-Type: application/yang-data+xml' '<output xmlns="urn:example:clixon"><x>0</x><y>42</y></output>'
|
||||
expectpart "$(curl $CURLOPTS -X POST -H 'Content-Type: application/yang-data+xml' -H 'Accept: application/yang-data+xml' -d '<input xmlns="urn:example:clixon"><x>0</x></input>' $RCPROTO://localhost/restconf/operations/clixon-example:example)" 0 'Content-Type: application/yang-data+xml' '<output message-id="42" xmlns="urn:example:clixon"><x>0</x><y>42</y></output>'
|
||||
|
||||
new "restconf example rpc xml in w json encoding (expect fail)"
|
||||
expectpart "$(curl $CURLOPTS -X POST -H 'Content-Type: application/yang-data+json' -H 'Accept: application/yang-data+xml' -d '<input xmlns="urn:example:clixon"><x>0</x></input>' $RCPROTO://localhost/restconf/operations/clixon-example:example)" 0 "HTTP/$HVER 400" "<errors xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\"><error><error-type>rpc</error-type><error-tag>malformed-message</error-tag><error-severity>error</error-severity><error-message>json_parse: line 1: syntax error at or before: '<'</error-message></error></errors>"
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ EOF
|
|||
cat <<EOF > $fsub2
|
||||
submodule sub2 {
|
||||
yang-version 1.1;
|
||||
belongs-to sub1 {
|
||||
belongs-to main {
|
||||
prefix ex;
|
||||
}
|
||||
import extra2{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
# Advanced union types and generated code
|
||||
# and enum w values
|
||||
# The test is run twice, first with dbcache turned on, then turned off.
|
||||
# The test is run three times, with dbcache turned on, cache off and zero-copy
|
||||
# It is the only test with dbcache off.
|
||||
|
||||
# Magic line must be first in script (see README.md)
|
||||
|
|
@ -47,9 +47,9 @@ module example3{
|
|||
EOF
|
||||
cat <<EOF > $fyang2
|
||||
module example2{
|
||||
import example3 { prefix ex3; }
|
||||
namespace "urn:example:example2";
|
||||
prefix ex2;
|
||||
import example3 { prefix ex3; }
|
||||
grouping gr2 {
|
||||
leaf talle{
|
||||
type ex3:t;
|
||||
|
|
|
|||
|
|
@ -50,9 +50,9 @@ module example3{
|
|||
EOF
|
||||
cat <<EOF > $fyang2
|
||||
module example2{
|
||||
import example3 { prefix ex3; }
|
||||
namespace "urn:example:example2";
|
||||
prefix ex2;
|
||||
import example3 { prefix ex3; }
|
||||
grouping gr2 {
|
||||
leaf talle{
|
||||
type ex3:t;
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ EOF
|
|||
cat <<EOF > $fyang2
|
||||
module A{
|
||||
prefix a;
|
||||
revision 2021-01-01;
|
||||
namespace "urn:example:a";
|
||||
revision 2021-01-01;
|
||||
container upgraded{
|
||||
}
|
||||
}
|
||||
|
|
@ -95,8 +95,8 @@ for oldyang in true false; do
|
|||
cat <<EOF > $fyang1
|
||||
module A{
|
||||
prefix a;
|
||||
revision 2016-01-01;
|
||||
namespace "urn:example:a";
|
||||
revision 2016-01-01;
|
||||
container old{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ fyangB=$dir/B@2019-01-01.yang
|
|||
cat <<EOF > $fyangA0
|
||||
module A{
|
||||
prefix a;
|
||||
revision 0814-01-28;
|
||||
namespace "urn:example:a";
|
||||
revision 0814-01-28;
|
||||
leaf a0{
|
||||
type string;
|
||||
}
|
||||
|
|
@ -53,9 +53,9 @@ EOF
|
|||
cat <<EOF > $fyangA1
|
||||
module A{
|
||||
prefix a;
|
||||
namespace "urn:example:a";
|
||||
revision 2019-01-01;
|
||||
revision 0814-01-28;
|
||||
namespace "urn:example:a";
|
||||
/* leaf a0 has been removed */
|
||||
leaf a1{
|
||||
description "exists in both versions";
|
||||
|
|
@ -72,8 +72,8 @@ EOF
|
|||
cat <<EOF > $fyangB
|
||||
module B{
|
||||
prefix b;
|
||||
revision 2019-01-01;
|
||||
namespace "urn:example:b";
|
||||
revision 2019-01-01;
|
||||
leaf b{
|
||||
type string;
|
||||
}
|
||||
|
|
@ -84,8 +84,8 @@ EOF
|
|||
cat <<EOF > /dev/null
|
||||
module C{
|
||||
prefix c;
|
||||
revision 2019-01-01;
|
||||
namespace "urn:example:c";
|
||||
revision 2019-01-01;
|
||||
leaf c{
|
||||
type string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ touch $log
|
|||
cat <<EOF > $fyangb
|
||||
module B{
|
||||
prefix b;
|
||||
revision 2016-01-01;
|
||||
namespace "urn:example:b";
|
||||
revision 2016-01-01;
|
||||
container dummy{
|
||||
}
|
||||
}
|
||||
|
|
@ -258,8 +258,8 @@ function testall()
|
|||
cat <<EOF > $fyang
|
||||
module A{
|
||||
prefix a;
|
||||
revision 2016-01-01;
|
||||
namespace "urn:example:interfaces";
|
||||
revision 2016-01-01;
|
||||
container dummy{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ NEWXML='<a2 xmlns="urn:example:a">new version</a2>'
|
|||
cat <<EOF > $fyangA0
|
||||
module A{
|
||||
prefix a;
|
||||
revision 0814-01-28;
|
||||
namespace "urn:example:a";
|
||||
revision 0814-01-28;
|
||||
leaf a0{
|
||||
type string;
|
||||
}
|
||||
|
|
@ -38,9 +38,9 @@ EOF
|
|||
cat <<EOF > $fyangA1
|
||||
module A{
|
||||
prefix a;
|
||||
namespace "urn:example:a";
|
||||
revision 2019-01-01;
|
||||
revision 0814-01-28;
|
||||
namespace "urn:example:a";
|
||||
/* leaf a0 has been removed */
|
||||
leaf a1{
|
||||
description "exists in both versions";
|
||||
|
|
|
|||
|
|
@ -48,13 +48,13 @@ new "xpath canonical form (other)"
|
|||
expectpart "$($clixon_util_xpath -c -y $ydir -p /i:x/j:y -n i:urn:example:a -n j:urn:example:b)" 0 '/a:x/b:y' '0 : a = "urn:example:a"' '1 : b = "urn:example:b"'
|
||||
|
||||
new "xpath canonical form predicate 1"
|
||||
expectpart "$($clixon_util_xpath -c -y $ydir -p "/i:x[j:y='e1']" -n i:urn:example:a -n j:urn:example:b)" 0 "/a:x\[b:y = 'e1'\]" '0 : a = "urn:example:a"' '1 : b = "urn:example:b"'
|
||||
expectpart "$($clixon_util_xpath -c -y $ydir -p "/i:x[j:y='e1']" -n i:urn:example:a -n j:urn:example:b)" 0 "/a:x\[b:y='e1'\]" '0 : a = "urn:example:a"' '1 : b = "urn:example:b"'
|
||||
|
||||
new "xpath canonical form predicate self"
|
||||
expectpart "$($clixon_util_xpath -c -y $ydir -p "/i:x[.='42']" -n i:urn:example:a -n j:urn:example:b)" 0 "/a:x\[. = '42'\]" '0 : a = "urn:example:a"'
|
||||
expectpart "$($clixon_util_xpath -c -y $ydir -p "/i:x[.='42']" -n i:urn:example:a -n j:urn:example:b)" 0 "/a:x\[.='42'\]" '0 : a = "urn:example:a"'
|
||||
|
||||
new "xpath canonical form descendants"
|
||||
expectpart "$($clixon_util_xpath -c -y $ydir -p "//x[.='42']" -n null:urn:example:a -n j:urn:example:b)" 0 "//a:x\[. = '42'\]" '0 : a = "urn:example:a"'
|
||||
expectpart "$($clixon_util_xpath -c -y $ydir -p "//x[.='42']" -n null:urn:example:a -n j:urn:example:b)" 0 "//a:x\[.='42'\]" '0 : a = "urn:example:a"'
|
||||
|
||||
new "xpath canonical form (no default should fail)"
|
||||
expectpart "$($clixon_util_xpath -c -y $ydir -p /x/j:y -n i:urn:example:a -n j:urn:example:b 2> /dev/null)" 255
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ fyang3=$dir/other.yang
|
|||
cat <<EOF > $fyang1
|
||||
module example{
|
||||
prefix ex;
|
||||
namespace "urn:example:clixon";
|
||||
revision $NEWDATE;
|
||||
revision $OLDDATE;
|
||||
namespace "urn:example:clixon";
|
||||
leaf newex{
|
||||
type string;
|
||||
}
|
||||
|
|
@ -35,8 +35,8 @@ EOF
|
|||
cat <<EOF > $fyang2
|
||||
module example{
|
||||
prefix ex;
|
||||
revision $OLDDATE;
|
||||
namespace "urn:example:clixon";
|
||||
revision $OLDDATE;
|
||||
leaf oldex{
|
||||
type string;
|
||||
}
|
||||
|
|
@ -47,8 +47,8 @@ EOF
|
|||
cat <<EOF > $fyang3
|
||||
module other{
|
||||
prefix oth;
|
||||
revision $NEWDATE;
|
||||
namespace "urn:example:clixon2";
|
||||
revision $NEWDATE;
|
||||
leaf other{
|
||||
type string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ case $release in
|
|||
native)
|
||||
$sshcmd sudo yum install -y libevent openssl
|
||||
$sshcmd sudo yum install -y libevent-devel openssl-devel
|
||||
$sshcmd sudo yum-config-manager --enable powertools
|
||||
$sshcmd sudo dnf config-manager --set-enabled powertools
|
||||
$sshcmd sudo yum install -y libnghttp2-devel
|
||||
;;
|
||||
esac
|
||||
|
|
@ -215,7 +215,7 @@ case $release in
|
|||
;;
|
||||
native)
|
||||
# $sshcmd sudo apt install -y libevent-2.1
|
||||
$sshcmd sudo apt install -y libevent-dev libssl-dev libnghttp2-dev
|
||||
$sshcmd sudo apt install -y libevent-dev libssl-dev
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue