summaryrefslogtreecommitdiffstats
path: root/tests/utests/data/test_parser_xml.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/utests/data/test_parser_xml.c')
-rw-r--r--tests/utests/data/test_parser_xml.c226
1 files changed, 214 insertions, 12 deletions
diff --git a/tests/utests/data/test_parser_xml.c b/tests/utests/data/test_parser_xml.c
index 7defd9c..4f33f00 100644
--- a/tests/utests/data/test_parser_xml.c
+++ b/tests/utests/data/test_parser_xml.c
@@ -31,6 +31,7 @@ setup(void **state)
" namespace urn:tests:a;\n"
" prefix a;\n"
" yang-version 1.1;\n"
+ " import ietf-yang-metadata {prefix md;}"
" list l1 { key \"a b c\"; leaf a {type string;} leaf b {type string;} leaf c {type int16;}"
" leaf d {type string;}"
" container cont {leaf e {type boolean;}}"
@@ -42,9 +43,12 @@ setup(void **state)
" notification n1 { leaf nl {type string;}}}\n"
" container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}\n"
" anydata any {config false;}\n"
+ " anyxml anyx;\n"
" leaf foo2 { type string; default \"default-val\"; }\n"
" leaf foo3 { type uint32; }\n"
- " notification n2;}";
+ " notification n2;"
+ " md:annotation attr {type enumeration {enum val;}}"
+ "}";
UTEST_SETUP;
@@ -122,6 +126,7 @@ static void
test_anydata(void **state)
{
const char *data;
+ char *str;
struct lyd_node *tree;
data = "<any xmlns=\"urn:tests:a\">\n"
@@ -145,6 +150,49 @@ test_anydata(void **state)
"</any>\n";
CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
+
+ assert_int_equal(LY_SUCCESS, lyd_any_value_str(tree, &str));
+ lyd_free_all(tree);
+
+ assert_int_equal(LY_SUCCESS, lyd_new_path2(NULL, UTEST_LYCTX, "/a:any", str, strlen(str), LYD_ANYDATA_XML, 0, &tree, NULL));
+ free(str);
+ CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
+ lyd_free_all(tree);
+}
+
+static void
+test_anyxml(void **state)
+{
+ const char *data;
+ char *str;
+ struct lyd_node *tree;
+
+ data = "<anyx xmlns=\"urn:tests:a\">\n"
+ " <element1>\n"
+ " <element2 x:attr2=\"test\" xmlns:x=\"urn:x\">data</element2>\n"
+ " </element1>\n"
+ " <element1a/>\n"
+ "</anyx>\n";
+ CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
+ assert_non_null(tree);
+ tree = tree->next;
+
+ const char *data_expected =
+ "<anyx xmlns=\"urn:tests:a\">\n"
+ " <element1>\n"
+ " <element2 xmlns:x=\"urn:x\" x:attr2=\"test\">data</element2>\n"
+ " </element1>\n"
+ " <element1a/>\n"
+ "</anyx>\n";
+
+ CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
+
+ assert_int_equal(LY_SUCCESS, lyd_any_value_str(tree, &str));
+ lyd_free_all(tree);
+
+ assert_int_equal(LY_SUCCESS, lyd_new_path2(NULL, UTEST_LYCTX, "/a:anyx", str, strlen(str), LYD_ANYDATA_XML, 0, &tree, NULL));
+ free(str);
+ CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
lyd_free_all(tree);
}
@@ -170,17 +218,21 @@ test_list(void **state)
/* missing keys */
PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
"List instance is missing its key \"a\".", "Data location \"/a:l1[b='b'][c='1']\", line number 1.");
+ CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
"List instance is missing its key \"b\".", "Data location \"/a:l1[a='a']\", line number 1.");
PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><b>b</b><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
"List instance is missing its key \"c\".", "Data location \"/a:l1[a='a'][b='b']\", line number 1.");
+ CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL);
/* key duplicate */
PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a><c>1</c></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
"Duplicate instance of \"c\".",
"Data location \"/a:l1[a='a'][b='b'][c='1'][c='1']/c\", line number 1.");
+ CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL);
+ CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
/* keys order */
CHECK_PARSE_LYD("<l1 xmlns=\"urn:tests:a\"><d>d</d><a>a</a><c>1</c><b>b</b></l1>", 0, LYD_VALIDATE_PRESENT, tree);
@@ -209,6 +261,7 @@ test_list(void **state)
assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0);
CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL);
+ CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
lyd_free_all(tree);
PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
@@ -250,14 +303,14 @@ test_opaq(void **state)
/* opaq flag */
CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
- CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "foo3", 0, 0, NULL, 0, "");
+ CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "foo3", 0, 0, NULL, 1, "");
CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<foo3 xmlns=\"urn:tests:a\"/>\n");
lyd_free_all(tree);
/* list, opaq flag */
data = "<l1 xmlns=\"urn:tests:a\"/>";
CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
- CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "l1", 0, 0, NULL, 0, "");
+ CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "l1", 0, 0, NULL, 1, "");
CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<l1 xmlns=\"urn:tests:a\"/>\n");
lyd_free_all(tree);
@@ -273,7 +326,7 @@ test_opaq(void **state)
/* opaq flag */
CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
- CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 0, "");
+ CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 1, "");
CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
lyd_free_all(tree);
@@ -289,7 +342,7 @@ test_opaq(void **state)
/* opaq flag */
CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
- CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 0, "");
+ CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 1, "");
CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
lyd_free_all(tree);
@@ -300,7 +353,7 @@ test_opaq(void **state)
" <c xmld:id=\"D\">1</c>\n"
"</a>\n",
LYD_XML, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
- CHECK_LOG_CTX("Unknown XML prefix \"xmld\".", "Line number 3.");
+ CHECK_LOG_CTX("Unknown XML prefix \"xmld\".", "Data location \"/a\", line number 3.");
}
static void
@@ -358,10 +411,10 @@ test_rpc(void **state)
node = lyd_child(node);
/* z has no value */
- CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_XML, "z", 0, 0, NULL, 0, "");
+ CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_XML, "z", 0, 0, NULL, 1, "");
node = node->parent->next;
/* l1 key c has invalid value so it is at the end */
- CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 0, "");
+ CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 1, "");
CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
"<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
@@ -554,10 +607,10 @@ test_netconf_rpc(void **state)
node = lyd_child(node);
/* z has no value */
- CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_XML, "z", 0, 0, NULL, 0, "");
+ CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_XML, "z", 0, 0, NULL, 1, "");
node = node->parent->next;
/* l1 key c has invalid value so it is at the end */
- CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 0, "");
+ CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 1, "");
CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
"<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"25\"/>\n");
@@ -581,8 +634,33 @@ test_netconf_rpc(void **state)
lyd_free_all(tree);
lyd_free_all(op);
- /* wrong namespace, element name, whatever... */
- /* TODO */
+ /* invalid anyxml nested metadata value */
+ data = "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\" pid=\"4114692032\">\n"
+ " <copy-config>\n"
+ " <target>\n"
+ " <running/>\n"
+ " </target>\n"
+ " <source>\n"
+ " <config>\n"
+ " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ " <a>val_a</a>\n"
+ " <b>val_b</b>\n"
+ " <c>5</c>\n"
+ " <cont nc:operation=\"merge\">\n"
+ " <e nc:operation=\"merge2\">false</e>\n"
+ " </cont>\n"
+ " </l1>\n"
+ " </config>\n"
+ " </source>\n"
+ " </copy-config>\n"
+ "</rpc>\n";
+ assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
+ assert_int_equal(LY_EVALID, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_NETCONF, &tree, &op));
+ ly_in_free(in, 0);
+ CHECK_LOG_CTX("Invalid enumeration value \"merge2\".",
+ "Path \"/ietf-netconf:copy-config/source/config/a:l1[a='val_a'][b='val_b'][c='5']/cont/e/@ietf-netconf:operation\", line number 13.");
+ lyd_free_all(tree);
+ assert_null(op);
}
static void
@@ -678,6 +756,22 @@ test_netconf_reply_or_notification(void **state)
lyd_free_all(tree);
lyd_free_all(op2);
+ /* notification with a different order */
+ data = "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
+ "<c xmlns=\"urn:tests:a\">\n"
+ " <n1>\n"
+ " <nl>value</nl>\n"
+ " </n1>\n"
+ "</c>\n"
+ "<eventTime>2010-12-06T08:00:01Z</eventTime>\n"
+ "</notification>\n";
+ assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
+ assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_NOTIF_NETCONF, &tree, &op2));
+ ly_in_free(in, 0);
+
+ lyd_free_all(tree);
+ lyd_free_all(op2);
+
/* parse a data reply */
data = "<rpc-reply message-id=\"55\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
" <al xmlns=\"urn:tests:a\">25</al>\n"
@@ -739,6 +833,64 @@ test_netconf_reply_or_notification(void **state)
}
static void
+test_restconf_rpc(void **state)
+{
+ const char *data;
+ struct ly_in *in;
+ struct lyd_node *tree, *envp;
+
+ assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-nmda", "2019-01-07", NULL)));
+
+ assert_int_equal(LY_SUCCESS, lyd_new_path(NULL, UTEST_LYCTX, "/ietf-netconf-nmda:edit-data", NULL, 0, &tree));
+
+ data = "<input xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-nmda\">"
+ "<datastore xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">ds:running</datastore>"
+ "<config>"
+ "<cp xmlns=\"urn:tests:a\"><z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\"/></cp>"
+ "<l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">"
+ "<a>val_a</a><b>val_b</b><c>val_c</c>"
+ "</l1>"
+ "</config></input>";
+ assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
+ assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, tree, in, LYD_XML, LYD_TYPE_RPC_RESTCONF, &envp, NULL));
+ ly_in_free(in, 0);
+
+ /* the same just connected to the edit-data RPC */
+ data = "<edit-data xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-nmda\">"
+ "<datastore xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">ds:running</datastore>"
+ "<config>"
+ "<cp xmlns=\"urn:tests:a\"><z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\"/></cp>"
+ "<l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">"
+ "<a>val_a</a><b>val_b</b><c>val_c</c>"
+ "</l1>"
+ "</config></edit-data>";
+ CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
+ lyd_free_all(tree);
+ lyd_free_all(envp);
+}
+
+static void
+test_restconf_reply(void **state)
+{
+ const char *data;
+ struct ly_in *in;
+ struct lyd_node *tree, *envp;
+
+ assert_int_equal(LY_SUCCESS, lyd_new_path(NULL, UTEST_LYCTX, "/a:c/act", NULL, 0, &tree));
+
+ data = "<output xmlns=\"urn:tests:a\"><al>25</al></output>";
+ assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
+ assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, lyd_child(tree), in, LYD_XML, LYD_TYPE_REPLY_RESTCONF, &envp, NULL));
+ ly_in_free(in, 0);
+
+ /* connected to the RPC with the parent */
+ data = "<c xmlns=\"urn:tests:a\"><act><al>25</al></act></c>";
+ CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
+ lyd_free_all(tree);
+ lyd_free_all(envp);
+}
+
+static void
test_filter_attributes(void **state)
{
const char *data;
@@ -812,12 +964,58 @@ test_data_skip(void **state)
lyd_free_all(tree);
}
+static void
+test_metadata(void **state)
+{
+ const char *data;
+ struct lyd_node *tree;
+
+ /* invalid metadata value */
+ data = "<c xmlns=\"urn:tests:a\" xmlns:a=\"urn:tests:a\"><x a:attr=\"value\">xval</x></c>";
+ assert_int_equal(LY_EVALID, lyd_parse_data_mem(_UC->ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
+ assert_null(tree);
+ CHECK_LOG_CTX("Invalid enumeration value \"value\".", "Path \"/a:c/x/@a:attr\", line number 1.");
+}
+
+static void
+test_subtree(void **state)
+{
+ const char *data;
+ struct ly_in *in;
+ struct lyd_node *tree;
+
+ /* prepare data with the parent */
+ data = "<l1 xmlns=\"urn:tests:a\">\n"
+ " <a>val_a</a>\n"
+ " <b>val_b</b>\n"
+ " <c>1</c>\n"
+ "</l1>\n";
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
+
+ /* parse a subtree of it */
+ data = "<cont xmlns=\"urn:tests:a\">\n"
+ " <e>true</e>\n"
+ "</cont>\n";
+ assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
+ assert_int_equal(LY_SUCCESS, lyd_parse_data(UTEST_LYCTX, tree, in, LYD_XML, 0, LYD_VALIDATE_PRESENT, NULL));
+ ly_in_free(in, 0);
+
+ /* parse another container, fails */
+ assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
+ assert_int_equal(LY_EVALID, lyd_parse_data(UTEST_LYCTX, tree, in, LYD_XML, 0, LYD_VALIDATE_PRESENT, NULL));
+ ly_in_free(in, 0);
+ CHECK_LOG_CTX("Duplicate instance of \"cont\".", "Data location \"/a:l1[a='val_a'][b='val_b'][c='1']/cont\".");
+
+ lyd_free_all(tree);
+}
+
int
main(void)
{
const struct CMUnitTest tests[] = {
UTEST(test_leaf, setup),
UTEST(test_anydata, setup),
+ UTEST(test_anyxml, setup),
UTEST(test_list, setup),
UTEST(test_container, setup),
UTEST(test_opaq, setup),
@@ -828,8 +1026,12 @@ main(void)
UTEST(test_netconf_rpc, setup),
UTEST(test_netconf_action, setup),
UTEST(test_netconf_reply_or_notification, setup),
+ UTEST(test_restconf_rpc, setup),
+ UTEST(test_restconf_reply, setup),
UTEST(test_filter_attributes, setup),
UTEST(test_data_skip, setup),
+ UTEST(test_metadata, setup),
+ UTEST(test_subtree, setup),
};
return cmocka_run_group_tests(tests, NULL, NULL);