blob: baf460837bd20e55902545258702d9a4fd90696a [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 *
6 * Copyright (c) 2019 CESNET, z.s.p.o.
7 *
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 */
14
Radek Krejci509e2592019-05-15 16:30:48 +020015#include <stdarg.h>
16#include <stddef.h>
17#include <setjmp.h>
18#include <cmocka.h>
19
20#include <stdio.h>
21#include <string.h>
22
Radek Krejci70593c12020-06-13 20:48:09 +020023#include "context.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020024#include "in.h"
Radek Krejci7931b192020-06-25 17:05:03 +020025#include "parser_data.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020026#include "out.h"
Radek Krejci70593c12020-06-13 20:48:09 +020027#include "printer_data.h"
28#include "tests/config.h"
29#include "tree_data_internal.h"
30#include "tree_schema.h"
Radek Krejci509e2592019-05-15 16:30:48 +020031
32#define BUFSIZE 1024
33char logbuf[BUFSIZE] = {0};
34int store = -1; /* negative for infinite logging, positive for limited logging */
35
36struct ly_ctx *ctx; /* context for tests */
37
38/* set to 0 to printing error messages to stderr instead of checking them in code */
39#define ENABLE_LOGGER_CHECKING 1
40
41#if ENABLE_LOGGER_CHECKING
42static void
43logger(LY_LOG_LEVEL level, const char *msg, const char *path)
44{
45 (void) level; /* unused */
46 if (store) {
47 if (path && path[0]) {
48 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
49 } else {
50 strncpy(logbuf, msg, BUFSIZE - 1);
51 }
52 if (store > 0) {
53 --store;
54 }
55 }
56}
57#endif
58
59static int
60setup(void **state)
61{
62 (void) state; /* unused */
63
64 const char *schema_a = "module a {namespace urn:tests:a;prefix a;yang-version 1.1;"
Michal Vasko44685da2020-03-17 15:38:06 +010065 "list l1 { key \"a b c\"; leaf a {type string;} leaf b {type string;} leaf c {type int16;} leaf d {type string;}}"
Radek Krejciee4cab22019-07-17 17:07:47 +020066 "leaf foo { type string;}"
Michal Vaskoa8edff02020-03-27 14:47:01 +010067 "container c {"
68 "leaf x {type string;}"
Michal Vasko1ce933a2020-03-30 12:38:22 +020069 "action act { input { leaf al {type string;} } output { leaf al {type uint8;} } }"
Michal Vaskoa8edff02020-03-27 14:47:01 +010070 "notification n1 { leaf nl {type string;} }"
71 "}"
Michal Vaskob36053d2020-03-26 15:49:30 +010072 "container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}"
Michal Vasko8d544252020-03-02 10:19:52 +010073 "anydata any {config false;}"
Michal Vasko44685da2020-03-17 15:38:06 +010074 "leaf foo2 { type string; default \"default-val\"; }"
Michal Vaskoa8edff02020-03-27 14:47:01 +010075 "leaf foo3 { type uint32; }"
76 "notification n2;}";
Michal Vaskob36053d2020-03-26 15:49:30 +010077 const struct lys_module *mod;
Michal Vasko7b1ad1a2020-11-02 15:41:27 +010078 const char *feats[] = {"writable-running", NULL};
Radek Krejci509e2592019-05-15 16:30:48 +020079
80#if ENABLE_LOGGER_CHECKING
81 ly_set_log_clb(logger, 1);
82#endif
83
Michal Vasko8d544252020-03-02 10:19:52 +010084 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &ctx));
Michal Vasko7b1ad1a2020-11-02 15:41:27 +010085 assert_non_null((mod = ly_ctx_load_module(ctx, "ietf-netconf", "2011-06-01", feats)));
86 assert_non_null(ly_ctx_load_module(ctx, "ietf-netconf-with-defaults", "2011-06-01", NULL));
Michal Vasko3a41dff2020-07-15 14:30:28 +020087 assert_int_equal(LY_SUCCESS, lys_parse_mem(ctx, schema_a, LYS_IN_YANG, NULL));
Radek Krejci509e2592019-05-15 16:30:48 +020088
89 return 0;
90}
91
92static int
93teardown(void **state)
94{
95#if ENABLE_LOGGER_CHECKING
96 if (*state) {
97 fprintf(stderr, "%s\n", logbuf);
98 }
99#else
100 (void) state; /* unused */
101#endif
102
103 ly_ctx_destroy(ctx, NULL);
104 ctx = NULL;
105
106 return 0;
107}
108
109void
110logbuf_clean(void)
111{
112 logbuf[0] = '\0';
113}
114
115#if ENABLE_LOGGER_CHECKING
116# define logbuf_assert(str) assert_string_equal(logbuf, str)
117#else
118# define logbuf_assert(str)
119#endif
120
Radek Krejci509e2592019-05-15 16:30:48 +0200121static void
122test_leaf(void **state)
123{
124 *state = test_leaf;
125
126 const char *data = "<foo xmlns=\"urn:tests:a\">foo value</foo>";
127 struct lyd_node *tree;
128 struct lyd_node_term *leaf;
129
Michal Vasko63f3d842020-07-08 10:10:14 +0200130 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Radek Krejci509e2592019-05-15 16:30:48 +0200131 assert_non_null(tree);
132 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
133 assert_string_equal("foo", tree->schema->name);
134 leaf = (struct lyd_node_term*)tree;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200135 assert_string_equal("foo value", leaf->value.canonical);
Radek Krejci509e2592019-05-15 16:30:48 +0200136
Michal Vasko8d544252020-03-02 10:19:52 +0100137 assert_int_equal(LYS_LEAF, tree->next->next->schema->nodetype);
138 assert_string_equal("foo2", tree->next->next->schema->name);
139 leaf = (struct lyd_node_term*)tree->next->next;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200140 assert_string_equal("default-val", leaf->value.canonical);
Michal Vasko8d544252020-03-02 10:19:52 +0100141 assert_true(leaf->flags & LYD_DEFAULT);
142
Radek Krejci509e2592019-05-15 16:30:48 +0200143 lyd_free_all(tree);
Michal Vasko8d544252020-03-02 10:19:52 +0100144
145 /* make foo2 explicit */
146 data = "<foo2 xmlns=\"urn:tests:a\">default-val</foo2>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200147 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko8d544252020-03-02 10:19:52 +0100148 assert_non_null(tree);
149 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
150 assert_string_equal("foo2", tree->schema->name);
151 leaf = (struct lyd_node_term*)tree;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200152 assert_string_equal("default-val", leaf->value.canonical);
Michal Vasko8d544252020-03-02 10:19:52 +0100153 assert_false(leaf->flags & LYD_DEFAULT);
154
155 lyd_free_all(tree);
156
Radek Krejci1798aae2020-07-14 13:26:06 +0200157 /* parse foo2 but make it implicit, skip metadata xxx from missing schema */
158 data = "<foo2 xmlns=\"urn:tests:a\" xmlns:wd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" wd:default=\"true\" xmlns:x=\"urn:x\" x:xxx=\"false\">default-val</foo2>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200159 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko8d544252020-03-02 10:19:52 +0100160 assert_non_null(tree);
161 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
162 assert_string_equal("foo2", tree->schema->name);
163 leaf = (struct lyd_node_term*)tree;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200164 assert_string_equal("default-val", leaf->value.canonical);
Michal Vasko8d544252020-03-02 10:19:52 +0100165 assert_true(leaf->flags & LYD_DEFAULT);
166
167 lyd_free_all(tree);
168
Radek Krejci509e2592019-05-15 16:30:48 +0200169 *state = NULL;
170}
171
Radek Krejciee4cab22019-07-17 17:07:47 +0200172static void
173test_anydata(void **state)
174{
175 *state = test_anydata;
176
Michal Vasko52927e22020-03-16 17:26:14 +0100177 const char *data;
178 char *str;
Radek Krejciee4cab22019-07-17 17:07:47 +0200179 struct lyd_node *tree;
Radek Krejciee4cab22019-07-17 17:07:47 +0200180
Radek Krejci241f6b52020-05-21 18:13:49 +0200181 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200182 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100183
Michal Vasko52927e22020-03-16 17:26:14 +0100184 data =
185 "<any xmlns=\"urn:tests:a\">"
186 "<element1>"
187 "<x:element2 x:attr2=\"test\" xmlns:a=\"urn:tests:a\" xmlns:x=\"urn:x\">a:data</x:element2>"
188 "</element1>"
189 "<element1a/>"
190 "</any>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200191 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Radek Krejciee4cab22019-07-17 17:07:47 +0200192 assert_non_null(tree);
193 assert_int_equal(LYS_ANYDATA, tree->schema->nodetype);
194 assert_string_equal("any", tree->schema->name);
Michal Vasko52927e22020-03-16 17:26:14 +0100195
Radek Krejci52f65552020-09-01 17:03:35 +0200196 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vasko52927e22020-03-16 17:26:14 +0100197 assert_string_equal(str,
198 "<any xmlns=\"urn:tests:a\">"
199 "<element1>"
200 "<element2 xmlns=\"urn:x\" xmlns:x=\"urn:x\" x:attr2=\"test\" xmlns:a=\"urn:tests:a\">a:data</element2>"
201 "</element1>"
202 "<element1a/>"
203 "</any>"
204 );
Radek Krejci241f6b52020-05-21 18:13:49 +0200205 ly_out_reset(out);
Radek Krejciee4cab22019-07-17 17:07:47 +0200206
207 lyd_free_all(tree);
Radek Krejci241f6b52020-05-21 18:13:49 +0200208 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100209
Radek Krejciee4cab22019-07-17 17:07:47 +0200210 *state = NULL;
211}
212
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200213static void
214test_list(void **state)
215{
216 *state = test_list;
217
Michal Vasko44685da2020-03-17 15:38:06 +0100218 const char *data = "<l1 xmlns=\"urn:tests:a\"><a>one</a><b>one</b><c>1</c></l1>";
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200219 struct lyd_node *tree, *iter;
220 struct lyd_node_inner *list;
Radek Krejci710226d2019-07-24 17:24:59 +0200221 struct lyd_node_term *leaf;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200222
Radek Krejci710226d2019-07-24 17:24:59 +0200223 /* check hashes */
Michal Vasko63f3d842020-07-08 10:10:14 +0200224 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200225 assert_non_null(tree);
226 assert_int_equal(LYS_LIST, tree->schema->nodetype);
227 assert_string_equal("l1", tree->schema->name);
228 list = (struct lyd_node_inner*)tree;
229 LY_LIST_FOR(list->child, iter) {
230 assert_int_not_equal(0, iter->hash);
231 }
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200232 lyd_free_all(tree);
Radek Krejci710226d2019-07-24 17:24:59 +0200233
Michal Vasko9f96a052020-03-10 09:41:45 +0100234 /* missing keys */
Michal Vasko44685da2020-03-17 15:38:06 +0100235 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b></l1>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200236 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100237 logbuf_assert("List instance is missing its key \"a\". /a:l1[b='b'][c='1']");
Michal Vasko9f96a052020-03-10 09:41:45 +0100238
239 data = "<l1 xmlns=\"urn:tests:a\"><a>a</a></l1>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200240 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko9f96a052020-03-10 09:41:45 +0100241 logbuf_assert("List instance is missing its key \"b\". /a:l1[a='a']");
242
243 data = "<l1 xmlns=\"urn:tests:a\"><b>b</b><a>a</a></l1>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200244 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko9f96a052020-03-10 09:41:45 +0100245 logbuf_assert("List instance is missing its key \"c\". /a:l1[a='a'][b='b']");
246
247 /* key duplicate */
Michal Vasko44685da2020-03-17 15:38:06 +0100248 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a><c>1</c></l1>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200249 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100250 logbuf_assert("Duplicate instance of \"c\". /a:l1[a='a'][b='b'][c='1'][c='1']/c");
Michal Vasko9f96a052020-03-10 09:41:45 +0100251
Radek Krejci710226d2019-07-24 17:24:59 +0200252 /* keys order */
Michal Vasko44685da2020-03-17 15:38:06 +0100253 data = "<l1 xmlns=\"urn:tests:a\"><d>d</d><a>a</a><c>1</c><b>b</b></l1>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200254 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Radek Krejci710226d2019-07-24 17:24:59 +0200255 assert_non_null(tree);
256 assert_int_equal(LYS_LIST, tree->schema->nodetype);
257 assert_string_equal("l1", tree->schema->name);
258 list = (struct lyd_node_inner*)tree;
259 assert_non_null(leaf = (struct lyd_node_term*)list->child);
260 assert_string_equal("a", leaf->schema->name);
261 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
262 assert_string_equal("b", leaf->schema->name);
263 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
264 assert_string_equal("c", leaf->schema->name);
265 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
266 assert_string_equal("d", leaf->schema->name);
267 logbuf_assert("Invalid position of the key \"b\" in a list.");
268 lyd_free_all(tree);
269
Michal Vasko44685da2020-03-17 15:38:06 +0100270 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a></l1>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200271 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Radek Krejci710226d2019-07-24 17:24:59 +0200272 assert_non_null(tree);
273 assert_int_equal(LYS_LIST, tree->schema->nodetype);
274 assert_string_equal("l1", tree->schema->name);
275 list = (struct lyd_node_inner*)tree;
276 assert_non_null(leaf = (struct lyd_node_term*)list->child);
277 assert_string_equal("a", leaf->schema->name);
278 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
279 assert_string_equal("b", leaf->schema->name);
280 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
281 assert_string_equal("c", leaf->schema->name);
282 logbuf_assert("Invalid position of the key \"a\" in a list.");
283 logbuf_clean();
284 lyd_free_all(tree);
285
Michal Vasko63f3d842020-07-08 10:10:14 +0200286 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_XML, LYD_PARSE_STRICT, 0, &tree));
Radek Krejci710226d2019-07-24 17:24:59 +0200287 logbuf_assert("Invalid position of the key \"b\" in a list. Line number 1.");
288
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200289 *state = NULL;
290}
291
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200292static void
293test_container(void **state)
294{
295 *state = test_container;
296
297 const char *data = "<c xmlns=\"urn:tests:a\"/>";
298 struct lyd_node *tree;
299 struct lyd_node_inner *cont;
300
Michal Vasko63f3d842020-07-08 10:10:14 +0200301 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200302 assert_non_null(tree);
303 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
304 assert_string_equal("c", tree->schema->name);
305 cont = (struct lyd_node_inner*)tree;
306 assert_true(cont->flags & LYD_DEFAULT);
307 lyd_free_all(tree);
308
309 data = "<cp xmlns=\"urn:tests:a\"/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200310 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200311 assert_non_null(tree);
312 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
313 assert_string_equal("cp", tree->schema->name);
314 cont = (struct lyd_node_inner*)tree;
315 assert_false(cont->flags & LYD_DEFAULT);
316 lyd_free_all(tree);
317
318 *state = NULL;
319}
320
Michal Vasko44685da2020-03-17 15:38:06 +0100321static void
322test_opaq(void **state)
323{
324 *state = test_opaq;
325
326 const char *data;
327 char *str;
328 struct lyd_node *tree;
329
Radek Krejci241f6b52020-05-21 18:13:49 +0200330 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200331 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100332
Michal Vasko44685da2020-03-17 15:38:06 +0100333 /* invalid value, no flags */
334 data = "<foo3 xmlns=\"urn:tests:a\"/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200335 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko1ce933a2020-03-30 12:38:22 +0200336 logbuf_assert("Invalid empty uint32 value. /a:foo3");
Michal Vasko44685da2020-03-17 15:38:06 +0100337 assert_null(tree);
338
339 /* opaq flag */
Michal Vasko63f3d842020-07-08 10:10:14 +0200340 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100341 assert_non_null(tree);
342 assert_null(tree->schema);
343 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "foo3");
344 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
345
Radek Krejci52f65552020-09-01 17:03:35 +0200346 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vasko44685da2020-03-17 15:38:06 +0100347 assert_string_equal(str, "<foo3 xmlns=\"urn:tests:a\"/>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200348 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100349 lyd_free_all(tree);
350
351 /* missing key, no flags */
352 data = "<l1 xmlns=\"urn:tests:a\"><a>val_a</a><b>val_b</b><d>val_d</d></l1>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200353 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100354 logbuf_assert("List instance is missing its key \"c\". /a:l1[a='val_a'][b='val_b']");
355 assert_null(tree);
356
357 /* opaq flag */
Michal Vasko63f3d842020-07-08 10:10:14 +0200358 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, LYD_PARSE_OPAQ , LYD_VALIDATE_PRESENT, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100359 assert_non_null(tree);
360 assert_null(tree->schema);
361 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "l1");
362 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
363
Radek Krejci52f65552020-09-01 17:03:35 +0200364 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vasko44685da2020-03-17 15:38:06 +0100365 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200366 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100367 lyd_free_all(tree);
368
369 /* invalid key, no flags */
370 data = "<l1 xmlns=\"urn:tests:a\"><a>val_a</a><b>val_b</b><c>val_c</c></l1>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200371 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
Michal Vaskof872e202020-05-27 11:49:06 +0200372 logbuf_assert("Invalid int16 value \"val_c\". /a:l1/c");
Michal Vasko44685da2020-03-17 15:38:06 +0100373 assert_null(tree);
374
375 /* opaq flag */
Michal Vasko63f3d842020-07-08 10:10:14 +0200376 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100377 assert_non_null(tree);
378 assert_null(tree->schema);
379 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "l1");
380 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
381
Radek Krejci52f65552020-09-01 17:03:35 +0200382 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vasko44685da2020-03-17 15:38:06 +0100383 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200384 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100385 lyd_free_all(tree);
386
Michal Vasko413c7f22020-05-05 12:34:06 +0200387 /* opaq flag and fail */
Michal Vasko63f3d842020-07-08 10:10:14 +0200388 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, "<a xmlns=\"ns\"><b>x</b><c xml:id=\"D\">1</c></a>", LYD_XML,
389 LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
Radek Krejci1798aae2020-07-14 13:26:06 +0200390 logbuf_assert("Unknown XML prefix \"xml\". Line number 1.");
Michal Vasko413c7f22020-05-05 12:34:06 +0200391 assert_null(tree);
Radek Krejci241f6b52020-05-21 18:13:49 +0200392 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100393
Michal Vasko44685da2020-03-17 15:38:06 +0100394 *state = NULL;
395}
396
Michal Vaskob36053d2020-03-26 15:49:30 +0100397static void
398test_rpc(void **state)
399{
400 *state = test_rpc;
401
402 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200403 struct ly_in *in;
Michal Vaskob36053d2020-03-26 15:49:30 +0100404 char *str;
405 struct lyd_node *tree, *op;
Michal Vasko1bf09392020-03-27 12:38:10 +0100406 const struct lyd_node *node;
Michal Vaskob36053d2020-03-26 15:49:30 +0100407
Radek Krejci241f6b52020-05-21 18:13:49 +0200408 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200409 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100410
Michal Vaskob36053d2020-03-26 15:49:30 +0100411 data =
412 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
413 "<edit-config>"
414 "<target>"
415 "<running/>"
Michal Vaskob36053d2020-03-26 15:49:30 +0100416 "</target>"
Michal Vasko1bf09392020-03-27 12:38:10 +0100417 "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
418 "<l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">"
419 "<a>val_a</a>"
420 "<b>val_b</b>"
421 "<c>val_c</c>"
422 "</l1>"
423 "<cp xmlns=\"urn:tests:a\">"
424 "<z nc:operation=\"delete\"/>"
425 "</cp>"
426 "</config>"
Michal Vaskob36053d2020-03-26 15:49:30 +0100427 "</edit-config>"
428 "</rpc>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200429 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
430 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(ctx, in, LYD_XML, &tree, &op));
431 ly_in_free(in, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100432
433 assert_non_null(op);
434 assert_string_equal(op->schema->name, "edit-config");
435
Michal Vaskob36053d2020-03-26 15:49:30 +0100436 assert_non_null(tree);
437 assert_null(tree->schema);
Michal Vasko1bf09392020-03-27 12:38:10 +0100438 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "rpc");
439 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200440 node = lyd_child(tree);
Michal Vasko1bf09392020-03-27 12:38:10 +0100441 assert_string_equal(node->schema->name, "edit-config");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200442 node = lyd_child(node)->next;
Michal Vasko1bf09392020-03-27 12:38:10 +0100443 assert_string_equal(node->schema->name, "config");
Michal Vaskob104f112020-07-17 09:54:54 +0200444
Michal Vasko1bf09392020-03-27 12:38:10 +0100445 node = ((struct lyd_node_any *)node)->value.tree;
Michal Vasko1bf09392020-03-27 12:38:10 +0100446 assert_non_null(node->schema);
447 assert_string_equal(node->schema->name, "cp");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200448 node = lyd_child(node);
Michal Vasko1bf09392020-03-27 12:38:10 +0100449 /* z has no value */
450 assert_null(node->schema);
451 assert_string_equal(((struct lyd_node_opaq *)node)->name, "z");
Michal Vaskob104f112020-07-17 09:54:54 +0200452 node = node->parent->next;
453 /* l1 key c has invalid value so it is at the end */
454 assert_null(node->schema);
455 assert_string_equal(((struct lyd_node_opaq *)node)->name, "l1");
Michal Vaskob36053d2020-03-26 15:49:30 +0100456
Radek Krejci52f65552020-09-01 17:03:35 +0200457 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vasko1bf09392020-03-27 12:38:10 +0100458 assert_string_equal(str,
459 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
460 "<edit-config>"
461 "<target>"
462 "<running/>"
463 "</target>"
464 "<config>"
Michal Vaskob104f112020-07-17 09:54:54 +0200465 "<cp xmlns=\"urn:tests:a\">"
466 "<z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>"
467 "</cp>"
Michal Vasko1bf09392020-03-27 12:38:10 +0100468 "<l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">"
469 "<a>val_a</a>"
470 "<b>val_b</b>"
471 "<c>val_c</c>"
472 "</l1>"
Michal Vasko1bf09392020-03-27 12:38:10 +0100473 "</config>"
474 "</edit-config>"
475 "</rpc>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200476 ly_out_reset(out);
Michal Vaskob36053d2020-03-26 15:49:30 +0100477 lyd_free_all(tree);
478
479 /* wrong namespace, element name, whatever... */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100480 /* TODO */
481
Radek Krejci241f6b52020-05-21 18:13:49 +0200482 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100483
Michal Vaskoa8edff02020-03-27 14:47:01 +0100484 *state = NULL;
485}
486
487static void
488test_action(void **state)
489{
490 *state = test_action;
491
492 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200493 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100494 char *str;
495 struct lyd_node *tree, *op;
496 const struct lyd_node *node;
497
Radek Krejci241f6b52020-05-21 18:13:49 +0200498 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200499 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100500
Michal Vaskoa8edff02020-03-27 14:47:01 +0100501 data =
502 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
503 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
504 "<c xmlns=\"urn:tests:a\">"
505 "<act>"
506 "<al>value</al>"
507 "</act>"
508 "</c>"
509 "</action>"
510 "</rpc>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200511 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
512 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(ctx, in, LYD_XML, &tree, &op));
513 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100514
515 assert_non_null(op);
516 assert_string_equal(op->schema->name, "act");
517
518 assert_non_null(tree);
519 assert_null(tree->schema);
520 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "rpc");
521 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200522 node = lyd_child(tree);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100523 assert_null(node->schema);
524 assert_string_equal(((struct lyd_node_opaq *)node)->name, "action");
525 assert_null(((struct lyd_node_opaq *)node)->attr);
526
Radek Krejci52f65552020-09-01 17:03:35 +0200527 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100528 assert_string_equal(str,
529 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
530 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
531 "<c xmlns=\"urn:tests:a\">"
532 "<act>"
533 "<al>value</al>"
534 "</act>"
535 "</c>"
536 "</action>"
537 "</rpc>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200538 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100539 lyd_free_all(tree);
540
541 /* wrong namespace, element name, whatever... */
542 /* TODO */
543
Radek Krejci241f6b52020-05-21 18:13:49 +0200544 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100545
Michal Vaskoa8edff02020-03-27 14:47:01 +0100546 *state = NULL;
547}
548
549static void
550test_notification(void **state)
551{
552 *state = test_notification;
553
554 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200555 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100556 char *str;
557 struct lyd_node *tree, *ntf;
558 const struct lyd_node *node;
559
Radek Krejci241f6b52020-05-21 18:13:49 +0200560 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200561 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100562
Michal Vaskoa8edff02020-03-27 14:47:01 +0100563 data =
564 "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">"
565 "<eventTime>2037-07-08T00:01:00Z</eventTime>"
566 "<c xmlns=\"urn:tests:a\">"
567 "<n1>"
568 "<nl>value</nl>"
569 "</n1>"
570 "</c>"
571 "</notification>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200572 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
573 assert_int_equal(LY_SUCCESS, lyd_parse_notif(ctx, in, LYD_XML, &tree, &ntf));
574 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100575
576 assert_non_null(ntf);
577 assert_string_equal(ntf->schema->name, "n1");
578
579 assert_non_null(tree);
580 assert_null(tree->schema);
581 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "notification");
582 assert_null(((struct lyd_node_opaq *)tree)->attr);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200583 node = lyd_child(tree);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100584 assert_null(node->schema);
585 assert_string_equal(((struct lyd_node_opaq *)node)->name, "eventTime");
586 assert_string_equal(((struct lyd_node_opaq *)node)->value, "2037-07-08T00:01:00Z");
587 assert_null(((struct lyd_node_opaq *)node)->attr);
588 node = node->next;
589 assert_non_null(node->schema);
590 assert_string_equal(node->schema->name, "c");
591
Radek Krejci52f65552020-09-01 17:03:35 +0200592 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100593 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200594 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100595 lyd_free_all(tree);
596
597 /* top-level notif without envelope */
598 data = "<n2 xmlns=\"urn:tests:a\"/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200599 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
600 assert_int_equal(LY_SUCCESS, lyd_parse_notif(ctx, in, LYD_XML, &tree, &ntf));
601 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100602
603 assert_non_null(ntf);
604 assert_string_equal(ntf->schema->name, "n2");
605
606 assert_non_null(tree);
607 assert_ptr_equal(ntf, tree);
608
Radek Krejci52f65552020-09-01 17:03:35 +0200609 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100610 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200611 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100612 lyd_free_all(tree);
613
614 /* wrong namespace, element name, whatever... */
615 /* TODO */
Michal Vaskob36053d2020-03-26 15:49:30 +0100616
Radek Krejci241f6b52020-05-21 18:13:49 +0200617 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100618
Michal Vaskob36053d2020-03-26 15:49:30 +0100619 *state = NULL;
620}
621
Michal Vasko1ce933a2020-03-30 12:38:22 +0200622static void
623test_reply(void **state)
624{
625 *state = test_reply;
626
627 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200628 struct ly_in *in;
Michal Vasko1ce933a2020-03-30 12:38:22 +0200629 char *str;
630 struct lyd_node *request, *tree, *op;
631 const struct lyd_node *node;
632
Radek Krejci241f6b52020-05-21 18:13:49 +0200633 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200634 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100635
Michal Vasko1ce933a2020-03-30 12:38:22 +0200636 data =
637 "<c xmlns=\"urn:tests:a\">"
638 "<act>"
639 "<al>value</al>"
640 "</act>"
641 "</c>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200642 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
643 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(ctx, in, LYD_XML, &request, NULL));
644 ly_in_free(in, 0);
645
Michal Vasko1ce933a2020-03-30 12:38:22 +0200646 data =
647 "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\">"
648 "<al xmlns=\"urn:tests:a\">25</al>"
649 "</rpc-reply>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200650 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
651 assert_int_equal(LY_SUCCESS, lyd_parse_reply(request, in, LYD_XML, &tree, &op));
652 ly_in_free(in, 0);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200653 lyd_free_all(request);
654
655 assert_non_null(op);
656 assert_string_equal(op->schema->name, "act");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200657 node = lyd_child(op);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200658 assert_non_null(node->schema);
659 assert_string_equal(node->schema->name, "al");
660 assert_true(node->schema->flags & LYS_CONFIG_R);
661
662 assert_non_null(tree);
663 assert_null(tree->schema);
664 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "rpc-reply");
665 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200666 node = lyd_child(tree);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200667 assert_non_null(node->schema);
668 assert_string_equal(node->schema->name, "c");
669
670 /* TODO print only rpc-reply node and then output subtree */
Radek Krejcia1c1e542020-09-29 16:06:52 +0200671 lyd_print_tree(out, lyd_child(op), LYD_XML, LYD_PRINT_SHRINK);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200672 assert_string_equal(str,
673 "<al xmlns=\"urn:tests:a\">25</al>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200674 ly_out_reset(out);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200675 lyd_free_all(tree);
676
677 /* wrong namespace, element name, whatever... */
678 /* TODO */
679
Radek Krejci241f6b52020-05-21 18:13:49 +0200680 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100681
Michal Vasko1ce933a2020-03-30 12:38:22 +0200682 *state = NULL;
683}
684
Radek Krejci509e2592019-05-15 16:30:48 +0200685int main(void)
686{
687 const struct CMUnitTest tests[] = {
688 cmocka_unit_test_setup_teardown(test_leaf, setup, teardown),
Radek Krejciee4cab22019-07-17 17:07:47 +0200689 cmocka_unit_test_setup_teardown(test_anydata, setup, teardown),
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200690 cmocka_unit_test_setup_teardown(test_list, setup, teardown),
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200691 cmocka_unit_test_setup_teardown(test_container, setup, teardown),
Michal Vasko44685da2020-03-17 15:38:06 +0100692 cmocka_unit_test_setup_teardown(test_opaq, setup, teardown),
Michal Vasko1bf09392020-03-27 12:38:10 +0100693 cmocka_unit_test_setup_teardown(test_rpc, setup, teardown),
Michal Vaskoa8edff02020-03-27 14:47:01 +0100694 cmocka_unit_test_setup_teardown(test_action, setup, teardown),
695 cmocka_unit_test_setup_teardown(test_notification, setup, teardown),
Michal Vasko1ce933a2020-03-30 12:38:22 +0200696 cmocka_unit_test_setup_teardown(test_reply, setup, teardown),
Radek Krejci509e2592019-05-15 16:30:48 +0200697 };
698
699 return cmocka_run_group_tests(tests, NULL, NULL);
700}