diff --git a/CHANGELOG.md b/CHANGELOG.md index 593e8f14..b292de24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,8 @@ Users may have to change how they access the system ### Corrected Bugs +* Fixed problems with XPATH composite operations and functions in netconf get/get-config operations. + * See [XPATH issues #219](https://github.com/clicon/clixon/issues/219) * Fix Union in xpath [XPATH issues #219](https://github.com/clicon/clixon/issues/219) * Fix: XPath:s used in netconf (eg get-config) did not correctly access default values * [RESTCONF GET request of single-key list with empty string returns all elements #213](https://github.com/clicon/clixon/issues/213) diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index 5be20e27..03d08f57 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -239,7 +239,7 @@ xpath_tree_print(FILE *f, * @param[in] xs XPATH tree * @param[out] xpath XPath string as CLIgen buf * @see xpath_tree_print - * @note NOT COMPLETE, just simple xpaths eg a/b + * @note XXX Not complete */ int xpath_tree2cbuf(xpath_tree *xs, @@ -248,22 +248,11 @@ xpath_tree2cbuf(xpath_tree *xs, int retval = -1; switch (xs->xs_type){ - case XP_NODE: /* s0 is namespace prefix, s1 is name */ - if (xs->xs_s0) - cprintf(xcb, "%s:", xs->xs_s0); - cprintf(xcb, "%s", xs->xs_s1); - break; case XP_ABSPATH: if (xs->xs_int == A_DESCENDANT_OR_SELF) cprintf(xcb, "/"); cprintf(xcb, "/"); break; - case XP_PRIME_STR: - cprintf(xcb, "'%s'", xs->xs_s0?xs->xs_s0:""); - break; - case XP_PRIME_NR: - cprintf(xcb, "%s", xs->xs_strnr?xs->xs_strnr:"0"); - break; case XP_STEP: switch (xs->xs_int){ case A_SELF: @@ -276,12 +265,34 @@ xpath_tree2cbuf(xpath_tree *xs, break; } break; + case XP_NODE: /* s0 is namespace prefix, s1 is name */ + if (xs->xs_s0) + cprintf(xcb, "%s:", xs->xs_s0); + cprintf(xcb, "%s", xs->xs_s1); + break; + case XP_PRIME_NR: + cprintf(xcb, "%s", xs->xs_strnr?xs->xs_strnr:"0"); + break; + case XP_PRIME_STR: + cprintf(xcb, "'%s'", xs->xs_s0?xs->xs_s0:""); + break; + case XP_PRIME_FN: + if (xs->xs_s0) + cprintf(xcb, "%s(", xs->xs_s0); + break; default: break; } if (xs->xs_c0 && xpath_tree2cbuf(xs->xs_c0, xcb) < 0) goto done; switch (xs->xs_type){ + case XP_AND: /* and or */ + case XP_ADD: /* div mod + * - */ + case XP_RELEX: /* !=, >= <= < > = */ + case XP_UNION: + if (xs->xs_c1) + cprintf(xcb, " %s ", clicon_int2str(xpopmap, xs->xs_int)); + break; case XP_RELLOCPATH: if (xs->xs_c1){ if (xs->xs_int == A_DESCENDANT_OR_SELF) @@ -293,9 +304,9 @@ xpath_tree2cbuf(xpath_tree *xs, if (xs->xs_c1) cprintf(xcb, "["); break; - case XP_RELEX: - if (xs->xs_c1) - cprintf(xcb, "%s", clicon_int2str(xpopmap, xs->xs_int)); + case XP_EXP: + if (xs->xs_c0 && xs->xs_c1) /* Function name and two arguments, insert , */ + cprintf(xcb, ","); break; default: break; @@ -307,6 +318,9 @@ xpath_tree2cbuf(xpath_tree *xs, if (xs->xs_c1) cprintf(xcb, "]"); break; + case XP_PRIME_FN: + if (xs->xs_s0) + cprintf(xcb, ")"); default: break; } diff --git a/test/test_netconf_filter.sh b/test/test_netconf_filter.sh index f20b2b07..73b5e4f6 100755 --- a/test/test_netconf_filter.sh +++ b/test/test_netconf_filter.sh @@ -80,6 +80,33 @@ expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^11]]>]]>$" +new "put more entries" +expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO31345425675]]>]]>" "^]]>]]>$" + +new "netconf commit" +expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^]]>]]>$" + +new "get xpath function not b=1" +expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^2231345425675]]>]]>$" + +new "get xpath function not(b)" +expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^5]]>]]>$" + +new "get xpath function contains" +expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^2242567]]>]]>$" + +new "get xpath function not(contains(fib,2))" +expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^11313455]]>]]>$" + +new "get xpath function or" +expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^3134542567]]>]]>$" + +new "get xpath function and" +expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^11]]>]]>$" + +new "get xpath function union" +expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO]]>]]>" "^115]]>]]>$" + if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill diff --git a/test/test_restconf.sh b/test/test_restconf.sh index cb01bb6e..8464d5d5 100755 --- a/test/test_restconf.sh +++ b/test/test_restconf.sh @@ -13,7 +13,7 @@ # - IPv6 by default disabled since docker does not support it out-of-the box # (4) local/backend config. Native only # - The tests runs through both (if compiled with native) -# See also test_restconf2.sh +# See also test_restconf_op.sh # See test_restconf_rpc.sh for cases when CLICON_BACKEND_RESTCONF_PROCESS is set # Magic line must be first in script (see README.md) diff --git a/test/test_xpath_canonical.sh b/test/test_xpath_canonical.sh index deb05fb0..e541234b 100755 --- a/test/test_xpath_canonical.sh +++ b/test/test_xpath_canonical.sh @@ -48,19 +48,19 @@ 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)" 255 +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 new "xpath canonical form (wrong namespace should fail)" -expectpart "$($clixon_util_xpath -c -y $ydir -p /i:x/j:y -n i:urn:example:c -n j:urn:example:b)" 255 +expectpart "$($clixon_util_xpath -c -y $ydir -p /i:x/j:y -n i:urn:example:c -n j:urn:example:b 2>/dev/null)" 255 rm -rf $dir diff --git a/test/test_xpath_functions.sh b/test/test_xpath_functions.sh index 5fd2cc5d..22d91465 100755 --- a/test/test_xpath_functions.sh +++ b/test/test_xpath_functions.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# From both: +# test xpath functions in YANG conditionals # XPATH base https://www.w3.org/TR/xpath-10/ # YANG XPATH functions: https://tools.ietf.org/html/rfc7950 # Tests: