blob: 0c51134dc6528fe24976fea747105287a6e67619 [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"
Michal Vasko52927e22020-03-16 17:26:14 +010027#include "../../src/printer_data.h"
Radek Krejci509e2592019-05-15 16:30:48 +020028
29#define BUFSIZE 1024
30char logbuf[BUFSIZE] = {0};
31int store = -1; /* negative for infinite logging, positive for limited logging */
32
33struct ly_ctx *ctx; /* context for tests */
34
35/* set to 0 to printing error messages to stderr instead of checking them in code */
36#define ENABLE_LOGGER_CHECKING 1
37
38#if ENABLE_LOGGER_CHECKING
39static void
40logger(LY_LOG_LEVEL level, const char *msg, const char *path)
41{
42 (void) level; /* unused */
43 if (store) {
44 if (path && path[0]) {
45 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
46 } else {
47 strncpy(logbuf, msg, BUFSIZE - 1);
48 }
49 if (store > 0) {
50 --store;
51 }
52 }
53}
54#endif
55
56static int
57setup(void **state)
58{
59 (void) state; /* unused */
60
61 const char *schema_a = "module a {namespace urn:tests:a;prefix a;yang-version 1.1;"
Michal Vasko44685da2020-03-17 15:38:06 +010062 "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 +020063 "leaf foo { type string;}"
Michal Vaskoa8edff02020-03-27 14:47:01 +010064 "container c {"
65 "leaf x {type string;}"
Michal Vasko1ce933a2020-03-30 12:38:22 +020066 "action act { input { leaf al {type string;} } output { leaf al {type uint8;} } }"
Michal Vaskoa8edff02020-03-27 14:47:01 +010067 "notification n1 { leaf nl {type string;} }"
68 "}"
Michal Vaskob36053d2020-03-26 15:49:30 +010069 "container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}"
Michal Vasko8d544252020-03-02 10:19:52 +010070 "anydata any {config false;}"
Michal Vasko44685da2020-03-17 15:38:06 +010071 "leaf foo2 { type string; default \"default-val\"; }"
Michal Vaskoa8edff02020-03-27 14:47:01 +010072 "leaf foo3 { type uint32; }"
73 "notification n2;}";
Michal Vaskob36053d2020-03-26 15:49:30 +010074 const struct lys_module *mod;
Radek Krejci509e2592019-05-15 16:30:48 +020075
76#if ENABLE_LOGGER_CHECKING
77 ly_set_log_clb(logger, 1);
78#endif
79
Michal Vasko8d544252020-03-02 10:19:52 +010080 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &ctx));
81 assert_non_null(ly_ctx_load_module(ctx, "ietf-netconf-with-defaults", "2011-06-01"));
Michal Vaskob36053d2020-03-26 15:49:30 +010082 assert_non_null((mod = ly_ctx_load_module(ctx, "ietf-netconf", "2011-06-01")));
83 assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "writable-running"));
Radek Krejci509e2592019-05-15 16:30:48 +020084 assert_non_null(lys_parse_mem(ctx, schema_a, LYS_IN_YANG));
85
86 return 0;
87}
88
89static int
90teardown(void **state)
91{
92#if ENABLE_LOGGER_CHECKING
93 if (*state) {
94 fprintf(stderr, "%s\n", logbuf);
95 }
96#else
97 (void) state; /* unused */
98#endif
99
100 ly_ctx_destroy(ctx, NULL);
101 ctx = NULL;
102
103 return 0;
104}
105
106void
107logbuf_clean(void)
108{
109 logbuf[0] = '\0';
110}
111
112#if ENABLE_LOGGER_CHECKING
113# define logbuf_assert(str) assert_string_equal(logbuf, str)
114#else
115# define logbuf_assert(str)
116#endif
117
Radek Krejci509e2592019-05-15 16:30:48 +0200118static void
119test_leaf(void **state)
120{
121 *state = test_leaf;
122
123 const char *data = "<foo xmlns=\"urn:tests:a\">foo value</foo>";
124 struct lyd_node *tree;
125 struct lyd_node_term *leaf;
126
Michal Vasko9f96a052020-03-10 09:41:45 +0100127 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejci509e2592019-05-15 16:30:48 +0200128 assert_non_null(tree);
129 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
130 assert_string_equal("foo", tree->schema->name);
131 leaf = (struct lyd_node_term*)tree;
Radek Krejci950f6a52019-09-12 17:15:32 +0200132 assert_string_equal("foo value", leaf->value.original);
Radek Krejci509e2592019-05-15 16:30:48 +0200133
Michal Vasko8d544252020-03-02 10:19:52 +0100134 assert_int_equal(LYS_LEAF, tree->next->next->schema->nodetype);
135 assert_string_equal("foo2", tree->next->next->schema->name);
136 leaf = (struct lyd_node_term*)tree->next->next;
137 assert_string_equal("default-val", leaf->value.original);
138 assert_true(leaf->flags & LYD_DEFAULT);
139
Radek Krejci509e2592019-05-15 16:30:48 +0200140 lyd_free_all(tree);
Michal Vasko8d544252020-03-02 10:19:52 +0100141
142 /* make foo2 explicit */
143 data = "<foo2 xmlns=\"urn:tests:a\">default-val</foo2>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100144 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko8d544252020-03-02 10:19:52 +0100145 assert_non_null(tree);
146 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
147 assert_string_equal("foo2", tree->schema->name);
148 leaf = (struct lyd_node_term*)tree;
149 assert_string_equal("default-val", leaf->value.original);
150 assert_false(leaf->flags & LYD_DEFAULT);
151
152 lyd_free_all(tree);
153
154 /* parse foo2 but make it implicit */
155 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 +0100156 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko8d544252020-03-02 10:19:52 +0100157 assert_non_null(tree);
158 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
159 assert_string_equal("foo2", tree->schema->name);
160 leaf = (struct lyd_node_term*)tree;
161 assert_string_equal("default-val", leaf->value.original);
162 assert_true(leaf->flags & LYD_DEFAULT);
163
164 lyd_free_all(tree);
165
Radek Krejci509e2592019-05-15 16:30:48 +0200166 *state = NULL;
167}
168
Radek Krejciee4cab22019-07-17 17:07:47 +0200169static void
170test_anydata(void **state)
171{
172 *state = test_anydata;
173
Michal Vasko52927e22020-03-16 17:26:14 +0100174 const char *data;
175 char *str;
Radek Krejciee4cab22019-07-17 17:07:47 +0200176 struct lyd_node *tree;
Radek Krejciee4cab22019-07-17 17:07:47 +0200177
Radek Krejci241f6b52020-05-21 18:13:49 +0200178 struct ly_out *out;
179 assert_non_null(out = ly_out_new_memory(&str, 0));
Radek Krejcia5bba312020-01-09 15:41:20 +0100180
Michal Vasko52927e22020-03-16 17:26:14 +0100181 data =
182 "<any xmlns=\"urn:tests:a\">"
183 "<element1>"
184 "<x:element2 x:attr2=\"test\" xmlns:a=\"urn:tests:a\" xmlns:x=\"urn:x\">a:data</x:element2>"
185 "</element1>"
186 "<element1a/>"
187 "</any>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100188 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejciee4cab22019-07-17 17:07:47 +0200189 assert_non_null(tree);
190 assert_int_equal(LYS_ANYDATA, tree->schema->nodetype);
191 assert_string_equal("any", tree->schema->name);
Michal Vasko52927e22020-03-16 17:26:14 +0100192
Radek Krejcia5bba312020-01-09 15:41:20 +0100193 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko52927e22020-03-16 17:26:14 +0100194 assert_string_equal(str,
195 "<any xmlns=\"urn:tests:a\">"
196 "<element1>"
197 "<element2 xmlns=\"urn:x\" xmlns:x=\"urn:x\" x:attr2=\"test\" xmlns:a=\"urn:tests:a\">a:data</element2>"
198 "</element1>"
199 "<element1a/>"
200 "</any>"
201 );
Radek Krejci241f6b52020-05-21 18:13:49 +0200202 ly_out_reset(out);
Radek Krejciee4cab22019-07-17 17:07:47 +0200203
204 lyd_free_all(tree);
Radek Krejci241f6b52020-05-21 18:13:49 +0200205 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100206
Radek Krejciee4cab22019-07-17 17:07:47 +0200207 *state = NULL;
208}
209
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200210static void
211test_list(void **state)
212{
213 *state = test_list;
214
Michal Vasko44685da2020-03-17 15:38:06 +0100215 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 +0200216 struct lyd_node *tree, *iter;
217 struct lyd_node_inner *list;
Radek Krejci710226d2019-07-24 17:24:59 +0200218 struct lyd_node_term *leaf;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200219
Radek Krejci710226d2019-07-24 17:24:59 +0200220 /* check hashes */
Michal Vasko9f96a052020-03-10 09:41:45 +0100221 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200222 assert_non_null(tree);
223 assert_int_equal(LYS_LIST, tree->schema->nodetype);
224 assert_string_equal("l1", tree->schema->name);
225 list = (struct lyd_node_inner*)tree;
226 LY_LIST_FOR(list->child, iter) {
227 assert_int_not_equal(0, iter->hash);
228 }
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200229 lyd_free_all(tree);
Radek Krejci710226d2019-07-24 17:24:59 +0200230
Michal Vasko9f96a052020-03-10 09:41:45 +0100231 /* missing keys */
Michal Vasko44685da2020-03-17 15:38:06 +0100232 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b></l1>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100233 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100234 logbuf_assert("List instance is missing its key \"a\". /a:l1[b='b'][c='1']");
Michal Vasko9f96a052020-03-10 09:41:45 +0100235
236 data = "<l1 xmlns=\"urn:tests:a\"><a>a</a></l1>";
237 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
238 logbuf_assert("List instance is missing its key \"b\". /a:l1[a='a']");
239
240 data = "<l1 xmlns=\"urn:tests:a\"><b>b</b><a>a</a></l1>";
241 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
242 logbuf_assert("List instance is missing its key \"c\". /a:l1[a='a'][b='b']");
243
244 /* key duplicate */
Michal Vasko44685da2020-03-17 15:38:06 +0100245 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 +0100246 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100247 logbuf_assert("Duplicate instance of \"c\". /a:l1[a='a'][b='b'][c='1'][c='1']/c");
Michal Vasko9f96a052020-03-10 09:41:45 +0100248
Radek Krejci710226d2019-07-24 17:24:59 +0200249 /* keys order */
Michal Vasko44685da2020-03-17 15:38:06 +0100250 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 +0100251 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejci710226d2019-07-24 17:24:59 +0200252 assert_non_null(tree);
253 assert_int_equal(LYS_LIST, tree->schema->nodetype);
254 assert_string_equal("l1", tree->schema->name);
255 list = (struct lyd_node_inner*)tree;
256 assert_non_null(leaf = (struct lyd_node_term*)list->child);
257 assert_string_equal("a", leaf->schema->name);
258 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
259 assert_string_equal("b", leaf->schema->name);
260 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
261 assert_string_equal("c", leaf->schema->name);
262 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
263 assert_string_equal("d", leaf->schema->name);
264 logbuf_assert("Invalid position of the key \"b\" in a list.");
265 lyd_free_all(tree);
266
Michal Vasko44685da2020-03-17 15:38:06 +0100267 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a></l1>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100268 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejci710226d2019-07-24 17:24:59 +0200269 assert_non_null(tree);
270 assert_int_equal(LYS_LIST, tree->schema->nodetype);
271 assert_string_equal("l1", tree->schema->name);
272 list = (struct lyd_node_inner*)tree;
273 assert_non_null(leaf = (struct lyd_node_term*)list->child);
274 assert_string_equal("a", leaf->schema->name);
275 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
276 assert_string_equal("b", leaf->schema->name);
277 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
278 assert_string_equal("c", leaf->schema->name);
279 logbuf_assert("Invalid position of the key \"a\" in a list.");
280 logbuf_clean();
281 lyd_free_all(tree);
282
Michal Vasko9f96a052020-03-10 09:41:45 +0100283 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_OPT_STRICT, &tree));
Radek Krejci710226d2019-07-24 17:24:59 +0200284 logbuf_assert("Invalid position of the key \"b\" in a list. Line number 1.");
285
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200286 *state = NULL;
287}
288
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200289static void
290test_container(void **state)
291{
292 *state = test_container;
293
294 const char *data = "<c xmlns=\"urn:tests:a\"/>";
295 struct lyd_node *tree;
296 struct lyd_node_inner *cont;
297
Michal Vasko9f96a052020-03-10 09:41:45 +0100298 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200299 assert_non_null(tree);
300 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
301 assert_string_equal("c", tree->schema->name);
302 cont = (struct lyd_node_inner*)tree;
303 assert_true(cont->flags & LYD_DEFAULT);
304 lyd_free_all(tree);
305
306 data = "<cp xmlns=\"urn:tests:a\"/>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100307 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200308 assert_non_null(tree);
309 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
310 assert_string_equal("cp", tree->schema->name);
311 cont = (struct lyd_node_inner*)tree;
312 assert_false(cont->flags & LYD_DEFAULT);
313 lyd_free_all(tree);
314
315 *state = NULL;
316}
317
Michal Vasko44685da2020-03-17 15:38:06 +0100318static void
319test_opaq(void **state)
320{
321 *state = test_opaq;
322
323 const char *data;
324 char *str;
325 struct lyd_node *tree;
326
Radek Krejci241f6b52020-05-21 18:13:49 +0200327 struct ly_out *out;
328 assert_non_null(out = ly_out_new_memory(&str, 0));
Radek Krejcia5bba312020-01-09 15:41:20 +0100329
Michal Vasko44685da2020-03-17 15:38:06 +0100330 /* invalid value, no flags */
331 data = "<foo3 xmlns=\"urn:tests:a\"/>";
332 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko1ce933a2020-03-30 12:38:22 +0200333 logbuf_assert("Invalid empty uint32 value. /a:foo3");
Michal Vasko44685da2020-03-17 15:38:06 +0100334 assert_null(tree);
335
336 /* opaq flag */
337 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_OPAQ | LYD_VALOPT_DATA_ONLY, &tree));
338 assert_non_null(tree);
339 assert_null(tree->schema);
340 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "foo3");
341 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
342
Radek Krejcia5bba312020-01-09 15:41:20 +0100343 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko44685da2020-03-17 15:38:06 +0100344 assert_string_equal(str, "<foo3 xmlns=\"urn:tests:a\"/>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200345 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100346 lyd_free_all(tree);
347
348 /* missing key, no flags */
349 data = "<l1 xmlns=\"urn:tests:a\"><a>val_a</a><b>val_b</b><d>val_d</d></l1>";
350 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
351 logbuf_assert("List instance is missing its key \"c\". /a:l1[a='val_a'][b='val_b']");
352 assert_null(tree);
353
354 /* opaq flag */
355 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_OPAQ | LYD_VALOPT_DATA_ONLY, &tree));
356 assert_non_null(tree);
357 assert_null(tree->schema);
358 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "l1");
359 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
360
Radek Krejcia5bba312020-01-09 15:41:20 +0100361 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko44685da2020-03-17 15:38:06 +0100362 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200363 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100364 lyd_free_all(tree);
365
366 /* invalid key, no flags */
367 data = "<l1 xmlns=\"urn:tests:a\"><a>val_a</a><b>val_b</b><c>val_c</c></l1>";
368 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko1ce933a2020-03-30 12:38:22 +0200369 logbuf_assert("Invalid int16 value \"val_c\". /a:c");
Michal Vasko44685da2020-03-17 15:38:06 +0100370 assert_null(tree);
371
372 /* opaq flag */
373 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_OPAQ | LYD_VALOPT_DATA_ONLY, &tree));
374 assert_non_null(tree);
375 assert_null(tree->schema);
376 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "l1");
377 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
378
Radek Krejcia5bba312020-01-09 15:41:20 +0100379 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko44685da2020-03-17 15:38:06 +0100380 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200381 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100382 lyd_free_all(tree);
383
Michal Vasko413c7f22020-05-05 12:34:06 +0200384 /* opaq flag and fail */
385 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, "<a xmlns=\"ns\"><b>x</b><c xml:id=\"D\">1</c></a>",
386 LYD_OPT_OPAQ | LYD_VALOPT_DATA_ONLY, &tree));
387 assert_null(tree);
388
Radek Krejci241f6b52020-05-21 18:13:49 +0200389 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100390
Michal Vasko44685da2020-03-17 15:38:06 +0100391 *state = NULL;
392}
393
Michal Vaskob36053d2020-03-26 15:49:30 +0100394static void
395test_rpc(void **state)
396{
397 *state = test_rpc;
398
399 const char *data;
400 char *str;
401 struct lyd_node *tree, *op;
Michal Vasko1bf09392020-03-27 12:38:10 +0100402 const struct lyd_node *node;
Michal Vaskob36053d2020-03-26 15:49:30 +0100403
Radek Krejci241f6b52020-05-21 18:13:49 +0200404 struct ly_out *out;
405 assert_non_null(out = ly_out_new_memory(&str, 0));
Radek Krejcia5bba312020-01-09 15:41:20 +0100406
Michal Vaskob36053d2020-03-26 15:49:30 +0100407 data =
408 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
409 "<edit-config>"
410 "<target>"
411 "<running/>"
Michal Vaskob36053d2020-03-26 15:49:30 +0100412 "</target>"
Michal Vasko1bf09392020-03-27 12:38:10 +0100413 "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
414 "<l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">"
415 "<a>val_a</a>"
416 "<b>val_b</b>"
417 "<c>val_c</c>"
418 "</l1>"
419 "<cp xmlns=\"urn:tests:a\">"
420 "<z nc:operation=\"delete\"/>"
421 "</cp>"
422 "</config>"
Michal Vaskob36053d2020-03-26 15:49:30 +0100423 "</edit-config>"
424 "</rpc>";
Michal Vasko1bf09392020-03-27 12:38:10 +0100425 assert_int_equal(LY_SUCCESS, lyd_parse_xml_rpc(ctx, data, &tree, &op));
426
427 assert_non_null(op);
428 assert_string_equal(op->schema->name, "edit-config");
429
Michal Vaskob36053d2020-03-26 15:49:30 +0100430 assert_non_null(tree);
431 assert_null(tree->schema);
Michal Vasko1bf09392020-03-27 12:38:10 +0100432 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "rpc");
433 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
434 node = lyd_node_children(tree);
435 assert_string_equal(node->schema->name, "edit-config");
436 node = lyd_node_children(node)->next;
437 assert_string_equal(node->schema->name, "config");
438 node = ((struct lyd_node_any *)node)->value.tree;
439 /* l1 key c has invalid value */
440 assert_null(node->schema);
441 assert_string_equal(((struct lyd_node_opaq *)node)->name, "l1");
442 node = node->next;
443 assert_non_null(node->schema);
444 assert_string_equal(node->schema->name, "cp");
445 node = lyd_node_children(node);
446 /* z has no value */
447 assert_null(node->schema);
448 assert_string_equal(((struct lyd_node_opaq *)node)->name, "z");
Michal Vaskob36053d2020-03-26 15:49:30 +0100449
Radek Krejcia5bba312020-01-09 15:41:20 +0100450 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100451 assert_string_equal(str,
452 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
453 "<edit-config>"
454 "<target>"
455 "<running/>"
456 "</target>"
457 "<config>"
458 "<l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">"
459 "<a>val_a</a>"
460 "<b>val_b</b>"
461 "<c>val_c</c>"
462 "</l1>"
463 "<cp xmlns=\"urn:tests:a\">"
464 "<z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>"
465 "</cp>"
466 "</config>"
467 "</edit-config>"
468 "</rpc>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200469 ly_out_reset(out);
Michal Vaskob36053d2020-03-26 15:49:30 +0100470 lyd_free_all(tree);
471
472 /* wrong namespace, element name, whatever... */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100473 /* TODO */
474
Radek Krejci241f6b52020-05-21 18:13:49 +0200475 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100476
Michal Vaskoa8edff02020-03-27 14:47:01 +0100477 *state = NULL;
478}
479
480static void
481test_action(void **state)
482{
483 *state = test_action;
484
485 const char *data;
486 char *str;
487 struct lyd_node *tree, *op;
488 const struct lyd_node *node;
489
Radek Krejci241f6b52020-05-21 18:13:49 +0200490 struct ly_out *out;
491 assert_non_null(out = ly_out_new_memory(&str, 0));
Radek Krejcia5bba312020-01-09 15:41:20 +0100492
Michal Vaskoa8edff02020-03-27 14:47:01 +0100493 data =
494 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
495 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
496 "<c xmlns=\"urn:tests:a\">"
497 "<act>"
498 "<al>value</al>"
499 "</act>"
500 "</c>"
501 "</action>"
502 "</rpc>";
503 assert_int_equal(LY_SUCCESS, lyd_parse_xml_rpc(ctx, data, &tree, &op));
504
505 assert_non_null(op);
506 assert_string_equal(op->schema->name, "act");
507
508 assert_non_null(tree);
509 assert_null(tree->schema);
510 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "rpc");
511 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
512 node = lyd_node_children(tree);
513 assert_null(node->schema);
514 assert_string_equal(((struct lyd_node_opaq *)node)->name, "action");
515 assert_null(((struct lyd_node_opaq *)node)->attr);
516
Radek Krejcia5bba312020-01-09 15:41:20 +0100517 lyd_print(out, tree, LYD_XML, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100518 assert_string_equal(str,
519 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
520 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
521 "<c xmlns=\"urn:tests:a\">"
522 "<act>"
523 "<al>value</al>"
524 "</act>"
525 "</c>"
526 "</action>"
527 "</rpc>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200528 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100529 lyd_free_all(tree);
530
531 /* wrong namespace, element name, whatever... */
532 /* TODO */
533
Radek Krejci241f6b52020-05-21 18:13:49 +0200534 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100535
Michal Vaskoa8edff02020-03-27 14:47:01 +0100536 *state = NULL;
537}
538
539static void
540test_notification(void **state)
541{
542 *state = test_notification;
543
544 const char *data;
545 char *str;
546 struct lyd_node *tree, *ntf;
547 const struct lyd_node *node;
548
Radek Krejci241f6b52020-05-21 18:13:49 +0200549 struct ly_out *out;
550 assert_non_null(out = ly_out_new_memory(&str, 0));
Radek Krejcia5bba312020-01-09 15:41:20 +0100551
Michal Vaskoa8edff02020-03-27 14:47:01 +0100552 data =
553 "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">"
554 "<eventTime>2037-07-08T00:01:00Z</eventTime>"
555 "<c xmlns=\"urn:tests:a\">"
556 "<n1>"
557 "<nl>value</nl>"
558 "</n1>"
559 "</c>"
560 "</notification>";
561 assert_int_equal(LY_SUCCESS, lyd_parse_xml_notif(ctx, data, &tree, &ntf));
562
563 assert_non_null(ntf);
564 assert_string_equal(ntf->schema->name, "n1");
565
566 assert_non_null(tree);
567 assert_null(tree->schema);
568 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "notification");
569 assert_null(((struct lyd_node_opaq *)tree)->attr);
570 node = lyd_node_children(tree);
571 assert_null(node->schema);
572 assert_string_equal(((struct lyd_node_opaq *)node)->name, "eventTime");
573 assert_string_equal(((struct lyd_node_opaq *)node)->value, "2037-07-08T00:01:00Z");
574 assert_null(((struct lyd_node_opaq *)node)->attr);
575 node = node->next;
576 assert_non_null(node->schema);
577 assert_string_equal(node->schema->name, "c");
578
Radek Krejcia5bba312020-01-09 15:41:20 +0100579 lyd_print(out, tree, LYD_XML, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100580 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200581 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100582 lyd_free_all(tree);
583
584 /* top-level notif without envelope */
585 data = "<n2 xmlns=\"urn:tests:a\"/>";
586 assert_int_equal(LY_SUCCESS, lyd_parse_xml_notif(ctx, data, &tree, &ntf));
587
588 assert_non_null(ntf);
589 assert_string_equal(ntf->schema->name, "n2");
590
591 assert_non_null(tree);
592 assert_ptr_equal(ntf, tree);
593
Radek Krejcia5bba312020-01-09 15:41:20 +0100594 lyd_print(out, tree, LYD_XML, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100595 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200596 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100597 lyd_free_all(tree);
598
599 /* wrong namespace, element name, whatever... */
600 /* TODO */
Michal Vaskob36053d2020-03-26 15:49:30 +0100601
Radek Krejci241f6b52020-05-21 18:13:49 +0200602 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100603
Michal Vaskob36053d2020-03-26 15:49:30 +0100604 *state = NULL;
605}
606
Michal Vasko1ce933a2020-03-30 12:38:22 +0200607static void
608test_reply(void **state)
609{
610 *state = test_reply;
611
612 const char *data;
613 char *str;
614 struct lyd_node *request, *tree, *op;
615 const struct lyd_node *node;
616
Radek Krejci241f6b52020-05-21 18:13:49 +0200617 struct ly_out *out;
618 assert_non_null(out = ly_out_new_memory(&str, 0));
Radek Krejcia5bba312020-01-09 15:41:20 +0100619
Michal Vasko1ce933a2020-03-30 12:38:22 +0200620 data =
621 "<c xmlns=\"urn:tests:a\">"
622 "<act>"
623 "<al>value</al>"
624 "</act>"
625 "</c>";
626 assert_int_equal(LY_SUCCESS, lyd_parse_xml_rpc(ctx, data, &request, NULL));
627 data =
628 "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\">"
629 "<al xmlns=\"urn:tests:a\">25</al>"
630 "</rpc-reply>";
631 assert_int_equal(LY_SUCCESS, lyd_parse_xml_reply(request, data, &tree, &op));
632 lyd_free_all(request);
633
634 assert_non_null(op);
635 assert_string_equal(op->schema->name, "act");
636 node = lyd_node_children(op);
637 assert_non_null(node->schema);
638 assert_string_equal(node->schema->name, "al");
639 assert_true(node->schema->flags & LYS_CONFIG_R);
640
641 assert_non_null(tree);
642 assert_null(tree->schema);
643 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "rpc-reply");
644 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
645 node = lyd_node_children(tree);
646 assert_non_null(node->schema);
647 assert_string_equal(node->schema->name, "c");
648
649 /* TODO print only rpc-reply node and then output subtree */
Radek Krejcia5bba312020-01-09 15:41:20 +0100650 lyd_print(out, lyd_node_children(op), LYD_XML, 0);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200651 assert_string_equal(str,
652 "<al xmlns=\"urn:tests:a\">25</al>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200653 ly_out_reset(out);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200654 lyd_free_all(tree);
655
656 /* wrong namespace, element name, whatever... */
657 /* TODO */
658
Radek Krejci241f6b52020-05-21 18:13:49 +0200659 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100660
Michal Vasko1ce933a2020-03-30 12:38:22 +0200661 *state = NULL;
662}
663
Radek Krejci509e2592019-05-15 16:30:48 +0200664int main(void)
665{
666 const struct CMUnitTest tests[] = {
667 cmocka_unit_test_setup_teardown(test_leaf, setup, teardown),
Radek Krejciee4cab22019-07-17 17:07:47 +0200668 cmocka_unit_test_setup_teardown(test_anydata, setup, teardown),
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200669 cmocka_unit_test_setup_teardown(test_list, setup, teardown),
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200670 cmocka_unit_test_setup_teardown(test_container, setup, teardown),
Michal Vasko44685da2020-03-17 15:38:06 +0100671 cmocka_unit_test_setup_teardown(test_opaq, setup, teardown),
Michal Vasko1bf09392020-03-27 12:38:10 +0100672 cmocka_unit_test_setup_teardown(test_rpc, setup, teardown),
Michal Vaskoa8edff02020-03-27 14:47:01 +0100673 cmocka_unit_test_setup_teardown(test_action, setup, teardown),
674 cmocka_unit_test_setup_teardown(test_notification, setup, teardown),
Michal Vasko1ce933a2020-03-30 12:38:22 +0200675 cmocka_unit_test_setup_teardown(test_reply, setup, teardown),
Radek Krejci509e2592019-05-15 16:30:48 +0200676 };
677
678 return cmocka_run_group_tests(tests, NULL, NULL);
679}