diff --git a/lib/src/clixon_json.c b/lib/src/clixon_json.c index 7a07312d..4000e2e8 100644 --- a/lib/src/clixon_json.c +++ b/lib/src/clixon_json.c @@ -1130,8 +1130,9 @@ _json_parse(char *str, cxobj *x; cbuf *cberr = NULL; int i; + int failed = 0; /* yang assignment */ - clicon_debug(1, "%s %s", __FUNCTION__, str); + clicon_debug(1, "%s %d %s", __FUNCTION__, yb, str); jy.jy_parse_string = str; jy.jy_linenum = 1; jy.jy_current = xt; @@ -1174,12 +1175,16 @@ _json_parse(char *str, case YB_NONE: break; case YB_PARENT: - if (xml_spec_populate0_parent(x, NULL) < 0) + if ((ret = xml_spec_populate0_parent(x, xerr)) < 0) goto done; + if (ret == 0) + failed++; break; case YB_TOP: - if (xml_spec_populate0(x, yspec, NULL) < 0) + if (xml_spec_populate0(x, yspec, xerr) < 0) goto done; + if (ret == 0) + failed++; break; } /* Now find leafs with identityrefs (+transitive) and translate @@ -1191,7 +1196,7 @@ _json_parse(char *str, } if (xml_apply0(xt, CX_ELMNT, xml_sort, NULL) < 0) goto done; - retval = 1; + retval = (failed==0) ? 1 : 0; done: clicon_debug(1, "%s retval:%d", __FUNCTION__, retval); if (cberr) diff --git a/lib/src/clixon_xml_sort.c b/lib/src/clixon_xml_sort.c index 7a62f422..1a991c56 100644 --- a/lib/src/clixon_xml_sort.c +++ b/lib/src/clixon_xml_sort.c @@ -196,9 +196,22 @@ xml_cmp(cxobj *x1, int nr2 = 0; cxobj *x1b; cxobj *x2b; + enum cxobj_type xt1; + enum cxobj_type xt2; if (x1==NULL || x2==NULL) goto done; /* shouldnt happen */ + /* Sort according to attributes first */ + if ((xt1 = xml_type(x1)) != (xt2 = xml_type(x2))){ + if (xt1 == CX_ATTR){ + equal = -1; + goto done; + } + else if (xt2 == CX_ATTR){ + equal = 1; + goto done; + } + } y1 = xml_spec(x1); y2 = xml_spec(x2); if (same){ @@ -301,10 +314,14 @@ xml_cmp(cxobj *x1, } /* while cvi */ break; default: + /* This is a very special case such as for two choices - which is not validation correct, but we + should sort them according to nr1, nr2 since their yang is equal order */ + if (same) + equal = nr1-nr2; break; } /* switch */ done: - clicon_debug(2, "%s %s %s %d nr: %d %d yi: %d %d", __FUNCTION__, xml_name(x1), xml_name(x2), equal, nr1, nr2, yi1, yi2); + clicon_debug(2, "%s %s %s eq:%d nr: %d %d yi: %d %d", __FUNCTION__, xml_name(x1), xml_name(x2), equal, nr1, nr2, yi1, yi2); return equal; } diff --git a/test/test_choice.sh b/test/test_choice.sh index d67dcb5d..433e296c 100755 --- a/test/test_choice.sh +++ b/test/test_choice.sh @@ -119,14 +119,16 @@ fi new "waiting" wait_backend -new "kill old restconf daemon" -sudo pkill -u $wwwuser -f clixon_restconf +if [ $RC -ne 0 ]; then + new "kill old restconf daemon" + sudo pkill -u $wwwuser -f clixon_restconf -new "start restconf daemon" -start_restconf -f $cfg + new "start restconf daemon" + start_restconf -f $cfg -new "waiting" -wait_restconf + new "waiting" + wait_restconf +fi # First vanilla (protocol) case new "netconf validate empty" @@ -279,8 +281,10 @@ expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>" '^applicationbad-elementmcerrorElement in choice statement already exists]]>]]>$' -new "Kill restconf daemon" -stop_restconf +if [ $RC -ne 0 ]; then + new "Kill restconf daemon" + stop_restconf +fi if [ $BE -eq 0 ]; then exit # BE diff --git a/test/test_identity.sh b/test/test_identity.sh index eba3c402..960ff01d 100755 --- a/test/test_identity.sh +++ b/test/test_identity.sh @@ -283,7 +283,11 @@ expectpart "$(curl -s -i -X DELETE http://localhost/restconf/data/example:crypt # 2. set identity in other module with restconf , read it with restconf and netconf new "restconf add POST instead of PUT (should fail)" -expectpart "$(curl -s -i -X POST -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/example:crypto -d '{"example:crypto":"example-des:des3"}')" 0 'HTTP/1.1 400 Bad Request' '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"unknown-element","error-info":{"bad-element":"crypto"},"error-severity":"error","error-message":"Leaf contains sub-element"}}}' +expectpart "$(curl -s -i -X POST -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/example:crypto -d '{"example:crypto":"example-des:des3"}')" 0 'HTTP/1.1 400 Bad Request' '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"bad-element","error-info":{"bad-element":"crypto"},"error-severity":"error","error-message":"Missing matching yang node"}}}' + +# Alternative error: +#'{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"unknown-element","error-info":{"bad-element":"crypto"},"error-severity":"error","error-message":"Leaf contains sub-element"}}}' + new "restconf add other (des) identity using POST" expectpart "$(curl -s -i -X POST -H "Content-Type: application/yang-data+json" http://localhost/restconf/data -d '{"example:crypto":"example-des:des3"}')" 0 'HTTP/1.1 201 Created' 'Location: http://localhost/restconf/data/example:crypto' diff --git a/test/test_restconf_listkey.sh b/test/test_restconf_listkey.sh index 07934b29..4da53336 100755 --- a/test/test_restconf_listkey.sh +++ b/test/test_restconf_listkey.sh @@ -129,7 +129,7 @@ new "restconf PUT list-list" expecteq "$(curl -s -X PUT -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/list:c/a=x,y/e=z -d '{"list:e":{"f":"z","nonkey":"0"}}')" 0 '' new "restconf PUT change list-lst entry (wrong keys)(expect fail)" -expecteq "$(curl -s -X PUT -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/list:c/a=x,y/e=z -d '{"list:e":{"f":"wrong","nonley":"0"}}')" 0 '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"operation-failed","error-severity":"error","error-message":"api-path keys do not match data keys"}}} ' +expecteq "$(curl -s -X PUT -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/list:c/a=x,y/e=z -d '{"list:e":{"f":"wrong","nonkey":"0"}}')" 0 '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"operation-failed","error-severity":"error","error-message":"api-path keys do not match data keys"}}} ' new "restconf PUT list-list sub non-key" expecteq "$(curl -s -X PUT -H "Content-Type: application/yang-data+json" http://localhost/restconf/data/list:c/a=x,y/e=z/nonkey -d '{"list:nonkey":"u"}')" 0 ''