blob: 494b3c5693c1ae69fd5e7bf994703d9c509c7358 [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);
Michal Vasko26123192020-11-09 21:02:34 +0100149 tree = tree->next;
Michal Vasko8d544252020-03-02 10:19:52 +0100150 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
151 assert_string_equal("foo2", tree->schema->name);
152 leaf = (struct lyd_node_term*)tree;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200153 assert_string_equal("default-val", leaf->value.canonical);
Michal Vasko8d544252020-03-02 10:19:52 +0100154 assert_false(leaf->flags & LYD_DEFAULT);
155
156 lyd_free_all(tree);
157
Radek Krejci1798aae2020-07-14 13:26:06 +0200158 /* parse foo2 but make it implicit, skip metadata xxx from missing schema */
159 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 +0200160 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 +0100161 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100162 tree = tree->next;
Michal Vasko8d544252020-03-02 10:19:52 +0100163 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
164 assert_string_equal("foo2", tree->schema->name);
165 leaf = (struct lyd_node_term*)tree;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200166 assert_string_equal("default-val", leaf->value.canonical);
Michal Vasko8d544252020-03-02 10:19:52 +0100167 assert_true(leaf->flags & LYD_DEFAULT);
168
169 lyd_free_all(tree);
170
Radek Krejci509e2592019-05-15 16:30:48 +0200171 *state = NULL;
172}
173
Radek Krejciee4cab22019-07-17 17:07:47 +0200174static void
175test_anydata(void **state)
176{
177 *state = test_anydata;
178
Michal Vasko52927e22020-03-16 17:26:14 +0100179 const char *data;
180 char *str;
Radek Krejciee4cab22019-07-17 17:07:47 +0200181 struct lyd_node *tree;
Radek Krejciee4cab22019-07-17 17:07:47 +0200182
Radek Krejci241f6b52020-05-21 18:13:49 +0200183 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200184 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100185
Michal Vasko52927e22020-03-16 17:26:14 +0100186 data =
187 "<any xmlns=\"urn:tests:a\">"
188 "<element1>"
189 "<x:element2 x:attr2=\"test\" xmlns:a=\"urn:tests:a\" xmlns:x=\"urn:x\">a:data</x:element2>"
190 "</element1>"
191 "<element1a/>"
192 "</any>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200193 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 +0200194 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100195 tree = tree->next;
Radek Krejciee4cab22019-07-17 17:07:47 +0200196 assert_int_equal(LYS_ANYDATA, tree->schema->nodetype);
197 assert_string_equal("any", tree->schema->name);
Michal Vasko52927e22020-03-16 17:26:14 +0100198
Radek Krejci52f65552020-09-01 17:03:35 +0200199 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vasko52927e22020-03-16 17:26:14 +0100200 assert_string_equal(str,
201 "<any xmlns=\"urn:tests:a\">"
202 "<element1>"
203 "<element2 xmlns=\"urn:x\" xmlns:x=\"urn:x\" x:attr2=\"test\" xmlns:a=\"urn:tests:a\">a:data</element2>"
204 "</element1>"
205 "<element1a/>"
206 "</any>"
207 );
Radek Krejci241f6b52020-05-21 18:13:49 +0200208 ly_out_reset(out);
Radek Krejciee4cab22019-07-17 17:07:47 +0200209
210 lyd_free_all(tree);
Radek Krejci241f6b52020-05-21 18:13:49 +0200211 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100212
Radek Krejciee4cab22019-07-17 17:07:47 +0200213 *state = NULL;
214}
215
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200216static void
217test_list(void **state)
218{
219 *state = test_list;
220
Michal Vasko44685da2020-03-17 15:38:06 +0100221 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 +0200222 struct lyd_node *tree, *iter;
223 struct lyd_node_inner *list;
Radek Krejci710226d2019-07-24 17:24:59 +0200224 struct lyd_node_term *leaf;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200225
Radek Krejci710226d2019-07-24 17:24:59 +0200226 /* check hashes */
Michal Vasko63f3d842020-07-08 10:10:14 +0200227 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 +0200228 assert_non_null(tree);
229 assert_int_equal(LYS_LIST, tree->schema->nodetype);
230 assert_string_equal("l1", tree->schema->name);
231 list = (struct lyd_node_inner*)tree;
232 LY_LIST_FOR(list->child, iter) {
233 assert_int_not_equal(0, iter->hash);
234 }
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200235 lyd_free_all(tree);
Radek Krejci710226d2019-07-24 17:24:59 +0200236
Michal Vasko9f96a052020-03-10 09:41:45 +0100237 /* missing keys */
Michal Vasko44685da2020-03-17 15:38:06 +0100238 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b></l1>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200239 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 +0100240 logbuf_assert("List instance is missing its key \"a\". /a:l1[b='b'][c='1']");
Michal Vasko9f96a052020-03-10 09:41:45 +0100241
242 data = "<l1 xmlns=\"urn:tests:a\"><a>a</a></l1>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200243 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 +0100244 logbuf_assert("List instance is missing its key \"b\". /a:l1[a='a']");
245
246 data = "<l1 xmlns=\"urn:tests:a\"><b>b</b><a>a</a></l1>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200247 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 +0100248 logbuf_assert("List instance is missing its key \"c\". /a:l1[a='a'][b='b']");
249
250 /* key duplicate */
Michal Vasko44685da2020-03-17 15:38:06 +0100251 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 +0200252 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 +0100253 logbuf_assert("Duplicate instance of \"c\". /a:l1[a='a'][b='b'][c='1'][c='1']/c");
Michal Vasko9f96a052020-03-10 09:41:45 +0100254
Radek Krejci710226d2019-07-24 17:24:59 +0200255 /* keys order */
Michal Vasko44685da2020-03-17 15:38:06 +0100256 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 +0200257 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 +0200258 assert_non_null(tree);
259 assert_int_equal(LYS_LIST, tree->schema->nodetype);
260 assert_string_equal("l1", tree->schema->name);
261 list = (struct lyd_node_inner*)tree;
262 assert_non_null(leaf = (struct lyd_node_term*)list->child);
263 assert_string_equal("a", leaf->schema->name);
264 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
265 assert_string_equal("b", leaf->schema->name);
266 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
267 assert_string_equal("c", leaf->schema->name);
268 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
269 assert_string_equal("d", leaf->schema->name);
270 logbuf_assert("Invalid position of the key \"b\" in a list.");
271 lyd_free_all(tree);
272
Michal Vasko44685da2020-03-17 15:38:06 +0100273 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a></l1>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200274 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 +0200275 assert_non_null(tree);
276 assert_int_equal(LYS_LIST, tree->schema->nodetype);
277 assert_string_equal("l1", tree->schema->name);
278 list = (struct lyd_node_inner*)tree;
279 assert_non_null(leaf = (struct lyd_node_term*)list->child);
280 assert_string_equal("a", leaf->schema->name);
281 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
282 assert_string_equal("b", leaf->schema->name);
283 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
284 assert_string_equal("c", leaf->schema->name);
285 logbuf_assert("Invalid position of the key \"a\" in a list.");
286 logbuf_clean();
287 lyd_free_all(tree);
288
Michal Vasko63f3d842020-07-08 10:10:14 +0200289 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 +0200290 logbuf_assert("Invalid position of the key \"b\" in a list. Line number 1.");
291
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200292 *state = NULL;
293}
294
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200295static void
296test_container(void **state)
297{
298 *state = test_container;
299
300 const char *data = "<c xmlns=\"urn:tests:a\"/>";
301 struct lyd_node *tree;
302 struct lyd_node_inner *cont;
303
Michal Vasko63f3d842020-07-08 10:10:14 +0200304 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 +0200305 assert_non_null(tree);
306 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
307 assert_string_equal("c", tree->schema->name);
308 cont = (struct lyd_node_inner*)tree;
309 assert_true(cont->flags & LYD_DEFAULT);
310 lyd_free_all(tree);
311
312 data = "<cp xmlns=\"urn:tests:a\"/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200313 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 +0200314 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100315 tree = tree->next;
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200316 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
317 assert_string_equal("cp", tree->schema->name);
318 cont = (struct lyd_node_inner*)tree;
319 assert_false(cont->flags & LYD_DEFAULT);
320 lyd_free_all(tree);
321
322 *state = NULL;
323}
324
Michal Vasko44685da2020-03-17 15:38:06 +0100325static void
326test_opaq(void **state)
327{
328 *state = test_opaq;
329
330 const char *data;
331 char *str;
332 struct lyd_node *tree;
333
Radek Krejci241f6b52020-05-21 18:13:49 +0200334 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200335 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100336
Michal Vasko44685da2020-03-17 15:38:06 +0100337 /* invalid value, no flags */
338 data = "<foo3 xmlns=\"urn:tests:a\"/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200339 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 +0200340 logbuf_assert("Invalid empty uint32 value. /a:foo3");
Michal Vasko44685da2020-03-17 15:38:06 +0100341 assert_null(tree);
342
343 /* opaq flag */
Michal Vasko54b50282020-11-23 17:00:32 +0100344 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100345 assert_non_null(tree);
346 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100347 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "foo3");
Michal Vasko44685da2020-03-17 15:38:06 +0100348 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
349
Radek Krejci52f65552020-09-01 17:03:35 +0200350 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vasko44685da2020-03-17 15:38:06 +0100351 assert_string_equal(str, "<foo3 xmlns=\"urn:tests:a\"/>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200352 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100353 lyd_free_all(tree);
354
355 /* missing key, no flags */
356 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 +0200357 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 +0100358 logbuf_assert("List instance is missing its key \"c\". /a:l1[a='val_a'][b='val_b']");
359 assert_null(tree);
360
361 /* opaq flag */
Michal Vasko54b50282020-11-23 17:00:32 +0100362 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100363 assert_non_null(tree);
364 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100365 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "l1");
Michal Vasko44685da2020-03-17 15:38:06 +0100366 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
367
Radek Krejci52f65552020-09-01 17:03:35 +0200368 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vasko44685da2020-03-17 15:38:06 +0100369 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200370 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100371 lyd_free_all(tree);
372
373 /* invalid key, no flags */
374 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 +0200375 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 +0200376 logbuf_assert("Invalid int16 value \"val_c\". /a:l1/c");
Michal Vasko44685da2020-03-17 15:38:06 +0100377 assert_null(tree);
378
379 /* opaq flag */
Michal Vasko54b50282020-11-23 17:00:32 +0100380 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_XML, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100381 assert_non_null(tree);
382 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100383 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "l1");
Michal Vasko44685da2020-03-17 15:38:06 +0100384 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
385
Radek Krejci52f65552020-09-01 17:03:35 +0200386 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vasko44685da2020-03-17 15:38:06 +0100387 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200388 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100389 lyd_free_all(tree);
390
Michal Vasko413c7f22020-05-05 12:34:06 +0200391 /* opaq flag and fail */
Michal Vasko63f3d842020-07-08 10:10:14 +0200392 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,
393 LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
Radek Krejci1798aae2020-07-14 13:26:06 +0200394 logbuf_assert("Unknown XML prefix \"xml\". Line number 1.");
Michal Vasko413c7f22020-05-05 12:34:06 +0200395 assert_null(tree);
Radek Krejci241f6b52020-05-21 18:13:49 +0200396 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100397
Michal Vasko44685da2020-03-17 15:38:06 +0100398 *state = NULL;
399}
400
Michal Vaskob36053d2020-03-26 15:49:30 +0100401static void
402test_rpc(void **state)
403{
404 *state = test_rpc;
405
406 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200407 struct ly_in *in;
Michal Vaskob36053d2020-03-26 15:49:30 +0100408 char *str;
409 struct lyd_node *tree, *op;
Michal Vasko1bf09392020-03-27 12:38:10 +0100410 const struct lyd_node *node;
Michal Vaskob36053d2020-03-26 15:49:30 +0100411
Radek Krejci241f6b52020-05-21 18:13:49 +0200412 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200413 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100414
Michal Vaskob36053d2020-03-26 15:49:30 +0100415 data =
416 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
417 "<edit-config>"
418 "<target>"
419 "<running/>"
Michal Vaskob36053d2020-03-26 15:49:30 +0100420 "</target>"
Michal Vasko1bf09392020-03-27 12:38:10 +0100421 "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
422 "<l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">"
423 "<a>val_a</a>"
424 "<b>val_b</b>"
425 "<c>val_c</c>"
426 "</l1>"
427 "<cp xmlns=\"urn:tests:a\">"
428 "<z nc:operation=\"delete\"/>"
429 "</cp>"
430 "</config>"
Michal Vaskob36053d2020-03-26 15:49:30 +0100431 "</edit-config>"
432 "</rpc>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200433 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
434 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(ctx, in, LYD_XML, &tree, &op));
435 ly_in_free(in, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100436
437 assert_non_null(op);
438 assert_string_equal(op->schema->name, "edit-config");
439
Michal Vaskob36053d2020-03-26 15:49:30 +0100440 assert_non_null(tree);
441 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100442 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "rpc");
Michal Vasko1bf09392020-03-27 12:38:10 +0100443 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200444 node = lyd_child(tree);
Michal Vasko1bf09392020-03-27 12:38:10 +0100445 assert_string_equal(node->schema->name, "edit-config");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200446 node = lyd_child(node)->next;
Michal Vasko1bf09392020-03-27 12:38:10 +0100447 assert_string_equal(node->schema->name, "config");
Michal Vaskob104f112020-07-17 09:54:54 +0200448
Michal Vasko1bf09392020-03-27 12:38:10 +0100449 node = ((struct lyd_node_any *)node)->value.tree;
Michal Vasko1bf09392020-03-27 12:38:10 +0100450 assert_non_null(node->schema);
451 assert_string_equal(node->schema->name, "cp");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200452 node = lyd_child(node);
Michal Vasko1bf09392020-03-27 12:38:10 +0100453 /* z has no value */
454 assert_null(node->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100455 assert_string_equal(((struct lyd_node_opaq *)node)->name.name, "z");
Michal Vaskob104f112020-07-17 09:54:54 +0200456 node = node->parent->next;
457 /* l1 key c has invalid value so it is at the end */
458 assert_null(node->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100459 assert_string_equal(((struct lyd_node_opaq *)node)->name.name, "l1");
Michal Vaskob36053d2020-03-26 15:49:30 +0100460
Radek Krejci52f65552020-09-01 17:03:35 +0200461 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vasko1bf09392020-03-27 12:38:10 +0100462 assert_string_equal(str,
463 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
464 "<edit-config>"
465 "<target>"
466 "<running/>"
467 "</target>"
468 "<config>"
Michal Vaskob104f112020-07-17 09:54:54 +0200469 "<cp xmlns=\"urn:tests:a\">"
470 "<z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>"
471 "</cp>"
Michal Vasko1bf09392020-03-27 12:38:10 +0100472 "<l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">"
473 "<a>val_a</a>"
474 "<b>val_b</b>"
475 "<c>val_c</c>"
476 "</l1>"
Michal Vasko1bf09392020-03-27 12:38:10 +0100477 "</config>"
478 "</edit-config>"
479 "</rpc>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200480 ly_out_reset(out);
Michal Vaskob36053d2020-03-26 15:49:30 +0100481 lyd_free_all(tree);
482
483 /* wrong namespace, element name, whatever... */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100484 /* TODO */
485
Radek Krejci241f6b52020-05-21 18:13:49 +0200486 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100487
Michal Vaskoa8edff02020-03-27 14:47:01 +0100488 *state = NULL;
489}
490
491static void
492test_action(void **state)
493{
494 *state = test_action;
495
496 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200497 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100498 char *str;
499 struct lyd_node *tree, *op;
500 const struct lyd_node *node;
501
Radek Krejci241f6b52020-05-21 18:13:49 +0200502 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200503 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100504
Michal Vaskoa8edff02020-03-27 14:47:01 +0100505 data =
506 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
507 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
508 "<c xmlns=\"urn:tests:a\">"
509 "<act>"
510 "<al>value</al>"
511 "</act>"
512 "</c>"
513 "</action>"
514 "</rpc>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200515 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
516 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(ctx, in, LYD_XML, &tree, &op));
517 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100518
519 assert_non_null(op);
520 assert_string_equal(op->schema->name, "act");
521
522 assert_non_null(tree);
523 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100524 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "rpc");
Michal Vaskoa8edff02020-03-27 14:47:01 +0100525 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200526 node = lyd_child(tree);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100527 assert_null(node->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100528 assert_string_equal(((struct lyd_node_opaq *)node)->name.name, "action");
Michal Vaskoa8edff02020-03-27 14:47:01 +0100529 assert_null(((struct lyd_node_opaq *)node)->attr);
530
Radek Krejci52f65552020-09-01 17:03:35 +0200531 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100532 assert_string_equal(str,
533 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
534 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
535 "<c xmlns=\"urn:tests:a\">"
536 "<act>"
537 "<al>value</al>"
538 "</act>"
539 "</c>"
540 "</action>"
541 "</rpc>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200542 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100543 lyd_free_all(tree);
544
545 /* wrong namespace, element name, whatever... */
546 /* TODO */
547
Radek Krejci241f6b52020-05-21 18:13:49 +0200548 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100549
Michal Vaskoa8edff02020-03-27 14:47:01 +0100550 *state = NULL;
551}
552
553static void
554test_notification(void **state)
555{
556 *state = test_notification;
557
558 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200559 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100560 char *str;
561 struct lyd_node *tree, *ntf;
562 const struct lyd_node *node;
563
Radek Krejci241f6b52020-05-21 18:13:49 +0200564 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200565 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100566
Michal Vaskoa8edff02020-03-27 14:47:01 +0100567 data =
568 "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">"
569 "<eventTime>2037-07-08T00:01:00Z</eventTime>"
570 "<c xmlns=\"urn:tests:a\">"
571 "<n1>"
572 "<nl>value</nl>"
573 "</n1>"
574 "</c>"
575 "</notification>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200576 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
577 assert_int_equal(LY_SUCCESS, lyd_parse_notif(ctx, in, LYD_XML, &tree, &ntf));
578 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100579
580 assert_non_null(ntf);
581 assert_string_equal(ntf->schema->name, "n1");
582
583 assert_non_null(tree);
584 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100585 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "notification");
Michal Vaskoa8edff02020-03-27 14:47:01 +0100586 assert_null(((struct lyd_node_opaq *)tree)->attr);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200587 node = lyd_child(tree);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100588 assert_null(node->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100589 assert_string_equal(((struct lyd_node_opaq *)node)->name.name, "eventTime");
Michal Vaskoa8edff02020-03-27 14:47:01 +0100590 assert_string_equal(((struct lyd_node_opaq *)node)->value, "2037-07-08T00:01:00Z");
591 assert_null(((struct lyd_node_opaq *)node)->attr);
592 node = node->next;
593 assert_non_null(node->schema);
594 assert_string_equal(node->schema->name, "c");
595
Radek Krejci52f65552020-09-01 17:03:35 +0200596 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100597 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200598 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100599 lyd_free_all(tree);
600
601 /* top-level notif without envelope */
602 data = "<n2 xmlns=\"urn:tests:a\"/>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200603 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
604 assert_int_equal(LY_SUCCESS, lyd_parse_notif(ctx, in, LYD_XML, &tree, &ntf));
605 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100606
607 assert_non_null(ntf);
608 assert_string_equal(ntf->schema->name, "n2");
609
610 assert_non_null(tree);
611 assert_ptr_equal(ntf, tree);
612
Radek Krejci52f65552020-09-01 17:03:35 +0200613 lyd_print_tree(out, tree, LYD_XML, LYD_PRINT_SHRINK);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100614 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200615 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100616 lyd_free_all(tree);
617
618 /* wrong namespace, element name, whatever... */
619 /* TODO */
Michal Vaskob36053d2020-03-26 15:49:30 +0100620
Radek Krejci241f6b52020-05-21 18:13:49 +0200621 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100622
Michal Vaskob36053d2020-03-26 15:49:30 +0100623 *state = NULL;
624}
625
Michal Vasko1ce933a2020-03-30 12:38:22 +0200626static void
627test_reply(void **state)
628{
629 *state = test_reply;
630
631 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200632 struct ly_in *in;
Michal Vasko1ce933a2020-03-30 12:38:22 +0200633 char *str;
634 struct lyd_node *request, *tree, *op;
635 const struct lyd_node *node;
636
Radek Krejci241f6b52020-05-21 18:13:49 +0200637 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200638 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100639
Michal Vasko1ce933a2020-03-30 12:38:22 +0200640 data =
641 "<c xmlns=\"urn:tests:a\">"
642 "<act>"
643 "<al>value</al>"
644 "</act>"
645 "</c>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200646 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
647 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(ctx, in, LYD_XML, &request, NULL));
648 ly_in_free(in, 0);
649
Michal Vasko1ce933a2020-03-30 12:38:22 +0200650 data =
651 "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\">"
652 "<al xmlns=\"urn:tests:a\">25</al>"
653 "</rpc-reply>";
Michal Vasko63f3d842020-07-08 10:10:14 +0200654 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
655 assert_int_equal(LY_SUCCESS, lyd_parse_reply(request, in, LYD_XML, &tree, &op));
656 ly_in_free(in, 0);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200657 lyd_free_all(request);
658
659 assert_non_null(op);
660 assert_string_equal(op->schema->name, "act");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200661 node = lyd_child(op);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200662 assert_non_null(node->schema);
663 assert_string_equal(node->schema->name, "al");
664 assert_true(node->schema->flags & LYS_CONFIG_R);
665
666 assert_non_null(tree);
667 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100668 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "rpc-reply");
Michal Vasko1ce933a2020-03-30 12:38:22 +0200669 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200670 node = lyd_child(tree);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200671 assert_non_null(node->schema);
672 assert_string_equal(node->schema->name, "c");
673
674 /* TODO print only rpc-reply node and then output subtree */
Radek Krejcia1c1e542020-09-29 16:06:52 +0200675 lyd_print_tree(out, lyd_child(op), LYD_XML, LYD_PRINT_SHRINK);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200676 assert_string_equal(str,
677 "<al xmlns=\"urn:tests:a\">25</al>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200678 ly_out_reset(out);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200679 lyd_free_all(tree);
680
681 /* wrong namespace, element name, whatever... */
682 /* TODO */
683
Radek Krejci241f6b52020-05-21 18:13:49 +0200684 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100685
Michal Vasko1ce933a2020-03-30 12:38:22 +0200686 *state = NULL;
687}
688
Radek Krejci509e2592019-05-15 16:30:48 +0200689int main(void)
690{
691 const struct CMUnitTest tests[] = {
692 cmocka_unit_test_setup_teardown(test_leaf, setup, teardown),
Radek Krejciee4cab22019-07-17 17:07:47 +0200693 cmocka_unit_test_setup_teardown(test_anydata, setup, teardown),
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200694 cmocka_unit_test_setup_teardown(test_list, setup, teardown),
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200695 cmocka_unit_test_setup_teardown(test_container, setup, teardown),
Michal Vasko44685da2020-03-17 15:38:06 +0100696 cmocka_unit_test_setup_teardown(test_opaq, setup, teardown),
Michal Vasko1bf09392020-03-27 12:38:10 +0100697 cmocka_unit_test_setup_teardown(test_rpc, setup, teardown),
Michal Vaskoa8edff02020-03-27 14:47:01 +0100698 cmocka_unit_test_setup_teardown(test_action, setup, teardown),
699 cmocka_unit_test_setup_teardown(test_notification, setup, teardown),
Michal Vasko1ce933a2020-03-30 12:38:22 +0200700 cmocka_unit_test_setup_teardown(test_reply, setup, teardown),
Radek Krejci509e2592019-05-15 16:30:48 +0200701 };
702
703 return cmocka_run_group_tests(tests, NULL, NULL);
704}