* xml_cmp() respects 'ordered-by user' for state nodes, which violates RFC 7950 [https://github.com/clicon/clixon/issues/63. (Thanks JDL)
This commit is contained in:
parent
376b75328c
commit
02d725b2c0
10 changed files with 85 additions and 53 deletions
|
|
@ -142,6 +142,7 @@
|
|||
* <!DOCTYPE (ie DTD) is not supported.
|
||||
|
||||
### Corrected Bugs
|
||||
* xml_cmp() respects 'ordered-by user' for state nodes, which violates RFC 7950 [https://github.com/clicon/clixon/issues/63. (Thanks JDL)
|
||||
* XML<>JSON conversion problems [https://github.com/clicon/clixon/issues/66]
|
||||
* CDATA sections stripped from XML when converted to JSON
|
||||
* Restconf returns error when RPC generates "ok" reply [https://github.com/clicon/clixon/issues/69]
|
||||
|
|
|
|||
|
|
@ -201,6 +201,8 @@ example_statedata(clicon_handle h,
|
|||
*/
|
||||
if (xml_parse_string("<state xmlns=\"urn:example:clixon\">"
|
||||
"<op>42</op>"
|
||||
"<op>41</op>"
|
||||
"<op>43</op>" /* should not be ordered */
|
||||
"</state>", NULL, &xstate) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@
|
|||
* Prototypes
|
||||
*/
|
||||
int xml_child_spec(cxobj *x, cxobj *xp, yang_spec *yspec, yang_stmt **yp);
|
||||
int xml_cmp(const void* arg1, const void* arg2);
|
||||
int xml_sort(cxobj *x0, void *arg);
|
||||
cxobj *xml_search(cxobj *x, char *name, int yangi, enum rfc_6020 keyword, int keynr, char **keyvec, char **keyval);
|
||||
int xml_insert_pos(cxobj *x0, char *name, int yangi, enum rfc_6020 keyword,
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ xml_child_spec(cxobj *x,
|
|||
* @see xml_cmp1 Similar, but for one object
|
||||
* @note empty value/NULL is smallest value
|
||||
*/
|
||||
int
|
||||
static int
|
||||
xml_cmp(const void* arg1,
|
||||
const void* arg2)
|
||||
{
|
||||
|
|
@ -162,11 +162,13 @@ xml_cmp(const void* arg1,
|
|||
if ((equal = yi1-yi2) != 0)
|
||||
return equal;
|
||||
}
|
||||
/* Now y1=y2, same Yang spec, can only be list or leaf-list,
|
||||
* sort according to key
|
||||
/* Now y1==y2, same Yang spec, can only be list or leaf-list,
|
||||
* But first check exceptions, eg config false or ordered-by user
|
||||
* otherwuse sort according to key
|
||||
*/
|
||||
if (yang_find((yang_node*)y1, Y_ORDERED_BY, "user") != NULL)
|
||||
return 0; /* Ordered by user: maintain existing order */
|
||||
if (yang_config(y1)==0 ||
|
||||
yang_find((yang_node*)y1, Y_ORDERED_BY, "user") != NULL)
|
||||
return 0; /* Ordered by user or state data : maintain existing order */
|
||||
switch (y1->ys_keyword){
|
||||
case Y_LEAF_LIST: /* Match with name and value */
|
||||
if ((b1 = xml_body(x1)) == NULL)
|
||||
|
|
@ -262,11 +264,20 @@ xml_cmp1(cxobj *x,
|
|||
* Assume populated by yang spec.
|
||||
* @param[in] x0 XML node
|
||||
* @param[in] arg Dummy so it can be called by xml_apply()
|
||||
* @retval -1 Error, aborted at first error encounter
|
||||
* @retval 0 OK, all nodes traversed (subparts may have been skipped)
|
||||
* @retval 1 OK, aborted on first fn returned 1
|
||||
* @see xml_apply - typically called by recursive apply function
|
||||
*/
|
||||
int
|
||||
xml_sort(cxobj *x,
|
||||
void *arg)
|
||||
{
|
||||
yang_stmt *ys;
|
||||
|
||||
/* Abort sort if non-config (=state) data */
|
||||
if ((ys = xml_spec(x)) != 0 && yang_config(ys)==0)
|
||||
return 1;
|
||||
qsort(xml_childvec_get(x), xml_child_nr(x), sizeof(cxobj *), xml_cmp);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -543,7 +554,13 @@ xml_sort_verify(cxobj *x0,
|
|||
int retval = -1;
|
||||
cxobj *x = NULL;
|
||||
cxobj *xprev = NULL;
|
||||
yang_stmt *ys;
|
||||
|
||||
/* Abort sort if non-config (=state) data */
|
||||
if ((ys = xml_spec(x0)) != 0 && yang_config(ys)==0){
|
||||
retval = 1;
|
||||
goto done;
|
||||
}
|
||||
while ((x = xml_child_each(x0, x, -1)) != NULL) {
|
||||
if (xprev != NULL){ /* Check xprev <= x */
|
||||
if (xml_cmp(&xprev, &x) > 0)
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ fi
|
|||
|
||||
# Note order of features in ietf-netconf yang is alphabetically: candidate, startup, validate, xpath
|
||||
new "netconf module ietf-netconf"
|
||||
expect="<module><name>ietf-netconf</name><revision>2011-06-01</revision><namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace><feature>candidate</feature><feature>startup</feature><feature>validate</feature><feature>xpath</feature><conformance-type>implement</conformance-type></module>"
|
||||
expect="<module><name>ietf-netconf</name><revision>2011-06-01</revision><namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace><feature>candidate</feature><feature>validate</feature><feature>startup</feature><feature>xpath</feature><conformance-type>implement</conformance-type></module>"
|
||||
match=`echo "$ret" | grep -GZo "$expect"`
|
||||
if [ -z "$match" ]; then
|
||||
err "$expect" "$ret"
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ sudo su -c "$clixon_restconf -f $cfg -D $DBG -- -a" -s /bin/sh www-data &
|
|||
sleep $RCWAIT
|
||||
|
||||
new "auth get"
|
||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": "42"}}
|
||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": ["42","41","43"]}}
|
||||
'
|
||||
|
||||
new "Set x to 0"
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-exam
|
|||
'
|
||||
|
||||
new "admin read state OK"
|
||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": "42"}}
|
||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": ["42","41","43"]}}
|
||||
'
|
||||
|
||||
new "admin read top ok (all)"
|
||||
|
|
@ -204,11 +204,11 @@ expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/nacm-exa
|
|||
'
|
||||
|
||||
new "limit read state OK"
|
||||
expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": "42"}}
|
||||
expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": ["42","41","43"]}}
|
||||
'
|
||||
|
||||
new "limit read top ok (part)"
|
||||
expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data)" '{"data": {"clixon-example:translate": [{"k": "key42","value": "val42"},{ "k": "key43","value": "val43"}],"clixon-example:state": {"op": "42"}}}
|
||||
expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data)" '{"data": {"clixon-example:translate": [{"k": "key42","value": "val42"},{ "k": "key43","value": "val43"}],"clixon-example:state": {"op": ["42","41","43"]}}}
|
||||
'
|
||||
|
||||
#user:guest
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ new "netconf edit state operation should fail"
|
|||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><state xmlns="urn:example:clixon"><op>42</op></state></config></edit-config></rpc>]]>]]>' "^<rpc-reply><rpc-error><error-type>protocol</error-type><error-tag>invalid-value</error-tag>"
|
||||
|
||||
new "netconf get state operation"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><get><filter type=\"xpath\" select=\"/state\"/></get></rpc>]]>]]>" '^<rpc-reply><data><state xmlns="urn:example:clixon"><op>42</op></state></data></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><get><filter type=\"xpath\" select=\"/state\"/></get></rpc>]]>]]>" '^<rpc-reply><data><state xmlns="urn:example:clixon"><op>42</op><op>41</op><op>43</op></state></data></rpc-reply>]]>]]>$'
|
||||
|
||||
new "netconf lock/unlock"
|
||||
expecteof "$clixon_netconf -qf $cfg" 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>]]>]]>$"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ APPNAME=example
|
|||
. ./lib.sh
|
||||
cfg=$dir/conf_yang.xml
|
||||
fyang=$dir/order.yang
|
||||
tmp=$dir/tmp.x
|
||||
|
||||
# For memcheck
|
||||
# clixon_netconf="valgrind --leak-check=full --show-leak-kinds=all clixon_netconf"
|
||||
|
|
@ -30,6 +31,7 @@ cat <<EOF > $cfg
|
|||
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
||||
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
|
||||
<CLICON_BACKEND_DIR>/usr/local/lib/example/backend</CLICON_BACKEND_DIR>
|
||||
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
|
||||
<CLICON_CLI_GENMODEL_COMPLETION>1</CLICON_CLI_GENMODEL_COMPLETION>
|
||||
<CLICON_XMLDB_DIR>$dbdir</CLICON_XMLDB_DIR>
|
||||
|
|
@ -39,10 +41,13 @@ cat <<EOF > $cfg
|
|||
EOF
|
||||
|
||||
cat <<EOF > $fyang
|
||||
module example{
|
||||
module order-example{
|
||||
yang-version 1.1;
|
||||
namespace "urn:example:clixon";
|
||||
namespace "urn:example:order";
|
||||
prefix ex;
|
||||
import clixon-example { /* for state callback */
|
||||
prefix ex;
|
||||
}
|
||||
container c{
|
||||
leaf d{
|
||||
type string;
|
||||
|
|
@ -86,24 +91,24 @@ rm -f $dbdir/candidate_db
|
|||
# alt
|
||||
cat <<EOF > $dbdir/running_db
|
||||
<config>
|
||||
<y0 xmlns="urn:example:clixon">d</y0>
|
||||
<y1 xmlns="urn:example:clixon">d</y1>
|
||||
<y2 xmlns="urn:example:clixon"><k>d</k><a>bar</a></y2>
|
||||
<y3 xmlns="urn:example:clixon"><k>d</k><a>bar</a></y3>
|
||||
<y0 xmlns="urn:example:clixon">b</y0>
|
||||
<y1 xmlns="urn:example:clixon">b</y1>
|
||||
<c xmlns="urn:example:clixon"><d>hej</d></c>
|
||||
<y0 xmlns="urn:example:clixon">c</y0>
|
||||
<y1 xmlns="urn:example:clixon">c</y1>
|
||||
<y2 xmlns="urn:example:clixon"><k>a</k><a>bar</a></y2>
|
||||
<y3 xmlns="urn:example:clixon"><k>a</k><a>bar</a></y3>
|
||||
<l xmlns="urn:example:clixon">hopp</l>
|
||||
<y0 xmlns="urn:example:clixon">a</y0>
|
||||
<y1 xmlns="urn:example:clixon">a</y1>
|
||||
<y2 xmlns="urn:example:clixon"><k>c</k><a>bar</a></y2>
|
||||
<y3 xmlns="urn:example:clixon"><k>c</k><a>bar</a></y3>
|
||||
<y2 xmlns="urn:example:clixon"><k>b</k><a>bar</a></y2>
|
||||
<y3 xmlns="urn:example:clixon"><k>b</k><a>bar</a></y3>
|
||||
<y0 xmlns="urn:example:order">d</y0>
|
||||
<y1 xmlns="urn:example:order">d</y1>
|
||||
<y2 xmlns="urn:example:order"><k>d</k><a>bar</a></y2>
|
||||
<y3 xmlns="urn:example:order"><k>d</k><a>bar</a></y3>
|
||||
<y0 xmlns="urn:example:order">b</y0>
|
||||
<y1 xmlns="urn:example:order">b</y1>
|
||||
<c xmlns="urn:example:order"><d>hej</d></c>
|
||||
<y0 xmlns="urn:example:order">c</y0>
|
||||
<y1 xmlns="urn:example:order">c</y1>
|
||||
<y2 xmlns="urn:example:order"><k>a</k><a>bar</a></y2>
|
||||
<y3 xmlns="urn:example:order"><k>a</k><a>bar</a></y3>
|
||||
<l xmlns="urn:example:order">hopp</l>
|
||||
<y0 xmlns="urn:example:order">a</y0>
|
||||
<y1 xmlns="urn:example:order">a</y1>
|
||||
<y2 xmlns="urn:example:order"><k>c</k><a>bar</a></y2>
|
||||
<y3 xmlns="urn:example:order"><k>c</k><a>bar</a></y3>
|
||||
<y2 xmlns="urn:example:order"><k>b</k><a>bar</a></y2>
|
||||
<y3 xmlns="urn:example:order"><k>b</k><a>bar</a></y3>
|
||||
</config>
|
||||
EOF
|
||||
|
||||
|
|
@ -122,21 +127,28 @@ if [ $BE -ne 0 ]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
# STATE (should not be ordered)
|
||||
new "state data (should be unordered: 42,41,43)"
|
||||
cat <<EOF > $tmp
|
||||
<rpc><get><filter type="xpath" select="state"/></get></rpc>]]>]]>
|
||||
EOF
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "$(cat $tmp)" '<rpc-reply><data><state xmlns="urn:example:clixon"><op>42</op><op>41</op><op>43</op></state></data></rpc-reply>]]>]]>'
|
||||
|
||||
# Check as file
|
||||
new "verify running from start, should be: c,l,y0,y1,y2,y3; y1 and y3 sorted. Note this fails if CLICON_XML_SORT set to false"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><c xmlns="urn:example:clixon"><d>hej</d></c><l xmlns="urn:example:clixon">hopp</l><y0 xmlns="urn:example:clixon">d</y0><y0 xmlns="urn:example:clixon">b</y0><y0 xmlns="urn:example:clixon">c</y0><y0 xmlns="urn:example:clixon">a</y0><y1 xmlns="urn:example:clixon">a</y1><y1 xmlns="urn:example:clixon">b</y1><y1 xmlns="urn:example:clixon">c</y1><y1 xmlns="urn:example:clixon">d</y1><y2 xmlns="urn:example:clixon"><k>d</k><a>bar</a></y2><y2 xmlns="urn:example:clixon"><k>a</k><a>bar</a></y2><y2 xmlns="urn:example:clixon"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:clixon"><k>b</k><a>bar</a></y2><y3 xmlns="urn:example:clixon"><k>a</k><a>bar</a></y3><y3 xmlns="urn:example:clixon"><k>b</k><a>bar</a></y3><y3 xmlns="urn:example:clixon"><k>c</k><a>bar</a></y3><y3 xmlns="urn:example:clixon"><k>d</k><a>bar</a></y3></data></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><c xmlns="urn:example:order"><d>hej</d></c><l xmlns="urn:example:order">hopp</l><y0 xmlns="urn:example:order">d</y0><y0 xmlns="urn:example:order">b</y0><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">a</y0><y1 xmlns="urn:example:order">a</y1><y1 xmlns="urn:example:order">b</y1><y1 xmlns="urn:example:order">c</y1><y1 xmlns="urn:example:order">d</y1><y2 xmlns="urn:example:order"><k>d</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>a</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>bar</a></y2><y3 xmlns="urn:example:order"><k>a</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>b</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>c</k><a>bar</a></y3><y3 xmlns="urn:example:order"><k>d</k><a>bar</a></y3><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>lo</name><type>ex:loopback</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$'
|
||||
|
||||
new "get each ordered-by user leaf-list"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k='a']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y2 xmlns="urn:example:clixon"><k>a</k><a>bar</a></y2></data></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k='a']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>a</k><a>bar</a></y2></data></rpc-reply>]]>]]>$'
|
||||
|
||||
new "get each ordered-by user leaf-list"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y3[k='a']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y3 xmlns="urn:example:clixon"><k>a</k><a>bar</a></y3></data></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y3[k='a']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y3 xmlns="urn:example:order"><k>a</k><a>bar</a></y3></data></rpc-reply>]]>]]>$'
|
||||
|
||||
new "get each ordered-by user leaf-list"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k='b']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y2 xmlns="urn:example:clixon"><k>b</k><a>bar</a></y2></data></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k='b']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>b</k><a>bar</a></y2></data></rpc-reply>]]>]]>$'
|
||||
|
||||
new "get each ordered-by user leaf-list"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y3[k='b']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y3 xmlns="urn:example:clixon"><k>b</k><a>bar</a></y3></data></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y3[k='b']\"/></get-config></rpc>]]>]]>" '^<rpc-reply><data><y3 xmlns="urn:example:order"><k>b</k><a>bar</a></y3></data></rpc-reply>]]>]]>$'
|
||||
|
||||
new "delete candidate"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><default-operation>none</default-operation><config operation="delete"/></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
@ -144,33 +156,33 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><can
|
|||
# LEAF_LISTS
|
||||
|
||||
new "add two entries (c,b) to leaf-list user order"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:clixon">c</y0><y0 xmlns="urn:example:clixon">b</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">b</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "add one entry (a) to leaf-list user order"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:clixon">a</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:order">a</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf commit"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "add one entry (0) to leaf-list user order after commit"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:clixon">0</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:order">0</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf commit"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "verify leaf-list user order in running (as entered: c,b,a,0)"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><running/></source><filter type="xpath" select="/y0"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><y0 xmlns="urn:example:clixon">c</y0><y0 xmlns="urn:example:clixon">b</y0><y0 xmlns="urn:example:clixon">a</y0><y0 xmlns="urn:example:clixon">0</y0></data></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><running/></source><filter type="xpath" select="/y0"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">b</y0><y0 xmlns="urn:example:order">a</y0><y0 xmlns="urn:example:order">0</y0></data></rpc-reply>]]>]]>$'
|
||||
|
||||
# LISTS
|
||||
|
||||
new "add two entries to list user order"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:clixon"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:clixon"><k>b</k><a>foo</a></y2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:order"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>foo</a></y2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "add one entry to list user order"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:clixon"><k>a</k><a>fie</a></y2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y2 xmlns="urn:example:order"><k>a</k><a>fie</a></y2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "verify list user order (as entered)"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/y2"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><y2 xmlns="urn:example:clixon"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:clixon"><k>b</k><a>foo</a></y2><y2 xmlns="urn:example:clixon"><k>a</k><a>fie</a></y2></data></rpc-reply>]]>]]>$'
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/y2"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>c</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>foo</a></y2><y2 xmlns="urn:example:order"><k>a</k><a>fie</a></y2></data></rpc-reply>]]>]]>$'
|
||||
|
||||
if [ $BE -eq 0 ]; then
|
||||
exit # BE
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ cat <<EOF > $cfg
|
|||
EOF
|
||||
|
||||
# This is a fixed 'state' implemented in routing_backend. It is assumed to be always there
|
||||
state='{"clixon-example:state": {"op": "42"}}'
|
||||
state='{"clixon-example:state": {"op": ["42","41","43"]}}
'
|
||||
|
||||
new "test params: -f $cfg"
|
||||
if [ $BE -ne 0 ]; then
|
||||
|
|
@ -113,11 +113,11 @@ new "restconf empty rpc with extra args (should fail)"
|
|||
expecteq "$(curl -s -X POST -d {\"clixon-example:input\":{\"extra\":null}} http://localhost/restconf/operations/clixon-example:empty)" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "unknown-element","error-info": {"bad-element": "extra"},"error-severity": "error"}}}
'
|
||||
|
||||
new "restconf get empty config + state json"
|
||||
expecteq "$(curl -sSG http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": "42"}}
|
||||
expecteq "$(curl -sSG http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": ["42","41","43"]}}
|
||||
'
|
||||
|
||||
new "restconf get empty config + state json + module"
|
||||
expecteq "$(curl -sSG http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": "42"}}
|
||||
expecteq "$(curl -sSG http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": ["42","41","43"]}}
|
||||
'
|
||||
|
||||
new "restconf get empty config + state json with wrong module name"
|
||||
|
|
@ -125,14 +125,14 @@ expecteq "$(curl -sSG http://localhost/restconf/data/badmodule:state)" '{"ietf-r
|
|||
|
||||
new "restconf get empty config + state xml"
|
||||
ret=$(curl -s -H "Accept: application/yang-data+xml" -G http://localhost/restconf/data/clixon-example:state)
|
||||
expect='<state xmlns="urn:example:clixon"><op>42</op></state>'
|
||||
expect='<state xmlns="urn:example:clixon"><op>42</op><op>41</op><op>43</op></state>'
|
||||
match=`echo $ret | grep -EZo "$expect"`
|
||||
if [ -z "$match" ]; then
|
||||
err "$expect" "$ret"
|
||||
fi
|
||||
|
||||
new "restconf get data/ json"
|
||||
expecteq "$(curl -s -G http://localhost/restconf/data/clixon-example:state/op=42)" '{"clixon-example:op": "42"}
|
||||
expecteq "$(curl -s -G http://localhost/restconf/data/clixon-example:state/op=42)" '{"clixon-example:op": ["42","41","43"]}
|
||||
'
|
||||
|
||||
new "restconf get state operation eth0 xml"
|
||||
|
|
@ -145,7 +145,7 @@ if [ -z "$match" ]; then
|
|||
fi
|
||||
|
||||
new "restconf get state operation eth0 type json"
|
||||
expecteq "$(curl -s -G http://localhost/restconf/data/clixon-example:state/op=42)" '{"clixon-example:op": "42"}
|
||||
expecteq "$(curl -s -G http://localhost/restconf/data/clixon-example:state/op=42)" '{"clixon-example:op": ["42","41","43"]}
|
||||
'
|
||||
|
||||
new "restconf get state operation eth0 type xml"
|
||||
|
|
@ -158,7 +158,7 @@ if [ -z "$match" ]; then
|
|||
fi
|
||||
|
||||
new "restconf GET datastore"
|
||||
expecteq "$(curl -s -X GET http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": "42"}}
|
||||
expecteq "$(curl -s -X GET http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": ["42","41","43"]}}
|
||||
'
|
||||
|
||||
# Exact match
|
||||
|
|
@ -178,7 +178,8 @@ new "restconf delete interfaces"
|
|||
expecteq $(curl -s -X DELETE http://localhost/restconf/data/ietf-interfaces:interfaces) ""
|
||||
|
||||
new "restconf Check empty config"
|
||||
expectfn "curl -sG http://localhost/restconf/data/clixon-example:state" 0 "$state"
|
||||
expectfn "curl -sG http://localhost/restconf/data/clixon-example:state" 0 "$state
|
||||
"
|
||||
|
||||
# XXX: gives <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
|
||||
# <interface xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
|
||||
|
|
@ -192,7 +193,7 @@ expecteq "$(curl -s -G http://localhost/restconf/data/ietf-interfaces:interfaces
|
|||
'
|
||||
|
||||
new "restconf Check eth/0/0 added state"
|
||||
expecteq "$(curl -s -G http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": "42"}}
|
||||
expecteq "$(curl -s -G http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": ["42","41","43"]}}
|
||||
'
|
||||
|
||||
new "restconf Re-post eth/0/0 which should generate error"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue