From cce76faa792d3d0c252a6c35575371742a3ea37a Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Sat, 24 Mar 2018 14:37:36 +0100 Subject: [PATCH] Fixed three-key list entry problem (reported by jdl@netgate) --- CHANGELOG.md | 1 + lib/src/clixon_xml_sort.c | 35 ++++++++++++++++++++--------------- test/test_yang.sh | 39 +++++++++++++++++++++++++++++++++++---- 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80851261..eb894f43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ enables saved files to be used as datastore without any editing. Thanks Matt. * Added cli_show_version() ### Corrected Bugs +* Fixed three-key list entry problem (reported by jdl@netgate) * Translate xml->json \n correctly * Fix issue: https://github.com/clicon/clixon/issues/15 Replace whole config diff --git a/lib/src/clixon_xml_sort.c b/lib/src/clixon_xml_sort.c index 0016a59b..e3aa4b23 100644 --- a/lib/src/clixon_xml_sort.c +++ b/lib/src/clixon_xml_sort.c @@ -167,7 +167,7 @@ xml_cmp(const void* arg1, return equal; } -/*! +/*! Compare xml object * @param[in] yangi Yang order * @param[in] keynr Length of keyvec/keyval vector when applicable * @param[in] keyvec Array of of yang key identifiers @@ -192,36 +192,38 @@ xml_cmp1(cxobj *x, int i; char *keyname; char *key; + int match = 0; /* Check if same yang spec (order in yang stmt list) */ switch (keyword){ case Y_CONTAINER: /* Match with name */ case Y_LEAF: /* Match with name */ - return strcmp(name, xml_name(x)); + match = strcmp(name, xml_name(x)); break; case Y_LEAF_LIST: /* Match with name and value */ if (userorder && yang_find((yang_node*)y, Y_ORDERED_BY, "user") != NULL) *userorder=1; b=xml_body(x); - return strcmp(keyval[0], b); + match = strcmp(keyval[0], b); break; case Y_LIST: /* Match with array of key values */ if (userorder && yang_find((yang_node*)y, Y_ORDERED_BY, "user") != NULL) *userorder=1; + /* All must match */ for (i=0; ie0 given "name" */ if ((b = xml_find_body(x, keyname)) == NULL) break; /* error case */ - return strcmp(key, b); + if ((match = strcmp(key, b)) != 0) + break; } - return 0; break; default: break; } - return 0; /* should not reach here */ + return match; /* should not reach here */ } /*! Sort children of an XML node @@ -273,12 +275,12 @@ xml_search_userorder(cxobj *x0, } /*! - * @param[in] yangi Yang order - * @param[in] keynr Length of keyvec/keyval vector when applicable - * @param[in] keyvec Array of of yang key identifiers - * @param[in] keyval Array of of yang key values - * @param[in] low Lower bound of childvec search interval - * @param[in] upper Lower bound of childvec search interval + * @param[in] yangi Yang order + * @param[in] keynr Length of keyvec/keyval vector when applicable + * @param[in] keyvec Array of of yang key identifiers + * @param[in] keyval Array of of yang key values + * @param[in] low Lower bound of childvec search interval + * @param[in] upper Lower bound of childvec search interval */ static cxobj * xml_search1(cxobj *x0, @@ -522,7 +524,7 @@ xml_sort_verify(cxobj *x0, return retval; } -/*! Given child tree x1c, find matching child in base tree x0 +/*! Given child tree x1c, find matching child in base tree x0 and return as x0cp * param[in] x0 Base tree node * param[in] x1c Modification tree child * param[in] yc Yang spec of tree child @@ -567,7 +569,10 @@ match_base_child(cxobj *x0, break; case Y_LIST: /* Match with key values */ cvk = yc->ys_cvec; /* Use Y_LIST cache, see ys_populate_list() */ - /* Count number of key indexes */ + /* Count number of key indexes + * Then create two vectors one with names and one with values of x1c, + * ec: keyvec: [a,b,c] keyval: [1,2,3] + */ cvi = NULL; keynr = 0; while ((cvi = cvec_each(cvk, cvi)) != NULL) keynr++; @@ -591,7 +596,7 @@ match_base_child(cxobj *x0, default: break; } - /* Get match */ + /* Get match. Sorting mode(optimized) or not?*/ if (xml_child_sort==0) *x0cp = xml_match(x0, xml_name(x1c), yc->ys_keyword, keynr, keyvec, keyval); else{ diff --git a/test/test_yang.sh b/test/test_yang.sh index b53ad8d3..4d5af03d 100755 --- a/test/test_yang.sh +++ b/test/test_yang.sh @@ -34,7 +34,7 @@ module example{ ex:c-define "MY_INTERFACES"; container x { list y { - key "a b"; + key "a b c"; leaf a { type string; } @@ -44,6 +44,9 @@ module example{ leaf c { type string; } + leaf val { + type string; + } } leaf d { type empty; @@ -115,7 +118,7 @@ new "cli not defined extension" #expectfn "$clixon_cli -1f $cfg -y $fyangerr show version" "Yang error: Extension ex:not-defined not found" new "netconf edit config" -expecteof "$clixon_netconf -qf $cfg -y $fyang" "125]]>]]>" "^]]>]]>$" +expecteof "$clixon_netconf -qf $cfg -y $fyang" "125one]]>]]>" "^]]>]]>$" new "netconf commit" expecteof "$clixon_netconf -qf $cfg -y $fyang" "]]>]]>" "^]]>]]>$" @@ -125,7 +128,7 @@ new "netconf commit 2nd" expecteof "$clixon_netconf -qf $cfg -y $fyang" "]]>]]>" "^]]>]]>$" new "netconf get config xpath" -expecteof "$clixon_netconf -qf $cfg -y $fyang" "]]>]]>" "^125]]>]]>$" +expecteof "$clixon_netconf -qf $cfg -y $fyang" "]]>]]>" "^125one]]>]]>$" new "netconf edit leaf-list" expecteof "$clixon_netconf -qf $cfg -y $fyang" "hejhopp]]>]]>" "^]]>]]>$" @@ -137,7 +140,7 @@ new "netconf get leaf-list path" expecteof "$clixon_netconf -qf $cfg -y $fyang" "]]>]]>" "^hejhopp]]>]]>$" new "netconf get (should be some)" -expecteof "$clixon_netconf -qf $cfg -y $fyang" "]]>]]>" "^125]]>]]>$" +expecteof "$clixon_netconf -qf $cfg -y $fyang" "]]>]]>" "^125one]]>]]>$" new "cli set leaf-list" expectfn "$clixon_cli -1f $cfg -y $fyang set x f e foo" "" @@ -162,6 +165,34 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" "]]>]]>" "^]]>]]>$" +new "netconf delete candidate" +expecteof "$clixon_netconf -qf $cfg" "]]>]]>" "^]]>]]>$" + +# Check 3-keys +new "netconf add one 3-key entry" +expecteof "$clixon_netconf -qf $cfg -y $fyang" "111one]]>]]>" "^]]>]]>$" + +new "netconf check add one 3-key" +expecteof "$clixon_netconf -qf $cfg -y $fyang" ']]>]]>' '111one]]>]]>' + +new "netconf add another (with same 1st key)" +expecteof "$clixon_netconf -qf $cfg -y $fyang" "121two]]>]]>" "^]]>]]>$" + +new "netconf check add another" +expecteof "$clixon_netconf -qf $cfg -y $fyang" ']]>]]>' '111one121two]]>]]>' + +new "netconf replace first" +expecteof "$clixon_netconf -qf $cfg -y $fyang" "111replace]]>]]>" "^]]>]]>$" + +new "netconf check replace" +expecteof "$clixon_netconf -qf $cfg -y $fyang" ']]>]]>' '111replace121two]]>]]>' + +new "netconf delete first" +expecteof "$clixon_netconf -qf $cfg -y $fyang" '111]]>]]>' "^]]>]]>$" + +new "netconf check delete" +expecteof "$clixon_netconf -qf $cfg -y $fyang" ']]>]]>' '121two]]>]]>' + # Check if still alive pid=`pgrep clixon_backend` if [ -z "$pid" ]; then