blob: b93d388c4f232b984b8e3f36b20a969abf3c901d [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 Vaskofea12c62020-03-30 11:00:15 +0200363 const char *schema_j =
364 "module j {"
365 "namespace urn:tests:j;"
366 "prefix j;"
367 "yang-version 1.1;"
368
369 "feature feat1;"
370
371 "container cont {"
372 "must \"false()\";"
373 "list l1 {"
374 "key \"k\";"
375 "leaf k {"
376 "type string;"
377 "}"
378 "action act {"
379 "if-feature feat1;"
380 "input {"
381 "must \"../../lf1 = 'true'\";"
382 "leaf lf2 {"
383 "type leafref {"
384 "path /lf3;"
385 "}"
386 "}"
387 "}"
388 "}"
389 "}"
390
391 "leaf lf1 {"
392 "type string;"
393 "}"
394 "}"
395
396 "leaf lf3 {"
397 "type string;"
398 "}"
399 "}";
Michal Vaskocde73ac2019-11-14 16:10:27 +0100400
401#if ENABLE_LOGGER_CHECKING
402 ly_set_log_clb(logger, 1);
403#endif
404
Michal Vaskof03ed032020-03-04 13:31:44 +0100405 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &ctx));
406 assert_non_null(ly_ctx_load_module(ctx, "ietf-netconf-with-defaults", "2011-06-01"));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100407 assert_non_null(lys_parse_mem(ctx, schema_a, LYS_IN_YANG));
Michal Vaskoa3881362020-01-21 15:57:35 +0100408 assert_non_null(lys_parse_mem(ctx, schema_b, LYS_IN_YANG));
Michal Vaskoacd83e72020-02-04 14:12:01 +0100409 assert_non_null(lys_parse_mem(ctx, schema_c, LYS_IN_YANG));
Michal Vasko14654712020-02-06 08:35:21 +0100410 assert_non_null(lys_parse_mem(ctx, schema_d, LYS_IN_YANG));
Michal Vaskof03ed032020-03-04 13:31:44 +0100411 assert_non_null(lys_parse_mem(ctx, schema_e, LYS_IN_YANG));
412 assert_non_null(lys_parse_mem(ctx, schema_f, LYS_IN_YANG));
Michal Vaskoc193ce92020-03-06 11:04:48 +0100413 assert_non_null(lys_parse_mem(ctx, schema_g, LYS_IN_YANG));
Michal Vasko5b37a352020-03-06 13:38:33 +0100414 assert_non_null(lys_parse_mem(ctx, schema_h, LYS_IN_YANG));
Michal Vaskocc048b22020-03-27 15:52:38 +0100415 assert_non_null(lys_parse_mem(ctx, schema_i, LYS_IN_YANG));
Michal Vaskofea12c62020-03-30 11:00:15 +0200416 assert_non_null(lys_parse_mem(ctx, schema_j, LYS_IN_YANG));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100417
418 return 0;
419}
420
421static int
422teardown(void **state)
423{
Michal Vaskoacd83e72020-02-04 14:12:01 +0100424 (void)state;
425 ly_ctx_destroy(ctx, NULL);
426 ctx = NULL;
427
428 return 0;
429}
430
431static int
432teardown_s(void **state)
433{
Michal Vaskocde73ac2019-11-14 16:10:27 +0100434#if ENABLE_LOGGER_CHECKING
435 if (*state) {
436 fprintf(stderr, "%s\n", logbuf);
437 }
438#else
439 (void) state; /* unused */
440#endif
441
Michal Vaskocde73ac2019-11-14 16:10:27 +0100442 return 0;
443}
444
445void
446logbuf_clean(void)
447{
448 logbuf[0] = '\0';
449}
450
451#if ENABLE_LOGGER_CHECKING
452# define logbuf_assert(str) assert_string_equal(logbuf, str)
453#else
454# define logbuf_assert(str)
455#endif
456
457static void
458test_when(void **state)
459{
460 *state = test_when;
461
462 const char *data;
463 struct lyd_node *tree;
464
465 data = "<c xmlns=\"urn:tests:a\">hey</c>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100466 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100467 assert_null(tree);
Michal Vasko9b368d32020-02-14 13:53:31 +0100468 logbuf_assert("When condition \"/cont/b = 'val_b'\" not satisfied. /a:c");
Michal Vaskocde73ac2019-11-14 16:10:27 +0100469
470 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 +0100471 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100472 assert_non_null(tree);
473 assert_string_equal("c", tree->next->schema->name);
474 assert_int_equal(LYD_WHEN_TRUE, tree->next->flags);
475 lyd_free_all(tree);
476
477 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 +0100478 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100479 assert_non_null(tree);
480 assert_string_equal("a", lyd_node_children(tree)->schema->name);
481 assert_int_equal(LYD_WHEN_TRUE, lyd_node_children(tree)->flags);
482 assert_string_equal("c", tree->next->schema->name);
483 assert_int_equal(LYD_WHEN_TRUE, tree->next->flags);
484 lyd_free_all(tree);
485
486 *state = NULL;
487}
488
Michal Vaskoa3881362020-01-21 15:57:35 +0100489static void
490test_mandatory(void **state)
491{
492 *state = test_mandatory;
493
494 const char *data;
495 struct lyd_node *tree;
496
497 data = "<d xmlns=\"urn:tests:b\"/>";
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 Vaskoa3881362020-01-21 15:57:35 +0100499 assert_null(tree);
500 logbuf_assert("Mandatory node \"choic\" instance does not exist. /b:choic");
501
502 data = "<l xmlns=\"urn:tests:b\">string</l><d xmlns=\"urn:tests:b\"/>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100503 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoa3881362020-01-21 15:57:35 +0100504 assert_null(tree);
505 logbuf_assert("Mandatory node \"c\" instance does not exist. /b:c");
506
507 data = "<a xmlns=\"urn:tests:b\">string</a>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100508 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoa3881362020-01-21 15:57:35 +0100509 assert_null(tree);
510 logbuf_assert("Mandatory node \"c\" instance does not exist. /b:c");
511
512 data = "<a xmlns=\"urn:tests:b\">string</a><c xmlns=\"urn:tests:b\">string2</c>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100513 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoa3881362020-01-21 15:57:35 +0100514 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100515 lyd_free_siblings(tree);
Michal Vaskoa3881362020-01-21 15:57:35 +0100516
517 *state = NULL;
518}
519
Michal Vaskoacd83e72020-02-04 14:12:01 +0100520static void
521test_minmax(void **state)
522{
523 *state = test_minmax;
524
525 const char *data;
526 struct lyd_node *tree;
527
528 data = "<d xmlns=\"urn:tests:c\"/>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100529 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoacd83e72020-02-04 14:12:01 +0100530 assert_null(tree);
531 logbuf_assert("Too few \"l\" instances. /c:choic/b/l");
532
533 data =
534 "<l xmlns=\"urn:tests:c\">val1</l>"
535 "<l xmlns=\"urn:tests:c\">val2</l>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100536 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoacd83e72020-02-04 14:12:01 +0100537 assert_null(tree);
538 logbuf_assert("Too few \"l\" instances. /c:choic/b/l");
539
540 data =
541 "<l xmlns=\"urn:tests:c\">val1</l>"
542 "<l xmlns=\"urn:tests:c\">val2</l>"
543 "<l xmlns=\"urn:tests:c\">val3</l>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100544 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoacd83e72020-02-04 14:12:01 +0100545 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100546 lyd_free_siblings(tree);
Michal Vaskoacd83e72020-02-04 14:12:01 +0100547
548 data =
549 "<l xmlns=\"urn:tests:c\">val1</l>"
550 "<l xmlns=\"urn:tests:c\">val2</l>"
551 "<l xmlns=\"urn:tests:c\">val3</l>"
552 "<lt xmlns=\"urn:tests:c\"><k>val1</k></lt>"
553 "<lt xmlns=\"urn:tests:c\"><k>val2</k></lt>"
554 "<lt xmlns=\"urn:tests:c\"><k>val3</k></lt>"
555 "<lt xmlns=\"urn:tests:c\"><k>val4</k></lt>"
556 "<lt xmlns=\"urn:tests:c\"><k>val5</k></lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100557 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoacd83e72020-02-04 14:12:01 +0100558 assert_null(tree);
559 logbuf_assert("Too many \"lt\" instances. /c:lt");
560
561 *state = NULL;
562}
563
Michal Vasko14654712020-02-06 08:35:21 +0100564static void
565test_unique(void **state)
566{
567 *state = test_unique;
568
569 const char *data;
570 struct lyd_node *tree;
571
572 data =
573 "<lt xmlns=\"urn:tests:d\">"
574 "<k>val1</k>"
575 "<l1>same</l1>"
576 "</lt>"
577 "<lt xmlns=\"urn:tests:d\">"
578 "<k>val2</k>"
579 "</lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100580 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100581 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100582 lyd_free_siblings(tree);
Michal Vasko14654712020-02-06 08:35:21 +0100583
584 data =
585 "<lt xmlns=\"urn:tests:d\">"
586 "<k>val1</k>"
587 "<l1>same</l1>"
588 "</lt>"
589 "<lt xmlns=\"urn:tests:d\">"
590 "<k>val2</k>"
591 "<l1>not-same</l1>"
592 "</lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100593 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100594 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100595 lyd_free_siblings(tree);
Michal Vasko14654712020-02-06 08:35:21 +0100596
597 data =
598 "<lt xmlns=\"urn:tests:d\">"
599 "<k>val1</k>"
600 "<l1>same</l1>"
601 "</lt>"
602 "<lt xmlns=\"urn:tests:d\">"
603 "<k>val2</k>"
604 "<l1>same</l1>"
605 "</lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100606 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100607 assert_null(tree);
Michal Vasko9b368d32020-02-14 13:53:31 +0100608 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 +0100609
610 /* now try with more instances */
611 data =
612 "<lt xmlns=\"urn:tests:d\">"
613 "<k>val1</k>"
614 "<l1>1</l1>"
615 "</lt>"
616 "<lt xmlns=\"urn:tests:d\">"
617 "<k>val2</k>"
618 "<l1>2</l1>"
619 "</lt>"
620 "<lt xmlns=\"urn:tests:d\">"
621 "<k>val3</k>"
622 "<l1>3</l1>"
623 "</lt>"
624 "<lt xmlns=\"urn:tests:d\">"
625 "<k>val4</k>"
626 "<l1>4</l1>"
627 "</lt>"
628 "<lt xmlns=\"urn:tests:d\">"
629 "<k>val5</k>"
630 "<l1>5</l1>"
631 "</lt>"
632 "<lt xmlns=\"urn:tests:d\">"
633 "<k>val6</k>"
634 "<l1>6</l1>"
635 "</lt>"
636 "<lt xmlns=\"urn:tests:d\">"
637 "<k>val7</k>"
638 "<l1>7</l1>"
639 "</lt>"
640 "<lt xmlns=\"urn:tests:d\">"
641 "<k>val8</k>"
642 "<l1>8</l1>"
643 "</lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100644 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100645 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100646 lyd_free_siblings(tree);
Michal Vasko14654712020-02-06 08:35:21 +0100647
648 data =
649 "<lt xmlns=\"urn:tests:d\">"
650 "<k>val1</k>"
651 "<l1>1</l1>"
652 "</lt>"
653 "<lt xmlns=\"urn:tests:d\">"
654 "<k>val2</k>"
655 "<l1>2</l1>"
656 "</lt>"
657 "<lt xmlns=\"urn:tests:d\">"
658 "<k>val3</k>"
659 "<l1>3</l1>"
660 "</lt>"
661 "<lt xmlns=\"urn:tests:d\">"
662 "<k>val4</k>"
663 "</lt>"
664 "<lt xmlns=\"urn:tests:d\">"
665 "<k>val5</k>"
666 "<l1>5</l1>"
667 "</lt>"
668 "<lt xmlns=\"urn:tests:d\">"
669 "<k>val6</k>"
670 "<l1>6</l1>"
671 "</lt>"
672 "<lt xmlns=\"urn:tests:d\">"
673 "<k>val7</k>"
674 "</lt>"
675 "<lt xmlns=\"urn:tests:d\">"
676 "<k>val8</k>"
677 "</lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100678 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100679 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100680 lyd_free_siblings(tree);
Michal Vasko14654712020-02-06 08:35:21 +0100681
682 data =
683 "<lt xmlns=\"urn:tests:d\">"
684 "<k>val1</k>"
685 "<l1>1</l1>"
686 "</lt>"
687 "<lt xmlns=\"urn:tests:d\">"
688 "<k>val2</k>"
689 "<l1>2</l1>"
690 "</lt>"
691 "<lt xmlns=\"urn:tests:d\">"
692 "<k>val3</k>"
693 "</lt>"
694 "<lt xmlns=\"urn:tests:d\">"
695 "<k>val4</k>"
696 "<l1>4</l1>"
697 "</lt>"
698 "<lt xmlns=\"urn:tests:d\">"
699 "<k>val5</k>"
700 "</lt>"
701 "<lt xmlns=\"urn:tests:d\">"
702 "<k>val6</k>"
703 "</lt>"
704 "<lt xmlns=\"urn:tests:d\">"
705 "<k>val7</k>"
706 "<l1>2</l1>"
707 "</lt>"
708 "<lt xmlns=\"urn:tests:d\">"
709 "<k>val8</k>"
710 "<l1>8</l1>"
711 "</lt>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100712 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100713 assert_null(tree);
Michal Vasko9b368d32020-02-14 13:53:31 +0100714 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 +0100715
716 *state = NULL;
717}
718
719static void
720test_unique_nested(void **state)
721{
722 *state = test_unique_nested;
723
724 const char *data;
725 struct lyd_node *tree;
726
727 /* nested list uniquest are compared only with instances in the same parent list instance */
728 data =
729 "<lt2 xmlns=\"urn:tests:d\">"
730 "<k>val1</k>"
731 "<cont>"
732 "<l2>1</l2>"
733 "</cont>"
734 "<l4>1</l4>"
735 "</lt2>"
736 "<lt2 xmlns=\"urn:tests:d\">"
737 "<k>val2</k>"
738 "<cont>"
739 "<l2>2</l2>"
740 "</cont>"
741 "<l4>2</l4>"
742 "<lt3>"
743 "<kk>val1</kk>"
744 "<l3>1</l3>"
745 "</lt3>"
746 "<lt3>"
747 "<kk>val2</kk>"
748 "<l3>2</l3>"
749 "</lt3>"
750 "</lt2>"
751 "<lt2 xmlns=\"urn:tests:d\">"
752 "<k>val3</k>"
753 "<cont>"
754 "<l2>3</l2>"
755 "</cont>"
756 "<l4>3</l4>"
757 "<lt3>"
758 "<kk>val1</kk>"
759 "<l3>2</l3>"
760 "</lt3>"
761 "</lt2>"
762 "<lt2 xmlns=\"urn:tests:d\">"
763 "<k>val4</k>"
764 "<cont>"
765 "<l2>4</l2>"
766 "</cont>"
767 "<l4>4</l4>"
768 "<lt3>"
769 "<kk>val1</kk>"
770 "<l3>3</l3>"
771 "</lt3>"
772 "</lt2>"
773 "<lt2 xmlns=\"urn:tests:d\">"
774 "<k>val5</k>"
775 "<cont>"
776 "<l2>5</l2>"
777 "</cont>"
778 "<l4>5</l4>"
779 "<lt3>"
780 "<kk>val1</kk>"
781 "<l3>3</l3>"
782 "</lt3>"
783 "</lt2>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100784 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 +0100785 assert_non_null(tree);
Michal Vaskof03ed032020-03-04 13:31:44 +0100786 lyd_free_siblings(tree);
Michal Vasko14654712020-02-06 08:35:21 +0100787
788 data =
789 "<lt2 xmlns=\"urn:tests:d\">"
790 "<k>val1</k>"
791 "<cont>"
792 "<l2>1</l2>"
793 "</cont>"
794 "<l4>1</l4>"
795 "</lt2>"
796 "<lt2 xmlns=\"urn:tests:d\">"
797 "<k>val2</k>"
798 "<cont>"
799 "<l2>2</l2>"
800 "</cont>"
801 "<lt3>"
802 "<kk>val1</kk>"
803 "<l3>1</l3>"
804 "</lt3>"
805 "<lt3>"
806 "<kk>val2</kk>"
807 "<l3>2</l3>"
808 "</lt3>"
809 "<lt3>"
810 "<kk>val3</kk>"
811 "<l3>1</l3>"
812 "</lt3>"
813 "</lt2>"
814 "<lt2 xmlns=\"urn:tests:d\">"
815 "<k>val3</k>"
816 "<cont>"
817 "<l2>3</l2>"
818 "</cont>"
819 "<l4>1</l4>"
820 "<lt3>"
821 "<kk>val1</kk>"
822 "<l3>2</l3>"
823 "</lt3>"
824 "</lt2>"
825 "<lt2 xmlns=\"urn:tests:d\">"
826 "<k>val4</k>"
827 "<cont>"
828 "<l2>4</l2>"
829 "</cont>"
830 "<lt3>"
831 "<kk>val1</kk>"
832 "<l3>3</l3>"
833 "</lt3>"
834 "</lt2>"
835 "<lt2 xmlns=\"urn:tests:d\">"
836 "<k>val5</k>"
837 "<cont>"
838 "<l2>5</l2>"
839 "</cont>"
840 "<lt3>"
841 "<kk>val1</kk>"
842 "<l3>3</l3>"
843 "</lt3>"
844 "</lt2>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100845 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100846 assert_null(tree);
847 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 +0100848 " \"/d:lt2[k='val2']/lt3[kk='val1']\". /d:lt2[k='val2']/lt3[kk='val1']");
Michal Vasko14654712020-02-06 08:35:21 +0100849
850 data =
851 "<lt2 xmlns=\"urn:tests:d\">"
852 "<k>val1</k>"
853 "<cont>"
854 "<l2>1</l2>"
855 "</cont>"
856 "<l4>1</l4>"
857 "</lt2>"
858 "<lt2 xmlns=\"urn:tests:d\">"
859 "<k>val2</k>"
860 "<cont>"
861 "<l2>2</l2>"
862 "</cont>"
863 "<l4>2</l4>"
864 "</lt2>"
865 "<lt2 xmlns=\"urn:tests:d\">"
866 "<k>val3</k>"
867 "<cont>"
868 "<l2>3</l2>"
869 "</cont>"
870 "<l4>3</l4>"
871 "</lt2>"
872 "<lt2 xmlns=\"urn:tests:d\">"
873 "<k>val4</k>"
874 "<cont>"
875 "<l2>2</l2>"
876 "</cont>"
877 "<l4>2</l4>"
878 "</lt2>"
879 "<lt2 xmlns=\"urn:tests:d\">"
880 "<k>val5</k>"
881 "<cont>"
882 "<l2>5</l2>"
883 "</cont>"
884 "<l4>5</l4>"
885 "</lt2>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100886 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100887 assert_null(tree);
Michal Vasko9b368d32020-02-14 13:53:31 +0100888 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 +0100889
890 data =
891 "<lt2 xmlns=\"urn:tests:d\">"
892 "<k>val1</k>"
893 "<cont>"
894 "<l2>1</l2>"
895 "</cont>"
896 "<l4>1</l4>"
897 "<l5>1</l5>"
898 "<l6>1</l6>"
899 "</lt2>"
900 "<lt2 xmlns=\"urn:tests:d\">"
901 "<k>val2</k>"
902 "<cont>"
903 "<l2>2</l2>"
904 "</cont>"
905 "<l4>1</l4>"
906 "<l5>1</l5>"
907 "</lt2>"
908 "<lt2 xmlns=\"urn:tests:d\">"
909 "<k>val3</k>"
910 "<cont>"
911 "<l2>3</l2>"
912 "</cont>"
913 "<l4>1</l4>"
914 "<l5>3</l5>"
915 "<l6>3</l6>"
916 "</lt2>"
917 "<lt2 xmlns=\"urn:tests:d\">"
918 "<k>val4</k>"
919 "<cont>"
920 "<l2>4</l2>"
921 "</cont>"
922 "<l4>1</l4>"
923 "<l6>1</l6>"
924 "</lt2>"
925 "<lt2 xmlns=\"urn:tests:d\">"
926 "<k>val5</k>"
927 "<cont>"
928 "<l2>5</l2>"
929 "</cont>"
930 "<l4>1</l4>"
931 "<l5>3</l5>"
932 "<l6>3</l6>"
933 "</lt2>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100934 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vasko14654712020-02-06 08:35:21 +0100935 assert_null(tree);
Michal Vasko9b368d32020-02-14 13:53:31 +0100936 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 +0100937
938 *state = NULL;
939}
940
Michal Vaskof03ed032020-03-04 13:31:44 +0100941static void
942test_dup(void **state)
943{
944 *state = test_dup;
945
946 const char *data;
947 struct lyd_node *tree;
948
949 data = "<d xmlns=\"urn:tests:e\">25</d><d xmlns=\"urn:tests:e\">50</d>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100950 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100951 assert_null(tree);
952 logbuf_assert("Duplicate instance of \"d\". /e:d");
953
954 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 +0100955 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100956 assert_null(tree);
957 logbuf_assert("Duplicate instance of \"lt\". /e:lt[k='A']");
958
959 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 +0100960 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100961 assert_null(tree);
962 logbuf_assert("Duplicate instance of \"ll\". /e:ll[.='B']");
963
964 data = "<cont xmlns=\"urn:tests:e\"></cont><cont xmlns=\"urn:tests:e\"/>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100965 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100966 assert_null(tree);
967 logbuf_assert("Duplicate instance of \"cont\". /e:cont");
968
969 /* same tests again but using hashes */
970 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 +0100971 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100972 assert_null(tree);
973 logbuf_assert("Duplicate instance of \"d\". /e:cont/d");
974
975 data = "<cont xmlns=\"urn:tests:e\"><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll>"
976 "<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 +0100977 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100978 assert_null(tree);
979 logbuf_assert("Duplicate instance of \"lt\". /e:cont/lt[k='c']");
980
981 data = "<cont xmlns=\"urn:tests:e\"><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll>"
982 "<ll>a</ll><ll>b</ll><ll>c</ll><ll>d</ll><ll>d</ll></cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +0100983 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100984 assert_null(tree);
985 logbuf_assert("Duplicate instance of \"ll\". /e:cont/ll[.='d']");
986
987 /* cases */
988 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 +0100989 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100990 assert_null(tree);
991 logbuf_assert("Duplicate instance of \"l\". /e:l[.='b']");
992
993 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 +0100994 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskof03ed032020-03-04 13:31:44 +0100995 assert_null(tree);
996 logbuf_assert("Data for both cases \"a\" and \"b\" exist. /e:choic");
997
998 *state = NULL;
999}
1000
1001static void
1002test_defaults(void **state)
1003{
1004 *state = test_defaults;
1005
Michal Vaskof03ed032020-03-04 13:31:44 +01001006 char *str;
1007 struct lyd_node *tree, *node;
1008 const struct lys_module *mod = ly_ctx_get_module_latest(ctx, "f");
1009
Michal Vaskob1b5c262020-03-05 14:29:47 +01001010 /* get defaults */
1011 tree = NULL;
1012 assert_int_equal(lyd_validate_modules(&tree, &mod, 1, 0), LY_SUCCESS);
Michal Vaskof03ed032020-03-04 13:31:44 +01001013 assert_non_null(tree);
1014
1015 /* check all defaults exist */
1016 lyd_print_mem(&str, tree, LYD_XML, LYDP_WITHSIBLINGS | LYDP_WD_IMPL_TAG);
1017 assert_string_equal(str,
Michal Vaskof03ed032020-03-04 13:31:44 +01001018 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>"
1019 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>"
1020 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>"
1021 "<d xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
1022 "<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 +01001023 "<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 +01001024 "<cont xmlns=\"urn:tests:f\">"
1025 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>"
1026 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>"
1027 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>"
1028 "<d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
1029 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
1030 "<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 +01001031 "</cont>");
Michal Vaskof03ed032020-03-04 13:31:44 +01001032 free(str);
1033
1034 /* create another explicit case and validate */
1035 node = lyd_new_term(NULL, mod, "l", "value");
1036 assert_non_null(node);
Michal Vaskob1b5c262020-03-05 14:29:47 +01001037 assert_int_equal(lyd_insert_sibling(tree, node), LY_SUCCESS);
1038 assert_int_equal(lyd_validate(&tree, ctx, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
Michal Vaskof03ed032020-03-04 13:31:44 +01001039
1040 /* check data tree */
1041 lyd_print_mem(&str, tree, LYD_XML, LYDP_WITHSIBLINGS | LYDP_WD_IMPL_TAG);
1042 assert_string_equal(str,
Michal Vaskob1b5c262020-03-05 14:29:47 +01001043 "<d xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
1044 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
1045 "<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 +01001046 "<cont xmlns=\"urn:tests:f\">"
1047 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>"
1048 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>"
1049 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>"
1050 "<d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
1051 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
1052 "<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 +01001053 "</cont>"
Michal Vaskof03ed032020-03-04 13:31:44 +01001054 "<l xmlns=\"urn:tests:f\">value</l>");
1055 free(str);
1056
1057 /* create explicit leaf-list and leaf and validate */
1058 node = lyd_new_term(NULL, mod, "d", "15");
1059 assert_non_null(node);
Michal Vaskob1b5c262020-03-05 14:29:47 +01001060 assert_int_equal(lyd_insert_sibling(tree, node), LY_SUCCESS);
Michal Vaskof03ed032020-03-04 13:31:44 +01001061 node = lyd_new_term(NULL, mod, "ll2", "dflt2");
1062 assert_non_null(node);
Michal Vaskob1b5c262020-03-05 14:29:47 +01001063 assert_int_equal(lyd_insert_sibling(tree, node), LY_SUCCESS);
1064 assert_int_equal(lyd_validate(&tree, ctx, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
Michal Vaskof03ed032020-03-04 13:31:44 +01001065
1066 /* check data tree */
1067 lyd_print_mem(&str, tree, LYD_XML, LYDP_WITHSIBLINGS | LYDP_WD_IMPL_TAG);
1068 assert_string_equal(str,
Michal Vasko52927e22020-03-16 17:26:14 +01001069 "<cont xmlns=\"urn:tests:f\">"
1070 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>"
1071 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>"
1072 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>"
1073 "<d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
1074 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
1075 "<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 +01001076 "</cont>"
1077 "<l xmlns=\"urn:tests:f\">value</l>"
1078 "<d xmlns=\"urn:tests:f\">15</d>"
1079 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>");
1080 free(str);
1081
Michal Vaskob1b5c262020-03-05 14:29:47 +01001082 /* create first explicit container, which should become implicit */
1083 node = lyd_new_inner(NULL, mod, "cont");
1084 assert_non_null(node);
1085 assert_int_equal(lyd_insert_before(tree, node), LY_SUCCESS);
1086 tree = tree->prev;
1087 assert_int_equal(lyd_validate(&tree, ctx, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
1088
1089 /* check data tree */
1090 lyd_print_mem(&str, tree, LYD_XML, LYDP_WITHSIBLINGS | LYDP_WD_IMPL_TAG);
1091 assert_string_equal(str,
Michal Vasko52927e22020-03-16 17:26:14 +01001092 "<cont xmlns=\"urn:tests:f\">"
1093 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>"
1094 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>"
1095 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>"
1096 "<d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
1097 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
1098 "<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 +01001099 "</cont>"
1100 "<l xmlns=\"urn:tests:f\">value</l>"
1101 "<d xmlns=\"urn:tests:f\">15</d>"
1102 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>");
1103 free(str);
1104
1105 /* create second explicit container, which should become implicit, so the first tree node should be removed */
1106 node = lyd_new_inner(NULL, mod, "cont");
1107 assert_non_null(node);
1108 assert_int_equal(lyd_insert_after(tree, node), LY_SUCCESS);
1109 assert_int_equal(lyd_validate(&tree, ctx, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
1110
1111 /* check data tree */
1112 lyd_print_mem(&str, tree, LYD_XML, LYDP_WITHSIBLINGS | LYDP_WD_IMPL_TAG);
1113 assert_string_equal(str,
Michal Vasko52927e22020-03-16 17:26:14 +01001114 "<cont xmlns=\"urn:tests:f\">"
1115 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>"
1116 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>"
1117 "<ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>"
1118 "<d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>"
1119 "<ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>"
1120 "<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 +01001121 "</cont>"
1122 "<l xmlns=\"urn:tests:f\">value</l>"
1123 "<d xmlns=\"urn:tests:f\">15</d>"
1124 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>");
1125 free(str);
Michal Vaskof03ed032020-03-04 13:31:44 +01001126
1127 /* similar changes for nested defaults */
1128 assert_non_null(lyd_new_term(tree, NULL, "ll1", "def3"));
1129 assert_non_null(lyd_new_term(tree, NULL, "d", "5"));
1130 assert_non_null(lyd_new_term(tree, NULL, "ll2", "non-dflt"));
Michal Vaskob1b5c262020-03-05 14:29:47 +01001131 assert_int_equal(lyd_validate(&tree, ctx, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
Michal Vaskof03ed032020-03-04 13:31:44 +01001132
1133 /* check data tree */
1134 lyd_print_mem(&str, tree, LYD_XML, LYDP_WITHSIBLINGS | LYDP_WD_IMPL_TAG);
1135 assert_string_equal(str,
Michal Vasko52927e22020-03-16 17:26:14 +01001136 "<cont xmlns=\"urn:tests:f\">"
Michal Vaskof03ed032020-03-04 13:31:44 +01001137 "<ll1>def3</ll1>"
1138 "<d>5</d>"
1139 "<ll2>non-dflt</ll2>"
1140 "</cont>"
1141 "<l xmlns=\"urn:tests:f\">value</l>"
1142 "<d xmlns=\"urn:tests:f\">15</d>"
1143 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>");
1144 free(str);
1145
1146 lyd_free_siblings(tree);
1147
1148 *state = NULL;
1149}
1150
Michal Vaskoc193ce92020-03-06 11:04:48 +01001151static void
1152test_iffeature(void **state)
1153{
1154 *state = test_iffeature;
1155
1156 const char *data;
1157 struct lyd_node *tree;
1158 const struct lys_module *mod = ly_ctx_get_module_latest(ctx, "g");
1159
1160 /* get empty data */
1161 tree = NULL;
1162 assert_int_equal(lyd_validate_modules(&tree, &mod, 1, 0), LY_SUCCESS);
1163 assert_null(tree);
1164
1165 /* disabled by f1 */
1166 data =
1167 "<cont xmlns=\"urn:tests:g\">"
1168 "<d>51</d>"
1169 "</cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +01001170 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001171 assert_null(tree);
1172 logbuf_assert("Data are disabled by \"cont\" schema node if-feature. /g:cont");
1173
1174 /* enable f1 */
1175 assert_int_equal(lys_feature_enable(mod, "f1"), LY_SUCCESS);
1176
1177 /* get data with default container */
1178 assert_int_equal(lyd_validate_modules(&tree, &mod, 1, 0), LY_SUCCESS);
1179 assert_non_null(tree);
1180 lyd_free_siblings(tree);
1181
1182 /* disabled by f2 */
1183 data =
1184 "<cont xmlns=\"urn:tests:g\">"
1185 "<cont2>"
1186 "<e>val</e>"
1187 "</cont2>"
1188 "</cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +01001189 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001190 assert_null(tree);
1191 logbuf_assert("Data are disabled by \"cont2\" schema node if-feature. /g:cont/cont2");
1192
1193 data =
1194 "<cont xmlns=\"urn:tests:g\">"
1195 "<a>val</a>"
1196 "</cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +01001197 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001198 assert_null(tree);
1199 logbuf_assert("Data are disabled by \"choic\" schema node if-feature. /g:cont/a");
1200
1201 /* enable f3 */
1202 assert_int_equal(lys_feature_enable(mod, "f3"), LY_SUCCESS);
1203
Michal Vasko9f96a052020-03-10 09:41:45 +01001204 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001205 assert_non_null(tree);
1206 lyd_free_siblings(tree);
1207
1208 /* disabled by f2 */
1209 data =
1210 "<cont xmlns=\"urn:tests:g\">"
1211 "<l>val</l>"
1212 "</cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +01001213 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001214 assert_null(tree);
1215 logbuf_assert("Data are disabled by \"b\" schema node if-feature. /g:cont/l");
1216
1217 /* enable f2 */
1218 assert_int_equal(lys_feature_enable(mod, "f2"), LY_SUCCESS);
1219
Michal Vasko9f96a052020-03-10 09:41:45 +01001220 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001221 assert_non_null(tree);
1222 lyd_free_siblings(tree);
1223
1224 /* try separate validation */
1225 assert_int_equal(lys_feature_disable(mod, "f1"), LY_SUCCESS);
1226 assert_int_equal(lys_feature_disable(mod, "f2"), LY_SUCCESS);
1227 assert_int_equal(lys_feature_disable(mod, "f3"), LY_SUCCESS);
1228
1229 data =
1230 "<cont xmlns=\"urn:tests:g\">"
1231 "<l>val</l>"
1232 "<d>51</d>"
1233 "<cont2>"
1234 "<e>val</e>"
1235 "</cont2>"
1236 "</cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +01001237 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_PARSE_ONLY, &tree));
Michal Vaskoc193ce92020-03-06 11:04:48 +01001238 assert_non_null(tree);
1239
1240 assert_int_equal(LY_EVALID, lyd_validate(&tree, NULL, LYD_VALOPT_DATA_ONLY));
1241 logbuf_assert("Data are disabled by \"cont\" schema node if-feature. /g:cont");
1242
1243 assert_int_equal(lys_feature_enable(mod, "f1"), LY_SUCCESS);
1244
1245 assert_int_equal(LY_EVALID, lyd_validate(&tree, NULL, LYD_VALOPT_DATA_ONLY));
1246 logbuf_assert("Data are disabled by \"b\" schema node if-feature. /g:cont/l");
1247
1248 assert_int_equal(lys_feature_enable(mod, "f2"), LY_SUCCESS);
1249
1250 assert_int_equal(LY_SUCCESS, lyd_validate(&tree, NULL, LYD_VALOPT_DATA_ONLY));
1251
1252 lyd_free_siblings(tree);
1253
1254 *state = NULL;
1255}
1256
Michal Vasko5b37a352020-03-06 13:38:33 +01001257static void
1258test_state(void **state)
1259{
Michal Vaskocc048b22020-03-27 15:52:38 +01001260 *state = test_state;
Michal Vasko5b37a352020-03-06 13:38:33 +01001261
1262 const char *data;
1263 struct lyd_node *tree;
1264
1265 data =
1266 "<cont xmlns=\"urn:tests:h\">"
1267 "<cont2>"
1268 "<l>val</l>"
1269 "</cont2>"
1270 "</cont>";
Michal Vasko9f96a052020-03-10 09:41:45 +01001271 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 +01001272 assert_null(tree);
1273 logbuf_assert("Invalid state data node \"cont2\" found. Line number 1.");
1274
Michal Vasko9f96a052020-03-10 09:41:45 +01001275 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 +01001276 assert_null(tree);
1277 logbuf_assert("Invalid state data node \"cont2\" found. /h:cont/cont2");
1278
Michal Vasko9f96a052020-03-10 09:41:45 +01001279 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_PARSE_ONLY, &tree));
Michal Vasko5b37a352020-03-06 13:38:33 +01001280 assert_non_null(tree);
1281
1282 assert_int_equal(LY_EVALID, lyd_validate(&tree, NULL, LYD_VALOPT_DATA_ONLY | LYD_VALOPT_NO_STATE));
1283 logbuf_assert("Invalid state data node \"cont2\" found. /h:cont/cont2");
1284
1285 lyd_free_siblings(tree);
1286
1287 *state = NULL;
1288}
1289
Michal Vaskocc048b22020-03-27 15:52:38 +01001290static void
1291test_must(void **state)
1292{
1293 *state = test_must;
1294
1295 const char *data;
1296 struct lyd_node *tree;
1297
1298 data =
1299 "<cont xmlns=\"urn:tests:i\">"
1300 "<l>wrong</l>"
1301 "<l2>val</l2>"
1302 "</cont>";
1303 assert_int_equal(LY_EVALID, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
1304 assert_null(tree);
1305 logbuf_assert("Must condition \"../l = 'right'\" not satisfied. /i:cont/l2");
1306
1307 data =
1308 "<cont xmlns=\"urn:tests:i\">"
1309 "<l>right</l>"
1310 "<l2>val</l2>"
1311 "</cont>";
1312 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_VALOPT_DATA_ONLY, &tree));
1313 assert_non_null(tree);
1314 lyd_free_tree(tree);
1315
1316 *state = NULL;
1317}
1318
Michal Vaskofea12c62020-03-30 11:00:15 +02001319static void
1320test_action(void **state)
1321{
1322 *state = test_action;
1323
1324 const char *data;
1325 struct lyd_node *tree, *op_tree;
1326 const struct lys_module *mod;
1327
1328 data =
1329 "<cont xmlns=\"urn:tests:j\">"
1330 "<l1>"
1331 "<k>val1</k>"
1332 "<act>"
1333 "<lf2>target</lf2>"
1334 "</act>"
1335 "</l1>"
1336 "</cont>";
1337 assert_int_equal(LY_SUCCESS, lyd_parse_xml_rpc(ctx, data, &op_tree, NULL));
1338 assert_non_null(op_tree);
1339
1340 /* missing leafref */
1341 assert_int_equal(LY_EVALID, lyd_validate_rpc_notif(op_tree, NULL));
1342 logbuf_assert("Invalid leafref - required instance \"/lf3\" does not exists in the data tree(s). /j:cont/l1[k='val1']/act/lf2");
1343
1344 data =
1345 "<cont xmlns=\"urn:tests:j\">"
1346 "<lf1>not true</lf1>"
1347 "</cont>"
1348 "<lf3 xmlns=\"urn:tests:j\">target</lf3>";
1349 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_PARSE_ONLY | LYD_OPT_TRUSTED, &tree));
1350 assert_non_null(tree);
1351
1352 /* disabled if-feature */
1353 assert_int_equal(LY_EVALID, lyd_validate_rpc_notif(op_tree, tree));
1354 logbuf_assert("Data are disabled by \"act\" schema node if-feature. /j:cont/l1[k='val1']/act");
1355
1356 mod = ly_ctx_get_module_latest(ctx, "j");
1357 assert_non_null(mod);
1358 assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "feat1"));
1359
1360 /* input must false */
1361 assert_int_equal(LY_EVALID, lyd_validate_rpc_notif(op_tree, tree));
1362 logbuf_assert("Must condition \"../../lf1 = 'true'\" not satisfied. /j:cont/l1[k='val1']/act");
1363
1364 lyd_free_siblings(tree);
1365 data =
1366 "<cont xmlns=\"urn:tests:j\">"
1367 "<lf1>true</lf1>"
1368 "</cont>"
1369 "<lf3 xmlns=\"urn:tests:j\">target</lf3>";
1370 assert_int_equal(LY_SUCCESS, lyd_parse_xml_data(ctx, data, LYD_OPT_PARSE_ONLY | LYD_OPT_TRUSTED, &tree));
1371 assert_non_null(tree);
1372
1373 /* success */
1374 assert_int_equal(LY_SUCCESS, lyd_validate_rpc_notif(op_tree, tree));
1375
1376 lyd_free_tree(op_tree);
1377 lyd_free_siblings(tree);
1378
1379 *state = NULL;
1380}
1381
Michal Vaskocde73ac2019-11-14 16:10:27 +01001382int main(void)
1383{
1384 const struct CMUnitTest tests[] = {
Michal Vaskoacd83e72020-02-04 14:12:01 +01001385 cmocka_unit_test_teardown(test_when, teardown_s),
1386 cmocka_unit_test_teardown(test_mandatory, teardown_s),
1387 cmocka_unit_test_teardown(test_minmax, teardown_s),
Michal Vasko14654712020-02-06 08:35:21 +01001388 cmocka_unit_test_teardown(test_unique, teardown_s),
1389 cmocka_unit_test_teardown(test_unique_nested, teardown_s),
Michal Vaskof03ed032020-03-04 13:31:44 +01001390 cmocka_unit_test_teardown(test_dup, teardown_s),
1391 cmocka_unit_test_teardown(test_defaults, teardown_s),
Michal Vaskoc193ce92020-03-06 11:04:48 +01001392 cmocka_unit_test_teardown(test_iffeature, teardown_s),
Michal Vasko5b37a352020-03-06 13:38:33 +01001393 cmocka_unit_test_teardown(test_state, teardown_s),
Michal Vaskocc048b22020-03-27 15:52:38 +01001394 cmocka_unit_test_teardown(test_must, teardown_s),
Michal Vaskofea12c62020-03-30 11:00:15 +02001395 cmocka_unit_test_teardown(test_action, teardown_s),
Michal Vaskocde73ac2019-11-14 16:10:27 +01001396 };
1397
Michal Vaskoacd83e72020-02-04 14:12:01 +01001398 return cmocka_run_group_tests(tests, setup, teardown);
Michal Vaskocde73ac2019-11-14 16:10:27 +01001399}