blob: 460eaa00352b0589442d710cf8be16485d74b5fe [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
Michal Vasko52927e22020-03-16 17:26:14 +010015#include "tests/config.h"
16
Radek Krejci509e2592019-05-15 16:30:48 +020017#include <stdarg.h>
18#include <stddef.h>
19#include <setjmp.h>
20#include <cmocka.h>
21
22#include <stdio.h>
23#include <string.h>
24
Radek Krejci2d7a47b2019-05-16 13:34:10 +020025#include "../../src/context.h"
26#include "../../src/tree_data_internal.h"
Radek Krejcica376bd2020-06-11 16:04:06 +020027#include "../../src/tree_schema.h"
Radek Krejci535ea9f2020-05-29 16:01:05 +020028#include "../../src/printer.h"
Michal Vasko52927e22020-03-16 17:26:14 +010029#include "../../src/printer_data.h"
Radek Krejci509e2592019-05-15 16:30:48 +020030
31#define BUFSIZE 1024
32char logbuf[BUFSIZE] = {0};
33int store = -1; /* negative for infinite logging, positive for limited logging */
34
35struct ly_ctx *ctx; /* context for tests */
36
37/* set to 0 to printing error messages to stderr instead of checking them in code */
38#define ENABLE_LOGGER_CHECKING 1
39
40#if ENABLE_LOGGER_CHECKING
41static void
42logger(LY_LOG_LEVEL level, const char *msg, const char *path)
43{
44 (void) level; /* unused */
45 if (store) {
46 if (path && path[0]) {
47 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
48 } else {
49 strncpy(logbuf, msg, BUFSIZE - 1);
50 }
51 if (store > 0) {
52 --store;
53 }
54 }
55}
56#endif
57
58static int
59setup(void **state)
60{
61 (void) state; /* unused */
62
63 const char *schema_a = "module a {namespace urn:tests:a;prefix a;yang-version 1.1;"
Michal Vasko44685da2020-03-17 15:38:06 +010064 "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 +020065 "leaf foo { type string;}"
Michal Vaskoa8edff02020-03-27 14:47:01 +010066 "container c {"
67 "leaf x {type string;}"
Michal Vasko1ce933a2020-03-30 12:38:22 +020068 "action act { input { leaf al {type string;} } output { leaf al {type uint8;} } }"
Michal Vaskoa8edff02020-03-27 14:47:01 +010069 "notification n1 { leaf nl {type string;} }"
70 "}"
Michal Vaskob36053d2020-03-26 15:49:30 +010071 "container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}"
Michal Vasko8d544252020-03-02 10:19:52 +010072 "anydata any {config false;}"
Michal Vasko44685da2020-03-17 15:38:06 +010073 "leaf foo2 { type string; default \"default-val\"; }"
Michal Vaskoa8edff02020-03-27 14:47:01 +010074 "leaf foo3 { type uint32; }"
75 "notification n2;}";
Michal Vaskob36053d2020-03-26 15:49:30 +010076 const struct lys_module *mod;
Radek Krejci509e2592019-05-15 16:30:48 +020077
78#if ENABLE_LOGGER_CHECKING
79 ly_set_log_clb(logger, 1);
80#endif
81
Michal Vasko8d544252020-03-02 10:19:52 +010082 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &ctx));
83 assert_non_null(ly_ctx_load_module(ctx, "ietf-netconf-with-defaults", "2011-06-01"));
Michal Vaskob36053d2020-03-26 15:49:30 +010084 assert_non_null((mod = ly_ctx_load_module(ctx, "ietf-netconf", "2011-06-01")));
85 assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "writable-running"));
Radek Krejci509e2592019-05-15 16:30:48 +020086 assert_non_null(lys_parse_mem(ctx, schema_a, LYS_IN_YANG));
87
88 return 0;
89}
90
91static int
92teardown(void **state)
93{
94#if ENABLE_LOGGER_CHECKING
95 if (*state) {
96 fprintf(stderr, "%s\n", logbuf);
97 }
98#else
99 (void) state; /* unused */
100#endif
101
102 ly_ctx_destroy(ctx, NULL);
103 ctx = NULL;
104
105 return 0;
106}
107
108void
109logbuf_clean(void)
110{
111 logbuf[0] = '\0';
112}
113
114#if ENABLE_LOGGER_CHECKING
115# define logbuf_assert(str) assert_string_equal(logbuf, str)
116#else
117# define logbuf_assert(str)
118#endif
119
Radek Krejci509e2592019-05-15 16:30:48 +0200120static void
121test_leaf(void **state)
122{
123 *state = test_leaf;
124
125 const char *data = "<foo xmlns=\"urn:tests:a\">foo value</foo>";
126 struct lyd_node *tree;
127 struct lyd_node_term *leaf;
128
Michal Vasko9f96a052020-03-10 09:41:45 +0100129 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejci509e2592019-05-15 16:30:48 +0200130 assert_non_null(tree);
131 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
132 assert_string_equal("foo", tree->schema->name);
133 leaf = (struct lyd_node_term*)tree;
Radek Krejci950f6a52019-09-12 17:15:32 +0200134 assert_string_equal("foo value", leaf->value.original);
Radek Krejci509e2592019-05-15 16:30:48 +0200135
Michal Vasko8d544252020-03-02 10:19:52 +0100136 assert_int_equal(LYS_LEAF, tree->next->next->schema->nodetype);
137 assert_string_equal("foo2", tree->next->next->schema->name);
138 leaf = (struct lyd_node_term*)tree->next->next;
139 assert_string_equal("default-val", leaf->value.original);
140 assert_true(leaf->flags & LYD_DEFAULT);
141
Radek Krejci509e2592019-05-15 16:30:48 +0200142 lyd_free_all(tree);
Michal Vasko8d544252020-03-02 10:19:52 +0100143
144 /* make foo2 explicit */
145 data = "<foo2 xmlns=\"urn:tests:a\">default-val</foo2>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100146 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko8d544252020-03-02 10:19:52 +0100147 assert_non_null(tree);
148 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
149 assert_string_equal("foo2", tree->schema->name);
150 leaf = (struct lyd_node_term*)tree;
151 assert_string_equal("default-val", leaf->value.original);
152 assert_false(leaf->flags & LYD_DEFAULT);
153
154 lyd_free_all(tree);
155
156 /* parse foo2 but make it implicit */
157 data = "<foo2 xmlns=\"urn:tests:a\" xmlns:wd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" wd:default=\"true\">default-val</foo2>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100158 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko8d544252020-03-02 10:19:52 +0100159 assert_non_null(tree);
160 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
161 assert_string_equal("foo2", tree->schema->name);
162 leaf = (struct lyd_node_term*)tree;
163 assert_string_equal("default-val", leaf->value.original);
164 assert_true(leaf->flags & LYD_DEFAULT);
165
166 lyd_free_all(tree);
167
Radek Krejci509e2592019-05-15 16:30:48 +0200168 *state = NULL;
169}
170
Radek Krejciee4cab22019-07-17 17:07:47 +0200171static void
172test_anydata(void **state)
173{
174 *state = test_anydata;
175
Michal Vasko52927e22020-03-16 17:26:14 +0100176 const char *data;
177 char *str;
Radek Krejciee4cab22019-07-17 17:07:47 +0200178 struct lyd_node *tree;
Radek Krejciee4cab22019-07-17 17:07:47 +0200179
Radek Krejci241f6b52020-05-21 18:13:49 +0200180 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200181 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100182
Michal Vasko52927e22020-03-16 17:26:14 +0100183 data =
184 "<any xmlns=\"urn:tests:a\">"
185 "<element1>"
186 "<x:element2 x:attr2=\"test\" xmlns:a=\"urn:tests:a\" xmlns:x=\"urn:x\">a:data</x:element2>"
187 "</element1>"
188 "<element1a/>"
189 "</any>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100190 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejciee4cab22019-07-17 17:07:47 +0200191 assert_non_null(tree);
192 assert_int_equal(LYS_ANYDATA, tree->schema->nodetype);
193 assert_string_equal("any", tree->schema->name);
Michal Vasko52927e22020-03-16 17:26:14 +0100194
Radek Krejcia5bba312020-01-09 15:41:20 +0100195 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko52927e22020-03-16 17:26:14 +0100196 assert_string_equal(str,
197 "<any xmlns=\"urn:tests:a\">"
198 "<element1>"
199 "<element2 xmlns=\"urn:x\" xmlns:x=\"urn:x\" x:attr2=\"test\" xmlns:a=\"urn:tests:a\">a:data</element2>"
200 "</element1>"
201 "<element1a/>"
202 "</any>"
203 );
Radek Krejci241f6b52020-05-21 18:13:49 +0200204 ly_out_reset(out);
Radek Krejciee4cab22019-07-17 17:07:47 +0200205
206 lyd_free_all(tree);
Radek Krejci241f6b52020-05-21 18:13:49 +0200207 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100208
Radek Krejciee4cab22019-07-17 17:07:47 +0200209 *state = NULL;
210}
211
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200212static void
213test_list(void **state)
214{
215 *state = test_list;
216
Michal Vasko44685da2020-03-17 15:38:06 +0100217 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 +0200218 struct lyd_node *tree, *iter;
219 struct lyd_node_inner *list;
Radek Krejci710226d2019-07-24 17:24:59 +0200220 struct lyd_node_term *leaf;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200221
Radek Krejci710226d2019-07-24 17:24:59 +0200222 /* check hashes */
Michal Vasko9f96a052020-03-10 09:41:45 +0100223 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200224 assert_non_null(tree);
225 assert_int_equal(LYS_LIST, tree->schema->nodetype);
226 assert_string_equal("l1", tree->schema->name);
227 list = (struct lyd_node_inner*)tree;
228 LY_LIST_FOR(list->child, iter) {
229 assert_int_not_equal(0, iter->hash);
230 }
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200231 lyd_free_all(tree);
Radek Krejci710226d2019-07-24 17:24:59 +0200232
Michal Vasko9f96a052020-03-10 09:41:45 +0100233 /* missing keys */
Michal Vasko44685da2020-03-17 15:38:06 +0100234 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b></l1>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100235 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100236 logbuf_assert("List instance is missing its key \"a\". /a:l1[b='b'][c='1']");
Michal Vasko9f96a052020-03-10 09:41:45 +0100237
238 data = "<l1 xmlns=\"urn:tests:a\"><a>a</a></l1>";
239 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
240 logbuf_assert("List instance is missing its key \"b\". /a:l1[a='a']");
241
242 data = "<l1 xmlns=\"urn:tests:a\"><b>b</b><a>a</a></l1>";
243 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
244 logbuf_assert("List instance is missing its key \"c\". /a:l1[a='a'][b='b']");
245
246 /* key duplicate */
Michal Vasko44685da2020-03-17 15:38:06 +0100247 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a><c>1</c></l1>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100248 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100249 logbuf_assert("Duplicate instance of \"c\". /a:l1[a='a'][b='b'][c='1'][c='1']/c");
Michal Vasko9f96a052020-03-10 09:41:45 +0100250
Radek Krejci710226d2019-07-24 17:24:59 +0200251 /* keys order */
Michal Vasko44685da2020-03-17 15:38:06 +0100252 data = "<l1 xmlns=\"urn:tests:a\"><d>d</d><a>a</a><c>1</c><b>b</b></l1>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100253 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejci710226d2019-07-24 17:24:59 +0200254 assert_non_null(tree);
255 assert_int_equal(LYS_LIST, tree->schema->nodetype);
256 assert_string_equal("l1", tree->schema->name);
257 list = (struct lyd_node_inner*)tree;
258 assert_non_null(leaf = (struct lyd_node_term*)list->child);
259 assert_string_equal("a", leaf->schema->name);
260 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
261 assert_string_equal("b", leaf->schema->name);
262 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
263 assert_string_equal("c", leaf->schema->name);
264 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
265 assert_string_equal("d", leaf->schema->name);
266 logbuf_assert("Invalid position of the key \"b\" in a list.");
267 lyd_free_all(tree);
268
Michal Vasko44685da2020-03-17 15:38:06 +0100269 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a></l1>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100270 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejci710226d2019-07-24 17:24:59 +0200271 assert_non_null(tree);
272 assert_int_equal(LYS_LIST, tree->schema->nodetype);
273 assert_string_equal("l1", tree->schema->name);
274 list = (struct lyd_node_inner*)tree;
275 assert_non_null(leaf = (struct lyd_node_term*)list->child);
276 assert_string_equal("a", leaf->schema->name);
277 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
278 assert_string_equal("b", leaf->schema->name);
279 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
280 assert_string_equal("c", leaf->schema->name);
281 logbuf_assert("Invalid position of the key \"a\" in a list.");
282 logbuf_clean();
283 lyd_free_all(tree);
284
Michal Vasko9f96a052020-03-10 09:41:45 +0100285 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_OPT_STRICT, &tree));
Radek Krejci710226d2019-07-24 17:24:59 +0200286 logbuf_assert("Invalid position of the key \"b\" in a list. Line number 1.");
287
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200288 *state = NULL;
289}
290
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200291static void
292test_container(void **state)
293{
294 *state = test_container;
295
296 const char *data = "<c xmlns=\"urn:tests:a\"/>";
297 struct lyd_node *tree;
298 struct lyd_node_inner *cont;
299
Michal Vasko9f96a052020-03-10 09:41:45 +0100300 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200301 assert_non_null(tree);
302 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
303 assert_string_equal("c", tree->schema->name);
304 cont = (struct lyd_node_inner*)tree;
305 assert_true(cont->flags & LYD_DEFAULT);
306 lyd_free_all(tree);
307
308 data = "<cp xmlns=\"urn:tests:a\"/>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100309 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200310 assert_non_null(tree);
311 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
312 assert_string_equal("cp", tree->schema->name);
313 cont = (struct lyd_node_inner*)tree;
314 assert_false(cont->flags & LYD_DEFAULT);
315 lyd_free_all(tree);
316
317 *state = NULL;
318}
319
Michal Vasko44685da2020-03-17 15:38:06 +0100320static void
321test_opaq(void **state)
322{
323 *state = test_opaq;
324
325 const char *data;
326 char *str;
327 struct lyd_node *tree;
328
Radek Krejci241f6b52020-05-21 18:13:49 +0200329 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200330 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100331
Michal Vasko44685da2020-03-17 15:38:06 +0100332 /* invalid value, no flags */
333 data = "<foo3 xmlns=\"urn:tests:a\"/>";
334 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko1ce933a2020-03-30 12:38:22 +0200335 logbuf_assert("Invalid empty uint32 value. /a:foo3");
Michal Vasko44685da2020-03-17 15:38:06 +0100336 assert_null(tree);
337
338 /* opaq flag */
339 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_OPAQ | LYD_VALOPT_DATA_ONLY, &tree));
340 assert_non_null(tree);
341 assert_null(tree->schema);
342 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "foo3");
343 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
344
Radek Krejcia5bba312020-01-09 15:41:20 +0100345 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko44685da2020-03-17 15:38:06 +0100346 assert_string_equal(str, "<foo3 xmlns=\"urn:tests:a\"/>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200347 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100348 lyd_free_all(tree);
349
350 /* missing key, no flags */
351 data = "<l1 xmlns=\"urn:tests:a\"><a>val_a</a><b>val_b</b><d>val_d</d></l1>";
352 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
353 logbuf_assert("List instance is missing its key \"c\". /a:l1[a='val_a'][b='val_b']");
354 assert_null(tree);
355
356 /* opaq flag */
357 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_OPAQ | LYD_VALOPT_DATA_ONLY, &tree));
358 assert_non_null(tree);
359 assert_null(tree->schema);
360 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "l1");
361 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
362
Radek Krejcia5bba312020-01-09 15:41:20 +0100363 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko44685da2020-03-17 15:38:06 +0100364 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200365 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100366 lyd_free_all(tree);
367
368 /* invalid key, no flags */
369 data = "<l1 xmlns=\"urn:tests:a\"><a>val_a</a><b>val_b</b><c>val_c</c></l1>";
370 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof872e202020-05-27 11:49:06 +0200371 logbuf_assert("Invalid int16 value \"val_c\". /a:l1/c");
Michal Vasko44685da2020-03-17 15:38:06 +0100372 assert_null(tree);
373
374 /* opaq flag */
375 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_OPAQ | LYD_VALOPT_DATA_ONLY, &tree));
376 assert_non_null(tree);
377 assert_null(tree->schema);
378 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "l1");
379 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
380
Radek Krejcia5bba312020-01-09 15:41:20 +0100381 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko44685da2020-03-17 15:38:06 +0100382 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200383 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100384 lyd_free_all(tree);
385
Michal Vasko413c7f22020-05-05 12:34:06 +0200386 /* opaq flag and fail */
387 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, "<a xmlns=\"ns\"><b>x</b><c xml:id=\"D\">1</c></a>",
388 LYD_OPT_OPAQ | LYD_VALOPT_DATA_ONLY, &tree));
389 assert_null(tree);
390
Radek Krejci241f6b52020-05-21 18:13:49 +0200391 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100392
Michal Vasko44685da2020-03-17 15:38:06 +0100393 *state = NULL;
394}
395
Michal Vaskob36053d2020-03-26 15:49:30 +0100396static void
397test_rpc(void **state)
398{
399 *state = test_rpc;
400
401 const char *data;
402 char *str;
403 struct lyd_node *tree, *op;
Michal Vasko1bf09392020-03-27 12:38:10 +0100404 const struct lyd_node *node;
Michal Vaskob36053d2020-03-26 15:49:30 +0100405
Radek Krejci241f6b52020-05-21 18:13:49 +0200406 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200407 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100408
Michal Vaskob36053d2020-03-26 15:49:30 +0100409 data =
410 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
411 "<edit-config>"
412 "<target>"
413 "<running/>"
Michal Vaskob36053d2020-03-26 15:49:30 +0100414 "</target>"
Michal Vasko1bf09392020-03-27 12:38:10 +0100415 "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
416 "<l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">"
417 "<a>val_a</a>"
418 "<b>val_b</b>"
419 "<c>val_c</c>"
420 "</l1>"
421 "<cp xmlns=\"urn:tests:a\">"
422 "<z nc:operation=\"delete\"/>"
423 "</cp>"
424 "</config>"
Michal Vaskob36053d2020-03-26 15:49:30 +0100425 "</edit-config>"
426 "</rpc>";
Michal Vasko1bf09392020-03-27 12:38:10 +0100427 assert_int_equal(LY_SUCCESS, lyd_parse_xml_rpc(ctx, data, &tree, &op));
428
429 assert_non_null(op);
430 assert_string_equal(op->schema->name, "edit-config");
431
Michal Vaskob36053d2020-03-26 15:49:30 +0100432 assert_non_null(tree);
433 assert_null(tree->schema);
Michal Vasko1bf09392020-03-27 12:38:10 +0100434 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "rpc");
435 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
436 node = lyd_node_children(tree);
437 assert_string_equal(node->schema->name, "edit-config");
438 node = lyd_node_children(node)->next;
439 assert_string_equal(node->schema->name, "config");
440 node = ((struct lyd_node_any *)node)->value.tree;
441 /* l1 key c has invalid value */
442 assert_null(node->schema);
443 assert_string_equal(((struct lyd_node_opaq *)node)->name, "l1");
444 node = node->next;
445 assert_non_null(node->schema);
446 assert_string_equal(node->schema->name, "cp");
447 node = lyd_node_children(node);
448 /* z has no value */
449 assert_null(node->schema);
450 assert_string_equal(((struct lyd_node_opaq *)node)->name, "z");
Michal Vaskob36053d2020-03-26 15:49:30 +0100451
Radek Krejcia5bba312020-01-09 15:41:20 +0100452 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100453 assert_string_equal(str,
454 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
455 "<edit-config>"
456 "<target>"
457 "<running/>"
458 "</target>"
459 "<config>"
460 "<l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">"
461 "<a>val_a</a>"
462 "<b>val_b</b>"
463 "<c>val_c</c>"
464 "</l1>"
465 "<cp xmlns=\"urn:tests:a\">"
466 "<z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>"
467 "</cp>"
468 "</config>"
469 "</edit-config>"
470 "</rpc>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200471 ly_out_reset(out);
Michal Vaskob36053d2020-03-26 15:49:30 +0100472 lyd_free_all(tree);
473
474 /* wrong namespace, element name, whatever... */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100475 /* TODO */
476
Radek Krejci241f6b52020-05-21 18:13:49 +0200477 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100478
Michal Vaskoa8edff02020-03-27 14:47:01 +0100479 *state = NULL;
480}
481
482static void
483test_action(void **state)
484{
485 *state = test_action;
486
487 const char *data;
488 char *str;
489 struct lyd_node *tree, *op;
490 const struct lyd_node *node;
491
Radek Krejci241f6b52020-05-21 18:13:49 +0200492 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200493 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100494
Michal Vaskoa8edff02020-03-27 14:47:01 +0100495 data =
496 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
497 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
498 "<c xmlns=\"urn:tests:a\">"
499 "<act>"
500 "<al>value</al>"
501 "</act>"
502 "</c>"
503 "</action>"
504 "</rpc>";
505 assert_int_equal(LY_SUCCESS, lyd_parse_xml_rpc(ctx, data, &tree, &op));
506
507 assert_non_null(op);
508 assert_string_equal(op->schema->name, "act");
509
510 assert_non_null(tree);
511 assert_null(tree->schema);
512 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "rpc");
513 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
514 node = lyd_node_children(tree);
515 assert_null(node->schema);
516 assert_string_equal(((struct lyd_node_opaq *)node)->name, "action");
517 assert_null(((struct lyd_node_opaq *)node)->attr);
518
Radek Krejcia5bba312020-01-09 15:41:20 +0100519 lyd_print(out, tree, LYD_XML, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100520 assert_string_equal(str,
521 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
522 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
523 "<c xmlns=\"urn:tests:a\">"
524 "<act>"
525 "<al>value</al>"
526 "</act>"
527 "</c>"
528 "</action>"
529 "</rpc>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200530 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100531 lyd_free_all(tree);
532
533 /* wrong namespace, element name, whatever... */
534 /* TODO */
535
Radek Krejci241f6b52020-05-21 18:13:49 +0200536 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100537
Michal Vaskoa8edff02020-03-27 14:47:01 +0100538 *state = NULL;
539}
540
541static void
542test_notification(void **state)
543{
544 *state = test_notification;
545
546 const char *data;
547 char *str;
548 struct lyd_node *tree, *ntf;
549 const struct lyd_node *node;
550
Radek Krejci241f6b52020-05-21 18:13:49 +0200551 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200552 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100553
Michal Vaskoa8edff02020-03-27 14:47:01 +0100554 data =
555 "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">"
556 "<eventTime>2037-07-08T00:01:00Z</eventTime>"
557 "<c xmlns=\"urn:tests:a\">"
558 "<n1>"
559 "<nl>value</nl>"
560 "</n1>"
561 "</c>"
562 "</notification>";
563 assert_int_equal(LY_SUCCESS, lyd_parse_xml_notif(ctx, data, &tree, &ntf));
564
565 assert_non_null(ntf);
566 assert_string_equal(ntf->schema->name, "n1");
567
568 assert_non_null(tree);
569 assert_null(tree->schema);
570 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "notification");
571 assert_null(((struct lyd_node_opaq *)tree)->attr);
572 node = lyd_node_children(tree);
573 assert_null(node->schema);
574 assert_string_equal(((struct lyd_node_opaq *)node)->name, "eventTime");
575 assert_string_equal(((struct lyd_node_opaq *)node)->value, "2037-07-08T00:01:00Z");
576 assert_null(((struct lyd_node_opaq *)node)->attr);
577 node = node->next;
578 assert_non_null(node->schema);
579 assert_string_equal(node->schema->name, "c");
580
Radek Krejcia5bba312020-01-09 15:41:20 +0100581 lyd_print(out, tree, LYD_XML, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100582 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200583 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100584 lyd_free_all(tree);
585
586 /* top-level notif without envelope */
587 data = "<n2 xmlns=\"urn:tests:a\"/>";
588 assert_int_equal(LY_SUCCESS, lyd_parse_xml_notif(ctx, data, &tree, &ntf));
589
590 assert_non_null(ntf);
591 assert_string_equal(ntf->schema->name, "n2");
592
593 assert_non_null(tree);
594 assert_ptr_equal(ntf, tree);
595
Radek Krejcia5bba312020-01-09 15:41:20 +0100596 lyd_print(out, tree, LYD_XML, 0);
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 /* wrong namespace, element name, whatever... */
602 /* TODO */
Michal Vaskob36053d2020-03-26 15:49:30 +0100603
Radek Krejci241f6b52020-05-21 18:13:49 +0200604 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100605
Michal Vaskob36053d2020-03-26 15:49:30 +0100606 *state = NULL;
607}
608
Michal Vasko1ce933a2020-03-30 12:38:22 +0200609static void
610test_reply(void **state)
611{
612 *state = test_reply;
613
614 const char *data;
615 char *str;
616 struct lyd_node *request, *tree, *op;
617 const struct lyd_node *node;
618
Radek Krejci241f6b52020-05-21 18:13:49 +0200619 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200620 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100621
Michal Vasko1ce933a2020-03-30 12:38:22 +0200622 data =
623 "<c xmlns=\"urn:tests:a\">"
624 "<act>"
625 "<al>value</al>"
626 "</act>"
627 "</c>";
628 assert_int_equal(LY_SUCCESS, lyd_parse_xml_rpc(ctx, data, &request, NULL));
629 data =
630 "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\">"
631 "<al xmlns=\"urn:tests:a\">25</al>"
632 "</rpc-reply>";
633 assert_int_equal(LY_SUCCESS, lyd_parse_xml_reply(request, data, &tree, &op));
634 lyd_free_all(request);
635
636 assert_non_null(op);
637 assert_string_equal(op->schema->name, "act");
638 node = lyd_node_children(op);
639 assert_non_null(node->schema);
640 assert_string_equal(node->schema->name, "al");
641 assert_true(node->schema->flags & LYS_CONFIG_R);
642
643 assert_non_null(tree);
644 assert_null(tree->schema);
645 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "rpc-reply");
646 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
647 node = lyd_node_children(tree);
648 assert_non_null(node->schema);
649 assert_string_equal(node->schema->name, "c");
650
651 /* TODO print only rpc-reply node and then output subtree */
Radek Krejcia5bba312020-01-09 15:41:20 +0100652 lyd_print(out, lyd_node_children(op), LYD_XML, 0);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200653 assert_string_equal(str,
654 "<al xmlns=\"urn:tests:a\">25</al>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200655 ly_out_reset(out);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200656 lyd_free_all(tree);
657
658 /* wrong namespace, element name, whatever... */
659 /* TODO */
660
Radek Krejci241f6b52020-05-21 18:13:49 +0200661 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100662
Michal Vasko1ce933a2020-03-30 12:38:22 +0200663 *state = NULL;
664}
665
Radek Krejci509e2592019-05-15 16:30:48 +0200666int main(void)
667{
668 const struct CMUnitTest tests[] = {
669 cmocka_unit_test_setup_teardown(test_leaf, setup, teardown),
Radek Krejciee4cab22019-07-17 17:07:47 +0200670 cmocka_unit_test_setup_teardown(test_anydata, setup, teardown),
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200671 cmocka_unit_test_setup_teardown(test_list, setup, teardown),
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200672 cmocka_unit_test_setup_teardown(test_container, setup, teardown),
Michal Vasko44685da2020-03-17 15:38:06 +0100673 cmocka_unit_test_setup_teardown(test_opaq, setup, teardown),
Michal Vasko1bf09392020-03-27 12:38:10 +0100674 cmocka_unit_test_setup_teardown(test_rpc, setup, teardown),
Michal Vaskoa8edff02020-03-27 14:47:01 +0100675 cmocka_unit_test_setup_teardown(test_action, setup, teardown),
676 cmocka_unit_test_setup_teardown(test_notification, setup, teardown),
Michal Vasko1ce933a2020-03-30 12:38:22 +0200677 cmocka_unit_test_setup_teardown(test_reply, setup, teardown),
Radek Krejci509e2592019-05-15 16:30:48 +0200678 };
679
680 return cmocka_run_group_tests(tests, NULL, NULL);
681}