blob: 1a07e7f9599322c199fca02df5f53d5705b16f10 [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"
Radek Krejcief5f7672021-04-01 17:04:12 +020025#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
Christian Hoppsb6ecaea2021-02-06 09:45:38 -050076test_mandatory_when(void **state)
77{
78 struct lyd_node *tree;
79 const char *schema =
80 "module a {\n"
81 " namespace urn:tests:a;\n"
82 " prefix a;\n"
83 " yang-version 1.1;\n"
84 "\n"
85 " container cont {\n"
86 " leaf a {\n"
87 " type string;\n"
88 " }\n"
89 " leaf b {\n"
90 " when \"../a = 'val_a'\";\n"
91 " mandatory true;\n"
92 " type string;\n"
93 " }\n"
94 " }\n"
95 " leaf c {\n"
96 " type string;\n"
97 " }\n"
98 " leaf d {\n"
99 " when \"../c = 'val_c'\";\n"
100 " mandatory true;\n"
101 " type string;\n"
102 " }\n"
103 "}";
104
105 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
106
107 CHECK_PARSE_LYD_PARAM("<d xmlns=\"urn:tests:a\">hey</d>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
108 CHECK_LOG_CTX("When condition \"../c = 'val_c'\" not satisfied.", "Schema location /a:d, data location /a:d.");
109
110 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:a\"><b>hey</b></cont>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
111 CHECK_LOG_CTX("When condition \"../a = 'val_a'\" not satisfied.", "Schema location /a:cont/b, data location /a:cont/b.");
112
113 LYD_TREE_CREATE("<c xmlns=\"urn:tests:a\">val_c</c><d xmlns=\"urn:tests:a\">hey</d>", tree);
114 CHECK_LYSC_NODE(tree->next->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_MAND_TRUE, 1, "d", 0, LYS_LEAF, 0, 0, NULL, 1);
115 assert_int_equal(LYD_WHEN_TRUE, tree->next->next->flags);
116 lyd_free_all(tree);
117
118 LYD_TREE_CREATE("<cont xmlns=\"urn:tests:a\"><a>val_a</a><b>hey</b></cont>", tree);
119 CHECK_LYSC_NODE(lyd_child(tree)->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_MAND_TRUE, 1, "b", 0, LYS_LEAF, tree->schema, 0, NULL, 1);
120 assert_int_equal(LYD_WHEN_TRUE, lyd_child(tree)->next->flags);
121 lyd_free_all(tree);
122}
123
124static void
Radek Iša56ca9e42020-09-08 18:42:00 +0200125test_mandatory(void **state)
126{
127 struct lyd_node *tree;
128 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100129 "module b {\n"
130 " namespace urn:tests:b;\n"
131 " prefix b;\n"
132 " yang-version 1.1;\n"
133 "\n"
134 " choice choic {\n"
135 " mandatory true;\n"
136 " leaf a {\n"
137 " type string;\n"
138 " }\n"
139 " case b {\n"
140 " leaf l {\n"
141 " type string;\n"
142 " }\n"
143 " }\n"
144 " }\n"
145 " leaf c {\n"
146 " mandatory true;\n"
147 " type string;\n"
148 " }\n"
149 " leaf d {\n"
150 " type empty;\n"
151 " }\n"
152 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200153
154 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
155
156 CHECK_PARSE_LYD_PARAM("<d xmlns=\"urn:tests:b\"/>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Michal Vaskoe9391c72021-10-05 10:04:56 +0200157 CHECK_LOG_CTX_APPTAG("Mandatory choice \"choic\" data do not exist.", "Schema location /b:choic.", "missing-choice");
Radek Iša56ca9e42020-09-08 18:42:00 +0200158
159 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 +0100160 CHECK_LOG_CTX("Mandatory node \"c\" instance does not exist.", "Schema location /b:c.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200161
162 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 +0100163 CHECK_LOG_CTX("Mandatory node \"c\" instance does not exist.", "Schema location /b:c.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200164
165 LYD_TREE_CREATE("<a xmlns=\"urn:tests:b\">string</a><c xmlns=\"urn:tests:b\">string2</c>", tree);
166 lyd_free_siblings(tree);
167}
168
169static void
170test_minmax(void **state)
171{
172 struct lyd_node *tree;
173 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100174 "module c {\n"
175 " namespace urn:tests:c;\n"
176 " prefix c;\n"
177 " yang-version 1.1;\n"
178 "\n"
179 " choice choic {\n"
180 " leaf a {\n"
181 " type string;\n"
182 " }\n"
183 " case b {\n"
184 " leaf-list l {\n"
185 " min-elements 3;\n"
186 " type string;\n"
187 " }\n"
188 " }\n"
189 " }\n"
190 " list lt {\n"
191 " max-elements 4;\n"
192 " key \"k\";\n"
193 " leaf k {\n"
194 " type string;\n"
195 " }\n"
196 " }\n"
197 " leaf d {\n"
198 " type empty;\n"
199 " }\n"
200 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200201
202 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
203
Michal Vasko6c16cda2021-02-04 11:05:52 +0100204 CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:c\">mate</l>"
205 "<d xmlns=\"urn:tests:c\"/>",
206 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Michal Vaskoe9391c72021-10-05 10:04:56 +0200207 CHECK_LOG_CTX_APPTAG("Too few \"l\" instances.", "Schema location /c:choic/b/l.", "too-few-elements");
Radek Iša56ca9e42020-09-08 18:42:00 +0200208
209 CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:c\">val1</l>"
210 "<l xmlns=\"urn:tests:c\">val2</l>",
211 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Michal Vaskoe9391c72021-10-05 10:04:56 +0200212 CHECK_LOG_CTX_APPTAG("Too few \"l\" instances.", "Schema location /c:choic/b/l.", "too-few-elements");
Radek Iša56ca9e42020-09-08 18:42:00 +0200213
214 LYD_TREE_CREATE("<l xmlns=\"urn:tests:c\">val1</l>"
215 "<l xmlns=\"urn:tests:c\">val2</l>"
216 "<l xmlns=\"urn:tests:c\">val3</l>", tree);
217 lyd_free_all(tree);
218
219 CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:c\">val1</l>"
220 "<l xmlns=\"urn:tests:c\">val2</l>"
221 "<l xmlns=\"urn:tests:c\">val3</l>"
222 "<lt xmlns=\"urn:tests:c\"><k>val1</k></lt>"
223 "<lt xmlns=\"urn:tests:c\"><k>val2</k></lt>"
224 "<lt xmlns=\"urn:tests:c\"><k>val3</k></lt>"
225 "<lt xmlns=\"urn:tests:c\"><k>val4</k></lt>"
Radek Krejci2efc45b2020-12-22 16:25:44 +0100226 "<lt xmlns=\"urn:tests:c\"><k>val5</k></lt>"
227 "<lt xmlns=\"urn:tests:c\"><k>val6</k></lt>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Michal Vaskoe9391c72021-10-05 10:04:56 +0200228 CHECK_LOG_CTX_APPTAG("Too many \"lt\" instances.", "Schema location /c:lt, data location /c:lt[k='val5'].",
229 "too-many-elements");
Radek Iša56ca9e42020-09-08 18:42:00 +0200230}
231
232const char *schema_d =
233 "module d {\n"
234 " namespace urn:tests:d;\n"
235 " prefix d;\n"
236 " yang-version 1.1;\n"
237 "\n"
238 " list lt {\n"
239 " key \"k\";\n"
240 " unique \"l1\";\n"
241 " leaf k {\n"
242 " type string;\n"
243 " }\n"
244 " leaf l1 {\n"
245 " type string;\n"
246 " }\n"
247 " }\n"
248 " list lt2 {\n"
249 " key \"k\";\n"
250 " unique \"cont/l2 l4\";\n"
251 " unique \"l5 l6\";\n"
252 " leaf k {\n"
253 " type string;\n"
254 " }\n"
255 " container cont {\n"
256 " leaf l2 {\n"
257 " type string;\n"
258 " }\n"
259 " }\n"
260 " leaf l4 {\n"
261 " type string;\n"
262 " }\n"
263 " leaf l5 {\n"
264 " type string;\n"
265 " }\n"
266 " leaf l6 {\n"
267 " type string;\n"
268 " }\n"
269 " list lt3 {\n"
270 " key \"kk\";\n"
271 " unique \"l3\";\n"
272 " leaf kk {\n"
273 " type string;\n"
274 " }\n"
275 " leaf l3 {\n"
276 " type string;\n"
277 " }\n"
278 " }\n"
279 " }\n"
280 "}";
281
282static void
283test_unique(void **state)
284{
285 struct lyd_node *tree;
286
287 UTEST_ADD_MODULE(schema_d, LYS_IN_YANG, NULL, NULL);
288
289 LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
290 " <k>val1</k>\n"
291 " <l1>same</l1>\n"
292 "</lt>\n"
293 "<lt xmlns=\"urn:tests:d\">\n"
294 " <k>val2</k>\n"
295 "</lt>", tree);
296 lyd_free_all(tree);
297
298 LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
299 " <k>val1</k>\n"
300 " <l1>same</l1>\n"
301 "</lt>\n"
302 "<lt xmlns=\"urn:tests:d\">\n"
303 " <k>val2</k>\n"
304 " <l1>not-same</l1>\n"
305 "</lt>", tree);
306 lyd_free_all(tree);
307
308 CHECK_PARSE_LYD_PARAM("<lt xmlns=\"urn:tests:d\">\n"
309 " <k>val1</k>\n"
310 " <l1>same</l1>\n"
311 "</lt>\n"
312 "<lt xmlns=\"urn:tests:d\">\n"
313 " <k>val2</k>\n"
314 " <l1>same</l1>\n"
315 "</lt>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Michal Vaskoe9391c72021-10-05 10:04:56 +0200316 CHECK_LOG_CTX_APPTAG("Unique data leaf(s) \"l1\" not satisfied in \"/d:lt[k='val1']\" and \"/d:lt[k='val2']\".",
317 "Schema location /d:lt, data location /d:lt[k='val2'].", "data-not-unique");
Radek Iša56ca9e42020-09-08 18:42:00 +0200318
319 /* now try with more instances */
320 LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
321 " <k>val1</k>\n"
322 " <l1>1</l1>\n"
323 "</lt>\n"
324 "<lt xmlns=\"urn:tests:d\">\n"
325 " <k>val2</k>\n"
326 " <l1>2</l1>\n"
327 "</lt>\n"
328 "<lt xmlns=\"urn:tests:d\">\n"
329 " <k>val3</k>\n"
330 " <l1>3</l1>\n"
331 "</lt>\n"
332 "<lt xmlns=\"urn:tests:d\">\n"
333 " <k>val4</k>\n"
334 " <l1>4</l1>\n"
335 "</lt>\n"
336 "<lt xmlns=\"urn:tests:d\">\n"
337 " <k>val5</k>\n"
338 " <l1>5</l1>\n"
339 "</lt>\n"
340 "<lt xmlns=\"urn:tests:d\">\n"
341 " <k>val6</k>\n"
342 " <l1>6</l1>\n"
343 "</lt>\n"
344 "<lt xmlns=\"urn:tests:d\">\n"
345 " <k>val7</k>\n"
346 " <l1>7</l1>\n"
347 "</lt>\n"
348 "<lt xmlns=\"urn:tests:d\">\n"
349 " <k>val8</k>\n"
350 " <l1>8</l1>\n"
351 "</lt>", tree);
352 lyd_free_all(tree);
353
354 LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
355 " <k>val1</k>\n"
356 " <l1>1</l1>\n"
357 "</lt>\n"
358 "<lt xmlns=\"urn:tests:d\">\n"
359 " <k>val2</k>\n"
360 " <l1>2</l1>\n"
361 "</lt>\n"
362 "<lt xmlns=\"urn:tests:d\">\n"
363 " <k>val3</k>\n"
364 " <l1>3</l1>\n"
365 "</lt>\n"
366 "<lt xmlns=\"urn:tests:d\">\n"
367 " <k>val4</k>\n"
368 "</lt>\n"
369 "<lt xmlns=\"urn:tests:d\">\n"
370 " <k>val5</k>\n"
371 " <l1>5</l1>\n"
372 "</lt>\n"
373 "<lt xmlns=\"urn:tests:d\">\n"
374 " <k>val6</k>\n"
375 " <l1>6</l1>\n"
376 "</lt>\n"
377 "<lt xmlns=\"urn:tests:d\">\n"
378 " <k>val7</k>\n"
379 "</lt>\n"
380 "<lt xmlns=\"urn:tests:d\">\n"
381 " <k>val8</k>\n"
382 "</lt>", tree);
383 lyd_free_all(tree);
384
385 CHECK_PARSE_LYD_PARAM("<lt xmlns=\"urn:tests:d\">\n"
386 " <k>val1</k>\n"
387 " <l1>1</l1>\n"
388 "</lt>\n"
389 "<lt xmlns=\"urn:tests:d\">\n"
390 " <k>val2</k>\n"
391 " <l1>2</l1>\n"
392 "</lt>\n"
393 "<lt xmlns=\"urn:tests:d\">\n"
394 " <k>val3</k>\n"
395 "</lt>\n"
396 "<lt xmlns=\"urn:tests:d\">\n"
397 " <k>val4</k>\n"
398 " <l1>4</l1>\n"
399 "</lt>\n"
400 "<lt xmlns=\"urn:tests:d\">\n"
401 " <k>val5</k>\n"
402 "</lt>\n"
403 "<lt xmlns=\"urn:tests:d\">\n"
404 " <k>val6</k>\n"
405 "</lt>\n"
406 "<lt xmlns=\"urn:tests:d\">\n"
407 " <k>val7</k>\n"
408 " <l1>2</l1>\n"
409 "</lt>\n"
410 "<lt xmlns=\"urn:tests:d\">\n"
411 " <k>val8</k>\n"
412 " <l1>8</l1>\n"
413 "</lt>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Michal Vaskoe9391c72021-10-05 10:04:56 +0200414 CHECK_LOG_CTX_APPTAG("Unique data leaf(s) \"l1\" not satisfied in \"/d:lt[k='val7']\" and \"/d:lt[k='val2']\".",
415 "Schema location /d:lt, data location /d:lt[k='val2'].", "data-not-unique");
Radek Iša56ca9e42020-09-08 18:42:00 +0200416}
417
418static void
419test_unique_nested(void **state)
420{
421 struct lyd_node *tree;
422
423 UTEST_ADD_MODULE(schema_d, LYS_IN_YANG, NULL, NULL);
424
425 /* nested list uniquest are compared only with instances in the same parent list instance */
426 LYD_TREE_CREATE("<lt2 xmlns=\"urn:tests:d\">\n"
427 " <k>val1</k>\n"
428 " <cont>\n"
429 " <l2>1</l2>\n"
430 " </cont>\n"
431 " <l4>1</l4>\n"
432 "</lt2>\n"
433 "<lt2 xmlns=\"urn:tests:d\">\n"
434 " <k>val2</k>\n"
435 " <cont>\n"
436 " <l2>2</l2>\n"
437 " </cont>\n"
438 " <l4>2</l4>\n"
439 " <lt3>\n"
440 " <kk>val1</kk>\n"
441 " <l3>1</l3>\n"
442 " </lt3>\n"
443 " <lt3>\n"
444 " <kk>val2</kk>\n"
445 " <l3>2</l3>\n"
446 " </lt3>\n"
447 "</lt2>\n"
448 "<lt2 xmlns=\"urn:tests:d\">\n"
449 " <k>val3</k>\n"
450 " <cont>\n"
451 " <l2>3</l2>\n"
452 " </cont>\n"
453 " <l4>3</l4>\n"
454 " <lt3>\n"
455 " <kk>val1</kk>\n"
456 " <l3>2</l3>\n"
457 " </lt3>\n"
458 "</lt2>\n"
459 "<lt2 xmlns=\"urn:tests:d\">\n"
460 " <k>val4</k>\n"
461 " <cont>\n"
462 " <l2>4</l2>\n"
463 " </cont>\n"
464 " <l4>4</l4>\n"
465 " <lt3>\n"
466 " <kk>val1</kk>\n"
467 " <l3>3</l3>\n"
468 " </lt3>\n"
469 "</lt2>\n"
470 "<lt2 xmlns=\"urn:tests:d\">\n"
471 " <k>val5</k>\n"
472 " <cont>\n"
473 " <l2>5</l2>\n"
474 " </cont>\n"
475 " <l4>5</l4>\n"
476 " <lt3>\n"
477 " <kk>val1</kk>\n"
478 " <l3>3</l3>\n"
479 " </lt3>\n"
480 "</lt2>", tree);
481 lyd_free_all(tree);
482
483 CHECK_PARSE_LYD_PARAM("<lt2 xmlns=\"urn:tests:d\">\n"
484 " <k>val1</k>\n"
485 " <cont>\n"
486 " <l2>1</l2>\n"
487 " </cont>\n"
488 " <l4>1</l4>\n"
489 "</lt2>\n"
490 "<lt2 xmlns=\"urn:tests:d\">\n"
491 " <k>val2</k>\n"
492 " <cont>\n"
493 " <l2>2</l2>\n"
494 " </cont>\n"
495 " <lt3>\n"
496 " <kk>val1</kk>\n"
497 " <l3>1</l3>\n"
498 " </lt3>\n"
499 " <lt3>\n"
500 " <kk>val2</kk>\n"
501 " <l3>2</l3>\n"
502 " </lt3>\n"
503 " <lt3>\n"
504 " <kk>val3</kk>\n"
505 " <l3>1</l3>\n"
506 " </lt3>\n"
507 "</lt2>\n"
508 "<lt2 xmlns=\"urn:tests:d\">\n"
509 " <k>val3</k>\n"
510 " <cont>\n"
511 " <l2>3</l2>\n"
512 " </cont>\n"
513 " <l4>1</l4>\n"
514 " <lt3>\n"
515 " <kk>val1</kk>\n"
516 " <l3>2</l3>\n"
517 " </lt3>\n"
518 "</lt2>\n"
519 "<lt2 xmlns=\"urn:tests:d\">\n"
520 " <k>val4</k>\n"
521 " <cont>\n"
522 " <l2>4</l2>\n"
523 " </cont>\n"
524 " <lt3>\n"
525 " <kk>val1</kk>\n"
526 " <l3>3</l3>\n"
527 " </lt3>\n"
528 "</lt2>\n"
529 "<lt2 xmlns=\"urn:tests:d\">\n"
530 " <k>val5</k>\n"
531 " <cont>\n"
532 " <l2>5</l2>\n"
533 " </cont>\n"
534 " <lt3>\n"
535 " <kk>val1</kk>\n"
536 " <l3>3</l3>\n"
537 " </lt3>\n"
538 "</lt2>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Michal Vaskoe9391c72021-10-05 10:04:56 +0200539 CHECK_LOG_CTX_APPTAG("Unique data leaf(s) \"l3\" not satisfied in \"/d:lt2[k='val2']/lt3[kk='val3']\" and "
540 "\"/d:lt2[k='val2']/lt3[kk='val1']\".",
541 "Schema location /d:lt2/lt3, data location /d:lt2[k='val2']/lt3[kk='val1'].", "data-not-unique");
Radek Iša56ca9e42020-09-08 18:42:00 +0200542
543 CHECK_PARSE_LYD_PARAM("<lt2 xmlns=\"urn:tests:d\">\n"
544 " <k>val1</k>\n"
545 " <cont>\n"
546 " <l2>1</l2>\n"
547 " </cont>\n"
548 " <l4>1</l4>\n"
549 "</lt2>\n"
550 "<lt2 xmlns=\"urn:tests:d\">\n"
551 " <k>val2</k>\n"
552 " <cont>\n"
553 " <l2>2</l2>\n"
554 " </cont>\n"
555 " <l4>2</l4>\n"
556 "</lt2>\n"
557 "<lt2 xmlns=\"urn:tests:d\">\n"
558 " <k>val3</k>\n"
559 " <cont>\n"
560 " <l2>3</l2>\n"
561 " </cont>\n"
562 " <l4>3</l4>\n"
563 "</lt2>\n"
564 "<lt2 xmlns=\"urn:tests:d\">\n"
565 " <k>val4</k>\n"
566 " <cont>\n"
567 " <l2>2</l2>\n"
568 " </cont>\n"
569 " <l4>2</l4>\n"
570 "</lt2>\n"
571 "<lt2 xmlns=\"urn:tests:d\">\n"
572 " <k>val5</k>\n"
573 " <cont>\n"
574 " <l2>5</l2>\n"
575 " </cont>\n"
576 " <l4>5</l4>\n"
577 "</lt2>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Michal Vaskoe9391c72021-10-05 10:04:56 +0200578 CHECK_LOG_CTX_APPTAG("Unique data leaf(s) \"cont/l2 l4\" not satisfied in \"/d:lt2[k='val4']\" and \"/d:lt2[k='val2']\".",
579 "Schema location /d:lt2, data location /d:lt2[k='val2'].", "data-not-unique");
Radek Iša56ca9e42020-09-08 18:42:00 +0200580
581 CHECK_PARSE_LYD_PARAM("<lt2 xmlns=\"urn:tests:d\">\n"
582 " <k>val1</k>\n"
583 " <cont>\n"
584 " <l2>1</l2>\n"
585 " </cont>\n"
586 " <l4>1</l4>\n"
587 " <l5>1</l5>\n"
588 " <l6>1</l6>\n"
589 "</lt2>\n"
590 "<lt2 xmlns=\"urn:tests:d\">\n"
591 " <k>val2</k>\n"
592 " <cont>\n"
593 " <l2>2</l2>\n"
594 " </cont>\n"
595 " <l4>1</l4>\n"
596 " <l5>1</l5>\n"
597 "</lt2>\n"
598 "<lt2 xmlns=\"urn:tests:d\">\n"
599 " <k>val3</k>\n"
600 " <cont>\n"
601 " <l2>3</l2>\n"
602 " </cont>\n"
603 " <l4>1</l4>\n"
604 " <l5>3</l5>\n"
605 " <l6>3</l6>\n"
606 "</lt2>\n"
607 "<lt2 xmlns=\"urn:tests:d\">\n"
608 " <k>val4</k>\n"
609 " <cont>\n"
610 " <l2>4</l2>\n"
611 " </cont>\n"
612 " <l4>1</l4>\n"
613 " <l6>1</l6>\n"
614 "</lt2>\n"
615 "<lt2 xmlns=\"urn:tests:d\">\n"
616 " <k>val5</k>\n"
617 " <cont>\n"
618 " <l2>5</l2>\n"
619 " </cont>\n"
620 " <l4>1</l4>\n"
621 " <l5>3</l5>\n"
622 " <l6>3</l6>\n"
623 "</lt2>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Michal Vaskoe9391c72021-10-05 10:04:56 +0200624 CHECK_LOG_CTX_APPTAG("Unique data leaf(s) \"l5 l6\" not satisfied in \"/d:lt2[k='val5']\" and \"/d:lt2[k='val3']\".",
625 "Schema location /d:lt2, data location /d:lt2[k='val3'].", "data-not-unique");
Radek Iša56ca9e42020-09-08 18:42:00 +0200626}
627
628static void
629test_dup(void **state)
630{
631 struct lyd_node *tree;
632 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100633 "module e {\n"
634 " namespace urn:tests:e;\n"
635 " prefix e;\n"
636 " yang-version 1.1;\n"
637 "\n"
638 " choice choic {\n"
639 " leaf a {\n"
640 " type string;\n"
641 " }\n"
642 " case b {\n"
643 " leaf-list l {\n"
644 " type string;\n"
645 " }\n"
646 " }\n"
647 " }\n"
648 " list lt {\n"
649 " key \"k\";\n"
650 " leaf k {\n"
651 " type string;\n"
652 " }\n"
653 " }\n"
654 " leaf d {\n"
655 " type uint32;\n"
656 " }\n"
657 " leaf-list ll {\n"
658 " type string;\n"
659 " }\n"
660 " container cont {\n"
661 " list lt {\n"
662 " key \"k\";\n"
663 " leaf k {\n"
664 " type string;\n"
665 " }\n"
666 " }\n"
667 " leaf d {\n"
668 " type uint32;\n"
669 " }\n"
670 " leaf-list ll {\n"
671 " type string;\n"
672 " }\n"
673 " leaf-list ll2 {\n"
674 " type enumeration {\n"
675 " enum one;\n"
676 " enum two;\n"
677 " }\n"
678 " }\n"
679 " }\n"
680 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200681
682 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
683
684 CHECK_PARSE_LYD_PARAM("<d xmlns=\"urn:tests:e\">25</d><d xmlns=\"urn:tests:e\">50</d>",
685 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100686 CHECK_LOG_CTX("Duplicate instance of \"d\".", "Schema location /e:d, data location /e:d.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200687
688 CHECK_PARSE_LYD_PARAM("<lt xmlns=\"urn:tests:e\"><k>A</k></lt>"
689 "<lt xmlns=\"urn:tests:e\"><k>B</k></lt>"
690 "<lt xmlns=\"urn:tests:e\"><k>A</k></lt>",
691 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100692 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 +0200693
694 CHECK_PARSE_LYD_PARAM("<ll xmlns=\"urn:tests:e\">A</ll>"
695 "<ll xmlns=\"urn:tests:e\">B</ll>"
696 "<ll xmlns=\"urn:tests:e\">B</ll>",
697 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100698 CHECK_LOG_CTX("Duplicate instance of \"ll\".", "Schema location /e:ll, data location /e:ll[.='B'].");
Radek Iša56ca9e42020-09-08 18:42:00 +0200699
700 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"></cont><cont xmlns=\"urn:tests:e\"/>",
701 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100702 CHECK_LOG_CTX("Duplicate instance of \"cont\".", "Schema location /e:cont, data location /e:cont.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200703
704 /* same tests again but using hashes */
705 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>",
706 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100707 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 +0200708
709 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll>"
710 "<lt><k>a</k></lt>"
711 "<lt><k>b</k></lt>"
712 "<lt><k>c</k></lt>"
713 "<lt><k>d</k></lt>"
714 "<lt><k>c</k></lt></cont>",
715 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100716 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 +0200717
718 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll>"
719 "<ll>a</ll><ll>b</ll><ll>c</ll><ll>d</ll><ll>d</ll></cont>",
720 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100721 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 +0200722
723 /* cases */
724 CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:e\">a</l>"
725 "<l xmlns=\"urn:tests:e\">b</l>"
726 "<l xmlns=\"urn:tests:e\">c</l>"
727 "<l xmlns=\"urn:tests:e\">b</l>",
728 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100729 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 +0200730
731 CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:e\">a</l><l xmlns=\"urn:tests:e\">b</l>"
732 "<l xmlns=\"urn:tests:e\">c</l>"
733 "<a xmlns=\"urn:tests:e\">aa</a>",
734 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Radek Krejci2efc45b2020-12-22 16:25:44 +0100735 CHECK_LOG_CTX("Data for both cases \"a\" and \"b\" exist.", "Schema location /e:choic.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200736}
737
738static void
739test_defaults(void **state)
740{
741 struct lyd_node *tree, *node, *diff;
Michal Vasko4de7d072021-07-09 09:13:18 +0200742 struct lys_module *mod;
Radek Iša56ca9e42020-09-08 18:42:00 +0200743 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100744 "module f {\n"
745 " namespace urn:tests:f;\n"
746 " prefix f;\n"
747 " yang-version 1.1;\n"
748 "\n"
749 " choice choic {\n"
750 " default \"c\";\n"
751 " leaf a {\n"
752 " type string;\n"
753 " }\n"
754 " case b {\n"
755 " leaf l {\n"
756 " type string;\n"
757 " }\n"
758 " }\n"
759 " case c {\n"
760 " leaf-list ll1 {\n"
761 " type string;\n"
762 " default \"def1\";\n"
763 " default \"def2\";\n"
764 " default \"def3\";\n"
765 " }\n"
766 " }\n"
767 " }\n"
768 " leaf d {\n"
769 " type uint32;\n"
770 " default 15;\n"
771 " }\n"
Radek Krejci7be7b9f2021-02-24 11:46:27 +0100772 " leaf dd {\n"
773 " type uint32;\n"
774 " when '../d = 666';\n"
775 " default 15;\n"
776 " }\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100777 " leaf-list ll2 {\n"
778 " type string;\n"
779 " default \"dflt1\";\n"
780 " default \"dflt2\";\n"
781 " }\n"
782 " container cont {\n"
783 " choice choic {\n"
784 " default \"c\";\n"
785 " leaf a {\n"
786 " type string;\n"
787 " }\n"
788 " case b {\n"
789 " leaf l {\n"
790 " type string;\n"
791 " }\n"
792 " }\n"
793 " case c {\n"
794 " leaf-list ll1 {\n"
795 " type string;\n"
796 " default \"def1\";\n"
797 " default \"def2\";\n"
798 " default \"def3\";\n"
799 " }\n"
800 " }\n"
801 " }\n"
802 " leaf d {\n"
803 " type uint32;\n"
804 " default 15;\n"
805 " }\n"
Radek Krejci7be7b9f2021-02-24 11:46:27 +0100806 " leaf dd {\n"
807 " type uint32;\n"
808 " when '../d = 666';\n"
809 " default 15;\n"
810 " }\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100811 " leaf-list ll2 {\n"
812 " type string;\n"
813 " default \"dflt1\";\n"
814 " default \"dflt2\";\n"
815 " }\n"
816 " }\n"
817 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200818
819 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
820
821 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
822 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-with-defaults", "2011-06-01", NULL));\
823
824 /* get defaults */
825 tree = NULL;
826 assert_int_equal(lyd_validate_module(&tree, mod, 0, &diff), LY_SUCCESS);
827 assert_non_null(tree);
828 assert_non_null(diff);
829
830 /* check all defaults exist */
831 CHECK_LYD_STRING_PARAM(tree,
832 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
833 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
834 "<ll1 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
835 "<d xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
836 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
837 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
838 "<cont xmlns=\"urn:tests:f\">\n"
839 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
840 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
841 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
842 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
843 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
844 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
845 "</cont>\n",
846 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
847
848 /* check diff */
849 CHECK_LYD_STRING_PARAM(diff,
850 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">def1</ll1>\n"
851 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">def2</ll1>\n"
852 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">def3</ll1>\n"
853 "<d xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">15</d>\n"
854 "<ll2 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">dflt1</ll2>\n"
855 "<ll2 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">dflt2</ll2>\n"
856 "<cont xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
857 " <ll1 yang:operation=\"create\">def1</ll1>\n"
858 " <ll1 yang:operation=\"create\">def2</ll1>\n"
859 " <ll1 yang:operation=\"create\">def3</ll1>\n"
860 " <d yang:operation=\"create\">15</d>\n"
861 " <ll2 yang:operation=\"create\">dflt1</ll2>\n"
862 " <ll2 yang:operation=\"create\">dflt2</ll2>\n"
863 "</cont>\n",
864 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
865 lyd_free_all(diff);
866
867 /* create another explicit case and validate */
868 assert_int_equal(lyd_new_term(NULL, mod, "l", "value", 0, &node), LY_SUCCESS);
869 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
870 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
871
872 /* check data tree */
873 CHECK_LYD_STRING_PARAM(tree,
874 "<l xmlns=\"urn:tests:f\">value</l>\n"
875 "<d xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
876 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
877 "<ll2 xmlns=\"urn:tests:f\" xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
878 "<cont xmlns=\"urn:tests:f\">\n"
879 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
880 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
881 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
882 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
883 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
884 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
885 "</cont>\n",
886 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
887
888 /* check diff */
889 CHECK_LYD_STRING_PARAM(diff,
890 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">def1</ll1>\n"
891 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">def2</ll1>\n"
892 "<ll1 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">def3</ll1>\n",
893 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
894 lyd_free_all(diff);
895
896 /* create explicit leaf-list and leaf and validate */
897 assert_int_equal(lyd_new_term(NULL, mod, "d", "15", 0, &node), LY_SUCCESS);
898 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
899 assert_int_equal(lyd_new_term(NULL, mod, "ll2", "dflt2", 0, &node), LY_SUCCESS);
900 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
901 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
902
903 /* check data tree */
904 CHECK_LYD_STRING_PARAM(tree,
905 "<l xmlns=\"urn:tests:f\">value</l>\n"
906 "<d xmlns=\"urn:tests:f\">15</d>\n"
907 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
908 "<cont xmlns=\"urn:tests:f\">\n"
909 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
910 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
911 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
912 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
913 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
914 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
915 "</cont>\n",
916 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
917
918 /* check diff */
919 CHECK_LYD_STRING_PARAM(diff,
920 "<d xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">15</d>\n"
921 "<ll2 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">dflt1</ll2>\n"
922 "<ll2 xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">dflt2</ll2>\n",
923 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
924 lyd_free_all(diff);
925
926 /* create first explicit container, which should become implicit */
927 assert_int_equal(lyd_new_inner(NULL, mod, "cont", 0, &node), LY_SUCCESS);
928 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
929 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
930
931 /* check data tree */
932 CHECK_LYD_STRING_PARAM(tree,
933 "<l xmlns=\"urn:tests:f\">value</l>\n"
934 "<d xmlns=\"urn:tests:f\">15</d>\n"
935 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
936 "<cont xmlns=\"urn:tests:f\">\n"
937 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
938 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
939 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
940 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
941 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
942 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
943 "</cont>\n",
944 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
945 /* check diff */
946 assert_null(diff);
947
948 /* create second explicit container, which should become implicit, so the first tree node should be removed */
949 assert_int_equal(lyd_new_inner(NULL, mod, "cont", 0, &node), LY_SUCCESS);
950 assert_int_equal(lyd_insert_sibling(tree, node, &tree), LY_SUCCESS);
951 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
952
953 /* check data tree */
954 CHECK_LYD_STRING_PARAM(tree,
955 "<l xmlns=\"urn:tests:f\">value</l>\n"
956 "<d xmlns=\"urn:tests:f\">15</d>\n"
957 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
958 "<cont xmlns=\"urn:tests:f\">\n"
959 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def1</ll1>\n"
960 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def2</ll1>\n"
961 " <ll1 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">def3</ll1>\n"
962 " <d xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">15</d>\n"
963 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt1</ll2>\n"
964 " <ll2 xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" ncwd:default=\"true\">dflt2</ll2>\n"
965 "</cont>\n",
966 LYD_XML, LYD_PRINT_WD_IMPL_TAG | LYD_PRINT_WITHSIBLINGS);
967 /* check diff */
968 assert_null(diff);
969
970 /* similar changes for nested defaults */
971 assert_int_equal(lyd_new_term(tree->prev, NULL, "ll1", "def3", 0, NULL), LY_SUCCESS);
972 assert_int_equal(lyd_new_term(tree->prev, NULL, "d", "5", 0, NULL), LY_SUCCESS);
973 assert_int_equal(lyd_new_term(tree->prev, NULL, "ll2", "non-dflt", 0, NULL), LY_SUCCESS);
974 assert_int_equal(lyd_validate_all(&tree, UTEST_LYCTX, LYD_VALIDATE_PRESENT, &diff), LY_SUCCESS);
975
976 /* check data tree */
977 CHECK_LYD_STRING_PARAM(tree,
978 "<l xmlns=\"urn:tests:f\">value</l>\n"
979 "<d xmlns=\"urn:tests:f\">15</d>\n"
980 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
981 "<cont xmlns=\"urn:tests:f\">\n"
982 " <ll1>def3</ll1>\n"
983 " <d>5</d>\n"
984 " <ll2>non-dflt</ll2>\n"
985 "</cont>\n",
986 LYD_XML, LYD_PRINT_WITHSIBLINGS);
987
988 /* check diff */
989 CHECK_LYD_STRING_PARAM(diff,
990 "<cont xmlns=\"urn:tests:f\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
991 " <ll1 yang:operation=\"delete\">def1</ll1>\n"
992 " <ll1 yang:operation=\"delete\">def2</ll1>\n"
993 " <ll1 yang:operation=\"delete\">def3</ll1>\n"
994 " <d yang:operation=\"delete\">15</d>\n"
995 " <ll2 yang:operation=\"delete\">dflt1</ll2>\n"
996 " <ll2 yang:operation=\"delete\">dflt2</ll2>\n"
997 "</cont>\n",
998 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
999 lyd_free_all(diff);
1000 lyd_free_all(tree);
Radek Krejci7be7b9f2021-02-24 11:46:27 +01001001
1002 /* check data tree - when enabled node */
1003 CHECK_PARSE_LYD_PARAM("<d xmlns=\"urn:tests:f\">666</d><cont xmlns=\"urn:tests:f\"><d>666</d></cont>",
1004 LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1005 CHECK_LYD_STRING_PARAM(tree,
1006 "<ll1 xmlns=\"urn:tests:f\">def1</ll1>\n"
1007 "<ll1 xmlns=\"urn:tests:f\">def2</ll1>\n"
1008 "<ll1 xmlns=\"urn:tests:f\">def3</ll1>\n"
1009 "<d xmlns=\"urn:tests:f\">666</d>\n"
1010 "<dd xmlns=\"urn:tests:f\">15</dd>\n"
1011 "<ll2 xmlns=\"urn:tests:f\">dflt1</ll2>\n"
1012 "<ll2 xmlns=\"urn:tests:f\">dflt2</ll2>\n"
1013 "<cont xmlns=\"urn:tests:f\">\n"
1014 " <ll1>def1</ll1>\n"
1015 " <ll1>def2</ll1>\n"
1016 " <ll1>def3</ll1>\n"
1017 " <d>666</d>\n"
1018 " <dd>15</dd>\n"
1019 " <ll2>dflt1</ll2>\n"
1020 " <ll2>dflt2</ll2>\n"
1021 "</cont>\n",
1022 LYD_XML, LYD_PRINT_WD_ALL | LYD_PRINT_WITHSIBLINGS);
1023 lyd_free_all(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +02001024}
1025
1026static void
1027test_state(void **state)
1028{
1029 const char *data;
1030 struct lyd_node *tree;
1031 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001032 "module h {\n"
1033 " namespace urn:tests:h;\n"
1034 " prefix h;\n"
1035 " yang-version 1.1;\n"
1036 "\n"
1037 " container cont {\n"
1038 " container cont2 {\n"
1039 " config false;\n"
1040 " leaf l {\n"
1041 " type string;\n"
1042 " }\n"
1043 " }\n"
1044 " }\n"
1045 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +02001046
1047 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1048
1049 data = "<cont xmlns=\"urn:tests:h\">\n"
1050 " <cont2>\n"
1051 " <l>val</l>\n"
1052 " </cont2>\n"
1053 "</cont>\n";
1054 CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_NO_STATE, 0, LY_EVALID, tree);
Michal Vasko224e7772021-02-18 14:22:33 +01001055 CHECK_LOG_CTX("Unexpected data state node \"cont2\" found.",
Radek Krejci2efc45b2020-12-22 16:25:44 +01001056 "Schema location /h:cont/cont2, data location /h:cont, line number 3.");
Radek Iša56ca9e42020-09-08 18:42:00 +02001057
1058 CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
1059 assert_int_equal(LY_EVALID, lyd_validate_all(&tree, NULL, LYD_VALIDATE_PRESENT | LYD_VALIDATE_NO_STATE, NULL));
Michal Vasko224e7772021-02-18 14:22:33 +01001060 CHECK_LOG_CTX("Unexpected data state node \"cont2\" found.",
Radek Krejci2efc45b2020-12-22 16:25:44 +01001061 "Schema location /h:cont/cont2, data location /h:cont/cont2.");
Radek Iša56ca9e42020-09-08 18:42:00 +02001062 lyd_free_all(tree);
1063}
1064
1065static void
1066test_must(void **state)
1067{
1068 struct lyd_node *tree;
1069 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001070 "module i {\n"
1071 " namespace urn:tests:i;\n"
1072 " prefix i;\n"
1073 " yang-version 1.1;\n"
1074 "\n"
1075 " container cont {\n"
1076 " leaf l {\n"
1077 " type string;\n"
1078 " }\n"
1079 " leaf l2 {\n"
1080 " must \"../l = 'right'\";\n"
1081 " type string;\n"
1082 " }\n"
Michal Vaskoe9391c72021-10-05 10:04:56 +02001083 " leaf l3 {\n"
1084 " must \"../l = 'left'\" {\n"
1085 " error-app-tag \"not-left\";\n"
1086 " error-message \"l leaf is not left\";\n"
1087 " }\n"
1088 " type string;\n"
1089 " }\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001090 " }\n"
1091 "}";
Michal Vaskocde73ac2019-11-14 16:10:27 +01001092
Radek Iša56ca9e42020-09-08 18:42:00 +02001093 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
Michal Vaskocde73ac2019-11-14 16:10:27 +01001094
Radek Iša56ca9e42020-09-08 18:42:00 +02001095 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:i\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001096 " <l>wrong</l>\n"
1097 " <l2>val</l2>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001098 "</cont>\n", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
Michal Vaskoe9391c72021-10-05 10:04:56 +02001099 CHECK_LOG_CTX_APPTAG("Must condition \"../l = 'right'\" not satisfied.",
1100 "Schema location /i:cont/l2, data location /i:cont/l2.", "must-violation");
Michal Vaskocc048b22020-03-27 15:52:38 +01001101
Radek Iša56ca9e42020-09-08 18:42:00 +02001102 LYD_TREE_CREATE("<cont xmlns=\"urn:tests:i\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001103 " <l>right</l>\n"
1104 " <l2>val</l2>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001105 "</cont>\n", tree);
1106 lyd_free_all(tree);
Michal Vaskoe9391c72021-10-05 10:04:56 +02001107
1108 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:i\">\n"
1109 " <l>wrong</l>\n"
1110 " <l3>val</l3>\n"
1111 "</cont>\n", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1112 CHECK_LOG_CTX_APPTAG("l leaf is not left", "Schema location /i:cont/l3, data location /i:cont/l3.", "not-left");
Michal Vaskocc048b22020-03-27 15:52:38 +01001113}
1114
Radek Iša56ca9e42020-09-08 18:42:00 +02001115const char *schema_j =
1116 "module j {\n"
1117 " namespace urn:tests:j;\n"
1118 " prefix j;\n"
1119 " yang-version 1.1;\n"
1120 "\n"
1121 " feature feat1;\n"
1122 "\n"
1123 " container cont {\n"
1124 " must \"false()\";\n"
1125 " list l1 {\n"
1126 " key \"k\";\n"
1127 " leaf k {\n"
1128 " type string;\n"
1129 " }\n"
1130 " action act {\n"
1131 " if-feature feat1;\n"
1132 " input {\n"
1133 " must \"../../lf1 = 'true'\";\n"
1134 " leaf lf2 {\n"
1135 " type leafref {\n"
1136 " path /lf3;\n"
1137 " }\n"
1138 " }\n"
1139 " }\n"
1140 " output {\n"
1141 " must \"../../lf1 = 'true2'\";\n"
1142 " leaf lf2 {\n"
1143 " type leafref {\n"
1144 " path /lf4;\n"
1145 " }\n"
1146 " }\n"
1147 " }\n"
1148 " }\n"
1149 " }\n"
1150 "\n"
1151 " leaf lf1 {\n"
1152 " type string;\n"
1153 " }\n"
1154 " }\n"
1155 "\n"
1156 " leaf lf3 {\n"
1157 " type string;\n"
1158 " }\n"
1159 "\n"
1160 " leaf lf4 {\n"
1161 " type string;\n"
1162 " }\n"
1163 "}";
1164const char *feats_j[] = {"feat1", NULL};
1165
Michal Vaskofea12c62020-03-30 11:00:15 +02001166static void
1167test_action(void **state)
1168{
Michal Vasko63f3d842020-07-08 10:10:14 +02001169 struct ly_in *in;
Michal Vaskofea12c62020-03-30 11:00:15 +02001170 struct lyd_node *tree, *op_tree;
Michal Vaskofea12c62020-03-30 11:00:15 +02001171
Radek Iša56ca9e42020-09-08 18:42:00 +02001172 UTEST_ADD_MODULE(schema_j, LYS_IN_YANG, feats_j, NULL);
1173
1174 assert_int_equal(LY_SUCCESS, ly_in_new_memory(
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001175 "<cont xmlns=\"urn:tests:j\">\n"
1176 " <l1>\n"
1177 " <k>val1</k>\n"
1178 " <act>\n"
1179 " <lf2>target</lf2>\n"
1180 " </act>\n"
1181 " </l1>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001182 "</cont>\n", &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +01001183 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_YANG, &op_tree, NULL));
Michal Vaskofea12c62020-03-30 11:00:15 +02001184 assert_non_null(op_tree);
1185
1186 /* missing leafref */
Michal Vasko1e4c68e2021-02-18 15:03:01 +01001187 assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, NULL, LYD_TYPE_RPC_YANG, NULL));
Radek Krejci2efc45b2020-12-22 16:25:44 +01001188 CHECK_LOG_CTX("Invalid leafref value \"target\" - no existing target instance \"/lf3\".",
Radek Krejci2a9fc652021-01-22 17:44:34 +01001189 "Schema location /j:cont/l1/act/input/lf2, data location /j:cont/l1[k='val1']/act/lf2.");
Michal Vasko63f3d842020-07-08 10:10:14 +02001190 ly_in_free(in, 0);
Michal Vaskofea12c62020-03-30 11:00:15 +02001191
Radek Iša56ca9e42020-09-08 18:42:00 +02001192 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001193 " <lf1>not true</lf1>\n"
1194 "</cont>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001195 "<lf3 xmlns=\"urn:tests:j\">target</lf3>\n",
1196 LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
Michal Vaskofea12c62020-03-30 11:00:15 +02001197
Michal Vaskofea12c62020-03-30 11:00:15 +02001198 /* input must false */
Michal Vasko1e4c68e2021-02-18 15:03:01 +01001199 assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, tree, LYD_TYPE_RPC_YANG, NULL));
Radek Krejci2efc45b2020-12-22 16:25:44 +01001200 CHECK_LOG_CTX("Must condition \"../../lf1 = 'true'\" not satisfied.",
1201 "Data location /j:cont/l1[k='val1']/act.");
Michal Vaskofea12c62020-03-30 11:00:15 +02001202
Radek Iša56ca9e42020-09-08 18:42:00 +02001203 lyd_free_all(tree);
1204 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001205 " <lf1>true</lf1>\n"
1206 "</cont>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001207 "<lf3 xmlns=\"urn:tests:j\">target</lf3>\n",
1208 LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
Michal Vaskofea12c62020-03-30 11:00:15 +02001209
1210 /* success */
Michal Vasko1e4c68e2021-02-18 15:03:01 +01001211 assert_int_equal(LY_SUCCESS, lyd_validate_op(op_tree, tree, LYD_TYPE_RPC_YANG, NULL));
Michal Vaskofea12c62020-03-30 11:00:15 +02001212
Michal Vaskocb7526d2020-03-30 15:08:26 +02001213 lyd_free_tree(op_tree);
1214 lyd_free_siblings(tree);
Michal Vaskocb7526d2020-03-30 15:08:26 +02001215}
1216
1217static void
aPiecek18a844e2021-08-10 11:06:24 +02001218test_rpc(void **state)
1219{
1220 const char *schema, *data;
1221 struct ly_in *in;
1222 struct lyd_node *tree;
1223
1224 /* Testing constraint violation in RPC. */
1225 schema =
1226 "module val-str {\n"
1227 " namespace \"urn:vstr\";\n"
1228 " prefix v;\n"
1229 "\n"
1230 " rpc modify-user-password {\n"
1231 " input {\n"
1232 " leaf old-password {\n"
1233 " type string {\n"
1234 " length \"4..8\";\n"
1235 " }\n"
1236 " }\n"
1237 " leaf new-password {\n"
1238 " type string {\n"
1239 " length \"4..8\";\n"
1240 " }\n"
1241 " }\n"
1242 " }\n"
1243 " }\n"
1244 "}\n";
1245 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1246 data =
1247 "<modify-user-password xmlns=\"urn:vstr\">\n"
1248 " <old-password>12345</old-password>\n"
1249 " <new-password>123</new-password>\n"
1250 "</modify-user-password>";
1251 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
1252 /* Success, although the validation found a violation of
1253 * the restriction. An \"opaq\" node was created instead of
1254 * the \"new-password\" node from schema.
1255 */
1256 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_YANG, &tree, NULL));
1257 assert_non_null(tree);
1258 /* Validate data as RPC request. */
1259 assert_int_equal(LY_EVALID, lyd_validate_op(tree, NULL, LYD_TYPE_RPC_YANG, NULL));
1260 CHECK_LOG_CTX("Invalid opaque node \"new-password\" found.",
1261 "Data location /val-str:modify-user-password/new-password.");
1262 ly_in_free(in, 0);
1263 lyd_free_all(tree);
1264}
1265
1266static void
Michal Vaskocb7526d2020-03-30 15:08:26 +02001267test_reply(void **state)
1268{
Michal Vasko63f3d842020-07-08 10:10:14 +02001269 struct ly_in *in;
Michal Vasko2552ea32020-12-08 15:32:34 +01001270 struct lyd_node *tree, *op_tree;
Michal Vaskocb7526d2020-03-30 15:08:26 +02001271
Radek Iša56ca9e42020-09-08 18:42:00 +02001272 UTEST_ADD_MODULE(schema_j, LYS_IN_YANG, feats_j, NULL);
1273
1274 assert_int_equal(LY_SUCCESS, ly_in_new_memory(
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001275 "<cont xmlns=\"urn:tests:j\">\n"
1276 " <l1>\n"
1277 " <k>val1</k>\n"
1278 " <act>\n"
1279 " <lf2>target</lf2>\n"
1280 " </act>\n"
1281 " </l1>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001282 "</cont>\n", &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +01001283 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_REPLY_YANG, &op_tree, NULL));
Michal Vaskocb7526d2020-03-30 15:08:26 +02001284 assert_non_null(op_tree);
Michal Vasko63f3d842020-07-08 10:10:14 +02001285 ly_in_free(in, 0);
Michal Vaskocb7526d2020-03-30 15:08:26 +02001286
1287 /* missing leafref */
Michal Vasko1e4c68e2021-02-18 15:03:01 +01001288 assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, NULL, LYD_TYPE_REPLY_YANG, NULL));
Radek Krejci2efc45b2020-12-22 16:25:44 +01001289 CHECK_LOG_CTX("Invalid leafref value \"target\" - no existing target instance \"/lf4\".",
Radek Krejci2a9fc652021-01-22 17:44:34 +01001290 "Schema location /j:cont/l1/act/output/lf2, data location /j:cont/l1[k='val1']/act/lf2.");
Michal Vaskocb7526d2020-03-30 15:08:26 +02001291
Radek Iša56ca9e42020-09-08 18:42:00 +02001292 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001293 " <lf1>not true</lf1>\n"
1294 "</cont>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001295 "<lf4 xmlns=\"urn:tests:j\">target</lf4>\n",
1296 LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
Michal Vaskocb7526d2020-03-30 15:08:26 +02001297
Michal Vaskocb7526d2020-03-30 15:08:26 +02001298 /* input must false */
Michal Vasko1e4c68e2021-02-18 15:03:01 +01001299 assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, tree, LYD_TYPE_REPLY_YANG, NULL));
Radek Krejci2efc45b2020-12-22 16:25:44 +01001300 CHECK_LOG_CTX("Must condition \"../../lf1 = 'true2'\" not satisfied.", "Data location /j:cont/l1[k='val1']/act.");
Michal Vaskocb7526d2020-03-30 15:08:26 +02001301
Radek Iša56ca9e42020-09-08 18:42:00 +02001302 lyd_free_all(tree);
1303 CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001304 " <lf1>true2</lf1>\n"
1305 "</cont>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001306 "<lf4 xmlns=\"urn:tests:j\">target</lf4>\n",
1307 LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
Michal Vaskocb7526d2020-03-30 15:08:26 +02001308
1309 /* success */
Michal Vasko1e4c68e2021-02-18 15:03:01 +01001310 assert_int_equal(LY_SUCCESS, lyd_validate_op(op_tree, tree, LYD_TYPE_REPLY_YANG, NULL));
Michal Vaskocb7526d2020-03-30 15:08:26 +02001311
Michal Vaskofea12c62020-03-30 11:00:15 +02001312 lyd_free_tree(op_tree);
Radek Iša56ca9e42020-09-08 18:42:00 +02001313 lyd_free_all(tree);
Michal Vaskofea12c62020-03-30 11:00:15 +02001314}
1315
Michal Vasko8d151222021-07-22 12:12:41 +02001316static void
1317test_case(void **state)
1318{
1319 struct lyd_node *tree;
1320 const char *schema =
1321 "module k {\n"
1322 " namespace urn:tests:k;\n"
1323 " prefix k;\n"
1324 " yang-version 1.1;\n"
1325 "\n"
1326 " container ch {\n"
1327 " choice a0 {\n"
1328 " case v0 {\n"
1329 " leaf g0 {\n"
1330 " type string;\n"
1331 " }\n"
1332 " }\n"
1333 " case v1 {\n"
1334 " choice a1 {\n"
1335 " case r0 {\n"
1336 " leaf g1 {\n"
1337 " type string;\n"
1338 " }\n"
1339 " }\n"
1340 " case r1 {\n"
1341 " leaf g2 {\n"
1342 " type string;\n"
1343 " }\n"
1344 " leaf g3 {\n"
1345 " type string;\n"
1346 " }\n"
1347 " }\n"
1348 " case r2 {\n"
1349 " leaf g4 {\n"
1350 " type string;\n"
1351 " }\n"
1352 " }\n"
1353 " }\n"
1354 " }\n"
1355 " case v2 {\n"
1356 " choice a2 {\n"
1357 " case y0 {\n"
1358 " leaf g5 {\n"
1359 " type string;\n"
1360 " }\n"
1361 " }\n"
1362 " case y1 {\n"
1363 " leaf g6 {\n"
1364 " type string;\n"
1365 " }\n"
1366 " leaf g7 {\n"
1367 " type string;\n"
1368 " }\n"
1369 " }\n"
1370 " case y2 {\n"
1371 " leaf g8 {\n"
1372 " type string;\n"
1373 " }\n"
1374 " }\n"
1375 " }\n"
1376 " }\n"
1377 " }\n"
1378 " }\n"
1379 "}";
1380
1381 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1382
1383 CHECK_PARSE_LYD_PARAM(
1384 "{\n"
1385 " \"k:ch\": {\n"
1386 " \"g0\": \"value_g0\",\n"
1387 " \"g7\": \"value_g7\"\n"
1388 " }\n"
1389 "}\n", LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1390 CHECK_LOG_CTX("Data for both cases \"v0\" and \"v2\" exist.",
1391 "Schema location /k:ch/a0, data location /k:ch, line number 5.");
1392
1393 CHECK_PARSE_LYD_PARAM(
1394 "{\n"
1395 " \"k:ch\": {\n"
1396 " \"g7\": \"value_g7\",\n"
1397 " \"g0\": \"value_g0\"\n"
1398 " }\n"
1399 "}\n", LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1400 CHECK_LOG_CTX("Data for both cases \"v0\" and \"v2\" exist.",
1401 "Schema location /k:ch/a0, data location /k:ch, line number 5.");
1402}
1403
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001404int
1405main(void)
Michal Vaskocde73ac2019-11-14 16:10:27 +01001406{
1407 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +02001408 UTEST(test_when),
1409 UTEST(test_mandatory),
Christian Hoppsb6ecaea2021-02-06 09:45:38 -05001410 UTEST(test_mandatory_when),
Radek Iša56ca9e42020-09-08 18:42:00 +02001411 UTEST(test_minmax),
1412 UTEST(test_unique),
1413 UTEST(test_unique_nested),
1414 UTEST(test_dup),
1415 UTEST(test_defaults),
1416 UTEST(test_state),
1417 UTEST(test_must),
1418 UTEST(test_action),
aPiecek18a844e2021-08-10 11:06:24 +02001419 UTEST(test_rpc),
Radek Iša56ca9e42020-09-08 18:42:00 +02001420 UTEST(test_reply),
Michal Vasko8d151222021-07-22 12:12:41 +02001421 UTEST(test_case),
Michal Vaskocde73ac2019-11-14 16:10:27 +01001422 };
1423
Radek Iša56ca9e42020-09-08 18:42:00 +02001424 return cmocka_run_group_tests(tests, NULL, NULL);
Michal Vaskocde73ac2019-11-14 16:10:27 +01001425}