From cc6c7ae7a4b43125b3f42c56b41a106fd9c17059 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Wed, 18 Jul 2018 21:45:13 +0200 Subject: [PATCH] started min/max-element --- CHANGELOG.md | 4 +- lib/src/clixon_xml_map.c | 37 +++++++++-- test/test_list.sh | 129 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+), 7 deletions(-) create mode 100755 test/test_list.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 011ea488..b2626d1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,9 @@ ## 3.7.0 (Upcoming) ### Major changes: -* Support for YANG conditionals "must" and "when" according to RFC 7950 Sec 7.5.3 and 7.21.5 +* Support for YANG conditionals "must" and "when" according to RFC 7950 Sec 7.5.3 and 7.21.5. * XPATH checked at validation time -* Support for YANG identity, identityref, must and when according to RFC 7950 Sec 7.189. +* Support for YANG identity, identityref, according to RFC 7950 Sec 7.18 and 9.10. * Previous support did no validation of values. * Validation of types and CLI expansion * Example extended with inclusion of iana-if-type RFC 7224 interface identities diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 368c5822..761f2b65 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -430,7 +430,7 @@ xml_yang_validate_all(cxobj *xt, yang_stmt *yc; /* yang child */ yang_stmt *ye; /* yang must error-message */ char *xpath; - int b; + int nr; /* if not given by argument (overide) use default link and !Node has a config sub-statement and it is false */ @@ -453,6 +453,33 @@ xml_yang_validate_all(cxobj *xt, if (validate_identityref(xt, ys, yc) < 0) goto done; } + } + if ((yc = yang_find((yang_node*)ys, Y_MIN_ELEMENTS, NULL)) != NULL){ + /* The behavior of the constraint depends on the type of the + * leaf-list's or list's closest ancestor node in the schema tree + * that is not a non-presence container (see Section 7.5.1): + * o If no such ancestor exists in the schema tree, the constraint + * is enforced. + * o Otherwise, if this ancestor is a case node, the constraint is + * enforced if any other node from the case exists. + * o Otherwise, it is enforced if the ancestor node exists. + */ +#if 0 + cxobj *xp; + cxobj *x; + int i; + + if ((xp = xml_parent(xt)) != NULL){ + nr = atoi(yc->ys_argument); + x = NULL; + i = 0; + while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) + i++; + } +#endif + } + if ((yc = yang_find((yang_node*)ys, Y_MAX_ELEMENTS, NULL)) != NULL){ + } break; default: @@ -464,9 +491,9 @@ xml_yang_validate_all(cxobj *xt, if (yc->ys_keyword != Y_MUST) continue; xpath = yc->ys_argument; /* "must" has xpath argument */ - if ((b = xpath_vec_bool(xt, "%s", xpath)) < 0) + if ((nr = xpath_vec_bool(xt, "%s", xpath)) < 0) goto done; - if (!b){ + if (!nr){ if ((ye = yang_find((yang_node*)yc, Y_ERROR_MESSAGE, NULL)) != NULL) clicon_err(OE_DB, 0, "%s", ye->ys_argument); else @@ -477,9 +504,9 @@ xml_yang_validate_all(cxobj *xt, /* "when" sub-node RFC 7950 Sec 7.21.5. Can only be one. */ if ((yc = yang_find((yang_node*)ys, Y_WHEN, NULL)) != NULL){ xpath = yc->ys_argument; /* "when" has xpath argument */ - if ((b = xpath_vec_bool(xt, "%s", xpath)) < 0) + if ((nr = xpath_vec_bool(xt, "%s", xpath)) < 0) goto done; - if (!b){ + if (!nr){ clicon_err(OE_DB, 0, "xpath %s validation failed", xml_name(xt)); goto done; } diff --git a/test/test_list.sh b/test/test_list.sh new file mode 100755 index 00000000..657b5457 --- /dev/null +++ b/test/test_list.sh @@ -0,0 +1,129 @@ +#!/bin/bash +# Yang list / leaf-list operations. min/max-elements + +APPNAME=example +# include err() and new() functions and creates $dir +. ./lib.sh + +exit 0 # NYI + +cfg=$dir/conf_yang.xml +fyang=$dir/test.yang + +cat < $cfg + + $cfg + /usr/local/share/$APPNAME/yang + $APPNAME + /usr/local/lib/$APPNAME/clispec + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/$APPNAME/$APPNAME.sock + /usr/local/var/$APPNAME/$APPNAME.pidfile + 1 + /usr/local/var/$APPNAME + /usr/local/lib/xmldb/text.so + +EOF + +cat < $fyang +module $APPNAME{ + container c{ + presence true; + list a0{ + key k; + leaf k { + type string; + } + min-elements 0; + max-elements "unbounded"; + } + list a1{ + key k; + leaf k { + type string; + } + description "There must be at least one of these"; + min-elements 1; + max-elements 2; + } + leaf-list b0{ + type string; + min-elements 0; + max-elements "unbounded"; + } + leaf-list b1{ + description "There must be at least one of these"; + type string; + min-elements 1; + max-elements 2; + } + } +} +EOF + +# kill old backend (if any) +new "kill old backend" +sudo clixon_backend -zf $cfg -y $fyang +if [ $? -ne 0 ]; then + err +fi + +new "start backend -s init -f $cfg -y $fyang" +# start new backend +sudo clixon_backend -s init -f $cfg -y $fyang +if [ $? -ne 0 ]; then + err +fi + +new "minmax: minimal" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "replace00]]>]]>" "^]]>]]>$" + +new "minmax: minimal validate ok" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +new "minmax: maximal" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "replace01unbounded0101unbounded01]]>]]>" "^]]>]]>$" + +new "minmax: validate ok" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +new "minmax: empty" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "replace]]>]]>" "^]]>]]>$" + +new "minmax: validate should fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +new "minmax: no list" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "replace0]]>]]>" "^]]>]]>$" + +new "minmax: validate should fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +new "minmax: no leaf-list" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "replace0]]>]]>" "^]]>]]>$" + +new "minmax: validate should fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +new "minmax: Too large list" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "replace0120]]>]]>" "^]]>]]>$" + +new "minmax: validate should fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + +new "minmax: Too large leaf-list" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "replace0012]]>]]>" "^]]>]]>$" + +new "minmax: validate should fail" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" + + + +# kill backend +sudo clixon_backend -zf $cfg +if [ $? -ne 0 ]; then + err "kill backend" +fi + +rm -rf $dir