From b3545871c06db72ae869d6179a3dca017948355f Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Tue, 29 Sep 2020 20:53:24 +0200 Subject: [PATCH] * Added stricter check on schema-node identifier checking, such as for augments. * These checks are now made at YANG loading time --- CHANGELOG.md | 5 +- lib/clixon/clixon_yang.h | 12 +- lib/src/clixon_yang.c | 269 ++++++++++++++++------------- lib/src/clixon_yang_parse_lib.c | 289 +++++++++++++++++++++++--------- test/test_api_path.sh | 4 + test/test_datastore_repair.sh | 2 +- test/test_instance_id.sh | 3 + test/test_yang_models.sh | 1 + 8 files changed, 383 insertions(+), 202 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9c69b0c..d4d5f7b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,7 +46,8 @@ Users may have to change how they access the system ### Minor changes -* +* Added stricter check on schema-node identifier checking, such as for augments. + * These checks are now made at YANG loading time * Added sanity check that a yang module name matches the filename ### Corrected Bugs @@ -58,7 +59,7 @@ Users may have to change how they access the system 14 September 2020 This release is primarily a bugfix and usability improvement release, no major new features. - +ppp ### API changes on existing protocol/config features Users may have to change how they access the system diff --git a/lib/clixon/clixon_yang.h b/lib/clixon/clixon_yang.h index d4e0224d..22d5ad1e 100644 --- a/lib/clixon/clixon_yang.h +++ b/lib/clixon/clixon_yang.h @@ -51,9 +51,10 @@ /* * Yang flags used in */ -#define YANG_FLAG_MARK 0x01 /* (Dynamic) marker for dynamic algorithms, eg expand */ +#define YANG_FLAG_MARK 0x01 /* (Dynamic) marker for dynamic algorithms, eg expand and DAG */ +#define YANG_FLAG_TMP 0x02 /* (Dynamic) marker for dynamic algorithms, eg DAG detection */ #ifdef XML_EXPLICIT_INDEX -#define YANG_FLAG_INDEX 0x02 /* This yang node under list is (extra) index. --> you can access +#define YANG_FLAG_INDEX 0x04 /* This yang node under list is (extra) index. --> you can access * list elements using this index with binary search */ #endif @@ -240,11 +241,8 @@ int ys_populate2(yang_stmt *ys, void *arg); int yang_apply(yang_stmt *yn, enum rfc_6020 key, yang_applyfn_t fn, void *arg); int yang_datanode(yang_stmt *ys); -int yang_abs_schema_nodeid(yang_stmt *yspec, yang_stmt *ys, - char *schema_nodeid, - enum rfc_6020 keyword, yang_stmt **yres); -int yang_desc_schema_nodeid(yang_stmt *yn, char *schema_nodeid, - enum rfc_6020 keyword, yang_stmt **yres); +int yang_abs_schema_nodeid(yang_stmt *ys, char *schema_nodeid, yang_stmt **yres); +int yang_desc_schema_nodeid(yang_stmt *yn, char *schema_nodeid, yang_stmt **yres); int yang_mandatory(yang_stmt *ys); int yang_config(yang_stmt *ys); int yang_config_ancestor(yang_stmt *ys); diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index 4715585e..7cf2ac0d 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -707,6 +707,7 @@ ys_replace(yang_stmt *yorig, * @retval 0 OK * @retval -1 Error * Also add parent to child as up-pointer + * @see ys_prune */ int yn_insert(yang_stmt *ys_parent, @@ -732,6 +733,7 @@ yn_insert(yang_stmt *ys_parent, * } * @endcode * @note makes uses _ys_vector_i:can be changed if list changed between calls + * @note also does not work in recursive calls (to same node) */ yang_stmt * yn_each(yang_stmt *yparent, @@ -997,6 +999,10 @@ yang_find_myprefix(yang_stmt *ys) /* Not good enough with submodule, must be actual module */ if (ys_real_module(ys, &ymod) < 0) goto done; + if (ymod == NULL){ + clicon_err(OE_YANG, ENOENT, "Internal error: no module"); + goto done; + } if ((yprefix = yang_find(ymod, Y_PREFIX, NULL)) == NULL){ clicon_err(OE_YANG, ENOENT, "No prefix found for module %s", yang_argument_get(ymod)); goto done; @@ -2523,80 +2529,90 @@ yang_datanode(yang_stmt *ys) } /*! All the work for schema_nodeid functions both absolute and descendant - * Ignore prefixes, see _abs - * @param[in] yn Yang node. Find next yang stmt and return that if match. - * @param[in] vec Vector of nodeid's in a schema node identifier, eg a/b - * @param[in] nvec Length of vec - * @param[in] keyword A schemode of this type, or -1 if any + * + * @param[in] yn Yang node. For absolute schemanodeids this should be a module, otherwise any yang + * @param[in] cvv Schema-node path encoded as a name/value pair list. + * @param[in] nsc Namespace context from yang for the prefixes (names) of cvv * @param[out] yres Result yang statement node, or NULL if not found * @retval -1 Error, with clicon_err called * @retval 0 OK + * A schema node identifier consists of a path of identifiers, separated by slashes ("/"). + * References to identifiers defined in external modules MUST be + * qualified with appropriate prefixes, and references to identifiers + * defined in the current module and its submodules MAY use a prefix. + * prefixes are implemented by cvv names, and id:s by cvv strings. + * A namespace context of the original module is nsc as prefix context. + * + * @see RFC7950 Sec 6.5 */ static int -schema_nodeid_vec(yang_stmt *yn, - char **vec, - int nvec, - enum rfc_6020 keyword, - yang_stmt **yres) +schema_nodeid_iterate(yang_stmt *yn, + cvec *nodeid_cvv, + cvec *nsc, + yang_stmt **yres) { int retval = -1; - char *arg; - yang_stmt *ynext; - char *nodeid = NULL; - int i; + yang_stmt *ymod; + char *prefix; /* node-identifier = [prefix ":"] identifier */ + char *id; yang_stmt *ys; - int match; + yang_stmt *ym2; + yang_stmt *yp; + cg_var *cv; + char *ns; + yang_stmt *yspec; - if (nvec <= 0) - goto done; - arg = vec[0]; - clicon_debug(2, "%s: key=%s arg=%s match=%s len=%d", - __FUNCTION__, yang_key2str(yn->ys_keyword), yn->ys_argument, - arg, yn->ys_len); - if (strcmp(arg, "..") == 0) - ynext = yn->ys_parent; /* This could actually be a MODULE */ - else{ - /* ignore prefixes */ - if ((nodeid = strchr(arg, ':')) == NULL) - nodeid = arg; - else - nodeid++; - match = 0; + yspec = ys_spec(yn); + yp = yn; + /* Iterate over node identifiers /prefix:id/... */ + cv = NULL; + while ((cv = cvec_each(nodeid_cvv, cv)) != NULL){ + prefix = cv_name_get(cv); + id = cv_string_get(cv); + /* Top level is repeated from abs case, but here this is done to match with + * matching module below + * Get namespace */ + if ((ns = xml_nsctx_get(nsc, prefix)) == NULL){ + clicon_err(OE_YANG, EFAULT, "No namespace for prefix: %s in schema node identifier in module %s", + prefix, + yang_argument_get(ys_module(yn))); + goto done; + } + /* Get yang module */ + if ((ymod = yang_find_module_by_namespace(yspec, ns)) == NULL){ + clicon_err(OE_YANG, EFAULT, "No module for namespace: %s", ns); + goto done; + } + /* Iterate over children of current node to get a match + * XXX namespace????? + */ ys = NULL; - for (i=0; iys_len; i++){ - ys = yn->ys_stmt[i]; + while ((ys = yn_each(yp, ys)) != NULL) { if (!yang_schemanode(ys)) continue; - if ((int)keyword != -1 && keyword != ys->ys_keyword) - continue; /* some keys dont have arguments, match on key */ if (ys->ys_keyword == Y_INPUT || ys->ys_keyword == Y_OUTPUT){ - if (strcmp(nodeid, yang_key2str(ys->ys_keyword)) == 0){ - match++; + if (strcmp(id, yang_key2str(ys->ys_keyword)) == 0){ break; } - } else - if (ys->ys_argument && strcmp(nodeid, ys->ys_argument) == 0){ - match++; - break; + } + else { + if (ys->ys_argument && strcmp(id, ys->ys_argument) == 0){ + /* Also check for right prefix/module */ + ym2 = ys->ys_mymodule?ys->ys_mymodule:ys_module(ys); + if (ym2 == ymod) + break; } - } - if (!match){ - clicon_debug(1, "%s: %s not found", __FUNCTION__, nodeid); + } + } /* while ys */ + if (ys == NULL){ + clicon_debug(1, "%s: %s not found", __FUNCTION__, id); goto ok; } - ynext = ys; - } - if (nvec == 1){ /* match */ - if (yang_schemanode((yang_stmt*)ynext)) - *yres = (yang_stmt*)ynext; - else - clicon_debug(1, "%s not schema node", arg); - goto ok; - } - /* recursive call using ynext */ - if (schema_nodeid_vec(ynext, vec+1, nvec-1, keyword, yres) < 0) - goto done; + yp = ys; + } /* while cv */ + assert(yp && yang_schemanode((yang_stmt*)yp)); + *yres = (yang_stmt*)yp; ok: retval = 0; done: @@ -2610,80 +2626,82 @@ schema_nodeid_vec(yang_stmt *yn, * @param[in] keyword A schemode of this type, or -1 if any * @param[out] yres Result yang statement node, or NULL if not found * @retval -1 Error, with clicon_err called - * @retval 0 OK (if yres set then found, if yres=0 then not found) + * @retval 0 OK , with result in yres * Assume schema nodeid:s have prefixes, (actually the first). - * @see yang_desc_schema_nodeid * @see RFC7950 6.5 * o schema node: A node in the schema tree. One of action, container, * leaf, leaf-list, list, choice, case, rpc, input, output, * notification, anydata, and anyxml. * Used in yang: deviation, top-level augment + * @see yang_desc_schema_nodeid */ int -yang_abs_schema_nodeid(yang_stmt *yspec, - yang_stmt *yn, +yang_abs_schema_nodeid(yang_stmt *yn, char *schema_nodeid, - enum rfc_6020 keyword, yang_stmt **yres) { - int retval = -1; - char **vec = NULL; - int nvec; - yang_stmt *ymod = NULL; - char *id; - char *prefix = NULL; - yang_stmt *yprefix; + int retval = -1; + cvec *nodeid_cvv = NULL; + cvec *nsc = NULL; + cg_var *cv; + char *prefix; + char *ns; + yang_stmt *yspec; + yang_stmt *ymod; + char *str; *yres = NULL; + yspec = ys_spec(yn); /* check absolute schema_nodeid */ if (schema_nodeid[0] != '/'){ clicon_err(OE_YANG, EINVAL, "absolute schema nodeid should start with /"); goto done; } - if ((vec = clicon_strsep(schema_nodeid, "/", &nvec)) == NULL){ - clicon_err(OE_YANG, errno, "strsep"); + /* Split nodeid on the form /p0:i0/p1:i1 to a cvec with [name:p0 value:i0][...] + */ + if (str2cvec(schema_nodeid, '/', ':', &nodeid_cvv) < 0) goto done; - } - /* Assume schema nodeid looks like: "/prefix:id[/prefix:id]*" */ - if (nvec < 2){ - clicon_err(OE_YANG, 0, "NULL or truncated path: %s", schema_nodeid); - goto done; - } - /* split : */ - if ((id = strchr(vec[1], ':')) == NULL){ /* no prefix */ - clicon_log(LOG_WARNING, "%s: Absolute schema nodeid %s must have prefix", __FUNCTION__, schema_nodeid); + if (cvec_len(nodeid_cvv) == 0) goto ok; - } - if ((prefix = strdup(vec[1])) == NULL){ - clicon_err(OE_UNIX, errno, "strdup"); - goto done; - } - prefix[id-vec[1]] = '\0'; - id++; - if (yn) /* Find module using local prefix definition */ - ymod = yang_find_module_by_prefix(yn, prefix); - if (ymod == NULL){ /* Try (global) prefix the module itself uses */ - ymod = NULL; - while ((ymod = yn_each(yspec, ymod)) != NULL) { - if ((yprefix = yang_find(ymod, Y_PREFIX, NULL)) != NULL && - strcmp(yprefix->ys_argument, prefix) == 0){ - break; + /* If p0 is NULL an entry will be: [i0] which needs to be transformed to [NULL:i0] */ + cv = NULL; + while ((cv = cvec_each(nodeid_cvv, cv)) != NULL){ + if ((str = cv_string_get(cv)) == NULL || !strlen(str)){ + if (cv_string_set(cv, cv_name_get(cv)) < 0){ + clicon_err(OE_UNIX, errno, "cv_string_set"); + goto done; } + cv_name_set(cv, NULL); } } - if (ymod == NULL){ - clicon_err(OE_YANG, 0, "No module with prefix %s found", prefix); + /* Make a namespace context from yang for the prefixes (names) of nodeid_cvv */ + if (xml_nsctx_yang(yn, &nsc) < 0) + goto done; + /* Since this is an _absolute_ schema nodeid start from top + * Get namespace */ + cv = cvec_i(nodeid_cvv, 0); + prefix = cv_name_get(cv); + if ((ns = xml_nsctx_get(nsc, prefix)) == NULL){ + clicon_err(OE_YANG, EFAULT, "No namespace for prefix: %s in schema node identifier: %s in module %s", + prefix, schema_nodeid, yang_argument_get(ys_module(yn))); goto done; } - if (schema_nodeid_vec(ymod, vec+1, nvec-1, keyword, yres) < 0) + /* Get yang module */ + if ((ymod = yang_find_module_by_namespace(yspec, ns)) == NULL){ + clicon_err(OE_YANG, EFAULT, "No module for namespace: %s in schema node identifier: %s", + ns, schema_nodeid); goto done; - ok: /* yres may not be set */ + } + /* Iterate through cvv to find schemanode using ymod as starting point (since it is absolute) */ + if (schema_nodeid_iterate(ymod, nodeid_cvv, nsc, yres) < 0) + goto done; + ok: retval = 0; done: - if (vec) - free(vec); - if (prefix) - free(prefix); + if (nodeid_cvv) + cvec_free(nodeid_cvv); + if (nsc) + cvec_free(nsc); return retval; } @@ -2694,35 +2712,60 @@ yang_abs_schema_nodeid(yang_stmt *yspec, * @param[out] yres First yang node matching schema nodeid * @retval 0 OK * @retval -1 Error, with clicon_err called - * @see yang_abs_schema_nodeid * Used in yang: unique, refine, uses augment + * @see yang_abs_schema_nodeid */ int yang_desc_schema_nodeid(yang_stmt *yn, char *schema_nodeid, - enum rfc_6020 keyword, yang_stmt **yres) { - int retval = -1; - char **vec = NULL; - int nvec; - - *yres = NULL; - if (strlen(schema_nodeid) == 0) + int retval = -1; + cvec *nodeid_cvv = NULL; + cg_var *cv; + char *str; + cvec *nsc = NULL; + + if (schema_nodeid == NULL || strlen(schema_nodeid) == 0){ + clicon_err(OE_YANG, EINVAL, "nodeid is empty"); goto done; + } + *yres = NULL; /* check absolute schema_nodeid */ if (schema_nodeid[0] == '/'){ clicon_err(OE_YANG, EINVAL, "descendant schema nodeid should not start with /"); goto done; } - if ((vec = clicon_strsep(schema_nodeid, "/", &nvec)) == NULL) + /* Split nodeid on the form /p0:i0/p1:i1 to a cvec with [name:p0 value:i0][...] + */ + if (str2cvec(schema_nodeid, '/', ':', &nodeid_cvv) < 0) goto done; - if (schema_nodeid_vec(yn, vec, nvec, keyword, yres) < 0) + if (cvec_len(nodeid_cvv) == 0) + goto ok; + /* If p0 is NULL an entry will be: [i0] which needs to be transformed to [NULL:i0] */ + cv = NULL; + while ((cv = cvec_each(nodeid_cvv, cv)) != NULL){ + if ((str = cv_string_get(cv)) == NULL || !strlen(str)){ + if (cv_string_set(cv, cv_name_get(cv)) < 0){ + clicon_err(OE_UNIX, errno, "cv_string_set"); + goto done; + } + cv_name_set(cv, NULL); + } + } + /* Make a namespace context from yang for the prefixes (names) of nodeid_cvv */ + if (xml_nsctx_yang(yn, &nsc) < 0) goto done; + /* Iterate through cvv to find schemanode using yn as relative starting point */ + if (schema_nodeid_iterate(yn, nodeid_cvv, nsc, yres) < 0) + goto done; + ok: retval = 0; done: - if (vec) - free(vec); + if (nsc) + cvec_free(nsc); + if (nodeid_cvv) + cvec_free(nodeid_cvv); return retval; } diff --git a/lib/src/clixon_yang_parse_lib.c b/lib/src/clixon_yang_parse_lib.c index ff228881..0ec0e5fc 100644 --- a/lib/src/clixon_yang_parse_lib.c +++ b/lib/src/clixon_yang_parse_lib.c @@ -212,8 +212,7 @@ ys_grouping_resolve(yang_stmt *yuses, * struct to the yang statements being inserted. */ static int -yang_augment_node(yang_stmt *ys, - yang_stmt *ysp) +yang_augment_node(yang_stmt *ys) { int retval = -1; char *schema_nodeid; @@ -229,18 +228,19 @@ yang_augment_node(yang_stmt *ys, clicon_err(OE_YANG, 0, "My yang module not found"); goto done; } + /* */ schema_nodeid = yang_argument_get(ys); clicon_debug(2, "%s %s", __FUNCTION__, schema_nodeid); /* Find the target */ - if (yang_abs_schema_nodeid(ysp, ys, schema_nodeid, -1, &ytarget) < 0) + if (yang_abs_schema_nodeid(ys, schema_nodeid, &ytarget) < 0) goto done; if (ytarget == NULL){ -#if 0 +#if 0 /* Lots of yang models fail here */ clicon_err(OE_YANG, 0, "Augment failed in module %s: target node %s not found", yang_argument_get(ys_module(ys)), schema_nodeid); - goto done; + goto done; #else clicon_log(LOG_WARNING, "Warning: Augment failed in module %s: target node %s not found", yang_argument_get(ys_module(ys)), @@ -274,38 +274,36 @@ yang_augment_node(yang_stmt *ys, } } ok: - retval = 0; + retval = 0; done: if (wnsc) cvec_free(wnsc); return retval; } -/*! Find all top-level augments and change original datamodels. */ +/*! Find all top-level augments in a module and change original datamodels. + * @param[in] ymod Yang statement of type module/sub-module + * @retval 0 OK + * @retval -1 Error + * Note there is an ordering problem, where an augment in one module depends on an augment in + * another module not yet augmented. + */ static int -yang_augment_spec(yang_stmt *ysp, - int modnr) +yang_augment_module(yang_stmt *ymod) + { int retval = -1; - yang_stmt *ym; yang_stmt *ys; - int i; - int j; - i = modnr; /* cant use yang_each here since you dont start at 0 */ - while (i < yang_len_get(ysp)){ /* Loop through modules and sub-modules */ - ym = ysp->ys_stmt[i++]; - j = 0; - while (j < yang_len_get(ym)){ /* Top-level symbols in modules */ - ys = ym->ys_stmt[j++]; - switch (yang_keyword_get(ys)){ - case Y_AUGMENT: /* top-level */ - if (yang_augment_node(ys, ysp) < 0) - goto done; - break; - default: - break; - } + ys = NULL; + while ((ys = yn_each(ymod, ys)) != NULL){ + switch (yang_keyword_get(ys)){ + case Y_AUGMENT: /* top-level */ + if (yang_augment_node(ys) < 0) + goto done; + break; + default: + break; } } retval = 0; @@ -457,9 +455,12 @@ yang_expand_grouping(yang_stmt *yn) goto done; } /* Make a copy of the grouping, then make refinements to this copy + * Note this ygrouping2 object does not gave a parent and does not work in many + * functions which assume a full hierarchy, use the original ygrouping in those cases. */ if ((ygrouping2 = ys_dup(ygrouping)) == NULL) goto done; + /* Only replace data/schemanodes: * Compute the number of such nodes, and extend the child vector with that below */ @@ -495,9 +496,8 @@ yang_expand_grouping(yang_stmt *yn) if (yang_keyword_get(yr) != Y_REFINE) continue; /* Find a node */ - if (yang_desc_schema_nodeid(ygrouping2, + if (yang_desc_schema_nodeid(ygrouping, /* Cannot use ygrouping2 */ yang_argument_get(yr), - -1, &yrt) < 0) goto done; /* Not found, try next */ @@ -865,7 +865,7 @@ yang_parse_module(clicon_handle h, * RFC 7950 Sec 5.2 */ if (strcmp(yang_argument_get(ymod), module) != 0){ - clicon_err(OE_YANG, EINVAL, "File %s contains yang module \"%s\" which does not expected module %s", + clicon_err(OE_YANG, EINVAL, "File %s contains yang module \"%s\" which does not match expected module %s", filename, yang_argument_get(ymod), module); @@ -953,7 +953,6 @@ ys_schemanode_check(yang_stmt *ys, void *dummy) { int retval = -1; - yang_stmt *yspec; yang_stmt *yres = NULL; yang_stmt *yp; char *arg; @@ -973,7 +972,7 @@ ys_schemanode_check(yang_stmt *ys, break; /* fallthru */ case Y_REFINE: - if (yang_desc_schema_nodeid(yp, arg, -1, &yres) < 0) + if (yang_desc_schema_nodeid(yp, arg, &yres) < 0) goto done; if (yres == NULL){ clicon_err(OE_YANG, 0, "schemanode sanity check of %s %s", @@ -988,7 +987,7 @@ ys_schemanode_check(yang_stmt *ys, goto done; for (i=0; iys_stmt[i], yspec) < 0) + * NOTE: the list may grow on each iteration */ + for (i=modmin; iys_stmt[i], yang_argument_get(yspec->ys_stmt[i])) < 0) + /* 2. Check cardinality a first time (done again last) */ + for (i=modmin; iys_stmt[i])) < 0) goto done; /* 3: Check features/if-features: check if enabled and remove disabled features */ - for (i=modnr; iys_stmt[i]) < 0) + for (i=modmin; iys_stmt[i], h) < 0) /* Alt: make a yang_apply0 */ + for (i=modmin; iys_stmt[i], -1, ys_populate, (void*)h) < 0) + if (yang_apply(yang_child_i(yspec, i), -1, ys_populate, (void*)h) < 0) goto done; } @@ -1142,8 +1266,8 @@ yang_parse_post(clicon_handle h, * from ys_populate step. * Must be done using static binding. */ - for (i=modnr; iys_stmt[i], Y_TYPE, ys_resolve_type, h) < 0) + for (i=modmin; iys_stmt[i]) < 0) + for (i=0; iys_stmt[i], -1, (yang_applyfn_t*)yang_flag_reset, (void*)YANG_FLAG_MARK); + yang_apply(ylist[i], -1, (yang_applyfn_t*)yang_flag_reset, (void*)YANG_FLAG_MARK); } - /* 7: Top-level augmentation of all modules. (Augment also in uses) */ - if (yang_augment_spec(yspec, modnr) < 0) - goto done; + /* 7: Top-level augmentation of all modules. + * Note: Clixon does not implement augment in USES + * Note: There is an ordering problem, where an augment in one module depends on an augment in + * another module not yet augmented. + */ + for (i=0; iys_stmt[i], -1, ys_populate2, (void*)h) < 0) + for (i=0; iys_stmt[i], -1, ys_schemanode_check, NULL) < 0) + if (yang_apply(ylist[i], -1, ys_schemanode_check, NULL) < 0) goto done; /* Check list key values */ - if (ys_list_check(h, yspec->ys_stmt[i]) < 0) + if (ys_list_check(h, ylist[i]) < 0) goto done; } /* 9. Check cardinality a second time after grouping/augment etc */ - for (i=modnr; iys_stmt[i], yang_argument_get(yspec->ys_stmt[i])) < 0) + for (i=0; i $ydir/moda.yang module moda{ namespace "urn:example:a"; prefix a; + import modb{ + prefix b; + } container x1{ description "list with single string key"; list y{ @@ -150,6 +153,7 @@ done echo -n '' >> $xml1 new "api-path single string key k1=a$rnd" +echo "$clixon_util_path -f $xml1 -y $ydir -p /moda:x1/y=a$rnd" expectpart "$($clixon_util_path -f $xml1 -y $ydir -p /moda:x1/y=a$rnd)" 0 "^0: a$rndfoo$rnd$" new "api-path single string key /x1" diff --git a/test/test_datastore_repair.sh b/test/test_datastore_repair.sh index c3a26bbf..daaaa00e 100755 --- a/test/test_datastore_repair.sh +++ b/test/test_datastore_repair.sh @@ -60,7 +60,7 @@ module B{ import A { prefix "a"; } - augment "/a:x/ngrt:y" { + augment "/a:x/a:y" { container z { leaf w { type string; diff --git a/test/test_instance_id.sh b/test/test_instance_id.sh index 8b1777c7..842b30b3 100755 --- a/test/test_instance_id.sh +++ b/test/test_instance_id.sh @@ -30,6 +30,9 @@ cat < $ydir/moda.yang module moda{ namespace "urn:example:a"; prefix a; + import modb { + prefix b; + } container x1{ description "list with single string key"; list y{ diff --git a/test/test_yang_models.sh b/test/test_yang_models.sh index 4f610b91..2a94080b 100755 --- a/test/test_yang_models.sh +++ b/test/test_yang_models.sh @@ -34,6 +34,7 @@ fi cat < $cfg $cfg + ni-ieee1588-ptp:cmlds $YANGMODELS/standard/ietf/RFC $YANGMODELS/standard/ieee/draft/802.1/Qcr $YANGMODELS/standard/ieee/draft/802