blob: f7ea330ad07014362b36692e4727adf6946e4ca0 [file] [log] [blame]
Michal Vaskob1b5c262020-03-05 14:29:47 +01001/**
2 * @file test_validation.c
Michal Vaskocde73ac2019-11-14 16:10:27 +01003 * @author: Radek Krejci <rkrejci@cesnet.cz>
Michal Vaskob1b5c262020-03-05 14:29:47 +01004 * @brief unit tests for functions from validation.c
Michal Vaskocde73ac2019-11-14 16:10:27 +01005 *
Michal Vaskob1b5c262020-03-05 14:29:47 +01006 * Copyright (c) 2020 CESNET, z.s.p.o.
Michal Vaskocde73ac2019-11-14 16:10:27 +01007 *
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
Michal Vaskocde73ac2019-11-14 16:10:27 +010017#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
25#include "../../src/context.h"
26#include "../../src/tree_data_internal.h"
Michal Vaskof03ed032020-03-04 13:31:44 +010027#include "../../src/printer_data.h"
Michal Vaskocde73ac2019-11-14 16:10:27 +010028
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 =
62 "module a {"
63 "namespace urn:tests:a;"
64 "prefix a;"
65 "yang-version 1.1;"
66
67 "container cont {"
68 "leaf a {"
69 "when \"../../c = 'val_c'\";"
70 "type string;"
71 "}"
72 "leaf b {"
73 "type string;"
74 "}"
75 "}"
76 "leaf c {"
77 "when \"/cont/b = 'val_b'\";"
78 "type string;"
79 "}"
80 "}";
Michal Vaskoa3881362020-01-21 15:57:35 +010081 const char *schema_b =
82 "module b {"
83 "namespace urn:tests:b;"
84 "prefix b;"
85 "yang-version 1.1;"
86
87 "choice choic {"
88 "mandatory true;"
89 "leaf a {"
90 "type string;"
91 "}"
92 "case b {"
93 "leaf l {"
94 "type string;"
95 "}"
96 "}"
97 "}"
98 "leaf c {"
99 "mandatory true;"
100 "type string;"
101 "}"
102 "leaf d {"
103 "type empty;"
104 "}"
105 "}";
Michal Vaskoacd83e72020-02-04 14:12:01 +0100106 const char *schema_c =
107 "module c {"
108 "namespace urn:tests:c;"
109 "prefix c;"
110 "yang-version 1.1;"
111
112 "choice choic {"
113 "leaf a {"
114 "type string;"
115 "}"
116 "case b {"
117 "leaf-list l {"
118 "min-elements 3;"
119 "type string;"
120 "}"
121 "}"
122 "}"
123 "list lt {"
124 "max-elements 4;"
125 "key \"k\";"
126 "leaf k {"
127 "type string;"
128 "}"
129 "}"
130 "leaf d {"
131 "type empty;"
132 "}"
133 "}";
Michal Vasko14654712020-02-06 08:35:21 +0100134 const char *schema_d =
135 "module d {"
136 "namespace urn:tests:d;"
137 "prefix d;"
138 "yang-version 1.1;"
139
140 "list lt {"
141 "key \"k\";"
142 "unique \"l1\";"
143 "leaf k {"
144 "type string;"
145 "}"
146 "leaf l1 {"
147 "type string;"
148 "}"
149 "}"
150 "list lt2 {"
151 "key \"k\";"
152 "unique \"cont/l2 l4\";"
153 "unique \"l5 l6\";"
154 "leaf k {"
155 "type string;"
156 "}"
157 "container cont {"
158 "leaf l2 {"
159 "type string;"
160 "}"
161 "}"
162 "leaf l4 {"
163 "type string;"
164 "}"
165 "leaf l5 {"
166 "type string;"
167 "}"
168 "leaf l6 {"
169 "type string;"
170 "}"
171 "list lt3 {"
172 "key \"kk\";"
173 "unique \"l3\";"
174 "leaf kk {"
175 "type string;"
176 "}"
177 "leaf l3 {"
178 "type string;"
179 "}"
180 "}"
181 "}"
182 "}";
Michal Vaskof03ed032020-03-04 13:31:44 +0100183 const char *schema_e =
184 "module e {"
185 "namespace urn:tests:e;"
186 "prefix e;"
187 "yang-version 1.1;"
188
189 "choice choic {"
190 "leaf a {"
191 "type string;"
192 "}"
193 "case b {"
194 "leaf-list l {"
195 "type string;"
196 "}"
197 "}"
198 "}"
199 "list lt {"
200 "key \"k\";"
201 "leaf k {"
202 "type string;"
203 "}"
204 "}"
205 "leaf d {"
206 "type uint32;"
207 "}"
208 "leaf-list ll {"
209 "type string;"
210 "}"
211 "container cont {"
212 "list lt {"
213 "key \"k\";"
214 "leaf k {"
215 "type string;"
216 "}"
217 "}"
218 "leaf d {"
219 "type uint32;"
220 "}"
221 "leaf-list ll {"
222 "type string;"
223 "}"
Michal Vasko9f96a052020-03-10 09:41:45 +0100224 "leaf-list ll2 {"
225 "type enumeration {"
226 "enum one;"
227 "enum two;"
228 "}"
229 "}"
Michal Vaskof03ed032020-03-04 13:31:44 +0100230 "}"
231 "}";
232 const char *schema_f =
233 "module f {"
234 "namespace urn:tests:f;"
235 "prefix f;"
236 "yang-version 1.1;"
237
238 "choice choic {"
239 "default \"c\";"
240 "leaf a {"
241 "type string;"
242 "}"
243 "case b {"
244 "leaf l {"
245 "type string;"
246 "}"
247 "}"
248 "case c {"
249 "leaf-list ll1 {"
250 "type string;"
251 "default \"def1\";"
252 "default \"def2\";"
253 "default \"def3\";"
254 "}"
255 "}"
256 "}"
257 "leaf d {"
258 "type uint32;"
259 "default 15;"
260 "}"
261 "leaf-list ll2 {"
262 "type string;"
263 "default \"dflt1\";"
264 "default \"dflt2\";"
265 "}"
266 "container cont {"
267 "choice choic {"
268 "default \"c\";"
269 "leaf a {"
270 "type string;"
271 "}"
272 "case b {"
273 "leaf l {"
274 "type string;"
275 "}"
276 "}"
277 "case c {"
278 "leaf-list ll1 {"
279 "type string;"
280 "default \"def1\";"
281 "default \"def2\";"
282 "default \"def3\";"
283 "}"
284 "}"
285 "}"
286 "leaf d {"
287 "type uint32;"
288 "default 15;"
289 "}"
290 "leaf-list ll2 {"
291 "type string;"
292 "default \"dflt1\";"
293 "default \"dflt2\";"
294 "}"
295 "}"
296 "}";
Michal Vaskoc193ce92020-03-06 11:04:48 +0100297 const char *schema_g =
298 "module g {"
299 "namespace urn:tests:g;"
300 "prefix g;"
301 "yang-version 1.1;"
302
303 "feature f1;"
304 "feature f2;"
305 "feature f3;"
306
307 "container cont {"
308 "if-feature \"f1\";"
309 "choice choic {"
310 "if-feature \"f2 or f3\";"
311 "leaf a {"
312 "type string;"
313 "}"
314 "case b {"
315 "if-feature \"f2 and f1\";"
316 "leaf l {"
317 "type string;"
318 "}"
319 "}"
320 "}"
321 "leaf d {"
322 "type uint32;"
323 "}"
324 "container cont2 {"
325 "if-feature \"f2\";"
326 "leaf e {"
327 "type string;"
328 "}"
329 "}"
330 "}"
331 "}";
Michal Vasko5b37a352020-03-06 13:38:33 +0100332 const char *schema_h =
333 "module h {"
334 "namespace urn:tests:h;"
335 "prefix h;"
336 "yang-version 1.1;"
337
338 "container cont {"
339 "container cont2 {"
340 "config false;"
341 "leaf l {"
342 "type string;"
343 "}"
344 "}"
345 "}"
346 "}";
Michal Vaskocc048b22020-03-27 15:52:38 +0100347 const char *schema_i =
348 "module i {"
349 "namespace urn:tests:i;"
350 "prefix i;"
351 "yang-version 1.1;"
352
353 "container cont {"
354 "leaf l {"
355 "type string;"
356 "}"
357 "leaf l2 {"
358 "must \"../l = 'right'\";"
359 "type string;"
360 "}"
361 "}"
362 "}";
Michal Vaskocde73ac2019-11-14 16:10:27 +0100363
364#if ENABLE_LOGGER_CHECKING
365 ly_set_log_clb(logger, 1);
366#endif
367
Michal Vaskof03ed032020-03-04 13:31:44 +0100368 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &ctx));
369 assert_non_null(ly_ctx_load_module(ctx, "ietf-netconf-with-defaults", "2011-06-01"));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100370 assert_non_null(lys_parse_mem(ctx, schema_a, LYS_IN_YANG));
Michal Vaskoa3881362020-01-21 15:57:35 +0100371 assert_non_null(lys_parse_mem(ctx, schema_b, LYS_IN_YANG));
Michal Vaskoacd83e72020-02-04 14:12:01 +0100372 assert_non_null(lys_parse_mem(ctx, schema_c, LYS_IN_YANG));
Michal Vasko14654712020-02-06 08:35:21 +0100373 assert_non_null(lys_parse_mem(ctx, schema_d, LYS_IN_YANG));
Michal Vaskof03ed032020-03-04 13:31:44 +0100374 assert_non_null(lys_parse_mem(ctx, schema_e, LYS_IN_YANG));
375 assert_non_null(lys_parse_mem(ctx, schema_f, LYS_IN_YANG));
Michal Vaskoc193ce92020-03-06 11:04:48 +0100376 assert_non_null(lys_parse_mem(ctx, schema_g, LYS_IN_YANG));
Michal Vasko5b37a352020-03-06 13:38:33 +0100377 assert_non_null(lys_parse_mem(ctx, schema_h, LYS_IN_YANG));
Michal Vaskocc048b22020-03-27 15:52:38 +0100378 assert_non_null(lys_parse_mem(ctx, schema_i, LYS_IN_YANG));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100379
380 return 0;
381}
382
383static int
384teardown(void **state)
385{
Michal Vaskoacd83e72020-02-04 14:12:01 +0100386 (void)state;
387 ly_ctx_destroy(ctx, NULL);
388 ctx = NULL;
389
390 return 0;
391}
392
393static int
394teardown_s(void **state)
395{
Michal Vaskocde73ac2019-11-14 16:10:27 +0100396#if ENABLE_LOGGER_CHECKING
397 if (*state) {
398 fprintf(stderr, "%s\n", logbuf);
399 }
400#else
401 (void) state; /* unused */
402#endif
403
Michal Vaskocde73ac2019-11-14 16:10:27 +0100404 return 0;
405}
406
407void
408logbuf_clean(void)
409{
410 logbuf[0] = '\0';
411}
412
413#if ENABLE_LOGGER_CHECKING
414# define logbuf_assert(str) assert_string_equal(logbuf, str)
415#else
416# define logbuf_assert(str)
417#endif
418
419static void
420test_when(void **state)
421{
422 *state = test_when;
423
424 const char *data;
425 struct lyd_node *tree;
426
427 data = "<c xmlns=\"urn:tests:a\">hey</c>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100428 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100429 assert_null(tree);
Michal Vasko9b368d32020-02-14 13:53:31 +0100430 logbuf_assert("When condition \"/cont/b = 'val_b'\" not satisfied. /a:c");
Michal Vaskocde73ac2019-11-14 16:10:27 +0100431
432 data = "<cont xmlns=\"urn:tests:a\"><b>val_b</b></cont><c xmlns=\"urn:tests:a\">hey</c>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100433 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100434 assert_non_null(tree);
435 assert_string_equal("c", tree->next->schema->name);
436 assert_int_equal(LYD_WHEN_TRUE, tree->next->flags);
437 lyd_free_all(tree);
438
439 data = "<cont xmlns=\"urn:tests:a\"><a>val</a><b>val_b</b></cont><c xmlns=\"urn:tests:a\">val_c</c>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100440 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100441 assert_non_null(tree);
442 assert_string_equal("a", lyd_node_children(tree)->schema->name);
443 assert_int_equal(LYD_WHEN_TRUE, lyd_node_children(tree)->flags);
444 assert_string_equal("c", tree->next->schema->name);
445 assert_int_equal(LYD_WHEN_TRUE, tree->next->flags);
446 lyd_free_all(tree);
447
448 *state = NULL;
449}
450
Michal Vaskoa3881362020-01-21 15:57:35 +0100451static void
452test_mandatory(void **state)
453{
454 *state = test_mandatory;
455
456 const char *data;
457 struct lyd_node *tree;
458
459 data = "<d xmlns=\"urn:tests:b\"/>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100460 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoa3881362020-01-21 15:57:35 +0100461 assert_null(tree);
462 logbuf_assert("Mandatory node \"choic\" instance does not exist. /b:choic");
463
464 data = "<l xmlns=\"urn:tests:b\">string</l><d xmlns=\"urn:tests:b\"/>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100465 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoa3881362020-01-21 15:57:35 +0100466 assert_null(tree);
467 logbuf_assert("Mandatory node \"c\" instance does not exist. /b:c");
468
469 data = "<a xmlns=\"urn:tests:b\">string</a>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100470 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoa3881362020-01-21 15:57:35 +0100471 assert_null(tree);
472 logbuf_assert("Mandatory node \"c\" instance does not exist. /b:c");
473
474 data = "<a xmlns=\"urn:tests:b\">string</a><c xmlns=\"urn:tests:b\">string2</c>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100475 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoa3881362020-01-21 15:57:35 +0100476 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100477 lyd_free_siblings(tree);
Michal Vaskoa3881362020-01-21 15:57:35 +0100478
479 *state = NULL;
480}
481
Michal Vaskoacd83e72020-02-04 14:12:01 +0100482static void
483test_minmax(void **state)
484{
485 *state = test_minmax;
486
487 const char *data;
488 struct lyd_node *tree;
489
490 data = "<d xmlns=\"urn:tests:c\"/>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100491 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoacd83e72020-02-04 14:12:01 +0100492 assert_null(tree);
493 logbuf_assert("Too few \"l\" instances. /c:choic/b/l");
494
495 data =
496 "<l xmlns=\"urn:tests:c\">val1</l>"
497 "<l xmlns=\"urn:tests:c\">val2</l>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100498 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoacd83e72020-02-04 14:12:01 +0100499 assert_null(tree);
500 logbuf_assert("Too few \"l\" instances. /c:choic/b/l");
501
502 data =
503 "<l xmlns=\"urn:tests:c\">val1</l>"
504 "<l xmlns=\"urn:tests:c\">val2</l>"
505 "<l xmlns=\"urn:tests:c\">val3</l>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100506 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoacd83e72020-02-04 14:12:01 +0100507 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100508 lyd_free_siblings(tree);
Michal Vaskoacd83e72020-02-04 14:12:01 +0100509
510 data =
511 "<l xmlns=\"urn:tests:c\">val1</l>"
512 "<l xmlns=\"urn:tests:c\">val2</l>"
513 "<l xmlns=\"urn:tests:c\">val3</l>"
514 "<lt xmlns=\"urn:tests:c\"><k>val1</k></lt>"
515 "<lt xmlns=\"urn:tests:c\"><k>val2</k></lt>"
516 "<lt xmlns=\"urn:tests:c\"><k>val3</k></lt>"
517 "<lt xmlns=\"urn:tests:c\"><k>val4</k></lt>"
518 "<lt xmlns=\"urn:tests:c\"><k>val5</k></lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100519 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoacd83e72020-02-04 14:12:01 +0100520 assert_null(tree);
521 logbuf_assert("Too many \"lt\" instances. /c:lt");
522
523 *state = NULL;
524}
525
Michal Vasko14654712020-02-06 08:35:21 +0100526static void
527test_unique(void **state)
528{
529 *state = test_unique;
530
531 const char *data;
532 struct lyd_node *tree;
533
534 data =
535 "<lt xmlns=\"urn:tests:d\">"
536 "<k>val1</k>"
537 "<l1>same</l1>"
538 "</lt>"
539 "<lt xmlns=\"urn:tests:d\">"
540 "<k>val2</k>"
541 "</lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100542 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100543 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100544 lyd_free_siblings(tree);
Michal Vasko14654712020-02-06 08:35:21 +0100545
546 data =
547 "<lt xmlns=\"urn:tests:d\">"
548 "<k>val1</k>"
549 "<l1>same</l1>"
550 "</lt>"
551 "<lt xmlns=\"urn:tests:d\">"
552 "<k>val2</k>"
553 "<l1>not-same</l1>"
554 "</lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100555 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100556 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100557 lyd_free_siblings(tree);
Michal Vasko14654712020-02-06 08:35:21 +0100558
559 data =
560 "<lt xmlns=\"urn:tests:d\">"
561 "<k>val1</k>"
562 "<l1>same</l1>"
563 "</lt>"
564 "<lt xmlns=\"urn:tests:d\">"
565 "<k>val2</k>"
566 "<l1>same</l1>"
567 "</lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100568 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100569 assert_null(tree);
Michal Vasko9b368d32020-02-14 13:53:31 +0100570 logbuf_assert("Unique data leaf(s) \"l1\" not satisfied in \"/d:lt[k='val1']\" and \"/d:lt[k='val2']\". /d:lt[k='val2']");
Michal Vasko14654712020-02-06 08:35:21 +0100571
572 /* now try with more instances */
573 data =
574 "<lt xmlns=\"urn:tests:d\">"
575 "<k>val1</k>"
576 "<l1>1</l1>"
577 "</lt>"
578 "<lt xmlns=\"urn:tests:d\">"
579 "<k>val2</k>"
580 "<l1>2</l1>"
581 "</lt>"
582 "<lt xmlns=\"urn:tests:d\">"
583 "<k>val3</k>"
584 "<l1>3</l1>"
585 "</lt>"
586 "<lt xmlns=\"urn:tests:d\">"
587 "<k>val4</k>"
588 "<l1>4</l1>"
589 "</lt>"
590 "<lt xmlns=\"urn:tests:d\">"
591 "<k>val5</k>"
592 "<l1>5</l1>"
593 "</lt>"
594 "<lt xmlns=\"urn:tests:d\">"
595 "<k>val6</k>"
596 "<l1>6</l1>"
597 "</lt>"
598 "<lt xmlns=\"urn:tests:d\">"
599 "<k>val7</k>"
600 "<l1>7</l1>"
601 "</lt>"
602 "<lt xmlns=\"urn:tests:d\">"
603 "<k>val8</k>"
604 "<l1>8</l1>"
605 "</lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100606 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100607 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100608 lyd_free_siblings(tree);
Michal Vasko14654712020-02-06 08:35:21 +0100609
610 data =
611 "<lt xmlns=\"urn:tests:d\">"
612 "<k>val1</k>"
613 "<l1>1</l1>"
614 "</lt>"
615 "<lt xmlns=\"urn:tests:d\">"
616 "<k>val2</k>"
617 "<l1>2</l1>"
618 "</lt>"
619 "<lt xmlns=\"urn:tests:d\">"
620 "<k>val3</k>"
621 "<l1>3</l1>"
622 "</lt>"
623 "<lt xmlns=\"urn:tests:d\">"
624 "<k>val4</k>"
625 "</lt>"
626 "<lt xmlns=\"urn:tests:d\">"
627 "<k>val5</k>"
628 "<l1>5</l1>"
629 "</lt>"
630 "<lt xmlns=\"urn:tests:d\">"
631 "<k>val6</k>"
632 "<l1>6</l1>"
633 "</lt>"
634 "<lt xmlns=\"urn:tests:d\">"
635 "<k>val7</k>"
636 "</lt>"
637 "<lt xmlns=\"urn:tests:d\">"
638 "<k>val8</k>"
639 "</lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100640 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100641 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100642 lyd_free_siblings(tree);
Michal Vasko14654712020-02-06 08:35:21 +0100643
644 data =
645 "<lt xmlns=\"urn:tests:d\">"
646 "<k>val1</k>"
647 "<l1>1</l1>"
648 "</lt>"
649 "<lt xmlns=\"urn:tests:d\">"
650 "<k>val2</k>"
651 "<l1>2</l1>"
652 "</lt>"
653 "<lt xmlns=\"urn:tests:d\">"
654 "<k>val3</k>"
655 "</lt>"
656 "<lt xmlns=\"urn:tests:d\">"
657 "<k>val4</k>"
658 "<l1>4</l1>"
659 "</lt>"
660 "<lt xmlns=\"urn:tests:d\">"
661 "<k>val5</k>"
662 "</lt>"
663 "<lt xmlns=\"urn:tests:d\">"
664 "<k>val6</k>"
665 "</lt>"
666 "<lt xmlns=\"urn:tests:d\">"
667 "<k>val7</k>"
668 "<l1>2</l1>"
669 "</lt>"
670 "<lt xmlns=\"urn:tests:d\">"
671 "<k>val8</k>"
672 "<l1>8</l1>"
673 "</lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100674 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100675 assert_null(tree);
Michal Vasko9b368d32020-02-14 13:53:31 +0100676 logbuf_assert("Unique data leaf(s) \"l1\" not satisfied in \"/d:lt[k='val7']\" and \"/d:lt[k='val2']\". /d:lt[k='val2']");
Michal Vasko14654712020-02-06 08:35:21 +0100677
678 *state = NULL;
679}
680
681static void
682test_unique_nested(void **state)
683{
684 *state = test_unique_nested;
685
686 const char *data;
687 struct lyd_node *tree;
688
689 /* nested list uniquest are compared only with instances in the same parent list instance */
690 data =
691 "<lt2 xmlns=\"urn:tests:d\">"
692 "<k>val1</k>"
693 "<cont>"
694 "<l2>1</l2>"
695 "</cont>"
696 "<l4>1</l4>"
697 "</lt2>"
698 "<lt2 xmlns=\"urn:tests:d\">"
699 "<k>val2</k>"
700 "<cont>"
701 "<l2>2</l2>"
702 "</cont>"
703 "<l4>2</l4>"
704 "<lt3>"
705 "<kk>val1</kk>"
706 "<l3>1</l3>"
707 "</lt3>"
708 "<lt3>"
709 "<kk>val2</kk>"
710 "<l3>2</l3>"
711 "</lt3>"
712 "</lt2>"
713 "<lt2 xmlns=\"urn:tests:d\">"
714 "<k>val3</k>"
715 "<cont>"
716 "<l2>3</l2>"
717 "</cont>"
718 "<l4>3</l4>"
719 "<lt3>"
720 "<kk>val1</kk>"
721 "<l3>2</l3>"
722 "</lt3>"
723 "</lt2>"
724 "<lt2 xmlns=\"urn:tests:d\">"
725 "<k>val4</k>"
726 "<cont>"
727 "<l2>4</l2>"
728 "</cont>"
729 "<l4>4</l4>"
730 "<lt3>"
731 "<kk>val1</kk>"
732 "<l3>3</l3>"
733 "</lt3>"
734 "</lt2>"
735 "<lt2 xmlns=\"urn:tests:d\">"
736 "<k>val5</k>"
737 "<cont>"
738 "<l2>5</l2>"
739 "</cont>"
740 "<l4>5</l4>"
741 "<lt3>"
742 "<kk>val1</kk>"
743 "<l3>3</l3>"
744 "</lt3>"
745 "</lt2>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100746 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY | LYD_OPT_STRICT, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100747 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100748 lyd_free_siblings(tree);
Michal Vasko14654712020-02-06 08:35:21 +0100749
750 data =
751 "<lt2 xmlns=\"urn:tests:d\">"
752 "<k>val1</k>"
753 "<cont>"
754 "<l2>1</l2>"
755 "</cont>"
756 "<l4>1</l4>"
757 "</lt2>"
758 "<lt2 xmlns=\"urn:tests:d\">"
759 "<k>val2</k>"
760 "<cont>"
761 "<l2>2</l2>"
762 "</cont>"
763 "<lt3>"
764 "<kk>val1</kk>"
765 "<l3>1</l3>"
766 "</lt3>"
767 "<lt3>"
768 "<kk>val2</kk>"
769 "<l3>2</l3>"
770 "</lt3>"
771 "<lt3>"
772 "<kk>val3</kk>"
773 "<l3>1</l3>"
774 "</lt3>"
775 "</lt2>"
776 "<lt2 xmlns=\"urn:tests:d\">"
777 "<k>val3</k>"
778 "<cont>"
779 "<l2>3</l2>"
780 "</cont>"
781 "<l4>1</l4>"
782 "<lt3>"
783 "<kk>val1</kk>"
784 "<l3>2</l3>"
785 "</lt3>"
786 "</lt2>"
787 "<lt2 xmlns=\"urn:tests:d\">"
788 "<k>val4</k>"
789 "<cont>"
790 "<l2>4</l2>"
791 "</cont>"
792 "<lt3>"
793 "<kk>val1</kk>"
794 "<l3>3</l3>"
795 "</lt3>"
796 "</lt2>"
797 "<lt2 xmlns=\"urn:tests:d\">"
798 "<k>val5</k>"
799 "<cont>"
800 "<l2>5</l2>"
801 "</cont>"
802 "<lt3>"
803 "<kk>val1</kk>"
804 "<l3>3</l3>"
805 "</lt3>"
806 "</lt2>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100807 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100808 assert_null(tree);
809 logbuf_assert("Unique data leaf(s) \"l3\" not satisfied in \"/d:lt2[k='val2']/lt3[kk='val3']\" and"
Michal Vasko9b368d32020-02-14 13:53:31 +0100810 " \"/d:lt2[k='val2']/lt3[kk='val1']\". /d:lt2[k='val2']/lt3[kk='val1']");
Michal Vasko14654712020-02-06 08:35:21 +0100811
812 data =
813 "<lt2 xmlns=\"urn:tests:d\">"
814 "<k>val1</k>"
815 "<cont>"
816 "<l2>1</l2>"
817 "</cont>"
818 "<l4>1</l4>"
819 "</lt2>"
820 "<lt2 xmlns=\"urn:tests:d\">"
821 "<k>val2</k>"
822 "<cont>"
823 "<l2>2</l2>"
824 "</cont>"
825 "<l4>2</l4>"
826 "</lt2>"
827 "<lt2 xmlns=\"urn:tests:d\">"
828 "<k>val3</k>"
829 "<cont>"
830 "<l2>3</l2>"
831 "</cont>"
832 "<l4>3</l4>"
833 "</lt2>"
834 "<lt2 xmlns=\"urn:tests:d\">"
835 "<k>val4</k>"
836 "<cont>"
837 "<l2>2</l2>"
838 "</cont>"
839 "<l4>2</l4>"
840 "</lt2>"
841 "<lt2 xmlns=\"urn:tests:d\">"
842 "<k>val5</k>"
843 "<cont>"
844 "<l2>5</l2>"
845 "</cont>"
846 "<l4>5</l4>"
847 "</lt2>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100848 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100849 assert_null(tree);
Michal Vasko9b368d32020-02-14 13:53:31 +0100850 logbuf_assert("Unique data leaf(s) \"cont/l2 l4\" not satisfied in \"/d:lt2[k='val4']\" and \"/d:lt2[k='val2']\". /d:lt2[k='val2']");
Michal Vasko14654712020-02-06 08:35:21 +0100851
852 data =
853 "<lt2 xmlns=\"urn:tests:d\">"
854 "<k>val1</k>"
855 "<cont>"
856 "<l2>1</l2>"
857 "</cont>"
858 "<l4>1</l4>"
859 "<l5>1</l5>"
860 "<l6>1</l6>"
861 "</lt2>"
862 "<lt2 xmlns=\"urn:tests:d\">"
863 "<k>val2</k>"
864 "<cont>"
865 "<l2>2</l2>"
866 "</cont>"
867 "<l4>1</l4>"
868 "<l5>1</l5>"
869 "</lt2>"
870 "<lt2 xmlns=\"urn:tests:d\">"
871 "<k>val3</k>"
872 "<cont>"
873 "<l2>3</l2>"
874 "</cont>"
875 "<l4>1</l4>"
876 "<l5>3</l5>"
877 "<l6>3</l6>"
878 "</lt2>"
879 "<lt2 xmlns=\"urn:tests:d\">"
880 "<k>val4</k>"
881 "<cont>"
882 "<l2>4</l2>"
883 "</cont>"
884 "<l4>1</l4>"
885 "<l6>1</l6>"
886 "</lt2>"
887 "<lt2 xmlns=\"urn:tests:d\">"
888 "<k>val5</k>"
889 "<cont>"
890 "<l2>5</l2>"
891 "</cont>"
892 "<l4>1</l4>"
893 "<l5>3</l5>"
894 "<l6>3</l6>"
895 "</lt2>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100896 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100897 assert_null(tree);
Michal Vasko9b368d32020-02-14 13:53:31 +0100898 logbuf_assert("Unique data leaf(s) \"l5 l6\" not satisfied in \"/d:lt2[k='val5']\" and \"/d:lt2[k='val3']\". /d:lt2[k='val3']");
Michal Vasko14654712020-02-06 08:35:21 +0100899
900 *state = NULL;
901}
902
Michal Vaskof03ed032020-03-04 13:31:44 +0100903static void
904test_dup(void **state)
905{
906 *state = test_dup;
907
908 const char *data;
909 struct lyd_node *tree;
910
911 data = "<d xmlns=\"urn:tests:e\">25</d><d xmlns=\"urn:tests:e\">50</d>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100912 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100913 assert_null(tree);
914 logbuf_assert("Duplicate instance of \"d\". /e:d");
915
916 data = "<lt xmlns=\"urn:tests:e\"><k>A</k></lt><lt xmlns=\"urn:tests:e\"><k>B</k></lt><lt xmlns=\"urn:tests:e\"><k>A</k></lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100917 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100918 assert_null(tree);
919 logbuf_assert("Duplicate instance of \"lt\". /e:lt[k='A']");
920
921 data = "<ll xmlns=\"urn:tests:e\">A</ll><ll xmlns=\"urn:tests:e\">B</ll><ll xmlns=\"urn:tests:e\">B</ll>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100922 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100923 assert_null(tree);
924 logbuf_assert("Duplicate instance of \"ll\". /e:ll[.='B']");
925
926 data = "<cont xmlns=\"urn:tests:e\"></cont><cont xmlns=\"urn:tests:e\"/>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100927 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100928 assert_null(tree);
929 logbuf_assert("Duplicate instance of \"cont\". /e:cont");
930
931 /* same tests again but using hashes */
932 data = "<cont xmlns=\"urn:tests:e\"><d>25</d><d>50</d><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll></cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100933 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100934 assert_null(tree);
935 logbuf_assert("Duplicate instance of \"d\". /e:cont/d");
936
937 data = "<cont xmlns=\"urn:tests:e\"><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll>"
938 "<lt><k>a</k></lt><lt><k>b</k></lt><lt><k>c</k></lt><lt><k>d</k></lt><lt><k>c</k></lt></cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100939 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100940 assert_null(tree);
941 logbuf_assert("Duplicate instance of \"lt\". /e:cont/lt[k='c']");
942
943 data = "<cont xmlns=\"urn:tests:e\"><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll>"
944 "<ll>a</ll><ll>b</ll><ll>c</ll><ll>d</ll><ll>d</ll></cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100945 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100946 assert_null(tree);
947 logbuf_assert("Duplicate instance of \"ll\". /e:cont/ll[.='d']");
948
949 /* cases */
950 data = "<l xmlns=\"urn:tests:e\">a</l><l xmlns=\"urn:tests:e\">b</l><l xmlns=\"urn:tests:e\">c</l><l xmlns=\"urn:tests:e\">b</l>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100951 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100952 assert_null(tree);
953 logbuf_assert("Duplicate instance of \"l\". /e:l[.='b']");
954
955 data = "<l xmlns=\"urn:tests:e\">a</l><l xmlns=\"urn:tests:e\">b</l><l xmlns=\"urn:tests:e\">c</l><a xmlns=\"urn:tests:e\">aa</a>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100956 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100957 assert_null(tree);
958 logbuf_assert("Data for both cases \"a\" and \"b\" exist. /e:choic");
959
960 *state = NULL;
961}
962
963static void
964test_defaults(void **state)
965{
966 *state = test_defaults;
967
Michal Vaskof03ed032020-03-04 13:31:44 +0100968 char *str;
969 struct lyd_node *tree, *node;
970 const struct lys_module *mod = ly_ctx_get_module_latest(ctx, "f");
971
Michal Vaskob1b5c262020-03-05 14:29:47 +0100972 /* get defaults */
973 tree = NULL;
974 assert_int_equal(lyd_validate_modules(&tree, &mod, 1, 0), LY_SUCCESS);
Michal Vaskof03ed032020-03-04 13:31:44 +0100975 assert_non_null(tree);
976
977 /* check all defaults exist */
978 lyd_print_mem(&str, tree, LYD_XML, LYDP_WITHSIBLINGS | LYDP_WD_IMPL_TAG);
979 assert_string_equal(str,
Michal Vaskof03ed032020-03-04 13:31:44 +0100980 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>"
981 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>"
982 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>"
983 "<d xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
984 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
Michal Vaskob1b5c262020-03-05 14:29:47 +0100985 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>"
Michal Vasko52927e22020-03-16 17:26:14 +0100986 "<cont xmlns=\"urn:tests:f\">"
987 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>"
988 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>"
989 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>"
990 "<d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
991 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
992 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>"
Michal Vaskob1b5c262020-03-05 14:29:47 +0100993 "</cont>");
Michal Vaskof03ed032020-03-04 13:31:44 +0100994 free(str);
995
996 /* create another explicit case and validate */
997 node = lyd_new_term(NULL, mod, "l", "value");
998 assert_non_null(node);
Michal Vaskob1b5c262020-03-05 14:29:47 +0100999 assert_int_equal(lyd_insert_sibling(tree, node), LY_SUCCESS);
1000 assert_int_equal(lyd_validate(&tree, ctx, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
Michal Vaskof03ed032020-03-04 13:31:44 +01001001
1002 /* check data tree */
1003 lyd_print_mem(&str, tree, LYD_XML, LYDP_WITHSIBLINGS | LYDP_WD_IMPL_TAG);
1004 assert_string_equal(str,
Michal Vaskob1b5c262020-03-05 14:29:47 +01001005 "<d xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
1006 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
1007 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>"
Michal Vasko52927e22020-03-16 17:26:14 +01001008 "<cont xmlns=\"urn:tests:f\">"
1009 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>"
1010 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>"
1011 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>"
1012 "<d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
1013 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
1014 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>"
Michal Vaskof03ed032020-03-04 13:31:44 +01001015 "</cont>"
Michal Vaskof03ed032020-03-04 13:31:44 +01001016 "<l xmlns=\"urn:tests:f\">value</l>");
1017 free(str);
1018
1019 /* create explicit leaf-list and leaf and validate */
1020 node = lyd_new_term(NULL, mod, "d", "15");
1021 assert_non_null(node);
Michal Vaskob1b5c262020-03-05 14:29:47 +01001022 assert_int_equal(lyd_insert_sibling(tree, node), LY_SUCCESS);
Michal Vaskof03ed032020-03-04 13:31:44 +01001023 node = lyd_new_term(NULL, mod, "ll2", "dflt2");
1024 assert_non_null(node);
Michal Vaskob1b5c262020-03-05 14:29:47 +01001025 assert_int_equal(lyd_insert_sibling(tree, node), LY_SUCCESS);
1026 assert_int_equal(lyd_validate(&tree, ctx, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
Michal Vaskof03ed032020-03-04 13:31:44 +01001027
1028 /* check data tree */
1029 lyd_print_mem(&str, tree, LYD_XML, LYDP_WITHSIBLINGS | LYDP_WD_IMPL_TAG);
1030 assert_string_equal(str,
Michal Vasko52927e22020-03-16 17:26:14 +01001031 "<cont xmlns=\"urn:tests:f\">"
1032 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>"
1033 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>"
1034 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>"
1035 "<d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
1036 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
1037 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>"
Michal Vaskof03ed032020-03-04 13:31:44 +01001038 "</cont>"
1039 "<l xmlns=\"urn:tests:f\">value</l>"
1040 "<d xmlns=\"urn:tests:f\">15</d>"
1041 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>");
1042 free(str);
1043
Michal Vaskob1b5c262020-03-05 14:29:47 +01001044 /* create first explicit container, which should become implicit */
1045 node = lyd_new_inner(NULL, mod, "cont");
1046 assert_non_null(node);
1047 assert_int_equal(lyd_insert_before(tree, node), LY_SUCCESS);
1048 tree = tree->prev;
1049 assert_int_equal(lyd_validate(&tree, ctx, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
1050
1051 /* check data tree */
1052 lyd_print_mem(&str, tree, LYD_XML, LYDP_WITHSIBLINGS | LYDP_WD_IMPL_TAG);
1053 assert_string_equal(str,
Michal Vasko52927e22020-03-16 17:26:14 +01001054 "<cont xmlns=\"urn:tests:f\">"
1055 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>"
1056 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>"
1057 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>"
1058 "<d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
1059 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
1060 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>"
Michal Vaskob1b5c262020-03-05 14:29:47 +01001061 "</cont>"
1062 "<l xmlns=\"urn:tests:f\">value</l>"
1063 "<d xmlns=\"urn:tests:f\">15</d>"
1064 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>");
1065 free(str);
1066
1067 /* create second explicit container, which should become implicit, so the first tree node should be removed */
1068 node = lyd_new_inner(NULL, mod, "cont");
1069 assert_non_null(node);
1070 assert_int_equal(lyd_insert_after(tree, node), LY_SUCCESS);
1071 assert_int_equal(lyd_validate(&tree, ctx, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
1072
1073 /* check data tree */
1074 lyd_print_mem(&str, tree, LYD_XML, LYDP_WITHSIBLINGS | LYDP_WD_IMPL_TAG);
1075 assert_string_equal(str,
Michal Vasko52927e22020-03-16 17:26:14 +01001076 "<cont xmlns=\"urn:tests:f\">"
1077 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>"
1078 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>"
1079 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>"
1080 "<d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
1081 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
1082 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>"
Michal Vaskob1b5c262020-03-05 14:29:47 +01001083 "</cont>"
1084 "<l xmlns=\"urn:tests:f\">value</l>"
1085 "<d xmlns=\"urn:tests:f\">15</d>"
1086 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>");
1087 free(str);
Michal Vaskof03ed032020-03-04 13:31:44 +01001088
1089 /* similar changes for nested defaults */
1090 assert_non_null(lyd_new_term(tree, NULL, "ll1", "def3"));
1091 assert_non_null(lyd_new_term(tree, NULL, "d", "5"));
1092 assert_non_null(lyd_new_term(tree, NULL, "ll2", "non-dflt"));
Michal Vaskob1b5c262020-03-05 14:29:47 +01001093 assert_int_equal(lyd_validate(&tree, ctx, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
Michal Vaskof03ed032020-03-04 13:31:44 +01001094
1095 /* check data tree */
1096 lyd_print_mem(&str, tree, LYD_XML, LYDP_WITHSIBLINGS | LYDP_WD_IMPL_TAG);
1097 assert_string_equal(str,
Michal Vasko52927e22020-03-16 17:26:14 +01001098 "<cont xmlns=\"urn:tests:f\">"
Michal Vaskof03ed032020-03-04 13:31:44 +01001099 "<ll1>def3</ll1>"
1100 "<d>5</d>"
1101 "<ll2>non-dflt</ll2>"
1102 "</cont>"
1103 "<l xmlns=\"urn:tests:f\">value</l>"
1104 "<d xmlns=\"urn:tests:f\">15</d>"
1105 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>");
1106 free(str);
1107
1108 lyd_free_siblings(tree);
1109
1110 *state = NULL;
1111}
1112
Michal Vaskoc193ce92020-03-06 11:04:48 +01001113static void
1114test_iffeature(void **state)
1115{
1116 *state = test_iffeature;
1117
1118 const char *data;
1119 struct lyd_node *tree;
1120 const struct lys_module *mod = ly_ctx_get_module_latest(ctx, "g");
1121
1122 /* get empty data */
1123 tree = NULL;
1124 assert_int_equal(lyd_validate_modules(&tree, &mod, 1, 0), LY_SUCCESS);
1125 assert_null(tree);
1126
1127 /* disabled by f1 */
1128 data =
1129 "<cont xmlns=\"urn:tests:g\">"
1130 "<d>51</d>"
1131 "</cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +01001132 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001133 assert_null(tree);
1134 logbuf_assert("Data are disabled by \"cont\" schema node if-feature. /g:cont");
1135
1136 /* enable f1 */
1137 assert_int_equal(lys_feature_enable(mod, "f1"), LY_SUCCESS);
1138
1139 /* get data with default container */
1140 assert_int_equal(lyd_validate_modules(&tree, &mod, 1, 0), LY_SUCCESS);
1141 assert_non_null(tree);
1142 lyd_free_siblings(tree);
1143
1144 /* disabled by f2 */
1145 data =
1146 "<cont xmlns=\"urn:tests:g\">"
1147 "<cont2>"
1148 "<e>val</e>"
1149 "</cont2>"
1150 "</cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +01001151 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001152 assert_null(tree);
1153 logbuf_assert("Data are disabled by \"cont2\" schema node if-feature. /g:cont/cont2");
1154
1155 data =
1156 "<cont xmlns=\"urn:tests:g\">"
1157 "<a>val</a>"
1158 "</cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +01001159 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001160 assert_null(tree);
1161 logbuf_assert("Data are disabled by \"choic\" schema node if-feature. /g:cont/a");
1162
1163 /* enable f3 */
1164 assert_int_equal(lys_feature_enable(mod, "f3"), LY_SUCCESS);
1165
Michal Vasko9f96a052020-03-10 09:41:45 +01001166 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001167 assert_non_null(tree);
1168 lyd_free_siblings(tree);
1169
1170 /* disabled by f2 */
1171 data =
1172 "<cont xmlns=\"urn:tests:g\">"
1173 "<l>val</l>"
1174 "</cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +01001175 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001176 assert_null(tree);
1177 logbuf_assert("Data are disabled by \"b\" schema node if-feature. /g:cont/l");
1178
1179 /* enable f2 */
1180 assert_int_equal(lys_feature_enable(mod, "f2"), LY_SUCCESS);
1181
Michal Vasko9f96a052020-03-10 09:41:45 +01001182 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001183 assert_non_null(tree);
1184 lyd_free_siblings(tree);
1185
1186 /* try separate validation */
1187 assert_int_equal(lys_feature_disable(mod, "f1"), LY_SUCCESS);
1188 assert_int_equal(lys_feature_disable(mod, "f2"), LY_SUCCESS);
1189 assert_int_equal(lys_feature_disable(mod, "f3"), LY_SUCCESS);
1190
1191 data =
1192 "<cont xmlns=\"urn:tests:g\">"
1193 "<l>val</l>"
1194 "<d>51</d>"
1195 "<cont2>"
1196 "<e>val</e>"
1197 "</cont2>"
1198 "</cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +01001199 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_PARSE_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001200 assert_non_null(tree);
1201
1202 assert_int_equal(LY_EVALID, lyd_validate(&tree, NULL, LYD_VALOPT_DATA_ONLY));
1203 logbuf_assert("Data are disabled by \"cont\" schema node if-feature. /g:cont");
1204
1205 assert_int_equal(lys_feature_enable(mod, "f1"), LY_SUCCESS);
1206
1207 assert_int_equal(LY_EVALID, lyd_validate(&tree, NULL, LYD_VALOPT_DATA_ONLY));
1208 logbuf_assert("Data are disabled by \"b\" schema node if-feature. /g:cont/l");
1209
1210 assert_int_equal(lys_feature_enable(mod, "f2"), LY_SUCCESS);
1211
1212 assert_int_equal(LY_SUCCESS, lyd_validate(&tree, NULL, LYD_VALOPT_DATA_ONLY));
1213
1214 lyd_free_siblings(tree);
1215
1216 *state = NULL;
1217}
1218
Michal Vasko5b37a352020-03-06 13:38:33 +01001219static void
1220test_state(void **state)
1221{
Michal Vaskocc048b22020-03-27 15:52:38 +01001222 *state = test_state;
Michal Vasko5b37a352020-03-06 13:38:33 +01001223
1224 const char *data;
1225 struct lyd_node *tree;
1226
1227 data =
1228 "<cont xmlns=\"urn:tests:h\">"
1229 "<cont2>"
1230 "<l>val</l>"
1231 "</cont2>"
1232 "</cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +01001233 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_OPT_PARSE_ONLY | LYD_OPT_NO_STATE, &tree));
Michal Vasko5b37a352020-03-06 13:38:33 +01001234 assert_null(tree);
1235 logbuf_assert("Invalid state data node \"cont2\" found. Line number 1.");
1236
Michal Vasko9f96a052020-03-10 09:41:45 +01001237 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY | LYD_VALOPT_NO_STATE, &tree));
Michal Vasko5b37a352020-03-06 13:38:33 +01001238 assert_null(tree);
1239 logbuf_assert("Invalid state data node \"cont2\" found. /h:cont/cont2");
1240
Michal Vasko9f96a052020-03-10 09:41:45 +01001241 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_PARSE_ONLY, &tree));
Michal Vasko5b37a352020-03-06 13:38:33 +01001242 assert_non_null(tree);
1243
1244 assert_int_equal(LY_EVALID, lyd_validate(&tree, NULL, LYD_VALOPT_DATA_ONLY | LYD_VALOPT_NO_STATE));
1245 logbuf_assert("Invalid state data node \"cont2\" found. /h:cont/cont2");
1246
1247 lyd_free_siblings(tree);
1248
1249 *state = NULL;
1250}
1251
Michal Vaskocc048b22020-03-27 15:52:38 +01001252static void
1253test_must(void **state)
1254{
1255 *state = test_must;
1256
1257 const char *data;
1258 struct lyd_node *tree;
1259
1260 data =
1261 "<cont xmlns=\"urn:tests:i\">"
1262 "<l>wrong</l>"
1263 "<l2>val</l2>"
1264 "</cont>";
1265 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
1266 assert_null(tree);
1267 logbuf_assert("Must condition \"../l = 'right'\" not satisfied. /i:cont/l2");
1268
1269 data =
1270 "<cont xmlns=\"urn:tests:i\">"
1271 "<l>right</l>"
1272 "<l2>val</l2>"
1273 "</cont>";
1274 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
1275 assert_non_null(tree);
1276 lyd_free_tree(tree);
1277
1278 *state = NULL;
1279}
1280
Michal Vaskocde73ac2019-11-14 16:10:27 +01001281int main(void)
1282{
1283 const struct CMUnitTest tests[] = {
Michal Vaskoacd83e72020-02-04 14:12:01 +01001284 cmocka_unit_test_teardown(test_when, teardown_s),
1285 cmocka_unit_test_teardown(test_mandatory, teardown_s),
1286 cmocka_unit_test_teardown(test_minmax, teardown_s),
Michal Vasko14654712020-02-06 08:35:21 +01001287 cmocka_unit_test_teardown(test_unique, teardown_s),
1288 cmocka_unit_test_teardown(test_unique_nested, teardown_s),
Michal Vaskof03ed032020-03-04 13:31:44 +01001289 cmocka_unit_test_teardown(test_dup, teardown_s),
1290 cmocka_unit_test_teardown(test_defaults, teardown_s),
Michal Vaskoc193ce92020-03-06 11:04:48 +01001291 cmocka_unit_test_teardown(test_iffeature, teardown_s),
Michal Vasko5b37a352020-03-06 13:38:33 +01001292 cmocka_unit_test_teardown(test_state, teardown_s),
Michal Vaskocc048b22020-03-27 15:52:38 +01001293 cmocka_unit_test_teardown(test_must, teardown_s),
Michal Vaskocde73ac2019-11-14 16:10:27 +01001294 };
1295
Michal Vaskoacd83e72020-02-04 14:12:01 +01001296 return cmocka_run_group_tests(tests, setup, teardown);
Michal Vaskocde73ac2019-11-14 16:10:27 +01001297}