blob: df6404c2cb0894875b6827b9df2eaea01eecd027 [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);
Radek Krejci2efc45b2020-12-22 16:25:44 +010060 CHECK_LOG_CTX("When condition \"/cont/b = 'val_b'\" not satisfied.", "Schema location /a:c, data location /a:c.");
Radek Iša56ca9e42020-09-08 18:42:00 +020061
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);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100108 CHECK_LOG_CTX("Mandatory node \"choic\" instance does not exist.", "Schema location /b:choic.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200109
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);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100111 CHECK_LOG_CTX("Mandatory node \"c\" instance does not exist.", "Schema location /b:c.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200112
113 CHECK_PARSE_LYD_PARAM("<a xmlns=\"urn:tests:b\">string</a>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100114 CHECK_LOG_CTX("Mandatory node \"c\" instance does not exist.", "Schema location /b:c.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200115
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);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100156 CHECK_LOG_CTX("Too few \"l\" instances.", "Schema location /c:choic/b/l.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200157
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);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100161 CHECK_LOG_CTX("Too few \"l\" instances.", "Schema location /c:choic/b/l.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200162
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>"
Radek Krejci2efc45b2020-12-22 16:25:44 +0100175 "<lt xmlns=\"urn:tests:c\"><k>val5</k></lt>"
176 "<lt xmlns=\"urn:tests:c\"><k>val6</k></lt>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
177 CHECK_LOG_CTX("Too many \"lt\" instances.", "Schema location /c:lt, data location /c:lt[k='val5'].");
Radek Iša56ca9e42020-09-08 18:42:00 +0200178}
179
180const char *schema_d =
181 "module d {\n"
182 " namespace urn:tests:d;\n"
183 " prefix d;\n"
184 " yang-version 1.1;\n"
185 "\n"
186 " list lt {\n"
187 " key \"k\";\n"
188 " unique \"l1\";\n"
189 " leaf k {\n"
190 " type string;\n"
191 " }\n"
192 " leaf l1 {\n"
193 " type string;\n"
194 " }\n"
195 " }\n"
196 " list lt2 {\n"
197 " key \"k\";\n"
198 " unique \"cont/l2 l4\";\n"
199 " unique \"l5 l6\";\n"
200 " leaf k {\n"
201 " type string;\n"
202 " }\n"
203 " container cont {\n"
204 " leaf l2 {\n"
205 " type string;\n"
206 " }\n"
207 " }\n"
208 " leaf l4 {\n"
209 " type string;\n"
210 " }\n"
211 " leaf l5 {\n"
212 " type string;\n"
213 " }\n"
214 " leaf l6 {\n"
215 " type string;\n"
216 " }\n"
217 " list lt3 {\n"
218 " key \"kk\";\n"
219 " unique \"l3\";\n"
220 " leaf kk {\n"
221 " type string;\n"
222 " }\n"
223 " leaf l3 {\n"
224 " type string;\n"
225 " }\n"
226 " }\n"
227 " }\n"
228 "}";
229
230static void
231test_unique(void **state)
232{
233 struct lyd_node *tree;
234
235 UTEST_ADD_MODULE(schema_d, LYS_IN_YANG, NULL, NULL);
236
237 LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
238 " <k>val1</k>\n"
239 " <l1>same</l1>\n"
240 "</lt>\n"
241 "<lt xmlns=\"urn:tests:d\">\n"
242 " <k>val2</k>\n"
243 "</lt>", tree);
244 lyd_free_all(tree);
245
246 LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
247 " <k>val1</k>\n"
248 " <l1>same</l1>\n"
249 "</lt>\n"
250 "<lt xmlns=\"urn:tests:d\">\n"
251 " <k>val2</k>\n"
252 " <l1>not-same</l1>\n"
253 "</lt>", tree);
254 lyd_free_all(tree);
255
256 CHECK_PARSE_LYD_PARAM("<lt xmlns=\"urn:tests:d\">\n"
257 " <k>val1</k>\n"
258 " <l1>same</l1>\n"
259 "</lt>\n"
260 "<lt xmlns=\"urn:tests:d\">\n"
261 " <k>val2</k>\n"
262 " <l1>same</l1>\n"
263 "</lt>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100264 CHECK_LOG_CTX("Unique data leaf(s) \"l1\" not satisfied in \"/d:lt[k='val1']\" and \"/d:lt[k='val2']\".",
265 "Schema location /d:lt, data location /d:lt[k='val2'].");
Radek Iša56ca9e42020-09-08 18:42:00 +0200266
267 /* now try with more instances */
268 LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
269 " <k>val1</k>\n"
270 " <l1>1</l1>\n"
271 "</lt>\n"
272 "<lt xmlns=\"urn:tests:d\">\n"
273 " <k>val2</k>\n"
274 " <l1>2</l1>\n"
275 "</lt>\n"
276 "<lt xmlns=\"urn:tests:d\">\n"
277 " <k>val3</k>\n"
278 " <l1>3</l1>\n"
279 "</lt>\n"
280 "<lt xmlns=\"urn:tests:d\">\n"
281 " <k>val4</k>\n"
282 " <l1>4</l1>\n"
283 "</lt>\n"
284 "<lt xmlns=\"urn:tests:d\">\n"
285 " <k>val5</k>\n"
286 " <l1>5</l1>\n"
287 "</lt>\n"
288 "<lt xmlns=\"urn:tests:d\">\n"
289 " <k>val6</k>\n"
290 " <l1>6</l1>\n"
291 "</lt>\n"
292 "<lt xmlns=\"urn:tests:d\">\n"
293 " <k>val7</k>\n"
294 " <l1>7</l1>\n"
295 "</lt>\n"
296 "<lt xmlns=\"urn:tests:d\">\n"
297 " <k>val8</k>\n"
298 " <l1>8</l1>\n"
299 "</lt>", tree);
300 lyd_free_all(tree);
301
302 LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
303 " <k>val1</k>\n"
304 " <l1>1</l1>\n"
305 "</lt>\n"
306 "<lt xmlns=\"urn:tests:d\">\n"
307 " <k>val2</k>\n"
308 " <l1>2</l1>\n"
309 "</lt>\n"
310 "<lt xmlns=\"urn:tests:d\">\n"
311 " <k>val3</k>\n"
312 " <l1>3</l1>\n"
313 "</lt>\n"
314 "<lt xmlns=\"urn:tests:d\">\n"
315 " <k>val4</k>\n"
316 "</lt>\n"
317 "<lt xmlns=\"urn:tests:d\">\n"
318 " <k>val5</k>\n"
319 " <l1>5</l1>\n"
320 "</lt>\n"
321 "<lt xmlns=\"urn:tests:d\">\n"
322 " <k>val6</k>\n"
323 " <l1>6</l1>\n"
324 "</lt>\n"
325 "<lt xmlns=\"urn:tests:d\">\n"
326 " <k>val7</k>\n"
327 "</lt>\n"
328 "<lt xmlns=\"urn:tests:d\">\n"
329 " <k>val8</k>\n"
330 "</lt>", tree);
331 lyd_free_all(tree);
332
333 CHECK_PARSE_LYD_PARAM("<lt xmlns=\"urn:tests:d\">\n"
334 " <k>val1</k>\n"
335 " <l1>1</l1>\n"
336 "</lt>\n"
337 "<lt xmlns=\"urn:tests:d\">\n"
338 " <k>val2</k>\n"
339 " <l1>2</l1>\n"
340 "</lt>\n"
341 "<lt xmlns=\"urn:tests:d\">\n"
342 " <k>val3</k>\n"
343 "</lt>\n"
344 "<lt xmlns=\"urn:tests:d\">\n"
345 " <k>val4</k>\n"
346 " <l1>4</l1>\n"
347 "</lt>\n"
348 "<lt xmlns=\"urn:tests:d\">\n"
349 " <k>val5</k>\n"
350 "</lt>\n"
351 "<lt xmlns=\"urn:tests:d\">\n"
352 " <k>val6</k>\n"
353 "</lt>\n"
354 "<lt xmlns=\"urn:tests:d\">\n"
355 " <k>val7</k>\n"
356 " <l1>2</l1>\n"
357 "</lt>\n"
358 "<lt xmlns=\"urn:tests:d\">\n"
359 " <k>val8</k>\n"
360 " <l1>8</l1>\n"
361 "</lt>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100362 CHECK_LOG_CTX("Unique data leaf(s) \"l1\" not satisfied in \"/d:lt[k='val7']\" and \"/d:lt[k='val2']\".",
363 "Schema location /d:lt, data location /d:lt[k='val2'].");
Radek Iša56ca9e42020-09-08 18:42:00 +0200364}
365
366static void
367test_unique_nested(void **state)
368{
369 struct lyd_node *tree;
370
371 UTEST_ADD_MODULE(schema_d, LYS_IN_YANG, NULL, NULL);
372
373 /* nested list uniquest are compared only with instances in the same parent list instance */
374 LYD_TREE_CREATE("<lt2 xmlns=\"urn:tests:d\">\n"
375 " <k>val1</k>\n"
376 " <cont>\n"
377 " <l2>1</l2>\n"
378 " </cont>\n"
379 " <l4>1</l4>\n"
380 "</lt2>\n"
381 "<lt2 xmlns=\"urn:tests:d\">\n"
382 " <k>val2</k>\n"
383 " <cont>\n"
384 " <l2>2</l2>\n"
385 " </cont>\n"
386 " <l4>2</l4>\n"
387 " <lt3>\n"
388 " <kk>val1</kk>\n"
389 " <l3>1</l3>\n"
390 " </lt3>\n"
391 " <lt3>\n"
392 " <kk>val2</kk>\n"
393 " <l3>2</l3>\n"
394 " </lt3>\n"
395 "</lt2>\n"
396 "<lt2 xmlns=\"urn:tests:d\">\n"
397 " <k>val3</k>\n"
398 " <cont>\n"
399 " <l2>3</l2>\n"
400 " </cont>\n"
401 " <l4>3</l4>\n"
402 " <lt3>\n"
403 " <kk>val1</kk>\n"
404 " <l3>2</l3>\n"
405 " </lt3>\n"
406 "</lt2>\n"
407 "<lt2 xmlns=\"urn:tests:d\">\n"
408 " <k>val4</k>\n"
409 " <cont>\n"
410 " <l2>4</l2>\n"
411 " </cont>\n"
412 " <l4>4</l4>\n"
413 " <lt3>\n"
414 " <kk>val1</kk>\n"
415 " <l3>3</l3>\n"
416 " </lt3>\n"
417 "</lt2>\n"
418 "<lt2 xmlns=\"urn:tests:d\">\n"
419 " <k>val5</k>\n"
420 " <cont>\n"
421 " <l2>5</l2>\n"
422 " </cont>\n"
423 " <l4>5</l4>\n"
424 " <lt3>\n"
425 " <kk>val1</kk>\n"
426 " <l3>3</l3>\n"
427 " </lt3>\n"
428 "</lt2>", tree);
429 lyd_free_all(tree);
430
431 CHECK_PARSE_LYD_PARAM("<lt2 xmlns=\"urn:tests:d\">\n"
432 " <k>val1</k>\n"
433 " <cont>\n"
434 " <l2>1</l2>\n"
435 " </cont>\n"
436 " <l4>1</l4>\n"
437 "</lt2>\n"
438 "<lt2 xmlns=\"urn:tests:d\">\n"
439 " <k>val2</k>\n"
440 " <cont>\n"
441 " <l2>2</l2>\n"
442 " </cont>\n"
443 " <lt3>\n"
444 " <kk>val1</kk>\n"
445 " <l3>1</l3>\n"
446 " </lt3>\n"
447 " <lt3>\n"
448 " <kk>val2</kk>\n"
449 " <l3>2</l3>\n"
450 " </lt3>\n"
451 " <lt3>\n"
452 " <kk>val3</kk>\n"
453 " <l3>1</l3>\n"
454 " </lt3>\n"
455 "</lt2>\n"
456 "<lt2 xmlns=\"urn:tests:d\">\n"
457 " <k>val3</k>\n"
458 " <cont>\n"
459 " <l2>3</l2>\n"
460 " </cont>\n"
461 " <l4>1</l4>\n"
462 " <lt3>\n"
463 " <kk>val1</kk>\n"
464 " <l3>2</l3>\n"
465 " </lt3>\n"
466 "</lt2>\n"
467 "<lt2 xmlns=\"urn:tests:d\">\n"
468 " <k>val4</k>\n"
469 " <cont>\n"
470 " <l2>4</l2>\n"
471 " </cont>\n"
472 " <lt3>\n"
473 " <kk>val1</kk>\n"
474 " <l3>3</l3>\n"
475 " </lt3>\n"
476 "</lt2>\n"
477 "<lt2 xmlns=\"urn:tests:d\">\n"
478 " <k>val5</k>\n"
479 " <cont>\n"
480 " <l2>5</l2>\n"
481 " </cont>\n"
482 " <lt3>\n"
483 " <kk>val1</kk>\n"
484 " <l3>3</l3>\n"
485 " </lt3>\n"
486 "</lt2>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100487 CHECK_LOG_CTX("Unique data leaf(s) \"l3\" not satisfied in \"/d:lt2[k='val2']/lt3[kk='val3']\" and \"/d:lt2[k='val2']/lt3[kk='val1']\".",
488 "Schema location /d:lt2/lt3, data location /d:lt2[k='val2']/lt3[kk='val1'].");
Radek Iša56ca9e42020-09-08 18:42:00 +0200489
490 CHECK_PARSE_LYD_PARAM("<lt2 xmlns=\"urn:tests:d\">\n"
491 " <k>val1</k>\n"
492 " <cont>\n"
493 " <l2>1</l2>\n"
494 " </cont>\n"
495 " <l4>1</l4>\n"
496 "</lt2>\n"
497 "<lt2 xmlns=\"urn:tests:d\">\n"
498 " <k>val2</k>\n"
499 " <cont>\n"
500 " <l2>2</l2>\n"
501 " </cont>\n"
502 " <l4>2</l4>\n"
503 "</lt2>\n"
504 "<lt2 xmlns=\"urn:tests:d\">\n"
505 " <k>val3</k>\n"
506 " <cont>\n"
507 " <l2>3</l2>\n"
508 " </cont>\n"
509 " <l4>3</l4>\n"
510 "</lt2>\n"
511 "<lt2 xmlns=\"urn:tests:d\">\n"
512 " <k>val4</k>\n"
513 " <cont>\n"
514 " <l2>2</l2>\n"
515 " </cont>\n"
516 " <l4>2</l4>\n"
517 "</lt2>\n"
518 "<lt2 xmlns=\"urn:tests:d\">\n"
519 " <k>val5</k>\n"
520 " <cont>\n"
521 " <l2>5</l2>\n"
522 " </cont>\n"
523 " <l4>5</l4>\n"
524 "</lt2>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100525 CHECK_LOG_CTX("Unique data leaf(s) \"cont/l2 l4\" not satisfied in \"/d:lt2[k='val4']\" and \"/d:lt2[k='val2']\".",
526 "Schema location /d:lt2, data location /d:lt2[k='val2'].");
Radek Iša56ca9e42020-09-08 18:42:00 +0200527
528 CHECK_PARSE_LYD_PARAM("<lt2 xmlns=\"urn:tests:d\">\n"
529 " <k>val1</k>\n"
530 " <cont>\n"
531 " <l2>1</l2>\n"
532 " </cont>\n"
533 " <l4>1</l4>\n"
534 " <l5>1</l5>\n"
535 " <l6>1</l6>\n"
536 "</lt2>\n"
537 "<lt2 xmlns=\"urn:tests:d\">\n"
538 " <k>val2</k>\n"
539 " <cont>\n"
540 " <l2>2</l2>\n"
541 " </cont>\n"
542 " <l4>1</l4>\n"
543 " <l5>1</l5>\n"
544 "</lt2>\n"
545 "<lt2 xmlns=\"urn:tests:d\">\n"
546 " <k>val3</k>\n"
547 " <cont>\n"
548 " <l2>3</l2>\n"
549 " </cont>\n"
550 " <l4>1</l4>\n"
551 " <l5>3</l5>\n"
552 " <l6>3</l6>\n"
553 "</lt2>\n"
554 "<lt2 xmlns=\"urn:tests:d\">\n"
555 " <k>val4</k>\n"
556 " <cont>\n"
557 " <l2>4</l2>\n"
558 " </cont>\n"
559 " <l4>1</l4>\n"
560 " <l6>1</l6>\n"
561 "</lt2>\n"
562 "<lt2 xmlns=\"urn:tests:d\">\n"
563 " <k>val5</k>\n"
564 " <cont>\n"
565 " <l2>5</l2>\n"
566 " </cont>\n"
567 " <l4>1</l4>\n"
568 " <l5>3</l5>\n"
569 " <l6>3</l6>\n"
570 "</lt2>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
571 CHECK_LOG_CTX("Unique data leaf(s) \"l5 l6\" not satisfied in \"/d:lt2[k='val5']\" and \"/d:lt2[k='val3']\".",
Radek Krejci2efc45b2020-12-22 16:25:44 +0100572 "Schema location /d:lt2, data location /d:lt2[k='val3'].");
Radek Iša56ca9e42020-09-08 18:42:00 +0200573}
574
575static void
576test_dup(void **state)
577{
578 struct lyd_node *tree;
579 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100580 "module e {\n"
581 " namespace urn:tests:e;\n"
582 " prefix e;\n"
583 " yang-version 1.1;\n"
584 "\n"
585 " choice choic {\n"
586 " leaf a {\n"
587 " type string;\n"
588 " }\n"
589 " case b {\n"
590 " leaf-list l {\n"
591 " type string;\n"
592 " }\n"
593 " }\n"
594 " }\n"
595 " list lt {\n"
596 " key \"k\";\n"
597 " leaf k {\n"
598 " type string;\n"
599 " }\n"
600 " }\n"
601 " leaf d {\n"
602 " type uint32;\n"
603 " }\n"
604 " leaf-list ll {\n"
605 " type string;\n"
606 " }\n"
607 " container cont {\n"
608 " list lt {\n"
609 " key \"k\";\n"
610 " leaf k {\n"
611 " type string;\n"
612 " }\n"
613 " }\n"
614 " leaf d {\n"
615 " type uint32;\n"
616 " }\n"
617 " leaf-list ll {\n"
618 " type string;\n"
619 " }\n"
620 " leaf-list ll2 {\n"
621 " type enumeration {\n"
622 " enum one;\n"
623 " enum two;\n"
624 " }\n"
625 " }\n"
626 " }\n"
627 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200628
629 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
630
631 CHECK_PARSE_LYD_PARAM("<d xmlns=\"urn:tests:e\">25</d><d xmlns=\"urn:tests:e\">50</d>",
632 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100633 CHECK_LOG_CTX("Duplicate instance of \"d\".", "Schema location /e:d, data location /e:d.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200634
635 CHECK_PARSE_LYD_PARAM("<lt xmlns=\"urn:tests:e\"><k>A</k></lt>"
636 "<lt xmlns=\"urn:tests:e\"><k>B</k></lt>"
637 "<lt xmlns=\"urn:tests:e\"><k>A</k></lt>",
638 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100639 CHECK_LOG_CTX("Duplicate instance of \"lt\".", "Schema location /e:lt, data location /e:lt[k='A'].");
Radek Iša56ca9e42020-09-08 18:42:00 +0200640
641 CHECK_PARSE_LYD_PARAM("<ll xmlns=\"urn:tests:e\">A</ll>"
642 "<ll xmlns=\"urn:tests:e\">B</ll>"
643 "<ll xmlns=\"urn:tests:e\">B</ll>",
644 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100645 CHECK_LOG_CTX("Duplicate instance of \"ll\".", "Schema location /e:ll, data location /e:ll[.='B'].");
Radek Iša56ca9e42020-09-08 18:42:00 +0200646
647 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"></cont><cont xmlns=\"urn:tests:e\"/>",
648 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100649 CHECK_LOG_CTX("Duplicate instance of \"cont\".", "Schema location /e:cont, data location /e:cont.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200650
651 /* same tests again but using hashes */
652 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>",
653 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100654 CHECK_LOG_CTX("Duplicate instance of \"d\".", "Schema location /e:cont/d, data location /e:cont/d, line number 1.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200655
656 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll>"
657 "<lt><k>a</k></lt>"
658 "<lt><k>b</k></lt>"
659 "<lt><k>c</k></lt>"
660 "<lt><k>d</k></lt>"
661 "<lt><k>c</k></lt></cont>",
662 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100663 CHECK_LOG_CTX("Duplicate instance of \"lt\".", "Schema location /e:cont/lt, data location /e:cont/lt[k='c'], line number 1.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200664
665 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll>"
666 "<ll>a</ll><ll>b</ll><ll>c</ll><ll>d</ll><ll>d</ll></cont>",
667 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100668 CHECK_LOG_CTX("Duplicate instance of \"ll\".", "Schema location /e:cont/ll, data location /e:cont/ll[.='d'], line number 1.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200669
670 /* cases */
671 CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:e\">a</l>"
672 "<l xmlns=\"urn:tests:e\">b</l>"
673 "<l xmlns=\"urn:tests:e\">c</l>"
674 "<l xmlns=\"urn:tests:e\">b</l>",
675 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100676 CHECK_LOG_CTX("Duplicate instance of \"l\".", "Schema location /e:choic/b/l, data location /e:l[.='b'].");
Radek Iša56ca9e42020-09-08 18:42:00 +0200677
678 CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:e\">a</l><l xmlns=\"urn:tests:e\">b</l>"
679 "<l xmlns=\"urn:tests:e\">c</l>"
680 "<a xmlns=\"urn:tests:e\">aa</a>",
681 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100682 CHECK_LOG_CTX("Data for both cases \"a\" and \"b\" exist.", "Schema location /e:choic.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200683}
684
685static void
686test_defaults(void **state)
687{
688 struct lyd_node *tree, *node, *diff;
689 const struct lys_module *mod;
690 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100691 "module f {\n"
692 " namespace urn:tests:f;\n"
693 " prefix f;\n"
694 " yang-version 1.1;\n"
695 "\n"
696 " choice choic {\n"
697 " default \"c\";\n"
698 " leaf a {\n"
699 " type string;\n"
700 " }\n"
701 " case b {\n"
702 " leaf l {\n"
703 " type string;\n"
704 " }\n"
705 " }\n"
706 " case c {\n"
707 " leaf-list ll1 {\n"
708 " type string;\n"
709 " default \"def1\";\n"
710 " default \"def2\";\n"
711 " default \"def3\";\n"
712 " }\n"
713 " }\n"
714 " }\n"
715 " leaf d {\n"
716 " type uint32;\n"
717 " default 15;\n"
718 " }\n"
719 " leaf-list ll2 {\n"
720 " type string;\n"
721 " default \"dflt1\";\n"
722 " default \"dflt2\";\n"
723 " }\n"
724 " container cont {\n"
725 " choice choic {\n"
726 " default \"c\";\n"
727 " leaf a {\n"
728 " type string;\n"
729 " }\n"
730 " case b {\n"
731 " leaf l {\n"
732 " type string;\n"
733 " }\n"
734 " }\n"
735 " case c {\n"
736 " leaf-list ll1 {\n"
737 " type string;\n"
738 " default \"def1\";\n"
739 " default \"def2\";\n"
740 " default \"def3\";\n"
741 " }\n"
742 " }\n"
743 " }\n"
744 " leaf d {\n"
745 " type uint32;\n"
746 " default 15;\n"
747 " }\n"
748 " leaf-list ll2 {\n"
749 " type string;\n"
750 " default \"dflt1\";\n"
751 " default \"dflt2\";\n"
752 " }\n"
753 " }\n"
754 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200755
756 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
757
758 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
759 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-with-defaults", "2011-06-01", NULL));\
760
761 /* get defaults */
762 tree = NULL;
763 assert_int_equal(lyd_validate_module(&tree, mod, 0, &diff), LY_SUCCESS);
764 assert_non_null(tree);
765 assert_non_null(diff);
766
767 /* check all defaults exist */
768 CHECK_LYD_STRING_PARAM(tree,
769 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
770 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
771 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
772 "<d xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
773 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
774 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
775 "<cont xmlns=\"urn:tests:f\">\n"
776 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
777 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
778 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
779 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
780 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
781 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
782 "</cont>\n",
783 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
784
785 /* check diff */
786 CHECK_LYD_STRING_PARAM(diff,
787 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">def1</ll1>\n"
788 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">def2</ll1>\n"
789 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">def3</ll1>\n"
790 "<d xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">15</d>\n"
791 "<ll2 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">dflt1</ll2>\n"
792 "<ll2 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">dflt2</ll2>\n"
793 "<cont xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
794 " <ll1 yang:operation=\"create\">def1</ll1>\n"
795 " <ll1 yang:operation=\"create\">def2</ll1>\n"
796 " <ll1 yang:operation=\"create\">def3</ll1>\n"
797 " <d yang:operation=\"create\">15</d>\n"
798 " <ll2 yang:operation=\"create\">dflt1</ll2>\n"
799 " <ll2 yang:operation=\"create\">dflt2</ll2>\n"
800 "</cont>\n",
801 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
802 lyd_free_all(diff);
803
804 /* create another explicit case and validate */
805 assert_int_equal(lyd_new_term(NULL, mod, "l", "value", 0, &node), LY_SUCCESS);
806 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
807 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
808
809 /* check data tree */
810 CHECK_LYD_STRING_PARAM(tree,
811 "<l xmlns=\"urn:tests:f\">value</l>\n"
812 "<d xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
813 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
814 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
815 "<cont xmlns=\"urn:tests:f\">\n"
816 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
817 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
818 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
819 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
820 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
821 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
822 "</cont>\n",
823 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
824
825 /* check diff */
826 CHECK_LYD_STRING_PARAM(diff,
827 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">def1</ll1>\n"
828 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">def2</ll1>\n"
829 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">def3</ll1>\n",
830 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
831 lyd_free_all(diff);
832
833 /* create explicit leaf-list and leaf and validate */
834 assert_int_equal(lyd_new_term(NULL, mod, "d", "15", 0, &node), LY_SUCCESS);
835 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
836 assert_int_equal(lyd_new_term(NULL, mod, "ll2", "dflt2", 0, &node), LY_SUCCESS);
837 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
838 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
839
840 /* check data tree */
841 CHECK_LYD_STRING_PARAM(tree,
842 "<l xmlns=\"urn:tests:f\">value</l>\n"
843 "<d xmlns=\"urn:tests:f\">15</d>\n"
844 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
845 "<cont xmlns=\"urn:tests:f\">\n"
846 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
847 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
848 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
849 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
850 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
851 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
852 "</cont>\n",
853 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
854
855 /* check diff */
856 CHECK_LYD_STRING_PARAM(diff,
857 "<d xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">15</d>\n"
858 "<ll2 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">dflt1</ll2>\n"
859 "<ll2 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">dflt2</ll2>\n",
860 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
861 lyd_free_all(diff);
862
863 /* create first explicit container, which should become implicit */
864 assert_int_equal(lyd_new_inner(NULL, mod, "cont", 0, &node), LY_SUCCESS);
865 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
866 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
867
868 /* check data tree */
869 CHECK_LYD_STRING_PARAM(tree,
870 "<l xmlns=\"urn:tests:f\">value</l>\n"
871 "<d xmlns=\"urn:tests:f\">15</d>\n"
872 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
873 "<cont xmlns=\"urn:tests:f\">\n"
874 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
875 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
876 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
877 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
878 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
879 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
880 "</cont>\n",
881 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
882 /* check diff */
883 assert_null(diff);
884
885 /* create second explicit container, which should become implicit, so the first tree node should be removed */
886 assert_int_equal(lyd_new_inner(NULL, mod, "cont", 0, &node), LY_SUCCESS);
887 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
888 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
889
890 /* check data tree */
891 CHECK_LYD_STRING_PARAM(tree,
892 "<l xmlns=\"urn:tests:f\">value</l>\n"
893 "<d xmlns=\"urn:tests:f\">15</d>\n"
894 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
895 "<cont xmlns=\"urn:tests:f\">\n"
896 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
897 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
898 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
899 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
900 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
901 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
902 "</cont>\n",
903 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
904 /* check diff */
905 assert_null(diff);
906
907 /* similar changes for nested defaults */
908 assert_int_equal(lyd_new_term(tree->prev, NULL, "ll1", "def3", 0, NULL), LY_SUCCESS);
909 assert_int_equal(lyd_new_term(tree->prev, NULL, "d", "5", 0, NULL), LY_SUCCESS);
910 assert_int_equal(lyd_new_term(tree->prev, NULL, "ll2", "non-dflt", 0, NULL), LY_SUCCESS);
911 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
912
913 /* check data tree */
914 CHECK_LYD_STRING_PARAM(tree,
915 "<l xmlns=\"urn:tests:f\">value</l>\n"
916 "<d xmlns=\"urn:tests:f\">15</d>\n"
917 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
918 "<cont xmlns=\"urn:tests:f\">\n"
919 " <ll1>def3</ll1>\n"
920 " <d>5</d>\n"
921 " <ll2>non-dflt</ll2>\n"
922 "</cont>\n",
923 LYD_XML, LYD_PRINT_WITHSIBLINGS);
924
925 /* check diff */
926 CHECK_LYD_STRING_PARAM(diff,
927 "<cont xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
928 " <ll1 yang:operation=\"delete\">def1</ll1>\n"
929 " <ll1 yang:operation=\"delete\">def2</ll1>\n"
930 " <ll1 yang:operation=\"delete\">def3</ll1>\n"
931 " <d yang:operation=\"delete\">15</d>\n"
932 " <ll2 yang:operation=\"delete\">dflt1</ll2>\n"
933 " <ll2 yang:operation=\"delete\">dflt2</ll2>\n"
934 "</cont>\n",
935 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
936 lyd_free_all(diff);
937 lyd_free_all(tree);
938}
939
940static void
941test_state(void **state)
942{
943 const char *data;
944 struct lyd_node *tree;
945 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100946 "module h {\n"
947 " namespace urn:tests:h;\n"
948 " prefix h;\n"
949 " yang-version 1.1;\n"
950 "\n"
951 " container cont {\n"
952 " container cont2 {\n"
953 " config false;\n"
954 " leaf l {\n"
955 " type string;\n"
956 " }\n"
957 " }\n"
958 " }\n"
959 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200960
961 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
962
963 data = "<cont xmlns=\"urn:tests:h\">\n"
964 " <cont2>\n"
965 " <l>val</l>\n"
966 " </cont2>\n"
967 "</cont>\n";
968 CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_NO_STATE, 0, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100969 CHECK_LOG_CTX("Invalid state data node \"cont2\" found.",
970 "Schema location /h:cont/cont2, data location /h:cont, line number 3.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200971
972 CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
973 assert_int_equal(LY_EVALID, lyd_validate_all(&tree, NULL, LYD_VALIDATE_PRESENT | LYD_VALIDATE_NO_STATE, NULL));
Radek Krejci2efc45b2020-12-22 16:25:44 +0100974 CHECK_LOG_CTX("Invalid state data node \"cont2\" found.",
975 "Schema location /h:cont/cont2, data location /h:cont/cont2.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200976 lyd_free_all(tree);
977}
978
979static void
980test_must(void **state)
981{
982 struct lyd_node *tree;
983 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100984 "module i {\n"
985 " namespace urn:tests:i;\n"
986 " prefix i;\n"
987 " yang-version 1.1;\n"
988 "\n"
989 " container cont {\n"
990 " leaf l {\n"
991 " type string;\n"
992 " }\n"
993 " leaf l2 {\n"
994 " must \"../l = 'right'\";\n"
995 " type string;\n"
996 " }\n"
997 " }\n"
998 "}";
Michal Vaskocde73ac2019-11-14 16:10:27 +0100999
Radek Iša56ca9e42020-09-08 18:42:00 +02001000 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
Michal Vaskocde73ac2019-11-14 16:10:27 +01001001
Radek Iša56ca9e42020-09-08 18:42:00 +02001002 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:i\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001003 " <l>wrong</l>\n"
1004 " <l2>val</l2>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001005 "</cont>\n", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +01001006 CHECK_LOG_CTX("Must condition \"../l = 'right'\" not satisfied.",
1007 "Schema location /i:cont/l2, data location /i:cont/l2.");
Michal Vaskocc048b22020-03-27 15:52:38 +01001008
Radek Iša56ca9e42020-09-08 18:42:00 +02001009 LYD_TREE_CREATE("<cont xmlns=\"urn:tests:i\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001010 " <l>right</l>\n"
1011 " <l2>val</l2>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001012 "</cont>\n", tree);
1013 lyd_free_all(tree);
Michal Vaskocc048b22020-03-27 15:52:38 +01001014}
1015
Radek Iša56ca9e42020-09-08 18:42:00 +02001016const char *schema_j =
1017 "module j {\n"
1018 " namespace urn:tests:j;\n"
1019 " prefix j;\n"
1020 " yang-version 1.1;\n"
1021 "\n"
1022 " feature feat1;\n"
1023 "\n"
1024 " container cont {\n"
1025 " must \"false()\";\n"
1026 " list l1 {\n"
1027 " key \"k\";\n"
1028 " leaf k {\n"
1029 " type string;\n"
1030 " }\n"
1031 " action act {\n"
1032 " if-feature feat1;\n"
1033 " input {\n"
1034 " must \"../../lf1 = 'true'\";\n"
1035 " leaf lf2 {\n"
1036 " type leafref {\n"
1037 " path /lf3;\n"
1038 " }\n"
1039 " }\n"
1040 " }\n"
1041 " output {\n"
1042 " must \"../../lf1 = 'true2'\";\n"
1043 " leaf lf2 {\n"
1044 " type leafref {\n"
1045 " path /lf4;\n"
1046 " }\n"
1047 " }\n"
1048 " }\n"
1049 " }\n"
1050 " }\n"
1051 "\n"
1052 " leaf lf1 {\n"
1053 " type string;\n"
1054 " }\n"
1055 " }\n"
1056 "\n"
1057 " leaf lf3 {\n"
1058 " type string;\n"
1059 " }\n"
1060 "\n"
1061 " leaf lf4 {\n"
1062 " type string;\n"
1063 " }\n"
1064 "}";
1065const char *feats_j[] = {"feat1", NULL};
1066
Michal Vaskofea12c62020-03-30 11:00:15 +02001067static void
1068test_action(void **state)
1069{
Michal Vasko63f3d842020-07-08 10:10:14 +02001070 struct ly_in *in;
Michal Vaskofea12c62020-03-30 11:00:15 +02001071 struct lyd_node *tree, *op_tree;
Michal Vaskofea12c62020-03-30 11:00:15 +02001072
Radek Iša56ca9e42020-09-08 18:42:00 +02001073 UTEST_ADD_MODULE(schema_j, LYS_IN_YANG, feats_j, NULL);
1074
1075 assert_int_equal(LY_SUCCESS, ly_in_new_memory(
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001076 "<cont xmlns=\"urn:tests:j\">\n"
1077 " <l1>\n"
1078 " <k>val1</k>\n"
1079 " <act>\n"
1080 " <lf2>target</lf2>\n"
1081 " </act>\n"
1082 " </l1>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001083 "</cont>\n", &in));
1084 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(UTEST_LYCTX, in, LYD_XML, &op_tree, NULL));
Michal Vaskofea12c62020-03-30 11:00:15 +02001085 assert_non_null(op_tree);
1086
1087 /* missing leafref */
Michal Vasko8104fd42020-07-13 11:09:51 +02001088 assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, NULL, LYD_VALIDATE_OP_RPC, NULL));
Radek Krejci2efc45b2020-12-22 16:25:44 +01001089 CHECK_LOG_CTX("Invalid leafref value \"target\" - no existing target instance \"/lf3\".",
1090 "Schema location /j:cont/l1/act/lf2, data location /j:cont/l1[k='val1']/act/lf2.");
Michal Vasko63f3d842020-07-08 10:10:14 +02001091 ly_in_free(in, 0);
Michal Vaskofea12c62020-03-30 11:00:15 +02001092
Radek Iša56ca9e42020-09-08 18:42:00 +02001093 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001094 " <lf1>not true</lf1>\n"
1095 "</cont>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001096 "<lf3 xmlns=\"urn:tests:j\">target</lf3>\n",
1097 LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
Michal Vaskofea12c62020-03-30 11:00:15 +02001098
Michal Vaskofea12c62020-03-30 11:00:15 +02001099 /* input must false */
Michal Vasko8104fd42020-07-13 11:09:51 +02001100 assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, tree, LYD_VALIDATE_OP_RPC, NULL));
Radek Krejci2efc45b2020-12-22 16:25:44 +01001101 CHECK_LOG_CTX("Must condition \"../../lf1 = 'true'\" not satisfied.",
1102 "Data location /j:cont/l1[k='val1']/act.");
Michal Vaskofea12c62020-03-30 11:00:15 +02001103
Radek Iša56ca9e42020-09-08 18:42:00 +02001104 lyd_free_all(tree);
1105 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001106 " <lf1>true</lf1>\n"
1107 "</cont>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001108 "<lf3 xmlns=\"urn:tests:j\">target</lf3>\n",
1109 LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
Michal Vaskofea12c62020-03-30 11:00:15 +02001110
1111 /* success */
Michal Vasko8104fd42020-07-13 11:09:51 +02001112 assert_int_equal(LY_SUCCESS, lyd_validate_op(op_tree, tree, LYD_VALIDATE_OP_RPC, NULL));
Michal Vaskofea12c62020-03-30 11:00:15 +02001113
Michal Vaskocb7526d2020-03-30 15:08:26 +02001114 lyd_free_tree(op_tree);
1115 lyd_free_siblings(tree);
Michal Vaskocb7526d2020-03-30 15:08:26 +02001116}
1117
1118static void
1119test_reply(void **state)
1120{
Michal Vasko63f3d842020-07-08 10:10:14 +02001121 struct ly_in *in;
Michal Vasko2552ea32020-12-08 15:32:34 +01001122 struct lyd_node *tree, *op_tree;
Michal Vaskocb7526d2020-03-30 15:08:26 +02001123
Radek Iša56ca9e42020-09-08 18:42:00 +02001124 UTEST_ADD_MODULE(schema_j, LYS_IN_YANG, feats_j, NULL);
1125
1126 assert_int_equal(LY_SUCCESS, ly_in_new_memory(
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001127 "<cont xmlns=\"urn:tests:j\">\n"
1128 " <l1>\n"
1129 " <k>val1</k>\n"
1130 " <act>\n"
1131 " <lf2>target</lf2>\n"
1132 " </act>\n"
1133 " </l1>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001134 "</cont>\n", &in));
Michal Vasko2552ea32020-12-08 15:32:34 +01001135 assert_int_equal(LY_SUCCESS, lyd_parse_reply(UTEST_LYCTX, in, LYD_XML, &op_tree, NULL));
Michal Vaskocb7526d2020-03-30 15:08:26 +02001136 assert_non_null(op_tree);
Michal Vasko63f3d842020-07-08 10:10:14 +02001137 ly_in_free(in, 0);
Michal Vaskocb7526d2020-03-30 15:08:26 +02001138
1139 /* missing leafref */
Michal Vasko8104fd42020-07-13 11:09:51 +02001140 assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, NULL, LYD_VALIDATE_OP_REPLY, NULL));
Radek Krejci2efc45b2020-12-22 16:25:44 +01001141 CHECK_LOG_CTX("Invalid leafref value \"target\" - no existing target instance \"/lf4\".",
1142 "Schema location /j:cont/l1/act/lf2, data location /j:cont/l1[k='val1']/act/lf2.");
Michal Vaskocb7526d2020-03-30 15:08:26 +02001143
Radek Iša56ca9e42020-09-08 18:42:00 +02001144 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001145 " <lf1>not true</lf1>\n"
1146 "</cont>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001147 "<lf4 xmlns=\"urn:tests:j\">target</lf4>\n",
1148 LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
Michal Vaskocb7526d2020-03-30 15:08:26 +02001149
Michal Vaskocb7526d2020-03-30 15:08:26 +02001150 /* input must false */
Michal Vasko8104fd42020-07-13 11:09:51 +02001151 assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, tree, LYD_VALIDATE_OP_REPLY, NULL));
Radek Krejci2efc45b2020-12-22 16:25:44 +01001152 CHECK_LOG_CTX("Must condition \"../../lf1 = 'true2'\" not satisfied.", "Data location /j:cont/l1[k='val1']/act.");
Michal Vaskocb7526d2020-03-30 15:08:26 +02001153
Radek Iša56ca9e42020-09-08 18:42:00 +02001154 lyd_free_all(tree);
1155 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001156 " <lf1>true2</lf1>\n"
1157 "</cont>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001158 "<lf4 xmlns=\"urn:tests:j\">target</lf4>\n",
1159 LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
Michal Vaskocb7526d2020-03-30 15:08:26 +02001160
1161 /* success */
Michal Vasko8104fd42020-07-13 11:09:51 +02001162 assert_int_equal(LY_SUCCESS, lyd_validate_op(op_tree, tree, LYD_VALIDATE_OP_REPLY, NULL));
Michal Vaskocb7526d2020-03-30 15:08:26 +02001163
Michal Vaskofea12c62020-03-30 11:00:15 +02001164 lyd_free_tree(op_tree);
Radek Iša56ca9e42020-09-08 18:42:00 +02001165 lyd_free_all(tree);
Michal Vaskofea12c62020-03-30 11:00:15 +02001166}
1167
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001168int
1169main(void)
Michal Vaskocde73ac2019-11-14 16:10:27 +01001170{
1171 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +02001172 UTEST(test_when),
1173 UTEST(test_mandatory),
1174 UTEST(test_minmax),
1175 UTEST(test_unique),
1176 UTEST(test_unique_nested),
1177 UTEST(test_dup),
1178 UTEST(test_defaults),
1179 UTEST(test_state),
1180 UTEST(test_must),
1181 UTEST(test_action),
1182 UTEST(test_reply),
Michal Vaskocde73ac2019-11-14 16:10:27 +01001183 };
1184
Radek Iša56ca9e42020-09-08 18:42:00 +02001185 return cmocka_run_group_tests(tests, NULL, NULL);
Michal Vaskocde73ac2019-11-14 16:10:27 +01001186}