blob: c29ac4da73986808d24fb785607cf9a68c300b0f [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 */
Radek Iša56ca9e42020-09-08 18:42:00 +020014#define _UTEST_MAIN_
15#include "utests.h"
Michal Vaskocde73ac2019-11-14 16:10:27 +010016
Michal Vaskocde73ac2019-11-14 16:10:27 +010017#include <stdio.h>
18#include <string.h>
19
Radek Krejci70593c12020-06-13 20:48:09 +020020#include "context.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020021#include "in.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020022#include "out.h"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010023#include "parser_data.h"
Radek Krejci70593c12020-06-13 20:48:09 +020024#include "printer_data.h"
25#include "tests/config.h"
Radek Krejci70593c12020-06-13 20:48:09 +020026#include "tree_data_internal.h"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010027#include "tree_schema.h"
Michal Vaskocde73ac2019-11-14 16:10:27 +010028
Radek Iša56ca9e42020-09-08 18:42:00 +020029#define LYD_TREE_CREATE(INPUT, MODEL) \
30 CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, MODEL)
Michal Vaskocde73ac2019-11-14 16:10:27 +010031
Michal Vaskocde73ac2019-11-14 16:10:27 +010032static void
Radek Iša56ca9e42020-09-08 18:42:00 +020033test_when(void **state)
Michal Vaskocde73ac2019-11-14 16:10:27 +010034{
Radek Iša56ca9e42020-09-08 18:42:00 +020035 struct lyd_node *tree;
36 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +010037 "module a {\n"
38 " namespace urn:tests:a;\n"
39 " prefix a;\n"
40 " yang-version 1.1;\n"
41 "\n"
42 " container cont {\n"
43 " leaf a {\n"
44 " when \"../../c = 'val_c'\";\n"
45 " type string;\n"
46 " }\n"
47 " leaf b {\n"
48 " type string;\n"
49 " }\n"
50 " }\n"
51 " leaf c {\n"
52 " when \"/cont/b = 'val_b'\";\n"
53 " type string;\n"
54 " }\n"
55 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +020056
57 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
58
59 CHECK_PARSE_LYD_PARAM("<c xmlns=\"urn:tests:a\">hey</c>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
60 CHECK_LOG_CTX("When condition \"/cont/b = 'val_b'\" not satisfied.", "/a:c");
61
62 LYD_TREE_CREATE("<cont xmlns=\"urn:tests:a\"><b>val_b</b></cont><c xmlns=\"urn:tests:a\">hey</c>", tree);
63 CHECK_LYSC_NODE(tree->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c", 0, LYS_LEAF, 0, 0, NULL, 1);
64 assert_int_equal(LYD_WHEN_TRUE, tree->next->flags);
65 lyd_free_all(tree);
66
67 LYD_TREE_CREATE("<cont xmlns=\"urn:tests:a\"><a>val</a><b>val_b</b></cont><c xmlns=\"urn:tests:a\">val_c</c>", tree);
68 CHECK_LYSC_NODE(lyd_child(tree)->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "a", 1, LYS_LEAF, 1, 0, NULL, 1);
69 assert_int_equal(LYD_WHEN_TRUE, lyd_child(tree)->flags);
70 CHECK_LYSC_NODE(tree->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c", 0, LYS_LEAF, 0, 0, NULL, 1);
71 assert_int_equal(LYD_WHEN_TRUE, tree->next->flags);
72 lyd_free_all(tree);
73}
74
75static void
76test_mandatory(void **state)
77{
78 struct lyd_node *tree;
79 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +010080 "module b {\n"
81 " namespace urn:tests:b;\n"
82 " prefix b;\n"
83 " yang-version 1.1;\n"
84 "\n"
85 " choice choic {\n"
86 " mandatory true;\n"
87 " leaf a {\n"
88 " type string;\n"
89 " }\n"
90 " case b {\n"
91 " leaf l {\n"
92 " type string;\n"
93 " }\n"
94 " }\n"
95 " }\n"
96 " leaf c {\n"
97 " mandatory true;\n"
98 " type string;\n"
99 " }\n"
100 " leaf d {\n"
101 " type empty;\n"
102 " }\n"
103 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200104
105 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
106
107 CHECK_PARSE_LYD_PARAM("<d xmlns=\"urn:tests:b\"/>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
108 CHECK_LOG_CTX("Mandatory node \"choic\" instance does not exist.", "/b:choic");
109
110 CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:b\">string</l><d xmlns=\"urn:tests:b\"/>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
111 CHECK_LOG_CTX("Mandatory node \"c\" instance does not exist.", "/b:c");
112
113 CHECK_PARSE_LYD_PARAM("<a xmlns=\"urn:tests:b\">string</a>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
114 CHECK_LOG_CTX("Mandatory node \"c\" instance does not exist.", "/b:c");
115
116 LYD_TREE_CREATE("<a xmlns=\"urn:tests:b\">string</a><c xmlns=\"urn:tests:b\">string2</c>", tree);
117 lyd_free_siblings(tree);
118}
119
120static void
121test_minmax(void **state)
122{
123 struct lyd_node *tree;
124 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100125 "module c {\n"
126 " namespace urn:tests:c;\n"
127 " prefix c;\n"
128 " yang-version 1.1;\n"
129 "\n"
130 " choice choic {\n"
131 " leaf a {\n"
132 " type string;\n"
133 " }\n"
134 " case b {\n"
135 " leaf-list l {\n"
136 " min-elements 3;\n"
137 " type string;\n"
138 " }\n"
139 " }\n"
140 " }\n"
141 " list lt {\n"
142 " max-elements 4;\n"
143 " key \"k\";\n"
144 " leaf k {\n"
145 " type string;\n"
146 " }\n"
147 " }\n"
148 " leaf d {\n"
149 " type empty;\n"
150 " }\n"
151 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200152
153 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
154
155 CHECK_PARSE_LYD_PARAM("<d xmlns=\"urn:tests:c\"/>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
156 CHECK_LOG_CTX("Too few \"l\" instances.", "/c:choic/b/l");
157
158 CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:c\">val1</l>"
159 "<l xmlns=\"urn:tests:c\">val2</l>",
160 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
161 CHECK_LOG_CTX("Too few \"l\" instances.", "/c:choic/b/l");
162
163 LYD_TREE_CREATE("<l xmlns=\"urn:tests:c\">val1</l>"
164 "<l xmlns=\"urn:tests:c\">val2</l>"
165 "<l xmlns=\"urn:tests:c\">val3</l>", tree);
166 lyd_free_all(tree);
167
168 CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:c\">val1</l>"
169 "<l xmlns=\"urn:tests:c\">val2</l>"
170 "<l xmlns=\"urn:tests:c\">val3</l>"
171 "<lt xmlns=\"urn:tests:c\"><k>val1</k></lt>"
172 "<lt xmlns=\"urn:tests:c\"><k>val2</k></lt>"
173 "<lt xmlns=\"urn:tests:c\"><k>val3</k></lt>"
174 "<lt xmlns=\"urn:tests:c\"><k>val4</k></lt>"
175 "<lt xmlns=\"urn:tests:c\"><k>val5</k></lt>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
176 CHECK_LOG_CTX("Too many \"lt\" instances.", "/c:lt");
177}
178
179const char *schema_d =
180 "module d {\n"
181 " namespace urn:tests:d;\n"
182 " prefix d;\n"
183 " yang-version 1.1;\n"
184 "\n"
185 " list lt {\n"
186 " key \"k\";\n"
187 " unique \"l1\";\n"
188 " leaf k {\n"
189 " type string;\n"
190 " }\n"
191 " leaf l1 {\n"
192 " type string;\n"
193 " }\n"
194 " }\n"
195 " list lt2 {\n"
196 " key \"k\";\n"
197 " unique \"cont/l2 l4\";\n"
198 " unique \"l5 l6\";\n"
199 " leaf k {\n"
200 " type string;\n"
201 " }\n"
202 " container cont {\n"
203 " leaf l2 {\n"
204 " type string;\n"
205 " }\n"
206 " }\n"
207 " leaf l4 {\n"
208 " type string;\n"
209 " }\n"
210 " leaf l5 {\n"
211 " type string;\n"
212 " }\n"
213 " leaf l6 {\n"
214 " type string;\n"
215 " }\n"
216 " list lt3 {\n"
217 " key \"kk\";\n"
218 " unique \"l3\";\n"
219 " leaf kk {\n"
220 " type string;\n"
221 " }\n"
222 " leaf l3 {\n"
223 " type string;\n"
224 " }\n"
225 " }\n"
226 " }\n"
227 "}";
228
229static void
230test_unique(void **state)
231{
232 struct lyd_node *tree;
233
234 UTEST_ADD_MODULE(schema_d, LYS_IN_YANG, NULL, NULL);
235
236 LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
237 " <k>val1</k>\n"
238 " <l1>same</l1>\n"
239 "</lt>\n"
240 "<lt xmlns=\"urn:tests:d\">\n"
241 " <k>val2</k>\n"
242 "</lt>", tree);
243 lyd_free_all(tree);
244
245 LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
246 " <k>val1</k>\n"
247 " <l1>same</l1>\n"
248 "</lt>\n"
249 "<lt xmlns=\"urn:tests:d\">\n"
250 " <k>val2</k>\n"
251 " <l1>not-same</l1>\n"
252 "</lt>", tree);
253 lyd_free_all(tree);
254
255 CHECK_PARSE_LYD_PARAM("<lt xmlns=\"urn:tests:d\">\n"
256 " <k>val1</k>\n"
257 " <l1>same</l1>\n"
258 "</lt>\n"
259 "<lt xmlns=\"urn:tests:d\">\n"
260 " <k>val2</k>\n"
261 " <l1>same</l1>\n"
262 "</lt>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
263 CHECK_LOG_CTX("Unique data leaf(s) \"l1\" not satisfied in \"/d:lt[k='val1']\" and \"/d:lt[k='val2']\".", "/d:lt[k='val2']");
264
265 /* now try with more instances */
266 LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
267 " <k>val1</k>\n"
268 " <l1>1</l1>\n"
269 "</lt>\n"
270 "<lt xmlns=\"urn:tests:d\">\n"
271 " <k>val2</k>\n"
272 " <l1>2</l1>\n"
273 "</lt>\n"
274 "<lt xmlns=\"urn:tests:d\">\n"
275 " <k>val3</k>\n"
276 " <l1>3</l1>\n"
277 "</lt>\n"
278 "<lt xmlns=\"urn:tests:d\">\n"
279 " <k>val4</k>\n"
280 " <l1>4</l1>\n"
281 "</lt>\n"
282 "<lt xmlns=\"urn:tests:d\">\n"
283 " <k>val5</k>\n"
284 " <l1>5</l1>\n"
285 "</lt>\n"
286 "<lt xmlns=\"urn:tests:d\">\n"
287 " <k>val6</k>\n"
288 " <l1>6</l1>\n"
289 "</lt>\n"
290 "<lt xmlns=\"urn:tests:d\">\n"
291 " <k>val7</k>\n"
292 " <l1>7</l1>\n"
293 "</lt>\n"
294 "<lt xmlns=\"urn:tests:d\">\n"
295 " <k>val8</k>\n"
296 " <l1>8</l1>\n"
297 "</lt>", tree);
298 lyd_free_all(tree);
299
300 LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
301 " <k>val1</k>\n"
302 " <l1>1</l1>\n"
303 "</lt>\n"
304 "<lt xmlns=\"urn:tests:d\">\n"
305 " <k>val2</k>\n"
306 " <l1>2</l1>\n"
307 "</lt>\n"
308 "<lt xmlns=\"urn:tests:d\">\n"
309 " <k>val3</k>\n"
310 " <l1>3</l1>\n"
311 "</lt>\n"
312 "<lt xmlns=\"urn:tests:d\">\n"
313 " <k>val4</k>\n"
314 "</lt>\n"
315 "<lt xmlns=\"urn:tests:d\">\n"
316 " <k>val5</k>\n"
317 " <l1>5</l1>\n"
318 "</lt>\n"
319 "<lt xmlns=\"urn:tests:d\">\n"
320 " <k>val6</k>\n"
321 " <l1>6</l1>\n"
322 "</lt>\n"
323 "<lt xmlns=\"urn:tests:d\">\n"
324 " <k>val7</k>\n"
325 "</lt>\n"
326 "<lt xmlns=\"urn:tests:d\">\n"
327 " <k>val8</k>\n"
328 "</lt>", tree);
329 lyd_free_all(tree);
330
331 CHECK_PARSE_LYD_PARAM("<lt xmlns=\"urn:tests:d\">\n"
332 " <k>val1</k>\n"
333 " <l1>1</l1>\n"
334 "</lt>\n"
335 "<lt xmlns=\"urn:tests:d\">\n"
336 " <k>val2</k>\n"
337 " <l1>2</l1>\n"
338 "</lt>\n"
339 "<lt xmlns=\"urn:tests:d\">\n"
340 " <k>val3</k>\n"
341 "</lt>\n"
342 "<lt xmlns=\"urn:tests:d\">\n"
343 " <k>val4</k>\n"
344 " <l1>4</l1>\n"
345 "</lt>\n"
346 "<lt xmlns=\"urn:tests:d\">\n"
347 " <k>val5</k>\n"
348 "</lt>\n"
349 "<lt xmlns=\"urn:tests:d\">\n"
350 " <k>val6</k>\n"
351 "</lt>\n"
352 "<lt xmlns=\"urn:tests:d\">\n"
353 " <k>val7</k>\n"
354 " <l1>2</l1>\n"
355 "</lt>\n"
356 "<lt xmlns=\"urn:tests:d\">\n"
357 " <k>val8</k>\n"
358 " <l1>8</l1>\n"
359 "</lt>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
360 CHECK_LOG_CTX("Unique data leaf(s) \"l1\" not satisfied in \"/d:lt[k='val7']\" and \"/d:lt[k='val2']\".", "/d:lt[k='val2']");
361}
362
363static void
364test_unique_nested(void **state)
365{
366 struct lyd_node *tree;
367
368 UTEST_ADD_MODULE(schema_d, LYS_IN_YANG, NULL, NULL);
369
370 /* nested list uniquest are compared only with instances in the same parent list instance */
371 LYD_TREE_CREATE("<lt2 xmlns=\"urn:tests:d\">\n"
372 " <k>val1</k>\n"
373 " <cont>\n"
374 " <l2>1</l2>\n"
375 " </cont>\n"
376 " <l4>1</l4>\n"
377 "</lt2>\n"
378 "<lt2 xmlns=\"urn:tests:d\">\n"
379 " <k>val2</k>\n"
380 " <cont>\n"
381 " <l2>2</l2>\n"
382 " </cont>\n"
383 " <l4>2</l4>\n"
384 " <lt3>\n"
385 " <kk>val1</kk>\n"
386 " <l3>1</l3>\n"
387 " </lt3>\n"
388 " <lt3>\n"
389 " <kk>val2</kk>\n"
390 " <l3>2</l3>\n"
391 " </lt3>\n"
392 "</lt2>\n"
393 "<lt2 xmlns=\"urn:tests:d\">\n"
394 " <k>val3</k>\n"
395 " <cont>\n"
396 " <l2>3</l2>\n"
397 " </cont>\n"
398 " <l4>3</l4>\n"
399 " <lt3>\n"
400 " <kk>val1</kk>\n"
401 " <l3>2</l3>\n"
402 " </lt3>\n"
403 "</lt2>\n"
404 "<lt2 xmlns=\"urn:tests:d\">\n"
405 " <k>val4</k>\n"
406 " <cont>\n"
407 " <l2>4</l2>\n"
408 " </cont>\n"
409 " <l4>4</l4>\n"
410 " <lt3>\n"
411 " <kk>val1</kk>\n"
412 " <l3>3</l3>\n"
413 " </lt3>\n"
414 "</lt2>\n"
415 "<lt2 xmlns=\"urn:tests:d\">\n"
416 " <k>val5</k>\n"
417 " <cont>\n"
418 " <l2>5</l2>\n"
419 " </cont>\n"
420 " <l4>5</l4>\n"
421 " <lt3>\n"
422 " <kk>val1</kk>\n"
423 " <l3>3</l3>\n"
424 " </lt3>\n"
425 "</lt2>", tree);
426 lyd_free_all(tree);
427
428 CHECK_PARSE_LYD_PARAM("<lt2 xmlns=\"urn:tests:d\">\n"
429 " <k>val1</k>\n"
430 " <cont>\n"
431 " <l2>1</l2>\n"
432 " </cont>\n"
433 " <l4>1</l4>\n"
434 "</lt2>\n"
435 "<lt2 xmlns=\"urn:tests:d\">\n"
436 " <k>val2</k>\n"
437 " <cont>\n"
438 " <l2>2</l2>\n"
439 " </cont>\n"
440 " <lt3>\n"
441 " <kk>val1</kk>\n"
442 " <l3>1</l3>\n"
443 " </lt3>\n"
444 " <lt3>\n"
445 " <kk>val2</kk>\n"
446 " <l3>2</l3>\n"
447 " </lt3>\n"
448 " <lt3>\n"
449 " <kk>val3</kk>\n"
450 " <l3>1</l3>\n"
451 " </lt3>\n"
452 "</lt2>\n"
453 "<lt2 xmlns=\"urn:tests:d\">\n"
454 " <k>val3</k>\n"
455 " <cont>\n"
456 " <l2>3</l2>\n"
457 " </cont>\n"
458 " <l4>1</l4>\n"
459 " <lt3>\n"
460 " <kk>val1</kk>\n"
461 " <l3>2</l3>\n"
462 " </lt3>\n"
463 "</lt2>\n"
464 "<lt2 xmlns=\"urn:tests:d\">\n"
465 " <k>val4</k>\n"
466 " <cont>\n"
467 " <l2>4</l2>\n"
468 " </cont>\n"
469 " <lt3>\n"
470 " <kk>val1</kk>\n"
471 " <l3>3</l3>\n"
472 " </lt3>\n"
473 "</lt2>\n"
474 "<lt2 xmlns=\"urn:tests:d\">\n"
475 " <k>val5</k>\n"
476 " <cont>\n"
477 " <l2>5</l2>\n"
478 " </cont>\n"
479 " <lt3>\n"
480 " <kk>val1</kk>\n"
481 " <l3>3</l3>\n"
482 " </lt3>\n"
483 "</lt2>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
484 CHECK_LOG_CTX("Unique data leaf(s) \"l3\" not satisfied in"
485 " \"/d:lt2[k='val2']/lt3[kk='val3']\" and"
486 " \"/d:lt2[k='val2']/lt3[kk='val1']\".", "/d:lt2[k='val2']/lt3[kk='val1']");
487
488 CHECK_PARSE_LYD_PARAM("<lt2 xmlns=\"urn:tests:d\">\n"
489 " <k>val1</k>\n"
490 " <cont>\n"
491 " <l2>1</l2>\n"
492 " </cont>\n"
493 " <l4>1</l4>\n"
494 "</lt2>\n"
495 "<lt2 xmlns=\"urn:tests:d\">\n"
496 " <k>val2</k>\n"
497 " <cont>\n"
498 " <l2>2</l2>\n"
499 " </cont>\n"
500 " <l4>2</l4>\n"
501 "</lt2>\n"
502 "<lt2 xmlns=\"urn:tests:d\">\n"
503 " <k>val3</k>\n"
504 " <cont>\n"
505 " <l2>3</l2>\n"
506 " </cont>\n"
507 " <l4>3</l4>\n"
508 "</lt2>\n"
509 "<lt2 xmlns=\"urn:tests:d\">\n"
510 " <k>val4</k>\n"
511 " <cont>\n"
512 " <l2>2</l2>\n"
513 " </cont>\n"
514 " <l4>2</l4>\n"
515 "</lt2>\n"
516 "<lt2 xmlns=\"urn:tests:d\">\n"
517 " <k>val5</k>\n"
518 " <cont>\n"
519 " <l2>5</l2>\n"
520 " </cont>\n"
521 " <l4>5</l4>\n"
522 "</lt2>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
523 CHECK_LOG_CTX("Unique data leaf(s) \"cont/l2 l4\" not satisfied in \"/d:lt2[k='val4']\" and \"/d:lt2[k='val2']\".", "/d:lt2[k='val2']");
524
525 CHECK_PARSE_LYD_PARAM("<lt2 xmlns=\"urn:tests:d\">\n"
526 " <k>val1</k>\n"
527 " <cont>\n"
528 " <l2>1</l2>\n"
529 " </cont>\n"
530 " <l4>1</l4>\n"
531 " <l5>1</l5>\n"
532 " <l6>1</l6>\n"
533 "</lt2>\n"
534 "<lt2 xmlns=\"urn:tests:d\">\n"
535 " <k>val2</k>\n"
536 " <cont>\n"
537 " <l2>2</l2>\n"
538 " </cont>\n"
539 " <l4>1</l4>\n"
540 " <l5>1</l5>\n"
541 "</lt2>\n"
542 "<lt2 xmlns=\"urn:tests:d\">\n"
543 " <k>val3</k>\n"
544 " <cont>\n"
545 " <l2>3</l2>\n"
546 " </cont>\n"
547 " <l4>1</l4>\n"
548 " <l5>3</l5>\n"
549 " <l6>3</l6>\n"
550 "</lt2>\n"
551 "<lt2 xmlns=\"urn:tests:d\">\n"
552 " <k>val4</k>\n"
553 " <cont>\n"
554 " <l2>4</l2>\n"
555 " </cont>\n"
556 " <l4>1</l4>\n"
557 " <l6>1</l6>\n"
558 "</lt2>\n"
559 "<lt2 xmlns=\"urn:tests:d\">\n"
560 " <k>val5</k>\n"
561 " <cont>\n"
562 " <l2>5</l2>\n"
563 " </cont>\n"
564 " <l4>1</l4>\n"
565 " <l5>3</l5>\n"
566 " <l6>3</l6>\n"
567 "</lt2>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
568 CHECK_LOG_CTX("Unique data leaf(s) \"l5 l6\" not satisfied in \"/d:lt2[k='val5']\" and \"/d:lt2[k='val3']\".",
569 "/d:lt2[k='val3']");
570}
571
572static void
573test_dup(void **state)
574{
575 struct lyd_node *tree;
576 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100577 "module e {\n"
578 " namespace urn:tests:e;\n"
579 " prefix e;\n"
580 " yang-version 1.1;\n"
581 "\n"
582 " choice choic {\n"
583 " leaf a {\n"
584 " type string;\n"
585 " }\n"
586 " case b {\n"
587 " leaf-list l {\n"
588 " type string;\n"
589 " }\n"
590 " }\n"
591 " }\n"
592 " list lt {\n"
593 " key \"k\";\n"
594 " leaf k {\n"
595 " type string;\n"
596 " }\n"
597 " }\n"
598 " leaf d {\n"
599 " type uint32;\n"
600 " }\n"
601 " leaf-list ll {\n"
602 " type string;\n"
603 " }\n"
604 " container cont {\n"
605 " list lt {\n"
606 " key \"k\";\n"
607 " leaf k {\n"
608 " type string;\n"
609 " }\n"
610 " }\n"
611 " leaf d {\n"
612 " type uint32;\n"
613 " }\n"
614 " leaf-list ll {\n"
615 " type string;\n"
616 " }\n"
617 " leaf-list ll2 {\n"
618 " type enumeration {\n"
619 " enum one;\n"
620 " enum two;\n"
621 " }\n"
622 " }\n"
623 " }\n"
624 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200625
626 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
627
628 CHECK_PARSE_LYD_PARAM("<d xmlns=\"urn:tests:e\">25</d><d xmlns=\"urn:tests:e\">50</d>",
629 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
630 CHECK_LOG_CTX("Duplicate instance of \"d\".", "/e:d");
631
632 CHECK_PARSE_LYD_PARAM("<lt xmlns=\"urn:tests:e\"><k>A</k></lt>"
633 "<lt xmlns=\"urn:tests:e\"><k>B</k></lt>"
634 "<lt xmlns=\"urn:tests:e\"><k>A</k></lt>",
635 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
636 CHECK_LOG_CTX("Duplicate instance of \"lt\".", "/e:lt[k='A']");
637
638 CHECK_PARSE_LYD_PARAM("<ll xmlns=\"urn:tests:e\">A</ll>"
639 "<ll xmlns=\"urn:tests:e\">B</ll>"
640 "<ll xmlns=\"urn:tests:e\">B</ll>",
641 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
642 CHECK_LOG_CTX("Duplicate instance of \"ll\".", "/e:ll[.='B']");
643
644 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"></cont><cont xmlns=\"urn:tests:e\"/>",
645 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
646 CHECK_LOG_CTX("Duplicate instance of \"cont\".", "/e:cont");
647
648 /* same tests again but using hashes */
649 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"><d>25</d><d>50</d><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll></cont>",
650 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
651 CHECK_LOG_CTX("Duplicate instance of \"d\".", "/e:cont/d");
652
653 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll>"
654 "<lt><k>a</k></lt>"
655 "<lt><k>b</k></lt>"
656 "<lt><k>c</k></lt>"
657 "<lt><k>d</k></lt>"
658 "<lt><k>c</k></lt></cont>",
659 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
660 CHECK_LOG_CTX("Duplicate instance of \"lt\".", "/e:cont/lt[k='c']");
661
662 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll>"
663 "<ll>a</ll><ll>b</ll><ll>c</ll><ll>d</ll><ll>d</ll></cont>",
664 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
665 CHECK_LOG_CTX("Duplicate instance of \"ll\".", "/e:cont/ll[.='d']");
666
667 /* cases */
668 CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:e\">a</l>"
669 "<l xmlns=\"urn:tests:e\">b</l>"
670 "<l xmlns=\"urn:tests:e\">c</l>"
671 "<l xmlns=\"urn:tests:e\">b</l>",
672 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
673 CHECK_LOG_CTX("Duplicate instance of \"l\".", "/e:l[.='b']");
674
675 CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:e\">a</l><l xmlns=\"urn:tests:e\">b</l>"
676 "<l xmlns=\"urn:tests:e\">c</l>"
677 "<a xmlns=\"urn:tests:e\">aa</a>",
678 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
679 CHECK_LOG_CTX("Data for both cases \"a\" and \"b\" exist.", "/e:choic");
680}
681
682static void
683test_defaults(void **state)
684{
685 struct lyd_node *tree, *node, *diff;
686 const struct lys_module *mod;
687 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100688 "module f {\n"
689 " namespace urn:tests:f;\n"
690 " prefix f;\n"
691 " yang-version 1.1;\n"
692 "\n"
693 " choice choic {\n"
694 " default \"c\";\n"
695 " leaf a {\n"
696 " type string;\n"
697 " }\n"
698 " case b {\n"
699 " leaf l {\n"
700 " type string;\n"
701 " }\n"
702 " }\n"
703 " case c {\n"
704 " leaf-list ll1 {\n"
705 " type string;\n"
706 " default \"def1\";\n"
707 " default \"def2\";\n"
708 " default \"def3\";\n"
709 " }\n"
710 " }\n"
711 " }\n"
712 " leaf d {\n"
713 " type uint32;\n"
714 " default 15;\n"
715 " }\n"
716 " leaf-list ll2 {\n"
717 " type string;\n"
718 " default \"dflt1\";\n"
719 " default \"dflt2\";\n"
720 " }\n"
721 " container cont {\n"
722 " choice choic {\n"
723 " default \"c\";\n"
724 " leaf a {\n"
725 " type string;\n"
726 " }\n"
727 " case b {\n"
728 " leaf l {\n"
729 " type string;\n"
730 " }\n"
731 " }\n"
732 " case c {\n"
733 " leaf-list ll1 {\n"
734 " type string;\n"
735 " default \"def1\";\n"
736 " default \"def2\";\n"
737 " default \"def3\";\n"
738 " }\n"
739 " }\n"
740 " }\n"
741 " leaf d {\n"
742 " type uint32;\n"
743 " default 15;\n"
744 " }\n"
745 " leaf-list ll2 {\n"
746 " type string;\n"
747 " default \"dflt1\";\n"
748 " default \"dflt2\";\n"
749 " }\n"
750 " }\n"
751 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200752
753 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
754
755 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
756 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-with-defaults", "2011-06-01", NULL));\
757
758 /* get defaults */
759 tree = NULL;
760 assert_int_equal(lyd_validate_module(&tree, mod, 0, &diff), LY_SUCCESS);
761 assert_non_null(tree);
762 assert_non_null(diff);
763
764 /* check all defaults exist */
765 CHECK_LYD_STRING_PARAM(tree,
766 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
767 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
768 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
769 "<d xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
770 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
771 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
772 "<cont xmlns=\"urn:tests:f\">\n"
773 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
774 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
775 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
776 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
777 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
778 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
779 "</cont>\n",
780 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
781
782 /* check diff */
783 CHECK_LYD_STRING_PARAM(diff,
784 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">def1</ll1>\n"
785 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">def2</ll1>\n"
786 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">def3</ll1>\n"
787 "<d xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">15</d>\n"
788 "<ll2 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">dflt1</ll2>\n"
789 "<ll2 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">dflt2</ll2>\n"
790 "<cont xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
791 " <ll1 yang:operation=\"create\">def1</ll1>\n"
792 " <ll1 yang:operation=\"create\">def2</ll1>\n"
793 " <ll1 yang:operation=\"create\">def3</ll1>\n"
794 " <d yang:operation=\"create\">15</d>\n"
795 " <ll2 yang:operation=\"create\">dflt1</ll2>\n"
796 " <ll2 yang:operation=\"create\">dflt2</ll2>\n"
797 "</cont>\n",
798 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
799 lyd_free_all(diff);
800
801 /* create another explicit case and validate */
802 assert_int_equal(lyd_new_term(NULL, mod, "l", "value", 0, &node), LY_SUCCESS);
803 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
804 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
805
806 /* check data tree */
807 CHECK_LYD_STRING_PARAM(tree,
808 "<l xmlns=\"urn:tests:f\">value</l>\n"
809 "<d xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
810 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
811 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
812 "<cont xmlns=\"urn:tests:f\">\n"
813 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
814 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
815 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
816 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
817 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
818 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
819 "</cont>\n",
820 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
821
822 /* check diff */
823 CHECK_LYD_STRING_PARAM(diff,
824 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">def1</ll1>\n"
825 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">def2</ll1>\n"
826 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">def3</ll1>\n",
827 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
828 lyd_free_all(diff);
829
830 /* create explicit leaf-list and leaf and validate */
831 assert_int_equal(lyd_new_term(NULL, mod, "d", "15", 0, &node), LY_SUCCESS);
832 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
833 assert_int_equal(lyd_new_term(NULL, mod, "ll2", "dflt2", 0, &node), LY_SUCCESS);
834 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
835 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
836
837 /* check data tree */
838 CHECK_LYD_STRING_PARAM(tree,
839 "<l xmlns=\"urn:tests:f\">value</l>\n"
840 "<d xmlns=\"urn:tests:f\">15</d>\n"
841 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
842 "<cont xmlns=\"urn:tests:f\">\n"
843 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
844 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
845 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
846 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
847 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
848 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
849 "</cont>\n",
850 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
851
852 /* check diff */
853 CHECK_LYD_STRING_PARAM(diff,
854 "<d xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">15</d>\n"
855 "<ll2 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">dflt1</ll2>\n"
856 "<ll2 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">dflt2</ll2>\n",
857 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
858 lyd_free_all(diff);
859
860 /* create first explicit container, which should become implicit */
861 assert_int_equal(lyd_new_inner(NULL, mod, "cont", 0, &node), LY_SUCCESS);
862 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
863 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
864
865 /* check data tree */
866 CHECK_LYD_STRING_PARAM(tree,
867 "<l xmlns=\"urn:tests:f\">value</l>\n"
868 "<d xmlns=\"urn:tests:f\">15</d>\n"
869 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
870 "<cont xmlns=\"urn:tests:f\">\n"
871 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
872 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
873 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
874 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
875 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
876 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
877 "</cont>\n",
878 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
879 /* check diff */
880 assert_null(diff);
881
882 /* create second explicit container, which should become implicit, so the first tree node should be removed */
883 assert_int_equal(lyd_new_inner(NULL, mod, "cont", 0, &node), LY_SUCCESS);
884 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
885 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
886
887 /* check data tree */
888 CHECK_LYD_STRING_PARAM(tree,
889 "<l xmlns=\"urn:tests:f\">value</l>\n"
890 "<d xmlns=\"urn:tests:f\">15</d>\n"
891 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
892 "<cont xmlns=\"urn:tests:f\">\n"
893 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
894 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
895 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
896 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
897 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
898 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
899 "</cont>\n",
900 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
901 /* check diff */
902 assert_null(diff);
903
904 /* similar changes for nested defaults */
905 assert_int_equal(lyd_new_term(tree->prev, NULL, "ll1", "def3", 0, NULL), LY_SUCCESS);
906 assert_int_equal(lyd_new_term(tree->prev, NULL, "d", "5", 0, NULL), LY_SUCCESS);
907 assert_int_equal(lyd_new_term(tree->prev, NULL, "ll2", "non-dflt", 0, NULL), LY_SUCCESS);
908 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
909
910 /* check data tree */
911 CHECK_LYD_STRING_PARAM(tree,
912 "<l xmlns=\"urn:tests:f\">value</l>\n"
913 "<d xmlns=\"urn:tests:f\">15</d>\n"
914 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
915 "<cont xmlns=\"urn:tests:f\">\n"
916 " <ll1>def3</ll1>\n"
917 " <d>5</d>\n"
918 " <ll2>non-dflt</ll2>\n"
919 "</cont>\n",
920 LYD_XML, LYD_PRINT_WITHSIBLINGS);
921
922 /* check diff */
923 CHECK_LYD_STRING_PARAM(diff,
924 "<cont xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
925 " <ll1 yang:operation=\"delete\">def1</ll1>\n"
926 " <ll1 yang:operation=\"delete\">def2</ll1>\n"
927 " <ll1 yang:operation=\"delete\">def3</ll1>\n"
928 " <d yang:operation=\"delete\">15</d>\n"
929 " <ll2 yang:operation=\"delete\">dflt1</ll2>\n"
930 " <ll2 yang:operation=\"delete\">dflt2</ll2>\n"
931 "</cont>\n",
932 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
933 lyd_free_all(diff);
934 lyd_free_all(tree);
935}
936
937static void
938test_state(void **state)
939{
940 const char *data;
941 struct lyd_node *tree;
942 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100943 "module h {\n"
944 " namespace urn:tests:h;\n"
945 " prefix h;\n"
946 " yang-version 1.1;\n"
947 "\n"
948 " container cont {\n"
949 " container cont2 {\n"
950 " config false;\n"
951 " leaf l {\n"
952 " type string;\n"
953 " }\n"
954 " }\n"
955 " }\n"
956 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200957
958 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
959
960 data = "<cont xmlns=\"urn:tests:h\">\n"
961 " <cont2>\n"
962 " <l>val</l>\n"
963 " </cont2>\n"
964 "</cont>\n";
965 CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_NO_STATE, 0, LY_EVALID, tree);
966 CHECK_LOG_CTX("Invalid state data node \"cont2\" found.", "/h:cont/cont2");
967
968 CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
969 assert_int_equal(LY_EVALID, lyd_validate_all(&tree, NULL, LYD_VALIDATE_PRESENT | LYD_VALIDATE_NO_STATE, NULL));
970 CHECK_LOG_CTX("Invalid state data node \"cont2\" found.", "/h:cont/cont2");
971 lyd_free_all(tree);
972}
973
974static void
975test_must(void **state)
976{
977 struct lyd_node *tree;
978 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100979 "module i {\n"
980 " namespace urn:tests:i;\n"
981 " prefix i;\n"
982 " yang-version 1.1;\n"
983 "\n"
984 " container cont {\n"
985 " leaf l {\n"
986 " type string;\n"
987 " }\n"
988 " leaf l2 {\n"
989 " must \"../l = 'right'\";\n"
990 " type string;\n"
991 " }\n"
992 " }\n"
993 "}";
Michal Vaskocde73ac2019-11-14 16:10:27 +0100994
Radek Iša56ca9e42020-09-08 18:42:00 +0200995 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
Michal Vaskocde73ac2019-11-14 16:10:27 +0100996
Radek Iša56ca9e42020-09-08 18:42:00 +0200997 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:i\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100998 " <l>wrong</l>\n"
999 " <l2>val</l2>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001000 "</cont>\n", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1001 CHECK_LOG_CTX("Must condition \"../l = 'right'\" not satisfied.", "/i:cont/l2");
Michal Vaskocc048b22020-03-27 15:52:38 +01001002
Radek Iša56ca9e42020-09-08 18:42:00 +02001003 LYD_TREE_CREATE("<cont xmlns=\"urn:tests:i\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001004 " <l>right</l>\n"
1005 " <l2>val</l2>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001006 "</cont>\n", tree);
1007 lyd_free_all(tree);
Michal Vaskocc048b22020-03-27 15:52:38 +01001008}
1009
Radek Iša56ca9e42020-09-08 18:42:00 +02001010const char *schema_j =
1011 "module j {\n"
1012 " namespace urn:tests:j;\n"
1013 " prefix j;\n"
1014 " yang-version 1.1;\n"
1015 "\n"
1016 " feature feat1;\n"
1017 "\n"
1018 " container cont {\n"
1019 " must \"false()\";\n"
1020 " list l1 {\n"
1021 " key \"k\";\n"
1022 " leaf k {\n"
1023 " type string;\n"
1024 " }\n"
1025 " action act {\n"
1026 " if-feature feat1;\n"
1027 " input {\n"
1028 " must \"../../lf1 = 'true'\";\n"
1029 " leaf lf2 {\n"
1030 " type leafref {\n"
1031 " path /lf3;\n"
1032 " }\n"
1033 " }\n"
1034 " }\n"
1035 " output {\n"
1036 " must \"../../lf1 = 'true2'\";\n"
1037 " leaf lf2 {\n"
1038 " type leafref {\n"
1039 " path /lf4;\n"
1040 " }\n"
1041 " }\n"
1042 " }\n"
1043 " }\n"
1044 " }\n"
1045 "\n"
1046 " leaf lf1 {\n"
1047 " type string;\n"
1048 " }\n"
1049 " }\n"
1050 "\n"
1051 " leaf lf3 {\n"
1052 " type string;\n"
1053 " }\n"
1054 "\n"
1055 " leaf lf4 {\n"
1056 " type string;\n"
1057 " }\n"
1058 "}";
1059const char *feats_j[] = {"feat1", NULL};
1060
Michal Vaskofea12c62020-03-30 11:00:15 +02001061static void
1062test_action(void **state)
1063{
Michal Vasko63f3d842020-07-08 10:10:14 +02001064 struct ly_in *in;
Michal Vaskofea12c62020-03-30 11:00:15 +02001065 struct lyd_node *tree, *op_tree;
Michal Vaskofea12c62020-03-30 11:00:15 +02001066
Radek Iša56ca9e42020-09-08 18:42:00 +02001067 UTEST_ADD_MODULE(schema_j, LYS_IN_YANG, feats_j, NULL);
1068
1069 assert_int_equal(LY_SUCCESS, ly_in_new_memory(
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001070 "<cont xmlns=\"urn:tests:j\">\n"
1071 " <l1>\n"
1072 " <k>val1</k>\n"
1073 " <act>\n"
1074 " <lf2>target</lf2>\n"
1075 " </act>\n"
1076 " </l1>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001077 "</cont>\n", &in));
1078 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(UTEST_LYCTX, in, LYD_XML, &op_tree, NULL));
Michal Vaskofea12c62020-03-30 11:00:15 +02001079 assert_non_null(op_tree);
1080
1081 /* missing leafref */
Michal Vasko8104fd42020-07-13 11:09:51 +02001082 assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, NULL, LYD_VALIDATE_OP_RPC, NULL));
Radek Iša56ca9e42020-09-08 18:42:00 +02001083 CHECK_LOG_CTX("Invalid leafref value \"target\" - no target instance \"/lf3\" with the same value.", "/j:cont/l1[k='val1']/act/lf2");
Michal Vasko63f3d842020-07-08 10:10:14 +02001084 ly_in_free(in, 0);
Michal Vaskofea12c62020-03-30 11:00:15 +02001085
Radek Iša56ca9e42020-09-08 18:42:00 +02001086 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001087 " <lf1>not true</lf1>\n"
1088 "</cont>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001089 "<lf3 xmlns=\"urn:tests:j\">target</lf3>\n",
1090 LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
Michal Vaskofea12c62020-03-30 11:00:15 +02001091
Michal Vaskofea12c62020-03-30 11:00:15 +02001092 /* input must false */
Michal Vasko8104fd42020-07-13 11:09:51 +02001093 assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, tree, LYD_VALIDATE_OP_RPC, NULL));
Radek Iša56ca9e42020-09-08 18:42:00 +02001094 CHECK_LOG_CTX("Must condition \"../../lf1 = 'true'\" not satisfied.", "/j:cont/l1[k='val1']/act");
Michal Vaskofea12c62020-03-30 11:00:15 +02001095
Radek Iša56ca9e42020-09-08 18:42:00 +02001096 lyd_free_all(tree);
1097 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001098 " <lf1>true</lf1>\n"
1099 "</cont>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001100 "<lf3 xmlns=\"urn:tests:j\">target</lf3>\n",
1101 LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
Michal Vaskofea12c62020-03-30 11:00:15 +02001102
1103 /* success */
Michal Vasko8104fd42020-07-13 11:09:51 +02001104 assert_int_equal(LY_SUCCESS, lyd_validate_op(op_tree, tree, LYD_VALIDATE_OP_RPC, NULL));
Michal Vaskofea12c62020-03-30 11:00:15 +02001105
Michal Vaskocb7526d2020-03-30 15:08:26 +02001106 lyd_free_tree(op_tree);
1107 lyd_free_siblings(tree);
Michal Vaskocb7526d2020-03-30 15:08:26 +02001108}
1109
1110static void
1111test_reply(void **state)
1112{
Michal Vasko63f3d842020-07-08 10:10:14 +02001113 struct ly_in *in;
Michal Vaskocb7526d2020-03-30 15:08:26 +02001114 struct lyd_node *tree, *op_tree, *request;
Michal Vaskocb7526d2020-03-30 15:08:26 +02001115
Radek Iša56ca9e42020-09-08 18:42:00 +02001116 UTEST_ADD_MODULE(schema_j, LYS_IN_YANG, feats_j, NULL);
1117
1118 assert_int_equal(LY_SUCCESS, ly_in_new_memory(
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001119 "<cont xmlns=\"urn:tests:j\">\n"
1120 " <l1>\n"
1121 " <k>val1</k>\n"
1122 " <act>\n"
1123 " <lf2>target</lf2>\n"
1124 " </act>\n"
1125 " </l1>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001126 "</cont>\n", &in));
1127 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(UTEST_LYCTX, in, LYD_XML, &request, NULL));
Michal Vaskocb7526d2020-03-30 15:08:26 +02001128 assert_non_null(request);
Michal Vasko63f3d842020-07-08 10:10:14 +02001129 ly_in_free(in, 0);
1130
Radek Iša56ca9e42020-09-08 18:42:00 +02001131 assert_int_equal(LY_SUCCESS, ly_in_new_memory("<lf2 xmlns=\"urn:tests:j\">target</lf2>", &in));
Michal Vasko63f3d842020-07-08 10:10:14 +02001132 assert_int_equal(LY_SUCCESS, lyd_parse_reply(request, in, LYD_XML, &op_tree, NULL));
Michal Vaskocb7526d2020-03-30 15:08:26 +02001133 lyd_free_all(request);
1134 assert_non_null(op_tree);
Michal Vasko63f3d842020-07-08 10:10:14 +02001135 ly_in_free(in, 0);
Michal Vaskocb7526d2020-03-30 15:08:26 +02001136
1137 /* missing leafref */
Michal Vasko8104fd42020-07-13 11:09:51 +02001138 assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, NULL, LYD_VALIDATE_OP_REPLY, NULL));
Radek Iša56ca9e42020-09-08 18:42:00 +02001139 CHECK_LOG_CTX("Invalid leafref value \"target\" - no target instance \"/lf4\" with the same value.", "/j:cont/l1[k='val1']/act/lf2");
Michal Vaskocb7526d2020-03-30 15:08:26 +02001140
Radek Iša56ca9e42020-09-08 18:42:00 +02001141 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001142 " <lf1>not true</lf1>\n"
1143 "</cont>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001144 "<lf4 xmlns=\"urn:tests:j\">target</lf4>\n",
1145 LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
Michal Vaskocb7526d2020-03-30 15:08:26 +02001146
Michal Vaskocb7526d2020-03-30 15:08:26 +02001147 /* input must false */
Michal Vasko8104fd42020-07-13 11:09:51 +02001148 assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, tree, LYD_VALIDATE_OP_REPLY, NULL));
Radek Iša56ca9e42020-09-08 18:42:00 +02001149 CHECK_LOG_CTX("Must condition \"../../lf1 = 'true2'\" not satisfied.", "/j:cont/l1[k='val1']/act");
Michal Vaskocb7526d2020-03-30 15:08:26 +02001150
Radek Iša56ca9e42020-09-08 18:42:00 +02001151 lyd_free_all(tree);
1152 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001153 " <lf1>true2</lf1>\n"
1154 "</cont>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001155 "<lf4 xmlns=\"urn:tests:j\">target</lf4>\n",
1156 LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
Michal Vaskocb7526d2020-03-30 15:08:26 +02001157
1158 /* success */
Michal Vasko8104fd42020-07-13 11:09:51 +02001159 assert_int_equal(LY_SUCCESS, lyd_validate_op(op_tree, tree, LYD_VALIDATE_OP_REPLY, NULL));
Michal Vaskocb7526d2020-03-30 15:08:26 +02001160
Michal Vaskofea12c62020-03-30 11:00:15 +02001161 lyd_free_tree(op_tree);
Radek Iša56ca9e42020-09-08 18:42:00 +02001162 lyd_free_all(tree);
Michal Vaskofea12c62020-03-30 11:00:15 +02001163}
1164
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001165int
1166main(void)
Michal Vaskocde73ac2019-11-14 16:10:27 +01001167{
1168 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +02001169 UTEST(test_when),
1170 UTEST(test_mandatory),
1171 UTEST(test_minmax),
1172 UTEST(test_unique),
1173 UTEST(test_unique_nested),
1174 UTEST(test_dup),
1175 UTEST(test_defaults),
1176 UTEST(test_state),
1177 UTEST(test_must),
1178 UTEST(test_action),
1179 UTEST(test_reply),
Michal Vaskocde73ac2019-11-14 16:10:27 +01001180 };
1181
Radek Iša56ca9e42020-09-08 18:42:00 +02001182 return cmocka_run_group_tests(tests, NULL, NULL);
Michal Vaskocde73ac2019-11-14 16:10:27 +01001183}