* Major rewrite of event streams
* If you used old event callbacks API, you need to switch to the streams API
* See clixon_stream.[ch]
* Old streams API which needs to be removed include:
* clicon_log_register_callback()
* subscription_add() --> stream_register()
* backend_notify() and backend_notify_xml() - use stream_notify() instead
* Example uses "NETCONF" stream instead of "ROUTING"
* Added timeout option -t for clixon_netconf - quit after max time.
This commit is contained in:
parent
d7fbe75c9e
commit
98f3cd0e32
31 changed files with 597 additions and 635 deletions
23
test/lib.sh
23
test/lib.sh
|
|
@ -2,6 +2,8 @@
|
|||
# Define test functions.
|
||||
# Create working dir as variable "dir"
|
||||
|
||||
#set -e
|
||||
|
||||
testnr=0
|
||||
testname=
|
||||
|
||||
|
|
@ -32,6 +34,7 @@ err(){
|
|||
echo -e "\e[31m\nError in Test$testnr [$testname]:"
|
||||
if [ $# -gt 0 ]; then
|
||||
echo "Expected: $1"
|
||||
echo
|
||||
fi
|
||||
if [ $# -gt 1 ]; then
|
||||
echo "Received: $2"
|
||||
|
|
@ -172,15 +175,27 @@ expectwait(){
|
|||
input=$2
|
||||
expect=$3
|
||||
wait=$4
|
||||
|
||||
|
||||
# Do while read stuff
|
||||
sleep 10|cat <(echo $input) -| $cmd | while [ 1 ] ; do
|
||||
read ret
|
||||
echo timeout > /tmp/flag
|
||||
ret=""
|
||||
sleep $wait | cat <(echo $input) -| $cmd | while [ 1 ] ; do
|
||||
read r
|
||||
# echo "r:$r"
|
||||
ret="$ret$r"
|
||||
match=$(echo "$ret" | grep -Eo "$expect");
|
||||
if [ -z "$match" ]; then
|
||||
echo error > /tmp/flag
|
||||
err $expect "$ret"
|
||||
else
|
||||
echo ok > /tmp/flag # only this is OK
|
||||
break;
|
||||
fi
|
||||
break
|
||||
done
|
||||
cat /tmp/flag
|
||||
if [ $(cat /tmp/flag) != "ok" ]; then
|
||||
cat /tmp/flag
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,12 +39,6 @@ EOF
|
|||
cat <<EOF > $fyang
|
||||
module $APPNAME{
|
||||
prefix ex;
|
||||
import ietf-interfaces {
|
||||
prefix if;
|
||||
}
|
||||
import iana-if-type {
|
||||
prefix ianaift;
|
||||
}
|
||||
container authentication {
|
||||
description "Example code for enabling www basic auth and some example
|
||||
users";
|
||||
|
|
@ -70,21 +64,13 @@ module $APPNAME{
|
|||
type int32;
|
||||
description "something to edit";
|
||||
}
|
||||
container interfaces-state {
|
||||
container state {
|
||||
config false;
|
||||
list interface{
|
||||
key "name";
|
||||
leaf name{
|
||||
type string;
|
||||
}
|
||||
leaf type{
|
||||
type string;
|
||||
}
|
||||
leaf if-index {
|
||||
type int32;
|
||||
}
|
||||
description "state data for example application";
|
||||
leaf-list op {
|
||||
type string;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
|
|
@ -191,7 +177,7 @@ new "restconf DELETE whole datastore"
|
|||
expecteq "$(curl -u adm1:bar -sS -X DELETE http://localhost/restconf/data)" ""
|
||||
|
||||
new2 "auth get"
|
||||
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data/ietf-interfaces:interfaces-state)" '{"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}
|
||||
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data/state)" '{"state": {"op": "42"}}
|
||||
'
|
||||
|
||||
new "Set x to 0"
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ cat <<EOF > $cfg
|
|||
<CLICON_YANG_MODULE_MAIN>$fyang</CLICON_YANG_MODULE_MAIN>
|
||||
<CLICON_RESTCONF_PRETTY>false</CLICON_RESTCONF_PRETTY>
|
||||
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
|
||||
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
|
||||
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>
|
||||
<CLICON_BACKEND_PIDFILE>$dir/restconf.pidfile</CLICON_BACKEND_PIDFILE>
|
||||
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
|
||||
<CLICON_XMLDB_PLUGIN>/usr/local/lib/xmldb/text.so</CLICON_XMLDB_PLUGIN>
|
||||
|
|
@ -28,12 +30,12 @@ cat <<EOF > $cfg
|
|||
</config>
|
||||
EOF
|
||||
|
||||
# RFC5277 NETCONF Event Notifications
|
||||
# RFC5277 NETCONF Event Notifications
|
||||
# using reportingEntity (rfc5277) not reporting-entity (rfc8040)
|
||||
cat <<EOF > $fyang
|
||||
module example {
|
||||
namespace "http://example.com/event/1.0";
|
||||
prefix ex;
|
||||
|
||||
organization "Example, Inc.";
|
||||
contact "support at example.com";
|
||||
description "Example Notification Data Model Module.";
|
||||
|
|
@ -41,14 +43,13 @@ cat <<EOF > $fyang
|
|||
description "Initial version.";
|
||||
reference "example.com document 2-9976.";
|
||||
}
|
||||
|
||||
notification event {
|
||||
description "Example notification event.";
|
||||
leaf event-class {
|
||||
type string;
|
||||
description "Event class identifier.";
|
||||
}
|
||||
container reporting-entity {
|
||||
container reportingEntity {
|
||||
description "Event specific information.";
|
||||
leaf card {
|
||||
type string;
|
||||
|
|
@ -60,7 +61,14 @@ cat <<EOF > $fyang
|
|||
description "Event severity description.";
|
||||
}
|
||||
}
|
||||
}
|
||||
container state {
|
||||
config false;
|
||||
description "state data for example application";
|
||||
leaf-list op {
|
||||
type string;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# kill old backend (if any)
|
||||
|
|
@ -78,30 +86,35 @@ fi
|
|||
|
||||
new "kill old restconf daemon"
|
||||
sudo pkill -u www-data clixon_restconf
|
||||
|
||||
|
||||
new "start restconf daemon"
|
||||
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -f $cfg -D 1
|
||||
|
||||
sleep 1
|
||||
|
||||
# get the stream list using netconf
|
||||
new "netconf event stream discovery RFC5277 Sec 3.2.5"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="xpath" select="netconf/streams" xmlns="urn:ietf:params:xml:ns:netmod:notification"/></get></rpc>]]>]]>' '<rpc-reply><data><netconf><streams><stream><name>CLICON</name><description>Clicon logs</description><replay-support>false</replay-support></stream><stream><name>NETCONF</name><description>default NETCONF event stream</description><replay-support>false</replay-support></stream></streams></netconf></data></rpc-reply>]]>]]>'
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="xpath" select="netconf/streams" xmlns="urn:ietf:params:xml:ns:netmod:notification"/></get></rpc>]]>]]>' '<rpc-reply><data><netconf><streams><stream><name>NETCONF</name><description>default NETCONF event stream</description><replay-support>false</replay-support></stream></streams></netconf></data></rpc-reply>]]>]]>'
|
||||
|
||||
new "netconf event stream discovery RFC8040 Sec 6.2"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="xpath" select="restconf-state/streams" xmlns="urn:ietf:params:xml:ns:netmod:notification"/></get></rpc>]]>]]>' '<rpc-reply><data><restconf-state><streams><stream><name>CLICON</name><description>Clicon logs</description><replay-support>false</replay-support><access><encoding>xml</encoding><location>https://example.com/stream/CLICON</location></access></stream><stream><name>NETCONF</name><description>default NETCONF event stream</description><replay-support>false</replay-support><access><encoding>xml</encoding><location>https://example.com/stream/NETCONF</location></access></stream></streams></restconf-state></data></rpc-reply>]]>]]>'
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="xpath" select="restconf-state/streams" xmlns="urn:ietf:params:xml:ns:netmod:notification"/></get></rpc>]]>]]>' '<rpc-reply><data><restconf-state><streams><stream><name>NETCONF</name><description>default NETCONF event stream</description><replay-support>false</replay-support><access><encoding>xml</encoding><location>/stream/NETCONF</location></access></stream></streams></restconf-state></data></rpc-reply>]]>]]>'
|
||||
|
||||
new "restconf event stream discovery RFC8040 Sec 6.2"
|
||||
expectfn "curl -s -X GET http://localhost/restconf/data/ietf-restconf-monitoring:restconf-state/streams" 0 '{"streams": {"stream": \[{"name": "CLICON","description": "Clicon logs","replay-support": false,"access": \[{"encoding": "xml","location": "https://example.com/stream/CLICON"}\]},{ "name": "NETCONF","description": "default NETCONF event stream","replay-support": false,"access": \[{"encoding": "xml","location": "https://example.com/stream/NETCONF"}\]}\]}'
|
||||
expectfn "curl -s -X GET http://localhost/restconf/data/ietf-restconf-monitoring:restconf-state/streams" 0 '{"streams": {"stream": \[{"name": "NETCONF","description": "default NETCONF event stream","replay-support": false,"access": \[{"encoding": "xml","location": "/stream/NETCONF"}\]}\]}'
|
||||
|
||||
new "restconf subscribe RFC8040 Sec 6.3, get location"
|
||||
expectfn "curl -s -X GET http://localhost/restconf/data/ietf-restconf-monitoring:restconf-state/streams/stream=NETCONF/access=xml/location" 0 '{"location": "https://example.com/stream/NETCONF"}'
|
||||
expectfn "curl -s -X GET http://localhost/restconf/data/ietf-restconf-monitoring:restconf-state/streams/stream=NETCONF/access=xml/location" 0 '{"location": "/stream/NETCONF"}'
|
||||
|
||||
new "restconf monitor event stream RFC8040 Sec 6.3"
|
||||
#expectfn "curl -s -X GET http://localhost/stream/NETCONF" 0 ''
|
||||
new "netconf NETCONF subscription"
|
||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription><stream>NETCONF</stream></create-subscription></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' 5
|
||||
|
||||
#new "netconf subscription" NOTYET
|
||||
#expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription><stream>ROUTING</stream></create-subscription></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><notification><event>Routing notification</event></notification>]]>]]>$" 30
|
||||
new "netconf NETCONF subscription with simple filter"
|
||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription><stream>NETCONF</stream><filter type=\"xpath\" select=\"event\"/></create-subscription></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' 5
|
||||
|
||||
new "netconf NETCONF subscription with filter classfier"
|
||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription><stream>NETCONF</stream><filter type=\"xpath\" select=\"event[event-class='fault']\"/></create-subscription></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>20' 5
|
||||
|
||||
#new "restconf monitor event stream RFC8040 Sec 6.3"
|
||||
#XXX expectfn "curl -s -X GET http://localhost/stream/NETCONF" 0 ''
|
||||
|
||||
new "Kill restconf daemon"
|
||||
sudo pkill -u www-data clixon_restconf
|
||||
|
|
@ -119,4 +132,4 @@ if [ -n "$pid" ]; then
|
|||
sudo kill $pid
|
||||
fi
|
||||
|
||||
rm -rf $dir
|
||||
#rm -rf $dir
|
||||
|
|
|
|||
|
|
@ -65,6 +65,13 @@ module example{
|
|||
}
|
||||
}
|
||||
}
|
||||
container state {
|
||||
config false;
|
||||
description "state data for example application";
|
||||
leaf-list op {
|
||||
type string;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
|
|
@ -180,10 +187,10 @@ new "netconf discard-changes"
|
|||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf edit state operation should fail"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><interfaces-state><interface><name>eth1</name><type>ex:eth</type></interface></interfaces-state></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>invalid-value</error-tag>"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><state><op>42</op></state></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>invalid-value</error-tag>"
|
||||
|
||||
new "netconf get state operation"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get><filter type=\"xpath\" select=\"/interfaces-state\"/></get></rpc>]]>]]>" "^<rpc-reply><data><interfaces-state><interface><name>eth0</name><type>ex:eth</type><if-index>42</if-index></interface></interfaces-state></data></rpc-reply>]]>]]>$"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get><filter type=\"xpath\" select=\"/state\"/></get></rpc>]]>]]>" "^<rpc-reply><data><state><op>42</op></state></data></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf lock/unlock"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]><rpc><unlock><target><candidate/></target></unlock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -225,18 +232,19 @@ new "netconf client-side rpc"
|
|||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><ex:client-rpc><request>example</request></ex:client-rpc></rpc>]]>]]>" "^<rpc-reply><result>ok</result></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf subscription"
|
||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription><stream>ROUTING</stream></create-subscription></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><notification><event>Routing notification</event></notification>]]>]]>$" 30
|
||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription><stream>NETCONF</stream></create-subscription></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]><notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime>201' 10
|
||||
|
||||
new "Kill backend"
|
||||
# Check if still alive
|
||||
pid=`pgrep clixon_backend`
|
||||
if [ -z "$pid" ]; then
|
||||
err "backend already dead"
|
||||
fi
|
||||
# kill backend
|
||||
sudo clixon_backend -zf $cfg
|
||||
if [ $? -ne 0 ]; then
|
||||
err "kill backend"
|
||||
fi
|
||||
|
||||
# Check if still alive
|
||||
pid=`pgrep clixon_backend`
|
||||
if [ -n "$pid" ]; then
|
||||
sudo kill $pid
|
||||
fi
|
||||
|
||||
rm -rf $dir
|
||||
|
|
|
|||
|
|
@ -71,11 +71,18 @@ module example{
|
|||
}
|
||||
}
|
||||
}
|
||||
container state {
|
||||
config false;
|
||||
description "state data for example application";
|
||||
leaf-list op {
|
||||
type string;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# This is a fixed 'state' implemented in routing_backend. It is assumed to be always there
|
||||
state='{"interfaces-state": {"interface": \[{"name": "eth0","type": "ex:eth","if-index": 42}\]}}'
|
||||
state='{"state": {"op": "42"}}'
|
||||
|
||||
# kill old backend (if any)
|
||||
new "kill old backend"
|
||||
|
|
@ -136,7 +143,7 @@ if [ -z "$match" ]; then
|
|||
err "$expect" "$ret"
|
||||
fi
|
||||
|
||||
new "restconf schema resource, RFC 8040 sec 3.7 according to RFC 7895"
|
||||
new2 "restconf schema resource, RFC 8040 sec 3.7 according to RFC 7895"
|
||||
expecteq "$(curl -s -H 'Accept: application/yang-data+json' -G http://localhost/restconf/data/ietf-yang-library:modules-state/module=ietf-routing,2014-10-26/)" '{"module": [{"name": "ietf-routing","revision": "2014-10-26","namespace": "urn:ietf:params:xml:ns:yang:ietf-routing"}]}
|
||||
'
|
||||
|
||||
|
|
@ -151,52 +158,52 @@ new "restconf empty rpc"
|
|||
expecteq "$(curl -s -X POST -d {\"input\":{\"name\":\"\"}} http://localhost/restconf/operations/example:empty)" ""
|
||||
|
||||
new2 "restconf get empty config + state json"
|
||||
expecteq "$(curl -sSG http://localhost/restconf/data/interfaces-state)" '{"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}
|
||||
expecteq "$(curl -sSG http://localhost/restconf/data/state)" '{"state": {"op": "42"}}
|
||||
'
|
||||
|
||||
new2 "restconf get empty config + state json with module name"
|
||||
expecteq "$(curl -sSG http://localhost/restconf/data/ietf-interfaces:interfaces-state)" '{"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}
|
||||
new2 "restconf get empty config + state json + module"
|
||||
expecteq "$(curl -sSG http://localhost/restconf/data/example:state)" '{"state": {"op": "42"}}
|
||||
'
|
||||
|
||||
new2 "restconf get empty config + state json with wrong module name"
|
||||
expecteq "$(curl -sSG http://localhost/restconf/data/badmodule:interfaces-state)" '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-tag": "operation-failed","error-type": "protocol","error-severity": "error","error-message": "No yang node found: badmodule:interfaces-state"}}}}
'
|
||||
expecteq "$(curl -sSG http://localhost/restconf/data/badmodule:state)" '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-tag": "operation-failed","error-type": "protocol","error-severity": "error","error-message": "No yang node found: badmodule:state"}}}}
'
|
||||
|
||||
new "restconf get empty config + state xml"
|
||||
ret=$(curl -s -H "Accept: application/yang-data+xml" -G http://localhost/restconf/data/interfaces-state)
|
||||
expect="<interfaces-state><interface><name>eth0</name><type>ex:eth</type><if-index>42</if-index></interface></interfaces-state>"
|
||||
ret=$(curl -s -H "Accept: application/yang-data+xml" -G http://localhost/restconf/data/state)
|
||||
expect="<state><op>42</op></state>"
|
||||
match=`echo $ret | grep -EZo "$expect"`
|
||||
if [ -z "$match" ]; then
|
||||
err "$expect" "$ret"
|
||||
fi
|
||||
|
||||
new2 "restconf get data/interfaces-state/interface=eth0 json"
|
||||
expecteq "$(curl -s -G http://localhost/restconf/data/interfaces-state/interface=eth0)" '{"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}
|
||||
new2 "restconf get data/ json"
|
||||
expecteq "$(curl -s -G http://localhost/restconf/data/state/op=42)" '{"op": "42"}
|
||||
'
|
||||
|
||||
new "restconf get state operation eth0 xml"
|
||||
# Cant get shell macros to work, inline matching from lib.sh
|
||||
ret=$(curl -s -H "Accept: application/yang-data+xml" -G http://localhost/restconf/data/interfaces-state/interface=eth0)
|
||||
expect="<interface><name>eth0</name><type>ex:eth</type><if-index>42</if-index></interface>"
|
||||
ret=$(curl -s -H "Accept: application/yang-data+xml" -G http://localhost/restconf/data/state/op=42)
|
||||
expect="<op>42</op>"
|
||||
match=`echo $ret | grep -EZo "$expect"`
|
||||
if [ -z "$match" ]; then
|
||||
err "$expect" "$ret"
|
||||
fi
|
||||
|
||||
new2 "restconf get state operation eth0 type json"
|
||||
expecteq "$(curl -s -G http://localhost/restconf/data/interfaces-state/interface=eth0/type)" '{"type": "ex:eth"}
|
||||
expecteq "$(curl -s -G http://localhost/restconf/data/state/op=42)" '{"op": "42"}
|
||||
'
|
||||
|
||||
new "restconf get state operation eth0 type xml"
|
||||
# Cant get shell macros to work, inline matching from lib.sh
|
||||
ret=$(curl -s -H "Accept: application/yang-data+xml" -G http://localhost/restconf/data/interfaces-state/interface=eth0/type)
|
||||
expect="<type>ex:eth</type>"
|
||||
ret=$(curl -s -H "Accept: application/yang-data+xml" -G http://localhost/restconf/data/state/op=42)
|
||||
expect="<op>42</op>"
|
||||
match=`echo $ret | grep -EZo "$expect"`
|
||||
if [ -z "$match" ]; then
|
||||
err "$expect" "$ret"
|
||||
fi
|
||||
|
||||
new2 "restconf GET datastore"
|
||||
expecteq "$(curl -s -X GET http://localhost/restconf/data/interfaces-state)" '{"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}
|
||||
expecteq "$(curl -s -X GET http://localhost/restconf/data/state)" '{"state": {"op": "42"}}
|
||||
'
|
||||
|
||||
# Exact match
|
||||
|
|
@ -210,14 +217,14 @@ expectfn 'curl -s -X POST -d {"interfaces":{"interface":{"name":"eth/0/0","type"
|
|||
#expecteq "$(curl -s -X POST -d {\"interfaces\":{\"interface\":{\"name\":\"eth/0/0\",\"type\":\"ex:eth\",\"enabled\":true}}} http://localhost/restconf/data)" '{"ietf-restconf:errors" : {"error": {"error-tag": "data-exists","error-type": "application","error-severity": "error","error-message": "Data already exists; cannot create new resource"}}}'
|
||||
|
||||
new "restconf Check interfaces eth/0/0 added"
|
||||
expectfn "curl -s -G http://localhost/restconf/data" 0 '{"interfaces": {"interface": \[{"name": "eth/0/0","type": "ex:eth","enabled": true}\]},"interfaces-state": {"interface": \[{"name": "eth0","type": "ex:eth","if-index": 42}\]}}
|
||||
expectfn "curl -s -G http://localhost/restconf/data" 0 '{"interfaces": {"interface": \[{"name": "eth/0/0","type": "ex:eth","enabled": true}\]},"state": {"op": "42"}}
|
||||
'
|
||||
|
||||
new "restconf delete interfaces"
|
||||
expecteq $(curl -s -X DELETE http://localhost/restconf/data/interfaces) ""
|
||||
|
||||
new "restconf Check empty config"
|
||||
expectfn "curl -sG http://localhost/restconf/data/interfaces-state" 0 "$state"
|
||||
expectfn "curl -sG http://localhost/restconf/data/state" 0 "$state"
|
||||
|
||||
new "restconf Add interfaces subtree eth/0/0 using POST"
|
||||
expectfn 'curl -s -X POST -d {"interface":{"name":"eth/0/0","type":"ex:eth","enabled":true}} http://localhost/restconf/data/interfaces' 0 ""
|
||||
|
|
@ -229,7 +236,7 @@ expecteq "$(curl -s -G http://localhost/restconf/data/interfaces)" '{"interfaces
|
|||
'
|
||||
|
||||
new2 "restconf Check eth/0/0 added state"
|
||||
expecteq "$(curl -s -G http://localhost/restconf/data/interfaces-state)" '{"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}
|
||||
expecteq "$(curl -s -G http://localhost/restconf/data/state)" '{"state": {"op": "42"}}
|
||||
'
|
||||
|
||||
new2 "restconf Re-post eth/0/0 which should generate error"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue