diff --git a/src/resolve.c b/src/resolve.c index 369281a2b..e7e616659 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -6157,7 +6157,8 @@ static int check_leafref_features(struct lys_type *type) { struct lys_node *iter; - struct ly_set *src_parents, *trg_parents, *features; + struct lys_node_augment *aug; + struct ly_set *src_parents, *trg_parents, *features, *resolved; unsigned int i, j, size, x; int ret = EXIT_SUCCESS; @@ -6172,6 +6173,19 @@ check_leafref_features(struct lys_type *type) if (iter->nodetype & (LYS_INPUT | LYS_OUTPUT)) { continue; } + if (iter->parent && iter->parent->nodetype == LYS_AUGMENT) { + aug = (struct lys_node_augment*)iter->parent; + if (!aug->target) { + resolve_schema_nodeid(aug->target_name, NULL, aug->module, &resolved, 0, 0); + + if (!resolved) { + LOGVAL(LYE_INRESOLV, LY_VLOG_LYS, aug, "augment", aug->target_name); + return EXIT_FAILURE; + } + aug->target = resolved->set.s[0]; + ly_set_free(resolved); + } + } ly_set_add(src_parents, iter, LY_SET_OPT_USEASLIST); } /* get parents chain of target */ @@ -6179,6 +6193,19 @@ check_leafref_features(struct lys_type *type) if (iter->nodetype & (LYS_INPUT | LYS_OUTPUT)) { continue; } + if (iter->parent && iter->parent->nodetype == LYS_AUGMENT) { + aug = (struct lys_node_augment*)iter->parent; + if (!aug->target) { + resolve_schema_nodeid(aug->target_name, NULL, aug->module, &resolved, 0, 0); + + if (!resolved) { + LOGVAL(LYE_INRESOLV, LY_VLOG_LYS, aug, "augment", aug->target_name); + return EXIT_FAILURE; + } + aug->target = resolved->set.s[0]; + ly_set_free(resolved); + } + } ly_set_add(trg_parents, iter, LY_SET_OPT_USEASLIST); } diff --git a/tests/schema/test_augment.c b/tests/schema/test_augment.c index dacb37d65..572a38ae8 100644 --- a/tests/schema/test_augment.c +++ b/tests/schema/test_augment.c @@ -43,7 +43,7 @@ char *yin_modules[2 * MOD_COUNT] = {0}; static int setup_ctx_yin(void **state) { - *state = malloc(strlen(TESTS_DIR) + 40); + *state = malloc(strlen(TESTS_DIR) + 100); assert_non_null(*state); memcpy(*state, SCHEMA_FOLDER_YIN, strlen(SCHEMA_FOLDER_YIN) + 1); @@ -58,7 +58,7 @@ setup_ctx_yin(void **state) static int setup_ctx_yang(void **state) { - *state = malloc(strlen(TESTS_DIR) + 40); + *state = malloc(strlen(TESTS_DIR) + 100); assert_non_null(*state); memcpy(*state, SCHEMA_FOLDER_YANG, strlen(SCHEMA_FOLDER_YANG) + 1); @@ -145,6 +145,36 @@ test_leafref(void **state) } } +static void +test_leafref_w_feature1(void **state) +{ + int length; + char *path = *state; + const struct lys_module *module; + + ly_ctx_set_searchdir(ctx, path); + length = strlen(path); + strcpy(path + length, "/leafref_w_feature1-mod3.yang"); + if (!(module = lys_parse_path(ctx, path, LYS_IN_YANG))) { + fail(); + } +} + +static void +test_leafref_w_feature2(void **state) +{ + int length; + char *path = *state; + const struct lys_module *module; + + ly_ctx_set_searchdir(ctx, path); + length = strlen(path); + strcpy(path + length, "/leafref_w_feature2-mod1.yang"); + if (!(module = lys_parse_path(ctx, path, LYS_IN_YANG))) { + fail(); + } +} + static void test_target_augment(void **state) { @@ -298,6 +328,8 @@ main(void) cmocka_unit_test_setup_teardown(test_target_augment, setup_ctx_yang, teardown_ctx), cmocka_unit_test_setup_teardown(test_unres_augment, setup_ctx_yang, teardown_ctx), cmocka_unit_test_setup_teardown(test_import_augment_target, setup_ctx_yang, teardown_ctx), + cmocka_unit_test_setup_teardown(test_leafref_w_feature1, setup_ctx_yang, teardown_ctx), + cmocka_unit_test_setup_teardown(test_leafref_w_feature2, setup_ctx_yang, teardown_ctx), cmocka_unit_test_teardown(compare_output, teardown_output), }; diff --git a/tests/schema/yang/files/leafref_w_feature1-mod1.yang b/tests/schema/yang/files/leafref_w_feature1-mod1.yang new file mode 100644 index 000000000..fc227d966 --- /dev/null +++ b/tests/schema/yang/files/leafref_w_feature1-mod1.yang @@ -0,0 +1,13 @@ +module leafref_w_feature1-mod1 { + + namespace "urn:fri:params:xml:ns:yang:leafref_w_feature1-mod1"; + prefix lr-w-ftr1-m1; + + feature feature1; + + container cont1 { + if-feature feature1; + } +} + + diff --git a/tests/schema/yang/files/leafref_w_feature1-mod2.yang b/tests/schema/yang/files/leafref_w_feature1-mod2.yang new file mode 100644 index 000000000..7aae18e6b --- /dev/null +++ b/tests/schema/yang/files/leafref_w_feature1-mod2.yang @@ -0,0 +1,34 @@ +module leafref_w_feature1-mod2 { + + namespace "urn:fri:params:xml:ns:yang:leafref_w_feature1-mod2"; + prefix lr-w-ftr1-m2; + + import leafref_w_feature1-mod1 { + prefix lr-w-ftr1-m1; + } + + typedef list2-ref { + type leafref { + path "/lr-w-ftr1-m1:cont1" + + "/lr-w-ftr1-m2:cont2" + + "/lr-w-ftr1-m2:list2" + + "/lr-w-ftr1-m2:name"; + } + } + + augment "/lr-w-ftr1-m1:cont1" { + + description "mod2's cont1 augment"; + + container cont2 { + list list2 { + key name; + leaf name { + type string; + } + } + } + } +} + + diff --git a/tests/schema/yang/files/leafref_w_feature1-mod3.yang b/tests/schema/yang/files/leafref_w_feature1-mod3.yang new file mode 100644 index 000000000..2c2201df4 --- /dev/null +++ b/tests/schema/yang/files/leafref_w_feature1-mod3.yang @@ -0,0 +1,33 @@ +module leafref_w_feature1-mod3 { + + namespace "urn:fri:params:xml:ns:yang:leafref_w_feature1-mod3"; + prefix lr-w-ftr1-m3; + + import leafref_w_feature1-mod1 { + prefix lr-w-ftr1-m1; + } + import leafref_w_feature1-mod2 { + prefix lr-w-ftr1-m2; + } + + augment "/lr-w-ftr1-m1:cont1" { + + description "mod3's cont1 augment"; + + container cont3 { + list list3 { + key name; + leaf name { + type string; + } + choice choice3 { + case case3 { + leaf-list llist3 { + type lr-w-ftr1-m2:list2-ref; + } + } + } + } + } + } +} diff --git a/tests/schema/yang/files/leafref_w_feature2-mod1.yang b/tests/schema/yang/files/leafref_w_feature2-mod1.yang new file mode 100644 index 000000000..bbfaa5fad --- /dev/null +++ b/tests/schema/yang/files/leafref_w_feature2-mod1.yang @@ -0,0 +1,45 @@ +module leafref_w_feature2-mod1 { + + namespace "urn:fri:params:xml:ns:yang:leafref_w_feature2-mod1"; + prefix lr-w-ftr2-m1; + + feature feature2; + + container cont1 { + if-feature feature2; + } + + augment "/cont1" { + + container cont11 { + + list list11 { + key name; + + leaf name { + type string; + } + } + } + } + + augment "/cont1" { + + container cont12 { + + list list12 { + key name; + + leaf name { + type string; + } + + leaf-list llist12 { + type leafref { + path "/cont1/cont11/list11/name"; + } + } + } + } + } +}