yanglint FEATURE schema mount support (#1901)
* modify existing context if provided
In ly_ctx_new_yldata(), check if *ctx is NULL. If so, proceed as before
with allocating a new context. Otherwise, load modules into the existing
context.
Signed-off-by: Eric Kinzie <ekinzie@labn.net>
* add parent-reference xpath helper to schema-mount plugin
This new function produces a list of schema nodes from the expanded
parent-reference xpath expressions.
Signed-off-by: Eric Kinzie <ekinzie@labn.net>
* add context lookup to schema-mount plugin
This function allocates a new context for a particular instance of the
yangmnt:mount-point extension.
Signed-off-by: Eric Kinzie <ekinzie@labn.net>
* yanglint: schema-mount extension callback
Add a commandline argument "-x" that accepts a file containing extension
data, used to create a context for the schema-mount extension. This file
has the same format as what is provided to the "-Y" option. A callback
function for the schema-mount extenion is registered if the new option
is specified.
This allows validating instance data for models that include a schema
mount point.
Signed-off-by: Eric Kinzie <ekinzie@labn.net>
* yanglint: print mounted schema trees
Display "mp" flag for mount point and print mounted tree. Also display
the / and @ opts in node names.
Signed-off-by: Eric Kinzie <ekinzie@labn.net>
* add unit test for tree mount-point flag
Test is courtesy of aPiecek <piecek@cesnet.cz>.
Signed-off-by: Eric Kinzie <ekinzie@labn.net>
* add example data files for validation with schema-mount
From tools/lint/examples directory:
% ../../../build/yanglint \
-f json -t config -p ../../../models -p . \
-Y ./sm-context-main.xml -x ./sm-context-extension.xml sm-data.xml
% ../../../build/yanglint \
-f tree -p ../../../models -p . \
-Y ./sm-context-main.xml -x ./sm-context-extension.xml sm-main.yang
Signed-off-by: Eric Kinzie <ekinzie@labn.net>
Signed-off-by: Eric Kinzie <ekinzie@labn.net>
Co-authored-by: Eric Kinzie <ekinzie@labn.net>
diff --git a/tests/utests/basic/test_context.c b/tests/utests/basic/test_context.c
index 3a9f617..bf7d203 100644
--- a/tests/utests/basic/test_context.c
+++ b/tests/utests/basic/test_context.c
@@ -744,6 +744,7 @@
assert_non_null(ly_ctx_get_module(ctx_test, "ietf-yang-library", "2019-01-04"));
assert_null(ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01"));
ly_ctx_destroy(ctx_test);
+ ctx_test = NULL;
/* test loading module, should also import other module */
assert_int_equal(LY_SUCCESS, ly_ctx_new_ylmem(TESTS_SRC "/modules/yang/", with_netconf, LYD_XML, 0, &ctx_test));
@@ -753,6 +754,7 @@
assert_int_equal(0, ly_ctx_get_module(ctx_test, "ietf-netconf-acm", "2018-02-14")->implemented);
assert_int_equal(LY_ENOT, lys_feature_value(ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01"), "url"));
ly_ctx_destroy(ctx_test);
+ ctx_test = NULL;
/* test loading module with feature if they are present */
assert_int_equal(LY_SUCCESS, ly_ctx_new_ylmem(TESTS_SRC "/modules/yang/", with_netconf_features, LYD_XML, 0, &ctx_test));
@@ -760,6 +762,7 @@
assert_non_null(ly_ctx_get_module(ctx_test, "ietf-netconf-acm", "2018-02-14"));
assert_int_equal(LY_SUCCESS, lys_feature_value(ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01"), "url"));
ly_ctx_destroy(ctx_test);
+ ctx_test = NULL;
/* test with not matching revision */
assert_int_equal(LY_EINVAL, ly_ctx_new_ylmem(TESTS_SRC "/modules/yang/", garbage_revision, LYD_XML, 0, &ctx_test));
diff --git a/tests/utests/schema/test_printer_tree.c b/tests/utests/schema/test_printer_tree.c
index 5627702..850216a 100644
--- a/tests/utests/schema/test_printer_tree.c
+++ b/tests/utests/schema/test_printer_tree.c
@@ -1841,6 +1841,54 @@
TEST_LOCAL_TEARDOWN;
}
+static void
+mount_point(void **state)
+{
+ TEST_LOCAL_SETUP;
+
+ orig =
+ "module a29 {\n"
+ " yang-version 1.1;\n"
+ " namespace \"x:y\";\n"
+ " prefix x;\n"
+ " import ietf-yang-schema-mount {\n"
+ "prefix yangmnt;\n"
+ " }\n"
+ " list my-list {\n"
+ " key name;\n"
+ " leaf name {\n"
+ " type string;\n"
+ " }\n"
+ " yangmnt:mount-point \"mnt-root\";\n"
+ " }\n"
+ " container my-cont {\n"
+ " yangmnt:mount-point \"mnt-root\";\n"
+ " }\n"
+ "}\n";
+
+ expect =
+ "module: a29\n"
+ " +--mp my-list* [name]\n"
+ " | +--rw name string\n"
+ " +--mp my-cont\n";
+
+ UTEST_ADD_MODULE(orig, LYS_IN_YANG, NULL, &mod);
+ TEST_LOCAL_PRINT(mod, 72);
+ assert_int_equal(strlen(expect), ly_out_printed(UTEST_OUT));
+ assert_string_equal(printed, expect);
+
+ ly_out_reset(UTEST_OUT);
+
+ /* using lysc tree */
+ ly_ctx_set_options(UTEST_LYCTX, LY_CTX_SET_PRIV_PARSED);
+ TEST_LOCAL_PRINT(mod, 72);
+ assert_int_equal(strlen(expect), ly_out_printed(UTEST_OUT));
+ assert_string_equal(printed, expect);
+ ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_SET_PRIV_PARSED);
+
+ TEST_LOCAL_TEARDOWN;
+}
+
int
main(void)
{
@@ -1873,6 +1921,7 @@
UTEST(print_compiled_node),
UTEST(print_parsed_submodule),
UTEST(yang_data),
+ UTEST(mount_point),
};
return cmocka_run_group_tests(tests, NULL, NULL);