blob: 18b54d4af995acd054d3ea841e530d17c4123adc [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"
24#include "printer.h"
25#include "printer_data.h"
26#include "tests/config.h"
27#include "tree_data_internal.h"
28#include "tree_schema.h"
Radek Krejci509e2592019-05-15 16:30:48 +020029
30#define BUFSIZE 1024
31char logbuf[BUFSIZE] = {0};
32int store = -1; /* negative for infinite logging, positive for limited logging */
33
34struct ly_ctx *ctx; /* context for tests */
35
36/* set to 0 to printing error messages to stderr instead of checking them in code */
37#define ENABLE_LOGGER_CHECKING 1
38
39#if ENABLE_LOGGER_CHECKING
40static void
41logger(LY_LOG_LEVEL level, const char *msg, const char *path)
42{
43 (void) level; /* unused */
44 if (store) {
45 if (path && path[0]) {
46 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
47 } else {
48 strncpy(logbuf, msg, BUFSIZE - 1);
49 }
50 if (store > 0) {
51 --store;
52 }
53 }
54}
55#endif
56
57static int
58setup(void **state)
59{
60 (void) state; /* unused */
61
62 const char *schema_a = "module a {namespace urn:tests:a;prefix a;yang-version 1.1;"
Michal Vasko44685da2020-03-17 15:38:06 +010063 "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 +020064 "leaf foo { type string;}"
Michal Vaskoa8edff02020-03-27 14:47:01 +010065 "container c {"
66 "leaf x {type string;}"
Michal Vasko1ce933a2020-03-30 12:38:22 +020067 "action act { input { leaf al {type string;} } output { leaf al {type uint8;} } }"
Michal Vaskoa8edff02020-03-27 14:47:01 +010068 "notification n1 { leaf nl {type string;} }"
69 "}"
Michal Vaskob36053d2020-03-26 15:49:30 +010070 "container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}"
Michal Vasko8d544252020-03-02 10:19:52 +010071 "anydata any {config false;}"
Michal Vasko44685da2020-03-17 15:38:06 +010072 "leaf foo2 { type string; default \"default-val\"; }"
Michal Vaskoa8edff02020-03-27 14:47:01 +010073 "leaf foo3 { type uint32; }"
74 "notification n2;}";
Michal Vaskob36053d2020-03-26 15:49:30 +010075 const struct lys_module *mod;
Radek Krejci509e2592019-05-15 16:30:48 +020076
77#if ENABLE_LOGGER_CHECKING
78 ly_set_log_clb(logger, 1);
79#endif
80
Michal Vasko8d544252020-03-02 10:19:52 +010081 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &ctx));
82 assert_non_null(ly_ctx_load_module(ctx, "ietf-netconf-with-defaults", "2011-06-01"));
Michal Vaskob36053d2020-03-26 15:49:30 +010083 assert_non_null((mod = ly_ctx_load_module(ctx, "ietf-netconf", "2011-06-01")));
84 assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "writable-running"));
Radek Krejci509e2592019-05-15 16:30:48 +020085 assert_non_null(lys_parse_mem(ctx, schema_a, LYS_IN_YANG));
86
87 return 0;
88}
89
90static int
91teardown(void **state)
92{
93#if ENABLE_LOGGER_CHECKING
94 if (*state) {
95 fprintf(stderr, "%s\n", logbuf);
96 }
97#else
98 (void) state; /* unused */
99#endif
100
101 ly_ctx_destroy(ctx, NULL);
102 ctx = NULL;
103
104 return 0;
105}
106
107void
108logbuf_clean(void)
109{
110 logbuf[0] = '\0';
111}
112
113#if ENABLE_LOGGER_CHECKING
114# define logbuf_assert(str) assert_string_equal(logbuf, str)
115#else
116# define logbuf_assert(str)
117#endif
118
Radek Krejci509e2592019-05-15 16:30:48 +0200119static void
120test_leaf(void **state)
121{
122 *state = test_leaf;
123
124 const char *data = "<foo xmlns=\"urn:tests:a\">foo value</foo>";
125 struct lyd_node *tree;
126 struct lyd_node_term *leaf;
127
Michal Vasko9f96a052020-03-10 09:41:45 +0100128 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejci509e2592019-05-15 16:30:48 +0200129 assert_non_null(tree);
130 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
131 assert_string_equal("foo", tree->schema->name);
132 leaf = (struct lyd_node_term*)tree;
Radek Krejci950f6a52019-09-12 17:15:32 +0200133 assert_string_equal("foo value", leaf->value.original);
Radek Krejci509e2592019-05-15 16:30:48 +0200134
Michal Vasko8d544252020-03-02 10:19:52 +0100135 assert_int_equal(LYS_LEAF, tree->next->next->schema->nodetype);
136 assert_string_equal("foo2", tree->next->next->schema->name);
137 leaf = (struct lyd_node_term*)tree->next->next;
138 assert_string_equal("default-val", leaf->value.original);
139 assert_true(leaf->flags & LYD_DEFAULT);
140
Radek Krejci509e2592019-05-15 16:30:48 +0200141 lyd_free_all(tree);
Michal Vasko8d544252020-03-02 10:19:52 +0100142
143 /* make foo2 explicit */
144 data = "<foo2 xmlns=\"urn:tests:a\">default-val</foo2>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100145 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko8d544252020-03-02 10:19:52 +0100146 assert_non_null(tree);
147 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
148 assert_string_equal("foo2", tree->schema->name);
149 leaf = (struct lyd_node_term*)tree;
150 assert_string_equal("default-val", leaf->value.original);
151 assert_false(leaf->flags & LYD_DEFAULT);
152
153 lyd_free_all(tree);
154
155 /* parse foo2 but make it implicit */
156 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 +0100157 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko8d544252020-03-02 10:19:52 +0100158 assert_non_null(tree);
159 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
160 assert_string_equal("foo2", tree->schema->name);
161 leaf = (struct lyd_node_term*)tree;
162 assert_string_equal("default-val", leaf->value.original);
163 assert_true(leaf->flags & LYD_DEFAULT);
164
165 lyd_free_all(tree);
166
Radek Krejci509e2592019-05-15 16:30:48 +0200167 *state = NULL;
168}
169
Radek Krejciee4cab22019-07-17 17:07:47 +0200170static void
171test_anydata(void **state)
172{
173 *state = test_anydata;
174
Michal Vasko52927e22020-03-16 17:26:14 +0100175 const char *data;
176 char *str;
Radek Krejciee4cab22019-07-17 17:07:47 +0200177 struct lyd_node *tree;
Radek Krejciee4cab22019-07-17 17:07:47 +0200178
Radek Krejci241f6b52020-05-21 18:13:49 +0200179 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200180 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100181
Michal Vasko52927e22020-03-16 17:26:14 +0100182 data =
183 "<any xmlns=\"urn:tests:a\">"
184 "<element1>"
185 "<x:element2 x:attr2=\"test\" xmlns:a=\"urn:tests:a\" xmlns:x=\"urn:x\">a:data</x:element2>"
186 "</element1>"
187 "<element1a/>"
188 "</any>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100189 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejciee4cab22019-07-17 17:07:47 +0200190 assert_non_null(tree);
191 assert_int_equal(LYS_ANYDATA, tree->schema->nodetype);
192 assert_string_equal("any", tree->schema->name);
Michal Vasko52927e22020-03-16 17:26:14 +0100193
Radek Krejcia5bba312020-01-09 15:41:20 +0100194 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko52927e22020-03-16 17:26:14 +0100195 assert_string_equal(str,
196 "<any xmlns=\"urn:tests:a\">"
197 "<element1>"
198 "<element2 xmlns=\"urn:x\" xmlns:x=\"urn:x\" x:attr2=\"test\" xmlns:a=\"urn:tests:a\">a:data</element2>"
199 "</element1>"
200 "<element1a/>"
201 "</any>"
202 );
Radek Krejci241f6b52020-05-21 18:13:49 +0200203 ly_out_reset(out);
Radek Krejciee4cab22019-07-17 17:07:47 +0200204
205 lyd_free_all(tree);
Radek Krejci241f6b52020-05-21 18:13:49 +0200206 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100207
Radek Krejciee4cab22019-07-17 17:07:47 +0200208 *state = NULL;
209}
210
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200211static void
212test_list(void **state)
213{
214 *state = test_list;
215
Michal Vasko44685da2020-03-17 15:38:06 +0100216 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 +0200217 struct lyd_node *tree, *iter;
218 struct lyd_node_inner *list;
Radek Krejci710226d2019-07-24 17:24:59 +0200219 struct lyd_node_term *leaf;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200220
Radek Krejci710226d2019-07-24 17:24:59 +0200221 /* check hashes */
Michal Vasko9f96a052020-03-10 09:41:45 +0100222 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200223 assert_non_null(tree);
224 assert_int_equal(LYS_LIST, tree->schema->nodetype);
225 assert_string_equal("l1", tree->schema->name);
226 list = (struct lyd_node_inner*)tree;
227 LY_LIST_FOR(list->child, iter) {
228 assert_int_not_equal(0, iter->hash);
229 }
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200230 lyd_free_all(tree);
Radek Krejci710226d2019-07-24 17:24:59 +0200231
Michal Vasko9f96a052020-03-10 09:41:45 +0100232 /* missing keys */
Michal Vasko44685da2020-03-17 15:38:06 +0100233 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b></l1>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100234 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100235 logbuf_assert("List instance is missing its key \"a\". /a:l1[b='b'][c='1']");
Michal Vasko9f96a052020-03-10 09:41:45 +0100236
237 data = "<l1 xmlns=\"urn:tests:a\"><a>a</a></l1>";
238 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
239 logbuf_assert("List instance is missing its key \"b\". /a:l1[a='a']");
240
241 data = "<l1 xmlns=\"urn:tests:a\"><b>b</b><a>a</a></l1>";
242 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
243 logbuf_assert("List instance is missing its key \"c\". /a:l1[a='a'][b='b']");
244
245 /* key duplicate */
Michal Vasko44685da2020-03-17 15:38:06 +0100246 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 +0100247 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko44685da2020-03-17 15:38:06 +0100248 logbuf_assert("Duplicate instance of \"c\". /a:l1[a='a'][b='b'][c='1'][c='1']/c");
Michal Vasko9f96a052020-03-10 09:41:45 +0100249
Radek Krejci710226d2019-07-24 17:24:59 +0200250 /* keys order */
Michal Vasko44685da2020-03-17 15:38:06 +0100251 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 +0100252 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejci710226d2019-07-24 17:24:59 +0200253 assert_non_null(tree);
254 assert_int_equal(LYS_LIST, tree->schema->nodetype);
255 assert_string_equal("l1", tree->schema->name);
256 list = (struct lyd_node_inner*)tree;
257 assert_non_null(leaf = (struct lyd_node_term*)list->child);
258 assert_string_equal("a", leaf->schema->name);
259 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
260 assert_string_equal("b", leaf->schema->name);
261 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
262 assert_string_equal("c", leaf->schema->name);
263 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
264 assert_string_equal("d", leaf->schema->name);
265 logbuf_assert("Invalid position of the key \"b\" in a list.");
266 lyd_free_all(tree);
267
Michal Vasko44685da2020-03-17 15:38:06 +0100268 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a></l1>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100269 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejci710226d2019-07-24 17:24:59 +0200270 assert_non_null(tree);
271 assert_int_equal(LYS_LIST, tree->schema->nodetype);
272 assert_string_equal("l1", tree->schema->name);
273 list = (struct lyd_node_inner*)tree;
274 assert_non_null(leaf = (struct lyd_node_term*)list->child);
275 assert_string_equal("a", leaf->schema->name);
276 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
277 assert_string_equal("b", leaf->schema->name);
278 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
279 assert_string_equal("c", leaf->schema->name);
280 logbuf_assert("Invalid position of the key \"a\" in a list.");
281 logbuf_clean();
282 lyd_free_all(tree);
283
Michal Vasko9f96a052020-03-10 09:41:45 +0100284 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_OPT_STRICT, &tree));
Radek Krejci710226d2019-07-24 17:24:59 +0200285 logbuf_assert("Invalid position of the key \"b\" in a list. Line number 1.");
286
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200287 *state = NULL;
288}
289
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200290static void
291test_container(void **state)
292{
293 *state = test_container;
294
295 const char *data = "<c xmlns=\"urn:tests:a\"/>";
296 struct lyd_node *tree;
297 struct lyd_node_inner *cont;
298
Michal Vasko9f96a052020-03-10 09:41:45 +0100299 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200300 assert_non_null(tree);
301 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
302 assert_string_equal("c", tree->schema->name);
303 cont = (struct lyd_node_inner*)tree;
304 assert_true(cont->flags & LYD_DEFAULT);
305 lyd_free_all(tree);
306
307 data = "<cp xmlns=\"urn:tests:a\"/>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100308 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200309 assert_non_null(tree);
310 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
311 assert_string_equal("cp", tree->schema->name);
312 cont = (struct lyd_node_inner*)tree;
313 assert_false(cont->flags & LYD_DEFAULT);
314 lyd_free_all(tree);
315
316 *state = NULL;
317}
318
Michal Vasko44685da2020-03-17 15:38:06 +0100319static void
320test_opaq(void **state)
321{
322 *state = test_opaq;
323
324 const char *data;
325 char *str;
326 struct lyd_node *tree;
327
Radek Krejci241f6b52020-05-21 18:13:49 +0200328 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200329 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100330
Michal Vasko44685da2020-03-17 15:38:06 +0100331 /* invalid value, no flags */
332 data = "<foo3 xmlns=\"urn:tests:a\"/>";
333 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko1ce933a2020-03-30 12:38:22 +0200334 logbuf_assert("Invalid empty uint32 value. /a:foo3");
Michal Vasko44685da2020-03-17 15:38:06 +0100335 assert_null(tree);
336
337 /* opaq flag */
338 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_OPAQ | LYD_VALOPT_DATA_ONLY, &tree));
339 assert_non_null(tree);
340 assert_null(tree->schema);
341 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "foo3");
342 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
343
Radek Krejcia5bba312020-01-09 15:41:20 +0100344 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko44685da2020-03-17 15:38:06 +0100345 assert_string_equal(str, "<foo3 xmlns=\"urn:tests:a\"/>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200346 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100347 lyd_free_all(tree);
348
349 /* missing key, no flags */
350 data = "<l1 xmlns=\"urn:tests:a\"><a>val_a</a><b>val_b</b><d>val_d</d></l1>";
351 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
352 logbuf_assert("List instance is missing its key \"c\". /a:l1[a='val_a'][b='val_b']");
353 assert_null(tree);
354
355 /* opaq flag */
356 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_OPAQ | LYD_VALOPT_DATA_ONLY, &tree));
357 assert_non_null(tree);
358 assert_null(tree->schema);
359 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "l1");
360 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
361
Radek Krejcia5bba312020-01-09 15:41:20 +0100362 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko44685da2020-03-17 15:38:06 +0100363 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200364 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100365 lyd_free_all(tree);
366
367 /* invalid key, no flags */
368 data = "<l1 xmlns=\"urn:tests:a\"><a>val_a</a><b>val_b</b><c>val_c</c></l1>";
369 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof872e202020-05-27 11:49:06 +0200370 logbuf_assert("Invalid int16 value \"val_c\". /a:l1/c");
Michal Vasko44685da2020-03-17 15:38:06 +0100371 assert_null(tree);
372
373 /* opaq flag */
374 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_OPAQ | LYD_VALOPT_DATA_ONLY, &tree));
375 assert_non_null(tree);
376 assert_null(tree->schema);
377 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "l1");
378 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
379
Radek Krejcia5bba312020-01-09 15:41:20 +0100380 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko44685da2020-03-17 15:38:06 +0100381 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200382 ly_out_reset(out);
Michal Vasko44685da2020-03-17 15:38:06 +0100383 lyd_free_all(tree);
384
Michal Vasko413c7f22020-05-05 12:34:06 +0200385 /* opaq flag and fail */
386 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, "<a xmlns=\"ns\"><b>x</b><c xml:id=\"D\">1</c></a>",
387 LYD_OPT_OPAQ | LYD_VALOPT_DATA_ONLY, &tree));
388 assert_null(tree);
389
Radek Krejci241f6b52020-05-21 18:13:49 +0200390 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100391
Michal Vasko44685da2020-03-17 15:38:06 +0100392 *state = NULL;
393}
394
Michal Vaskob36053d2020-03-26 15:49:30 +0100395static void
396test_rpc(void **state)
397{
398 *state = test_rpc;
399
400 const char *data;
401 char *str;
402 struct lyd_node *tree, *op;
Michal Vasko1bf09392020-03-27 12:38:10 +0100403 const struct lyd_node *node;
Michal Vaskob36053d2020-03-26 15:49:30 +0100404
Radek Krejci241f6b52020-05-21 18:13:49 +0200405 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200406 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100407
Michal Vaskob36053d2020-03-26 15:49:30 +0100408 data =
409 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
410 "<edit-config>"
411 "<target>"
412 "<running/>"
Michal Vaskob36053d2020-03-26 15:49:30 +0100413 "</target>"
Michal Vasko1bf09392020-03-27 12:38:10 +0100414 "<config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
415 "<l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">"
416 "<a>val_a</a>"
417 "<b>val_b</b>"
418 "<c>val_c</c>"
419 "</l1>"
420 "<cp xmlns=\"urn:tests:a\">"
421 "<z nc:operation=\"delete\"/>"
422 "</cp>"
423 "</config>"
Michal Vaskob36053d2020-03-26 15:49:30 +0100424 "</edit-config>"
425 "</rpc>";
Michal Vasko1bf09392020-03-27 12:38:10 +0100426 assert_int_equal(LY_SUCCESS, lyd_parse_xml_rpc(ctx, data, &tree, &op));
427
428 assert_non_null(op);
429 assert_string_equal(op->schema->name, "edit-config");
430
Michal Vaskob36053d2020-03-26 15:49:30 +0100431 assert_non_null(tree);
432 assert_null(tree->schema);
Michal Vasko1bf09392020-03-27 12:38:10 +0100433 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "rpc");
434 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200435 node = lyd_node_children(tree, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100436 assert_string_equal(node->schema->name, "edit-config");
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200437 node = lyd_node_children(node, 0)->next;
Michal Vasko1bf09392020-03-27 12:38:10 +0100438 assert_string_equal(node->schema->name, "config");
439 node = ((struct lyd_node_any *)node)->value.tree;
440 /* l1 key c has invalid value */
441 assert_null(node->schema);
442 assert_string_equal(((struct lyd_node_opaq *)node)->name, "l1");
443 node = node->next;
444 assert_non_null(node->schema);
445 assert_string_equal(node->schema->name, "cp");
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200446 node = lyd_node_children(node, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100447 /* z has no value */
448 assert_null(node->schema);
449 assert_string_equal(((struct lyd_node_opaq *)node)->name, "z");
Michal Vaskob36053d2020-03-26 15:49:30 +0100450
Radek Krejcia5bba312020-01-09 15:41:20 +0100451 lyd_print(out, tree, LYD_XML, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100452 assert_string_equal(str,
453 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
454 "<edit-config>"
455 "<target>"
456 "<running/>"
457 "</target>"
458 "<config>"
459 "<l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">"
460 "<a>val_a</a>"
461 "<b>val_b</b>"
462 "<c>val_c</c>"
463 "</l1>"
464 "<cp xmlns=\"urn:tests:a\">"
465 "<z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>"
466 "</cp>"
467 "</config>"
468 "</edit-config>"
469 "</rpc>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200470 ly_out_reset(out);
Michal Vaskob36053d2020-03-26 15:49:30 +0100471 lyd_free_all(tree);
472
473 /* wrong namespace, element name, whatever... */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100474 /* TODO */
475
Radek Krejci241f6b52020-05-21 18:13:49 +0200476 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100477
Michal Vaskoa8edff02020-03-27 14:47:01 +0100478 *state = NULL;
479}
480
481static void
482test_action(void **state)
483{
484 *state = test_action;
485
486 const char *data;
487 char *str;
488 struct lyd_node *tree, *op;
489 const struct lyd_node *node;
490
Radek Krejci241f6b52020-05-21 18:13:49 +0200491 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200492 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100493
Michal Vaskoa8edff02020-03-27 14:47:01 +0100494 data =
495 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
496 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
497 "<c xmlns=\"urn:tests:a\">"
498 "<act>"
499 "<al>value</al>"
500 "</act>"
501 "</c>"
502 "</action>"
503 "</rpc>";
504 assert_int_equal(LY_SUCCESS, lyd_parse_xml_rpc(ctx, data, &tree, &op));
505
506 assert_non_null(op);
507 assert_string_equal(op->schema->name, "act");
508
509 assert_non_null(tree);
510 assert_null(tree->schema);
511 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "rpc");
512 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200513 node = lyd_node_children(tree, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100514 assert_null(node->schema);
515 assert_string_equal(((struct lyd_node_opaq *)node)->name, "action");
516 assert_null(((struct lyd_node_opaq *)node)->attr);
517
Radek Krejcia5bba312020-01-09 15:41:20 +0100518 lyd_print(out, tree, LYD_XML, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100519 assert_string_equal(str,
520 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\" custom-attr=\"val\">"
521 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
522 "<c xmlns=\"urn:tests:a\">"
523 "<act>"
524 "<al>value</al>"
525 "</act>"
526 "</c>"
527 "</action>"
528 "</rpc>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200529 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100530 lyd_free_all(tree);
531
532 /* wrong namespace, element name, whatever... */
533 /* TODO */
534
Radek Krejci241f6b52020-05-21 18:13:49 +0200535 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100536
Michal Vaskoa8edff02020-03-27 14:47:01 +0100537 *state = NULL;
538}
539
540static void
541test_notification(void **state)
542{
543 *state = test_notification;
544
545 const char *data;
546 char *str;
547 struct lyd_node *tree, *ntf;
548 const struct lyd_node *node;
549
Radek Krejci241f6b52020-05-21 18:13:49 +0200550 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200551 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100552
Michal Vaskoa8edff02020-03-27 14:47:01 +0100553 data =
554 "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">"
555 "<eventTime>2037-07-08T00:01:00Z</eventTime>"
556 "<c xmlns=\"urn:tests:a\">"
557 "<n1>"
558 "<nl>value</nl>"
559 "</n1>"
560 "</c>"
561 "</notification>";
562 assert_int_equal(LY_SUCCESS, lyd_parse_xml_notif(ctx, data, &tree, &ntf));
563
564 assert_non_null(ntf);
565 assert_string_equal(ntf->schema->name, "n1");
566
567 assert_non_null(tree);
568 assert_null(tree->schema);
569 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "notification");
570 assert_null(((struct lyd_node_opaq *)tree)->attr);
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200571 node = lyd_node_children(tree, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100572 assert_null(node->schema);
573 assert_string_equal(((struct lyd_node_opaq *)node)->name, "eventTime");
574 assert_string_equal(((struct lyd_node_opaq *)node)->value, "2037-07-08T00:01:00Z");
575 assert_null(((struct lyd_node_opaq *)node)->attr);
576 node = node->next;
577 assert_non_null(node->schema);
578 assert_string_equal(node->schema->name, "c");
579
Radek Krejcia5bba312020-01-09 15:41:20 +0100580 lyd_print(out, tree, LYD_XML, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100581 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200582 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100583 lyd_free_all(tree);
584
585 /* top-level notif without envelope */
586 data = "<n2 xmlns=\"urn:tests:a\"/>";
587 assert_int_equal(LY_SUCCESS, lyd_parse_xml_notif(ctx, data, &tree, &ntf));
588
589 assert_non_null(ntf);
590 assert_string_equal(ntf->schema->name, "n2");
591
592 assert_non_null(tree);
593 assert_ptr_equal(ntf, tree);
594
Radek Krejcia5bba312020-01-09 15:41:20 +0100595 lyd_print(out, tree, LYD_XML, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100596 assert_string_equal(str, data);
Radek Krejci241f6b52020-05-21 18:13:49 +0200597 ly_out_reset(out);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100598 lyd_free_all(tree);
599
600 /* wrong namespace, element name, whatever... */
601 /* TODO */
Michal Vaskob36053d2020-03-26 15:49:30 +0100602
Radek Krejci241f6b52020-05-21 18:13:49 +0200603 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100604
Michal Vaskob36053d2020-03-26 15:49:30 +0100605 *state = NULL;
606}
607
Michal Vasko1ce933a2020-03-30 12:38:22 +0200608static void
609test_reply(void **state)
610{
611 *state = test_reply;
612
613 const char *data;
614 char *str;
615 struct lyd_node *request, *tree, *op;
616 const struct lyd_node *node;
617
Radek Krejci241f6b52020-05-21 18:13:49 +0200618 struct ly_out *out;
Radek Krejci84ce7b12020-06-11 17:28:25 +0200619 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
Radek Krejcia5bba312020-01-09 15:41:20 +0100620
Michal Vasko1ce933a2020-03-30 12:38:22 +0200621 data =
622 "<c xmlns=\"urn:tests:a\">"
623 "<act>"
624 "<al>value</al>"
625 "</act>"
626 "</c>";
627 assert_int_equal(LY_SUCCESS, lyd_parse_xml_rpc(ctx, data, &request, NULL));
628 data =
629 "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" msgid=\"25\">"
630 "<al xmlns=\"urn:tests:a\">25</al>"
631 "</rpc-reply>";
632 assert_int_equal(LY_SUCCESS, lyd_parse_xml_reply(request, data, &tree, &op));
633 lyd_free_all(request);
634
635 assert_non_null(op);
636 assert_string_equal(op->schema->name, "act");
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200637 node = lyd_node_children(op, 0);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200638 assert_non_null(node->schema);
639 assert_string_equal(node->schema->name, "al");
640 assert_true(node->schema->flags & LYS_CONFIG_R);
641
642 assert_non_null(tree);
643 assert_null(tree->schema);
644 assert_string_equal(((struct lyd_node_opaq *)tree)->name, "rpc-reply");
645 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200646 node = lyd_node_children(tree, 0);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200647 assert_non_null(node->schema);
648 assert_string_equal(node->schema->name, "c");
649
650 /* TODO print only rpc-reply node and then output subtree */
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200651 lyd_print(out, lyd_node_children(op, 0), LYD_XML, 0);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200652 assert_string_equal(str,
653 "<al xmlns=\"urn:tests:a\">25</al>");
Radek Krejci241f6b52020-05-21 18:13:49 +0200654 ly_out_reset(out);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200655 lyd_free_all(tree);
656
657 /* wrong namespace, element name, whatever... */
658 /* TODO */
659
Radek Krejci241f6b52020-05-21 18:13:49 +0200660 ly_out_free(out, NULL, 1);
Radek Krejcia5bba312020-01-09 15:41:20 +0100661
Michal Vasko1ce933a2020-03-30 12:38:22 +0200662 *state = NULL;
663}
664
Radek Krejci509e2592019-05-15 16:30:48 +0200665int main(void)
666{
667 const struct CMUnitTest tests[] = {
668 cmocka_unit_test_setup_teardown(test_leaf, setup, teardown),
Radek Krejciee4cab22019-07-17 17:07:47 +0200669 cmocka_unit_test_setup_teardown(test_anydata, setup, teardown),
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200670 cmocka_unit_test_setup_teardown(test_list, setup, teardown),
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200671 cmocka_unit_test_setup_teardown(test_container, setup, teardown),
Michal Vasko44685da2020-03-17 15:38:06 +0100672 cmocka_unit_test_setup_teardown(test_opaq, setup, teardown),
Michal Vasko1bf09392020-03-27 12:38:10 +0100673 cmocka_unit_test_setup_teardown(test_rpc, setup, teardown),
Michal Vaskoa8edff02020-03-27 14:47:01 +0100674 cmocka_unit_test_setup_teardown(test_action, setup, teardown),
675 cmocka_unit_test_setup_teardown(test_notification, setup, teardown),
Michal Vasko1ce933a2020-03-30 12:38:22 +0200676 cmocka_unit_test_setup_teardown(test_reply, setup, teardown),
Radek Krejci509e2592019-05-15 16:30:48 +0200677 };
678
679 return cmocka_run_group_tests(tests, NULL, NULL);
680}