blob: ba06db6b079ed663c0c2606e7f2a603154420c04 [file] [log] [blame]
Radek Krejci509e2592019-05-15 16:30:48 +02001/*
2 * @file test_parser_xml.c
3 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for functions from parser_xml.c
5 *
Radek Iša56ca9e42020-09-08 18:42:00 +02006 * Copyright (c) 2019-2020 CESNET, z.s.p.o.
Radek Krejci509e2592019-05-15 16:30:48 +02007 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
Radek Iša56ca9e42020-09-08 18:42:00 +020014#define _UTEST_MAIN_
15#include "utests.h"
Radek Krejci509e2592019-05-15 16:30:48 +020016
Radek Krejci70593c12020-06-13 20:48:09 +020017#include "context.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020018#include "in.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020019#include "out.h"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010020#include "parser_data.h"
Radek Krejci70593c12020-06-13 20:48:09 +020021#include "printer_data.h"
Radek Krejci70593c12020-06-13 20:48:09 +020022#include "tree_data_internal.h"
23#include "tree_schema.h"
Radek Krejci509e2592019-05-15 16:30:48 +020024
25static int
26setup(void **state)
27{
Radek Iša56ca9e42020-09-08 18:42:00 +020028 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +010029 "module a {\n"
30 " namespace urn:tests:a;\n"
31 " prefix a;\n"
32 " yang-version 1.1;\n"
33 " list l1 {\n"
34 " key \"a b c\";\n"
35 " leaf a {type string;}\n"
36 " leaf b {type string;}\n"
37 " leaf c {type int16;}\n"
38 " leaf d {type string;}}\n"
39 " leaf foo { type string;}\n"
40 " container c {\n"
41 " leaf x {type string;}\n"
42 " action act { input { leaf al {type string;} } output { leaf al {type uint8;} } }\n"
43 " notification n1 { leaf nl {type string;}}}\n"
44 " container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}\n"
45 " anydata any {config false;}\n"
46 " leaf foo2 { type string; default \"default-val\"; }\n"
47 " leaf foo3 { type uint32; }\n"
48 " notification n2;}";
Radek Krejci509e2592019-05-15 16:30:48 +020049
Radek Iša56ca9e42020-09-08 18:42:00 +020050 UTEST_SETUP;
Radek Krejci509e2592019-05-15 16:30:48 +020051
Radek Iša56ca9e42020-09-08 18:42:00 +020052 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
53 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
Radek Krejci509e2592019-05-15 16:30:48 +020054
55 return 0;
56}
57
Radek Iša56ca9e42020-09-08 18:42:00 +020058#define CHECK_PARSE_LYD(INPUT, PARSE_OPTION, VALIDATE_OPTION, TREE) \
59 CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, PARSE_OPTION, VALIDATE_OPTION, LY_SUCCESS, TREE)
Radek Krejci509e2592019-05-15 16:30:48 +020060
Radek Iša56ca9e42020-09-08 18:42:00 +020061#define PARSER_CHECK_ERROR(INPUT, PARSE_OPTION, VALIDATE_OPTION, MODEL, RET_VAL, ERR_MESSAGE, ERR_PATH) \
62 assert_int_equal(RET_VAL, lyd_parse_data_mem(UTEST_LYCTX, INPUT, LYD_XML, PARSE_OPTION, VALIDATE_OPTION, &MODEL));\
63 CHECK_LOG_CTX(ERR_MESSAGE, ERR_PATH);\
64 assert_null(MODEL)
Radek Krejci509e2592019-05-15 16:30:48 +020065
Radek Iša56ca9e42020-09-08 18:42:00 +020066#define CHECK_LYD_STRING(IN_MODEL, PRINT_OPTION, TEXT) \
67 CHECK_LYD_STRING_PARAM(IN_MODEL, TEXT, LYD_XML, PRINT_OPTION)
Radek Krejci509e2592019-05-15 16:30:48 +020068
Radek Krejci509e2592019-05-15 16:30:48 +020069static void
70test_leaf(void **state)
71{
Radek Krejci509e2592019-05-15 16:30:48 +020072 const char *data = "<foo xmlns=\"urn:tests:a\">foo value</foo>";
73 struct lyd_node *tree;
74 struct lyd_node_term *leaf;
75
Radek Iša56ca9e42020-09-08 18:42:00 +020076 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-with-defaults", "2011-06-01", NULL));
Radek Krejci509e2592019-05-15 16:30:48 +020077
Radek Iša56ca9e42020-09-08 18:42:00 +020078 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
79 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "foo", 1, LYS_LEAF, 0, 0, NULL, 0);
80 leaf = (struct lyd_node_term *)tree;
81 CHECK_LYD_VALUE(leaf->value, STRING, "foo value");
82
83 CHECK_LYSC_NODE(tree->next->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
84 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010085 leaf = (struct lyd_node_term *)tree->next->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020086 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +010087 assert_true(leaf->flags & LYD_DEFAULT);
88
Radek Krejci509e2592019-05-15 16:30:48 +020089 lyd_free_all(tree);
Michal Vasko8d544252020-03-02 10:19:52 +010090
91 /* make foo2 explicit */
92 data = "<foo2 xmlns=\"urn:tests:a\">default-val</foo2>";
Radek Iša56ca9e42020-09-08 18:42:00 +020093 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Michal Vasko8d544252020-03-02 10:19:52 +010094 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +010095 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020096 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
97 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010098 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +020099 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +0100100 assert_false(leaf->flags & LYD_DEFAULT);
101
102 lyd_free_all(tree);
103
Radek Krejci1798aae2020-07-14 13:26:06 +0200104 /* parse foo2 but make it implicit, skip metadata xxx from missing schema */
Radek Iša56ca9e42020-09-08 18:42:00 +0200105 data = "<foo2 xmlns=\"urn:tests:a\" xmlns:wd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" "
106 "wd:default=\"true\" xmlns:x=\"urn:x\" x:xxx=\"false\">default-val</foo2>";
107 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Michal Vasko8d544252020-03-02 10:19:52 +0100108 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100109 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200110 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
111 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100112 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200113 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +0100114 assert_true(leaf->flags & LYD_DEFAULT);
115
116 lyd_free_all(tree);
Radek Krejci509e2592019-05-15 16:30:48 +0200117}
118
Radek Krejciee4cab22019-07-17 17:07:47 +0200119static void
120test_anydata(void **state)
121{
Michal Vasko52927e22020-03-16 17:26:14 +0100122 const char *data;
Radek Krejciee4cab22019-07-17 17:07:47 +0200123 struct lyd_node *tree;
Radek Krejciee4cab22019-07-17 17:07:47 +0200124
Radek Iša56ca9e42020-09-08 18:42:00 +0200125 data = "<any xmlns=\"urn:tests:a\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100126 " <element1>\n"
127 " <x:element2 x:attr2=\"test\" xmlns:a=\"urn:tests:a\" xmlns:x=\"urn:x\">a:data</x:element2>\n"
128 " </element1>\n"
129 " <element1a/>\n"
130 "</any>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200131 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejciee4cab22019-07-17 17:07:47 +0200132 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100133 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200134 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_R | LYS_STATUS_CURR | LYS_SET_CONFIG, 1, "any",
135 1, LYS_ANYDATA, 0, 0, NULL, 0);
136 const char *data_expected =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100137 "<any xmlns=\"urn:tests:a\">\n"
138 " <element1>\n"
139 " <element2 xmlns=\"urn:x\" xmlns:x=\"urn:x\" x:attr2=\"test\" xmlns:a=\"urn:tests:a\">a:data</element2>\n"
140 " </element1>\n"
141 " <element1a/>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200142 "</any>\n";
143
144 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
Radek Krejciee4cab22019-07-17 17:07:47 +0200145
146 lyd_free_all(tree);
Radek Krejciee4cab22019-07-17 17:07:47 +0200147}
148
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200149static void
150test_list(void **state)
151{
Radek Iša56ca9e42020-09-08 18:42:00 +0200152 const char *data;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200153 struct lyd_node *tree, *iter;
154 struct lyd_node_inner *list;
Radek Krejci710226d2019-07-24 17:24:59 +0200155 struct lyd_node_term *leaf;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200156
Radek Krejci710226d2019-07-24 17:24:59 +0200157 /* check hashes */
Radek Iša56ca9e42020-09-08 18:42:00 +0200158 data = "<l1 xmlns=\"urn:tests:a\"><a>one</a><b>one</b><c>1</c></l1>";
159 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
160 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
161 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100162 list = (struct lyd_node_inner *)tree;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200163 LY_LIST_FOR(list->child, iter) {
164 assert_int_not_equal(0, iter->hash);
165 }
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200166 lyd_free_all(tree);
Radek Krejci710226d2019-07-24 17:24:59 +0200167
Michal Vasko9f96a052020-03-10 09:41:45 +0100168 /* missing keys */
Radek Iša56ca9e42020-09-08 18:42:00 +0200169 PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
170 "List instance is missing its key \"a\".", "/a:l1[b='b'][c='1']");
Michal Vasko9f96a052020-03-10 09:41:45 +0100171
Radek Iša56ca9e42020-09-08 18:42:00 +0200172 PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
173 "List instance is missing its key \"b\".", "/a:l1[a='a']");
Michal Vasko9f96a052020-03-10 09:41:45 +0100174
Radek Iša56ca9e42020-09-08 18:42:00 +0200175 PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><b>b</b><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
176 "List instance is missing its key \"c\".", "/a:l1[a='a'][b='b']");
Michal Vasko9f96a052020-03-10 09:41:45 +0100177
178 /* key duplicate */
Radek Iša56ca9e42020-09-08 18:42:00 +0200179 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,
180 "Duplicate instance of \"c\".", "/a:l1[a='a'][b='b'][c='1'][c='1']/c");
Michal Vasko9f96a052020-03-10 09:41:45 +0100181
Radek Krejci710226d2019-07-24 17:24:59 +0200182 /* keys order */
Radek Iša56ca9e42020-09-08 18:42:00 +0200183 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);
184 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
185 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100186 list = (struct lyd_node_inner *)tree;
187 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200188 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "a", 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100189 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200190 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "b", 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100191 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200192 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100193 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200194 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "d", 0, LYS_LEAF, 1, 0, NULL, 0);
195 CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
Radek Krejci710226d2019-07-24 17:24:59 +0200196 lyd_free_all(tree);
197
Michal Vasko44685da2020-03-17 15:38:06 +0100198 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a></l1>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200199 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
200 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1", 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100201 list = (struct lyd_node_inner *)tree;
202 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200203 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "a", 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100204 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200205 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "b", 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100206 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200207 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0);
208 CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL);
Radek Krejci710226d2019-07-24 17:24:59 +0200209 lyd_free_all(tree);
210
Radek Iša56ca9e42020-09-08 18:42:00 +0200211 PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
212 "Invalid position of the key \"b\" in a list.", "Line number 1.");
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200213}
214
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200215static void
216test_container(void **state)
217{
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200218 struct lyd_node *tree;
219 struct lyd_node_inner *cont;
220
Radek Iša56ca9e42020-09-08 18:42:00 +0200221 CHECK_PARSE_LYD("<c xmlns=\"urn:tests:a\"/>", 0, LYD_VALIDATE_PRESENT, tree);
222 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c", 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100223 cont = (struct lyd_node_inner *)tree;
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200224 assert_true(cont->flags & LYD_DEFAULT);
225 lyd_free_all(tree);
226
Radek Iša56ca9e42020-09-08 18:42:00 +0200227 CHECK_PARSE_LYD("<cp xmlns=\"urn:tests:a\"/>", 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200228 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100229 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200230 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_PRESENCE, 1, "cp",
231 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100232 cont = (struct lyd_node_inner *)tree;
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200233 assert_false(cont->flags & LYD_DEFAULT);
234 lyd_free_all(tree);
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200235}
236
Michal Vasko44685da2020-03-17 15:38:06 +0100237static void
238test_opaq(void **state)
239{
Michal Vasko44685da2020-03-17 15:38:06 +0100240 const char *data;
Michal Vasko44685da2020-03-17 15:38:06 +0100241 struct lyd_node *tree;
242
243 /* invalid value, no flags */
244 data = "<foo3 xmlns=\"urn:tests:a\"/>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200245 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
246 "Invalid empty uint32 value.", "/a:foo3");
Michal Vasko44685da2020-03-17 15:38:06 +0100247
248 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200249 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
250 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_PREF_XML, "foo3", 0, 0, NULL, 0, "");
251 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<foo3 xmlns=\"urn:tests:a\"/>\n");
Michal Vasko44685da2020-03-17 15:38:06 +0100252 lyd_free_all(tree);
253
254 /* missing key, no flags */
Radek Iša56ca9e42020-09-08 18:42:00 +0200255 data = "<l1 xmlns=\"urn:tests:a\">\n"
256 " <a>val_a</a>\n"
257 " <b>val_b</b>\n"
258 " <d>val_d</d>\n"
259 "</l1>\n";
260 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
261 "List instance is missing its key \"c\".", "/a:l1[a='val_a'][b='val_b']");
Michal Vasko44685da2020-03-17 15:38:06 +0100262
263 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200264 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
265 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_PREF_XML, "l1", 0, 0, NULL, 0, "");
266 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vasko44685da2020-03-17 15:38:06 +0100267 lyd_free_all(tree);
268
269 /* invalid key, no flags */
Radek Iša56ca9e42020-09-08 18:42:00 +0200270 data = "<l1 xmlns=\"urn:tests:a\">\n"
271 " <a>val_a</a>\n"
272 " <b>val_b</b>\n"
273 " <c>val_c</c>\n"
274 "</l1>\n";
275 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
276 "Invalid int16 value \"val_c\".", "/a:l1/c");
Michal Vasko44685da2020-03-17 15:38:06 +0100277
278 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200279 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
280 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_PREF_XML, "l1", 0, 0, NULL, 0, "");
281 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vasko44685da2020-03-17 15:38:06 +0100282 lyd_free_all(tree);
283
Michal Vasko413c7f22020-05-05 12:34:06 +0200284 /* opaq flag and fail */
Radek Iša56ca9e42020-09-08 18:42:00 +0200285 assert_int_equal(LY_EVALID, lyd_parse_data_mem(UTEST_LYCTX,
286 "<a xmlns=\"ns\">\n"
287 " <b>x</b>\n"
288 " <c xml:id=\"D\">1</c>\n"
289 "</a>\n",
290 LYD_XML, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
291 CHECK_LOG_CTX("Unknown XML prefix \"xml\".", "Line number 3.");
Michal Vasko44685da2020-03-17 15:38:06 +0100292}
293
Michal Vaskob36053d2020-03-26 15:49:30 +0100294static void
295test_rpc(void **state)
296{
Michal Vaskob36053d2020-03-26 15:49:30 +0100297 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200298 struct ly_in *in;
Michal Vaskob36053d2020-03-26 15:49:30 +0100299 struct lyd_node *tree, *op;
Michal Vasko1bf09392020-03-27 12:38:10 +0100300 const struct lyd_node *node;
Radek Iša56ca9e42020-09-08 18:42:00 +0200301 const char *dsc = "The <edit-config> operation loads all or part of a specified\n"
302 "configuration to the specified target configuration.";
303 const char *ref = "RFC 6241, Section 7.2";
304 const char *feats[] = {"writable-running", NULL};
Michal Vaskob36053d2020-03-26 15:49:30 +0100305
Radek Iša56ca9e42020-09-08 18:42:00 +0200306 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100307
Radek Iša56ca9e42020-09-08 18:42:00 +0200308 data = "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100309 " <edit-config>\n"
310 " <target>\n"
311 " <running/>\n"
312 " </target>\n"
313 " <config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
314 " <l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">\n"
315 " <a>val_a</a>\n"
316 " <b>val_b</b>\n"
317 " <c>val_c</c>\n"
318 " </l1>\n"
319 " <cp xmlns=\"urn:tests:a\">\n"
320 " <z nc:operation=\"delete\"/>\n"
321 " </cp>\n"
322 " </config>\n"
323 " </edit-config>\n"
324 "</rpc>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200325 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200326 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(UTEST_LYCTX, in, LYD_XML, &tree, &op));
Michal Vasko63f3d842020-07-08 10:10:14 +0200327 ly_in_free(in, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100328
329 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200330
331 CHECK_LYSC_ACTION((struct lysc_action *)op->schema, dsc, 0, LYS_STATUS_CURR,
332 1, 0, 0, 1, "edit-config", LYS_RPC,
333 0, 0, 0, 0, 0, ref, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100334
Michal Vaskob36053d2020-03-26 15:49:30 +0100335 assert_non_null(tree);
336 assert_null(tree->schema);
Radek Iša56ca9e42020-09-08 18:42:00 +0200337
338 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0x1, 0x1, LY_PREF_XML, "rpc", 0, 0, NULL, 0, "");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200339 node = lyd_child(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +0200340 CHECK_LYSC_ACTION((struct lysc_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
341 1, 0, 0, 1, "edit-config", LYS_RPC,
342 0, 0, 0, 0, 0, ref, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200343 node = lyd_child(node)->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200344 dsc = "Inline Config content.";
345 CHECK_LYSC_NODE(node->schema, dsc, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "config", 0, LYS_ANYXML, 1, 0, NULL, 0);
Michal Vaskob104f112020-07-17 09:54:54 +0200346
Michal Vasko1bf09392020-03-27 12:38:10 +0100347 node = ((struct lyd_node_any *)node)->value.tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200348 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_PRESENCE, 1, "cp",
349 1, LYS_CONTAINER, 0, 0, NULL, 0);
350
Radek Krejcia1c1e542020-09-29 16:06:52 +0200351 node = lyd_child(node);
Michal Vasko1bf09392020-03-27 12:38:10 +0100352 /* z has no value */
Radek Iša56ca9e42020-09-08 18:42:00 +0200353 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_PREF_XML, "z", 0, 0, NULL, 0, "");
Michal Vaskob104f112020-07-17 09:54:54 +0200354 node = node->parent->next;
355 /* l1 key c has invalid value so it is at the end */
Radek Iša56ca9e42020-09-08 18:42:00 +0200356 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_PREF_XML, "l1", 0, 0, NULL, 0, "");
Michal Vaskob36053d2020-03-26 15:49:30 +0100357
Radek Iša56ca9e42020-09-08 18:42:00 +0200358 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100359 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">\n"
360 " <edit-config>\n"
361 " <target>\n"
362 " <running/>\n"
363 " </target>\n"
364 " <config>\n"
365 " <cp xmlns=\"urn:tests:a\">\n"
366 " <z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>\n"
367 " </cp>\n"
368 " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">\n"
369 " <a>val_a</a>\n"
370 " <b>val_b</b>\n"
371 " <c>val_c</c>\n"
372 " </l1>\n"
373 " </config>\n"
374 " </edit-config>\n"
375 "</rpc>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200376
Michal Vaskob36053d2020-03-26 15:49:30 +0100377 lyd_free_all(tree);
378
379 /* wrong namespace, element name, whatever... */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100380 /* TODO */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100381}
382
383static void
384test_action(void **state)
385{
Michal Vaskoa8edff02020-03-27 14:47:01 +0100386 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200387 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100388 struct lyd_node *tree, *op;
389 const struct lyd_node *node;
390
Radek Iša56ca9e42020-09-08 18:42:00 +0200391 data = "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100392 " <action xmlns=\"urn:ietf:params:xml:ns:yang:1\">\n"
393 " <c xmlns=\"urn:tests:a\">\n"
394 " <act>\n"
395 " <al>value</al>\n"
396 " </act>\n"
397 " </c>\n"
398 " </action>\n"
399 "</rpc>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200400 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200401 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(UTEST_LYCTX, in, LYD_XML, &tree, &op));
Michal Vasko63f3d842020-07-08 10:10:14 +0200402 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100403
404 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200405 CHECK_LYSC_ACTION((struct lysc_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
406 1, 0, 0, 1, "act", LYS_ACTION,
407 1, 0, 0, 1, 0, NULL, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100408
Radek Iša56ca9e42020-09-08 18:42:00 +0200409 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0x1, 0x1, LY_PREF_XML, "rpc", 0, 0, NULL, 0, "");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200410 node = lyd_child(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +0200411 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x0, 0x1, LY_PREF_XML, "action", 0, 0, NULL, 0, "");
412 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100413 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">\n"
414 " <action xmlns=\"urn:ietf:params:xml:ns:yang:1\">\n"
415 " <c xmlns=\"urn:tests:a\">\n"
416 " <act>\n"
417 " <al>value</al>\n"
418 " </act>\n"
419 " </c>\n"
420 " </action>\n"
421 "</rpc>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200422
Michal Vaskoa8edff02020-03-27 14:47:01 +0100423 lyd_free_all(tree);
424
425 /* wrong namespace, element name, whatever... */
426 /* TODO */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100427}
428
429static void
430test_notification(void **state)
431{
Michal Vaskoa8edff02020-03-27 14:47:01 +0100432 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200433 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100434 struct lyd_node *tree, *ntf;
435 const struct lyd_node *node;
436
Radek Iša56ca9e42020-09-08 18:42:00 +0200437 data = "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100438 " <eventTime>2037-07-08T00:01:00Z</eventTime>\n"
439 " <c xmlns=\"urn:tests:a\">\n"
440 " <n1>\n"
441 " <nl>value</nl>\n"
442 " </n1>\n"
443 " </c>\n"
444 "</notification>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200445 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200446 assert_int_equal(LY_SUCCESS, lyd_parse_notif(UTEST_LYCTX, in, LYD_XML, &tree, &ntf));
Michal Vasko63f3d842020-07-08 10:10:14 +0200447 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100448
449 assert_non_null(ntf);
Radek Iša56ca9e42020-09-08 18:42:00 +0200450 CHECK_LYSC_NOTIF((struct lysc_notif *)ntf->schema, 1, NULL, 0, 0x4, 1, 0, "n1", 1, 0, NULL, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100451
Radek Iša56ca9e42020-09-08 18:42:00 +0200452 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0x0, 0x1, LY_PREF_XML, "notification", 0, 0, NULL, 0, "");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200453 node = lyd_child(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +0200454 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x0, 0, LY_PREF_XML, "eventTime", 0, 0, NULL, 0, "2037-07-08T00:01:00Z");
Michal Vaskoa8edff02020-03-27 14:47:01 +0100455 node = node->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200456 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c", 1, LYS_CONTAINER, 0, 0, NULL, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100457
Radek Iša56ca9e42020-09-08 18:42:00 +0200458 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100459 lyd_free_all(tree);
460
461 /* top-level notif without envelope */
Radek Iša56ca9e42020-09-08 18:42:00 +0200462 data = "<n2 xmlns=\"urn:tests:a\"/>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200463 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200464 assert_int_equal(LY_SUCCESS, lyd_parse_notif(UTEST_LYCTX, in, LYD_XML, &tree, &ntf));
Michal Vasko63f3d842020-07-08 10:10:14 +0200465 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100466
467 assert_non_null(ntf);
Radek Iša56ca9e42020-09-08 18:42:00 +0200468 CHECK_LYSC_NOTIF((struct lysc_notif *)ntf->schema, 0, NULL, 0, 0x4, 1, 0, "n2", 0, 0, NULL, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100469
470 assert_non_null(tree);
471 assert_ptr_equal(ntf, tree);
472
Radek Iša56ca9e42020-09-08 18:42:00 +0200473 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100474 lyd_free_all(tree);
475
476 /* wrong namespace, element name, whatever... */
477 /* TODO */
Michal Vaskob36053d2020-03-26 15:49:30 +0100478}
479
Michal Vasko1ce933a2020-03-30 12:38:22 +0200480static void
481test_reply(void **state)
482{
Michal Vasko1ce933a2020-03-30 12:38:22 +0200483 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200484 struct ly_in *in;
Michal Vasko1ce933a2020-03-30 12:38:22 +0200485 struct lyd_node *request, *tree, *op;
486 const struct lyd_node *node;
487
488 data =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100489 "<c xmlns=\"urn:tests:a\">\n"
490 " <act>\n"
491 " <al>value</al>\n"
492 " </act>\n"
493 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200494 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200495 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(UTEST_LYCTX, in, LYD_XML, &request, NULL));
Michal Vasko63f3d842020-07-08 10:10:14 +0200496 ly_in_free(in, 0);
497
Michal Vasko1ce933a2020-03-30 12:38:22 +0200498 data =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100499 "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\">\n"
500 " <al xmlns=\"urn:tests:a\">25</al>\n"
501 "</rpc-reply>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200502 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
503 assert_int_equal(LY_SUCCESS, lyd_parse_reply(request, in, LYD_XML, &tree, &op));
504 ly_in_free(in, 0);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200505 lyd_free_all(request);
506
507 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200508
509 CHECK_LYSC_ACTION((struct lysc_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
510 1, 0, 0, 1, "act", LYS_ACTION,
511 1, 0, 0, 1, 0, NULL, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200512 node = lyd_child(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200513 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "al", 0, LYS_LEAF, 1, 0, NULL, 0);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200514 assert_true(node->schema->flags & LYS_CONFIG_R);
515
Radek Iša56ca9e42020-09-08 18:42:00 +0200516 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0x1, 0x1, LY_PREF_XML, "rpc-reply", 0, 0, NULL, 0, "");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200517 node = lyd_child(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +0200518 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c", 1, LYS_CONTAINER, 0, 0, NULL, 0);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200519
520 /* TODO print only rpc-reply node and then output subtree */
Radek Iša56ca9e42020-09-08 18:42:00 +0200521 CHECK_LYD_STRING(lyd_child(op), LYD_PRINT_WITHSIBLINGS, "<al xmlns=\"urn:tests:a\">25</al>\n");
Michal Vasko1ce933a2020-03-30 12:38:22 +0200522 lyd_free_all(tree);
523
524 /* wrong namespace, element name, whatever... */
525 /* TODO */
Michal Vasko1ce933a2020-03-30 12:38:22 +0200526}
527
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100528int
529main(void)
Radek Krejci509e2592019-05-15 16:30:48 +0200530{
531 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200532 UTEST(test_leaf, setup),
533 UTEST(test_anydata, setup),
534 UTEST(test_list, setup),
535 UTEST(test_container, setup),
536 UTEST(test_opaq, setup),
537 UTEST(test_rpc, setup),
538 UTEST(test_action, setup),
539 UTEST(test_notification, setup),
540 UTEST(test_reply, setup),
Radek Krejci509e2592019-05-15 16:30:48 +0200541 };
542
543 return cmocka_run_group_tests(tests, NULL, NULL);
544}