yin parser CHANGE add interface functions for module and submodule parsing
diff --git a/tests/src/test_parser_yin.c b/tests/src/test_parser_yin.c
index e921c01..cdd8afe 100644
--- a/tests/src/test_parser_yin.c
+++ b/tests/src/test_parser_yin.c
@@ -190,6 +190,63 @@
logbuf[0] = '\0';
}
+static int
+setup_logger(void **state)
+{
+ (void)state; /* unused */
+#if ENABLE_LOGGER_CHECKING
+ /* setup logger */
+ ly_set_log_clb(logger, 1);
+#endif
+
+ logbuf[0] = '\0';
+
+ return EXIT_SUCCESS;
+}
+
+static int
+teardown_logger(void **state)
+{
+ struct state *st = *state;
+
+#if ENABLE_LOGGER_CHECKING
+ /* teardown logger */
+ if (!st->finished_correctly && logbuf[0] != '\0') {
+ fprintf(stderr, "%s\n", logbuf);
+ }
+#endif
+
+ return EXIT_SUCCESS;
+}
+
+static int
+setup_element_test(void **state)
+{
+ setup_logger(state);
+ struct state *st = *state;
+
+ st->yin_ctx = calloc(1, sizeof(*st->yin_ctx));
+
+ /* allocate parser context */
+ st->yin_ctx->xml_ctx.ctx = st->ctx;
+ st->yin_ctx->xml_ctx.line = 1;
+
+ return EXIT_SUCCESS;
+}
+
+static int
+teardown_element_test(void **state)
+{
+ struct state *st = *(struct state **)state;
+
+ lyxml_context_clear(&st->yin_ctx->xml_ctx);
+ free(st->yin_ctx);
+
+ teardown_logger(state);
+
+ return EXIT_SUCCESS;
+}
+
static void
test_yin_match_keyword(void **state)
{
@@ -585,45 +642,6 @@
st->finished_correctly = true;
}
-static int
-setup_element_test(void **state)
-{
- struct state *st = *state;
-
-#if ENABLE_LOGGER_CHECKING
- /* setup logger */
- ly_set_log_clb(logger, 1);
-#endif
-
- /* reset logbuf */
- logbuf[0] = '\0';
-
- /* allocate parser context */
- st->yin_ctx = calloc(1, sizeof(*st->yin_ctx));
- st->yin_ctx->xml_ctx.ctx = st->ctx;
- st->yin_ctx->xml_ctx.line = 1;
-
- return EXIT_SUCCESS;
-}
-
-static int
-teardown_element_test(void **state)
-{
- struct state *st = *(struct state **)state;
-
-#if ENABLE_LOGGER_CHECKING
- /* teardown logger */
- if (!st->finished_correctly && logbuf[0] != '\0') {
- fprintf(stderr, "%s\n", logbuf);
- }
-#endif
-
- lyxml_context_clear(&st->yin_ctx->xml_ctx);
- free(st->yin_ctx);
-
- return EXIT_SUCCESS;
-}
-
#define ELEMENT_WRAPPER_START "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
#define ELEMENT_WRAPPER_END "</module>"
@@ -3614,6 +3632,113 @@
st->finished_correctly = true;
}
+static void
+test_yin_parse_module(void **state)
+{
+ struct state *st = *state;
+ const char *data;
+ struct lys_module *mod;
+ struct yin_parser_ctx *yin_ctx = NULL;
+
+ mod = calloc(1, sizeof *mod);
+ mod->ctx = st->ctx;
+ data = "<module name=\"example-foo\""
+ "xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\""
+ "xmlns:foo=\"urn:example:foo\""
+ "xmlns:myext=\"urn:example:extensions\">\n"
+
+ "<yang-version value=\"1.0\"/>\n"
+
+ "<namespace uri=\"urn:example:foo\"/>\n"
+ "<prefix value=\"foo\"/>\n"
+
+ "<import module=\"example-extensions\">\n"
+ "<prefix value=\"myext\"/>\n"
+ "</import>\n"
+
+ "<list name=\"interface\">\n"
+ "<key value=\"name\"/>\n"
+ "<leaf name=\"name\">\n"
+ "<type name=\"string\"/>\n"
+ "</leaf>\n"
+ "<leaf name=\"mtu\">\n"
+ "<type name=\"uint32\"/>\n"
+ "<description>\n"
+ "<text>The MTU of the interface.</text>\n"
+ "</description>\n"
+ "<myext:c-define name=\"MY_MTU\"/>\n"
+ "</leaf>\n"
+ "</list>\n"
+ "</module>\n";
+ assert_int_equal(yin_parse_module(&yin_ctx, data, mod), LY_SUCCESS);
+ lys_module_free(mod, NULL);
+ yin_parser_ctx_free(yin_ctx);
+ mod = NULL;
+ yin_ctx = NULL;
+
+ mod = calloc(1, sizeof *mod);
+ mod->ctx = st->ctx;
+ data = "<submodule name=\"example-foo\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
+ "</submodule>\n";
+ assert_int_equal(yin_parse_module(&yin_ctx, data, mod), LY_EINVAL);
+ logbuf_assert("Input data contains submodule which cannot be parsed directly without its main module.");
+ lys_module_free(mod, NULL);
+ yin_parser_ctx_free(yin_ctx);
+
+ st->finished_correctly = true;
+}
+
+static void
+test_yin_parse_submodule(void **state)
+{
+ struct state *st = *state;
+ const char *data;
+ struct yin_parser_ctx *yin_ctx = NULL;
+ struct lysp_submodule *submod = NULL;
+
+ data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<submodule name=\"asub\""
+ "xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\""
+ "xmlns:a=\"urn:a\">"
+ "<yang-version value=\"1.0\"/>\n"
+ "<belongs-to module=\"a\">"
+ "<prefix value=\"a_pref\"/>"
+ "</belongs-to>"
+ "<include module=\"atop\"/>"
+ "<feature name=\"fox\"/>"
+ "<notification name=\"bar-notif\">"
+ "<if-feature name=\"bar\"/>"
+ "</notification>"
+ "<notification name=\"fox-notif\">"
+ "<if-feature name=\"fox\"/>"
+ "</notification>"
+ "<augment target-node=\"/a_pref:top\">"
+ "<if-feature name=\"bar\"/>"
+ "<container name=\"bar-sub\"/>"
+ "</augment>"
+ "<augment target-node=\"/top\">"
+ "<container name=\"bar-sub2\"/>"
+ "</augment>"
+ "</submodule>";
+ assert_int_equal(yin_parse_submodule(&yin_ctx, st->ctx, data, &submod), LY_SUCCESS);
+ lysp_submodule_free(st->ctx, submod);
+ yin_parser_ctx_free(yin_ctx);
+ yin_ctx = NULL;
+ submod = NULL;
+
+ data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<module name=\"inval\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
+ "</module>";
+ assert_int_equal(yin_parse_submodule(&yin_ctx, st->ctx, data, &submod), LY_EINVAL);
+ logbuf_assert("Input data contains module in situation when a submodule is expected.");
+ lysp_submodule_free(st->ctx, submod);
+ yin_parser_ctx_free(yin_ctx);
+ yin_ctx = NULL;
+ submod = NULL;
+
+ st->finished_correctly = true;
+}
+
int
main(void)
{
@@ -3686,6 +3811,9 @@
cmocka_unit_test_setup_teardown(test_deviation_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_module_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_submodule_elem, setup_element_test, teardown_element_test),
+
+ cmocka_unit_test_setup_teardown(test_yin_parse_module, setup_logger, teardown_logger),
+ cmocka_unit_test_setup_teardown(test_yin_parse_submodule, setup_logger, teardown_logger),
};
return cmocka_run_group_tests(tests, setup_ly_ctx, destroy_ly_ctx);