blob: 9002685d8ef00110ee39d13ca0a4cd9d01978076 [file] [log] [blame]
Radek Išaa76902f2021-03-29 08:52:51 +02001/**
2 * @file list.c
3 * @author Radek Iša <isa@cesnet.cz>
4 * @brief test for list node
5 *
6 * Copyright (c) 2021 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15/* INCLUDE UTEST HEADER */
16#define _UTEST_MAIN_
17#include "../utests.h"
18
19/* GLOBAL INCLUDE HEADERS */
20#include <ctype.h>
21
22/* LOCAL INCLUDE HEADERS */
23#include "libyang.h"
24#include "path.h"
25
26#define LYD_TREE_CREATE(INPUT, MODEL) \
27 CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, MODEL)
28
29#define MODULE_CREATE_YIN(MOD_NAME, NODES) \
30 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
31 "<module name=\"" MOD_NAME "\"\n" \
32 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n" \
33 " xmlns:pref=\"urn:tests:" MOD_NAME "\">\n" \
34 " <yang-version value=\"1.1\"/>\n" \
35 " <namespace uri=\"urn:tests:" MOD_NAME "\"/>\n" \
36 " <prefix value=\"pref\"/>\n" \
37 NODES \
38 "</module>\n"
39
40#define MODULE_CREATE_YANG(MOD_NAME, NODES) \
41 "module " MOD_NAME " {\n" \
42 " yang-version 1.1;\n" \
43 " namespace \"urn:tests:" MOD_NAME "\";\n" \
44 " prefix pref;\n" \
45 NODES \
46 "}\n"
47
48static void
49test_schema_yang(void **state)
50{
51 const char *schema;
52 const struct lys_module *mod;
53 struct lysc_node_list *lysc_leaf;
54 struct lysc_node *lysc_node;
55 struct lysp_node_list *lysp_leaf;
56
57 schema = MODULE_CREATE_YANG("T0", "list user {"
58 "key uid;"
59 "unique name;"
60 "leaf uid{type int32;}"
61 "leaf name{type string;}"
62 "leaf group{type string;}"
63 "}");
64 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
65 lysc_leaf = (void *)mod->compiled->data;
66 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
67 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
68 lysc_node = lysc_leaf->child;
69 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
70 lysc_node = lysc_node->next;
71 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
72 lysc_node = lysc_node->next;
73 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
74
75 schema = MODULE_CREATE_YANG("T1", "list user {"
76 "key uid;"
77 "container name{"
78 " leaf fist {type string;}"
79 " container second{leaf sub { type int32;}}"
80 "}"
81 "leaf uid{type int32;}"
82 "}");
83 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
84 lysc_leaf = (void *)mod->compiled->data;
85 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
86 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
87 lysc_node = lysc_leaf->child;
88 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
89 lysc_node = lysc_node->next;
90 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "name", 0, LYS_CONTAINER, 1, 0, 0, 0);
91
92 schema = MODULE_CREATE_YANG("T2", "list grup {"
93 "key \"guid\";"
94 "leaf guid{type int32;}"
95 "list users{ key name; leaf name {type string;}}"
96 "}");
97 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
98 lysc_leaf = (void *)mod->compiled->data;
99 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "grup", 0, \
100 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
101 lysc_node = lysc_leaf->child;
102 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
103 lysc_node = lysc_node->next;
104 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
105
106 /* restriction */
107 schema = MODULE_CREATE_YANG("T3", "list grup {"
108 "key guid;"
109 "min-elements 10;"
110 "max-elements 20;"
111 "leaf guid{type int32;}"
112 "list users{ key name; leaf name {type string;}}"
113 "}");
114 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
115 lysc_leaf = (void *)mod->compiled->data;
116 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0xa5, 1, "grup", 0, \
117 0, 0, 0, 0, 1, 20, 10, 0, 0, 0, 0);
118 lysc_node = lysc_leaf->child;
119 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
120 lysc_node = lysc_node->next;
121 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
122
123 schema = MODULE_CREATE_YANG("T4", "list user {"
124 "key \"uid name\";"
125 "unique name;"
126 "leaf uid{type int32;}"
127 "leaf name{type string;}"
128 "leaf group{type string;}"
129 "}");
130 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
131 lysc_leaf = (void *)mod->compiled->data;
132 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
133 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
134 lysc_node = lysc_leaf->child;
135 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
136 lysc_node = lysc_node->next;
137 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x185, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
138 lysc_node = lysc_node->next;
139 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
140
141 schema = MODULE_CREATE_YANG("T5", "list rule {"
142 "key \"id\";"
143 "unique \"name\";"
144 "unique \"ip port\";"
145 "leaf id{type int32;}"
146 "leaf name{type string;}"
147 "leaf ip{type string;}"
148 "leaf port{type int16;}"
149 "}");
150 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
151 lysc_leaf = (void *)mod->compiled->data;
152 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "rule", 0, \
153 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 2, 0);
154 lysc_node = lysc_leaf->child;
155 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "id", 1, LYS_LEAF, 1, 0, 0, 0);
156 lysc_node = lysc_node->next;
157 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
158 lysc_node = lysc_node->next;
159 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "ip", 1, LYS_LEAF, 1, 0, 0, 0);
160 lysc_node = lysc_node->next;
161 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
162
163 /* test error */
164 schema = MODULE_CREATE_YANG("TERR_0", "list user {"
165 "key uid;"
166 "min-elements 10;"
167 "max-elements -1;"
168 "leaf uid{type int32;}"
169 "leaf name{type string;}"
170 "leaf group{type string;}"
171 "}");
172 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
173 CHECK_LOG_CTX("Invalid value \"-1\" of \"max-elements\".",
174 "Line number 5.");
175
176 schema = MODULE_CREATE_YANG("TERR_0", "list user {"
177 "key uid;"
178 "min-elements 10;"
179 "max-elements 4294967298;"
180 "leaf uid{type int32;}"
181 "leaf name{type string;}"
182 "leaf group{type string;}"
183 "}");
184 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
185 CHECK_LOG_CTX("Value \"4294967298\" is out of \"max-elements\" bounds.",
186 "Line number 5.");
187
188 schema = MODULE_CREATE_YANG("TERR_0", "list user {"
189 "key uid;"
190 "min-elements 20;"
191 "max-elements 10;"
192 "leaf uid{type int32;}"
193 "leaf name{type string;}"
194 "leaf group{type string;}"
195 "}");
196 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
197 CHECK_LOG_CTX("List min-elements 20 is bigger than max-elements 10.",
198 "/TERR_0:user");
199
200 schema = MODULE_CREATE_YANG("TERR_0", "list user {"
201 "key uid;"
202 "min-elements -1;"
203 "max-elements 20;"
204 "leaf uid{type int32;}"
205 "leaf name{type string;}"
206 "leaf group{type string;}"
207 "}");
208 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
209 CHECK_LOG_CTX("Invalid value \"-1\" of \"min-elements\".",
210 "Line number 5.");
211
212 schema = MODULE_CREATE_YANG("TERR_0", "list user {"
213 "key uid;"
214 "key name;"
215 "leaf uid{type int32;}"
216 "leaf name{type string;}"
217 "leaf group{type string;}"
218 "}");
219 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
220 CHECK_LOG_CTX("Duplicate keyword \"key\".",
221 "Line number 5.");
222
223 schema = MODULE_CREATE_YANG("T6", "list user {"
224 "config false;"
225 "leaf uid{type int32;}"
226 "leaf name{type string;}"
227 "leaf group{type string;}"
228 "}");
229 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
230 lysc_leaf = (void *)mod->compiled->data;
231 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0xa86, 1, "user", 0, \
232 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
233 lysc_node = lysc_leaf->child;
234 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x6, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
235 lysc_node = lysc_node->next;
236 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x6, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
237 lysc_node = lysc_node->next;
238 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x6, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
239
240 schema = MODULE_CREATE_YANG("T7", "list user {"
241 "key uid;"
242 "unique name;"
243 "ordered-by user;"
244 "leaf uid{type int32;}"
245 "leaf name{type string;}"
246 "leaf group{type string;}"
247 "}");
248 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
249 lysc_leaf = (void *)mod->compiled->data;
250 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x45, 1, "user", 0, \
251 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
252 lysc_node = lysc_leaf->child;
253 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
254 lysc_node = lysc_node->next;
255 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
256 lysc_node = lysc_node->next;
257 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
258
259 schema = MODULE_CREATE_YANG("T8", "list user {"
260 "key uid;"
261 "unique name;"
262 "ordered-by system;"
263 "leaf uid{type int32;}"
264 "leaf name{type string;}"
265 "leaf group{type string;}"
266 "}");
267 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
268 lysc_leaf = (void *)mod->compiled->data;
269 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
270 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
271 lysc_node = lysc_leaf->child;
272 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
273 lysc_node = lysc_node->next;
274 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
275 lysc_node = lysc_node->next;
276 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
277
278 schema = MODULE_CREATE_YANG("TERROR0", "list user {"
279 "key uid;"
280 "unique name;"
281 "ordered-by systeme;"
282 "leaf uid{type int32;}"
283 "leaf name{type string;}"
284 "leaf group{type string;}"
285 "}");
286 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
287 CHECK_LOG_CTX("Invalid value \"systeme\" of \"ordered-by\".",
288 "Line number 5.");
289
290 schema = MODULE_CREATE_YANG("TERROR0", "list \"\" {"
291 "key uid;"
292 "unique name;"
293 "ordered-by system;"
294 "leaf uid{type int32;}"
295 "leaf name{type string;}"
296 "leaf group{type string;}"
297 "}");
298 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
299 CHECK_LOG_CTX("Statement argument is required.",
300 "Line number 5.");
301
302 schema = MODULE_CREATE_YANG("T9", "list user {"
303 "key uid;"
304 "unique name;"
305 "ordered-by system;"
306 "leaf uid{type int32;}"
307 "leaf name{type string;}"
308 "leaf group{type string; default \"abcd\";}"
309 "}");
310 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
311 lysc_leaf = (void *)mod->compiled->data;
312 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
313 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
314 lysc_node = lysc_leaf->child;
315 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
316 lysc_node = lysc_node->next;
317 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
318 lysc_node = lysc_node->next;
319 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x205, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
320
321 schema = MODULE_CREATE_YANG("T10", "list user {"
322 "key uid;"
323 "leaf uid{type int32; default \"25\";}"
324 "leaf name{type string;}"
325 "leaf group{type string;}"
326 "}");
327 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
328 lysc_leaf = (void *)mod->compiled->data;
329 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
330 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
331 lysc_node = lysc_leaf->child;
332 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x305, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
333 lysc_node = lysc_node->next;
334 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
335 lysc_node = lysc_node->next;
336 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
337
338 schema = MODULE_CREATE_YANG("T11",
339 "typedef my_type {"
340 " type int8; default \"25\";"
341 "}"
342 "list user {"
343 " key uid;"
344 " leaf uid{type my_type;}"
345 " leaf name{type string;}"
346 " leaf group{type string;}"
347 "}");
348 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
349 lysc_leaf = (void *)mod->compiled->data;
350 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
351 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
352 lysc_node = lysc_leaf->child;
353 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
354 lysc_node = lysc_node->next;
355 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
356 lysc_node = lysc_node->next;
357 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
358
359}
360
361static void
362test_schema_yin(void **state)
363{
364 const char *schema;
365 const struct lys_module *mod;
366 struct lysc_node_list *lysc_leaf;
367 struct lysc_node *lysc_node;
368 struct lysp_node_list *lysp_leaf;
369
370 schema = MODULE_CREATE_YIN("T0", "<list name=\"user\">"
371 " <key value=\"uid\"/>"
372 " <unique tag=\"name\"/>"
373 " <leaf name=\"uid\"><type name=\"int32\"/></leaf>"
374 " <leaf name=\"name\"><type name=\"string\"/></leaf>"
375 " <leaf name=\"group\"><type name=\"string\"/></leaf>"
376 "</list>");
377 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
378 lysc_leaf = (void *)mod->compiled->data;
379 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
380 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
381 lysc_node = lysc_leaf->child;
382 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
383 lysc_node = lysc_node->next;
384 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
385 lysc_node = lysc_node->next;
386 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
387
388 schema = MODULE_CREATE_YIN("T00", "<list name=\"user\">"
389 " <key value=\"u&lt;id\"/>"
390 " <leaf name=\"uid\"><type name=\"int32\"/></leaf>"
391 " <leaf name=\"name\"><type name=\"string\"/></leaf>"
392 " <leaf name=\"group\"><type name=\"string\"/></leaf>"
393 "</list>");
394 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
395 CHECK_LOG_CTX("The list's key \"u<id\" not found.",
396 "/T00:user");
397
398 schema = MODULE_CREATE_YIN("T1", "<list name=\"user\"> "
399 " <key value=\"uid\"/>"
400 " <container name=\"name\">"
401 " <leaf name=\"fist\"> <type name=\"string\"/> </leaf>"
402 " <container name=\"second\">"
403 " <leaf name=\"sub\"> <type name=\"int32\"/></leaf>"
404 " </container>"
405 " </container>"
406 " <leaf name=\"uid\"> <type name=\"int32\"/></leaf>"
407 "</list>");
408 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
409 lysc_leaf = (void *)mod->compiled->data;
410 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
411 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
412 lysc_node = lysc_leaf->child;
413 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
414 lysc_node = lysc_node->next;
415 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "name", 0, LYS_CONTAINER, 1, 0, 0, 0);
416
417 schema = MODULE_CREATE_YIN("T2", "<list name=\"grup\">"
418 "<key value=\"guid\"/>"
419 "<leaf name=\"guid\"> <type name=\"int32\"/> </leaf>"
420 "<list name=\"users\">"
421 " <key value=\"name\"/>"
422 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
423 "</list>"
424 "</list>");
425 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
426 lysc_leaf = (void *)mod->compiled->data;
427 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "grup", 0, \
428 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
429 lysc_node = lysc_leaf->child;
430 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
431 lysc_node = lysc_node->next;
432 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
433
434 /* restriction */
435 schema = MODULE_CREATE_YIN("T3",
436 "<list name = \"grup\">"
437 " <key value=\"guid\"/>"
438 " <min-elements value=\"10\"/>"
439 " <max-elements value=\"20\"/>"
440 " <leaf name=\"guid\"> <type name=\"int32\"/> </leaf>"
441 " <list name=\"users\"> <key value=\"name\"/>"
442 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
443 " </list>"
444 "</list>");
445 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
446 lysc_leaf = (void *)mod->compiled->data;
447 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0xa5, 1, "grup", 0, \
448 0, 0, 0, 0, 1, 20, 10, 0, 0, 0, 0);
449 lysc_node = lysc_leaf->child;
450 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
451 lysc_node = lysc_node->next;
452 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
453
454 /*schema = MODULE_CREATE_YIN("T4",
455 "<list name=\"user\">"
456 " <key value=\"uid name\"/>"
457 " <unique tag=\"name\"/>"
458 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
459 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
460 " <leaf name=\"group\"> <type name=\"string\"/> </leaf>"
461 "</list>");
462 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
463 lysc_leaf = (void *)mod->compiled->data;
464 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
465 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
466 lysc_node = lysc_leaf->child;
467 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
468 lysc_node = lysc_node->next;
469 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x185, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
470 lysc_node = lysc_node->next;
471 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);*/
472
473 schema = MODULE_CREATE_YIN("T5",
474 "<list name=\"rule\">"
475 " <key value=\"id\"/>"
476 " <unique tag=\"name\"/>"
477 " <unique tag=\"ip port\"/>"
478 " <leaf name=\"id\"> <type name=\"int32\"/></leaf>"
479 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
480 " <leaf name=\"ip\"> <type name=\"string\"/> </leaf>"
481 " <leaf name=\"port\"> <type name=\"int16\"/> </leaf>"
482 "</list>");
483 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
484 lysc_leaf = (void *)mod->compiled->data;
485 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "rule", 0, \
486 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 2, 0);
487 lysc_node = lysc_leaf->child;
488 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "id", 1, LYS_LEAF, 1, 0, 0, 0);
489 lysc_node = lysc_node->next;
490 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
491 lysc_node = lysc_node->next;
492 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "ip", 1, LYS_LEAF, 1, 0, 0, 0);
493 lysc_node = lysc_node->next;
494 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
495
496 /* test error */
497 schema = MODULE_CREATE_YIN("TERR_0",
498 "<list name=\"user\">"
499 " <key value=\"uid\"/>"
500 " <min-elements value=\"10\"/>"
501 " <max-elements value=\"-1\"/>"
502 " <leaf name=\"uid\"> <type name=\"int32\"> </leaf>"
503 "</list>");
504 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
505 CHECK_LOG_CTX("Invalid value \"-1\" of \"value\" attribute in \"max-elements\" element.",
506 "Line number 10.");
507
508 schema = MODULE_CREATE_YIN("TERR_0",
509 "<list name=\"user\">"
510 " <key value=\"uid\"/>"
511 " <min-elements value=\"10\"/>"
512 " <max-elements value=\"4294967298\"/>"
513 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
514 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
515 " <leaf name=\"group\"> <type name=\"string\"/> </leaf>"
516 "</list>");
517 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
518 CHECK_LOG_CTX("Value \"4294967298\" of \"value\" attribute in \"max-elements\" element is out of bounds.",
519 "Line number 10.");
520
521 schema = MODULE_CREATE_YIN("TERR_0",
522 "<list name=\"user\">"
523 " <key value=\"uid\"/>"
524 " <min-elements value=\"20\"/>"
525 " <max-elements value=\"10\"/>"
526 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
527 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
528 " <leaf name=\"group\"> <type name=\"string\"/> </leaf>"
529 "</list>");
530 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
531 CHECK_LOG_CTX("Invalid combination of min-elements and max-elements: min value 20 is bigger than the max value 10.",
532 "Line number 10.");
533
534 schema = MODULE_CREATE_YIN("TERR_0",
535 "<list name=\"user\">"
536 " <key value=\"uid\"/>"
537 " <min-elements value=\"-1\"/>"
538 " <max-elements value=\"20\"/>"
539 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
540 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
541 " <leaf name=\"group\"> <type name=\"string\"/> </leaf>"
542 "</list>");
543 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
544 CHECK_LOG_CTX("Value \"-1\" of \"value\" attribute in \"min-elements\" element is out of bounds.",
545 "Line number 10.");
546
547 schema = MODULE_CREATE_YIN("TERR_0",
548 "<list name=\"user\">"
549 " <key value=\"uid\"/>"
550 " <key value=\"name\"/>"
551 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
552 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
553 " <leaf name=\"group\"> <type name=\"string\"/> </leaf>"
554 "</list>");
555 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
556 CHECK_LOG_CTX("Redefinition of \"key\" sub-element in \"list\" element.",
557 "Line number 10.");
558
559 schema = MODULE_CREATE_YIN("T6",
560 "<list name=\"user\">"
561 " <config value=\"false\"/>"
562 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
563 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
564 " <leaf name=\"group\"><type name=\"string\"/> </leaf>"
565 "</list>");
566 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
567 lysc_leaf = (void *)mod->compiled->data;
568 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0xa86, 1, "user", 0, \
569 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
570 lysc_node = lysc_leaf->child;
571 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x6, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
572 lysc_node = lysc_node->next;
573 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x6, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
574 lysc_node = lysc_node->next;
575 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x6, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
576
577 schema = MODULE_CREATE_YIN("T7",
578 "<list name=\"user\">"
579 " <key value=\"uid\"/>"
580 " <unique tag=\"name\"/>"
581 " <ordered-by value=\"user\"/>"
582 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
583 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
584 " <leaf name=\"group\"><type name=\"string\"/> </leaf>"
585 "</list>");
586 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
587 lysc_leaf = (void *)mod->compiled->data;
588 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x45, 1, "user", 0, \
589 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
590 lysc_node = lysc_leaf->child;
591 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
592 lysc_node = lysc_node->next;
593 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
594 lysc_node = lysc_node->next;
595 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
596
597 schema = MODULE_CREATE_YIN("T8",
598 "<list name=\"user\">"
599 " <key value=\"uid\"/>"
600 " <unique tag=\"name\"/>"
601 " <ordered-by value=\"system\"/>"
602 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
603 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
604 " <leaf name=\"group\"><type name=\"string\"/> </leaf>"
605 "</list>");
606 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
607 lysc_leaf = (void *)mod->compiled->data;
608 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
609 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
610 lysc_node = lysc_leaf->child;
611 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
612 lysc_node = lysc_node->next;
613 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
614 lysc_node = lysc_node->next;
615 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
616
617 schema = MODULE_CREATE_YIN("TERROR0",
618 "<list name=\"user\">"
619 " <key value=\"uid\"/>"
620 " <unique tag=\"name\"/>"
621 " <ordered-by value=\"systeme\"/>"
622 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
623 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
624 " <leaf name=\"group\"><type name=\"string\"/> </leaf>"
625 "</list>");
626 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
627 CHECK_LOG_CTX("Invalid value \"systeme\" of \"value\" attribute in \"ordered-by\" element. Valid values are \"system\" and \"user\".",
628 "Line number 10.");
629
630 schema = MODULE_CREATE_YIN("T_DEFS1",
631 "<list name=\"user\">"
632 " <key value=\"uid\"/>"
633 " <unique tag=\"name\"/>"
634 " <ordered-by value=\"system\"/>"
635 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
636 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
637 " <leaf name=\"group\"><type name=\"string\"/> <default value=\"ath\"/> </leaf>"
638 "</list>");
639 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
640 lysc_leaf = (void *)mod->compiled->data;
641 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
642 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
643 lysc_node = lysc_leaf->child;
644 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
645 lysc_node = lysc_node->next;
646 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
647 lysc_node = lysc_node->next;
648 CHECK_LYSC_NODE(lysc_node, 0, 0, 0x205, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
649
650}
651
652static void
653test_schema_print(void **state)
654{
655 const char *schema_yang, *schema_yin;
656 char *printed;
657 const struct lys_module *mod;
658
659 /* test print yang to yin */
660 schema_yang = MODULE_CREATE_YANG("PRINT0",
661 "list user {"
662 " min-elements 10;"
663 " max-elements 20;"
664 " key \"uid name\";"
665 " unique name;"
666 " leaf uid{type int32;}"
667 " leaf name{type string;}"
668 " leaf group{type string;}"
669 "}");
670 schema_yin = MODULE_CREATE_YIN("PRINT0",
671 " <list name=\"user\">\n"
672 " <key value=\"uid name\"/>\n"
673 " <unique tag=\"name\"/>\n"
674 " <min-elements value=\"10\"/>\n"
675 " <max-elements value=\"20\"/>\n"
676 " <leaf name=\"uid\">\n"
677 " <type name=\"int32\"/>\n"
678 " </leaf>\n"
679 " <leaf name=\"name\">\n"
680 " <type name=\"string\"/>\n"
681 " </leaf>\n"
682 " <leaf name=\"group\">\n"
683 " <type name=\"string\"/>\n"
684 " </leaf>\n"
685 " </list>\n");
686
687 UTEST_ADD_MODULE(schema_yang, LYS_IN_YANG, NULL, &mod);
688 assert_non_null(mod);
689 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0));
690 assert_string_equal(printed, schema_yin);
691 free(printed);
692
693 /* test print yin to yang */
694 schema_yang = MODULE_CREATE_YANG("PRINT1",
695 " list user {\n"
696 " key \"uid name\";\n"
697 " unique \"name\";\n"
698 " min-elements 10;\n"
699 " max-elements 20;\n"
700 " leaf uid {\n"
701 " type int32;\n"
702 " }\n"
703 " leaf name {\n"
704 " type string;\n"
705 " }\n"
706 " leaf group {\n"
707 " type string;\n"
708 " }\n"
709 " }\n");
710 schema_yin = MODULE_CREATE_YIN("PRINT1",
711 " <list name=\"user\">\n"
712 " <key value=\"uid name\"/>\n"
713 " <unique tag=\"name\"/>\n"
714 " <min-elements value=\"10\"/>\n"
715 " <max-elements value=\"20\"/>\n"
716 " <leaf name=\"uid\">\n"
717 " <type name=\"int32\"/>\n"
718 " </leaf>\n"
719 " <leaf name=\"name\">\n"
720 " <type name=\"string\"/>\n"
721 " </leaf>\n"
722 " <leaf name=\"group\">\n"
723 " <type name=\"string\"/>\n"
724 " </leaf>\n"
725 " </list>\n");
726
727 UTEST_ADD_MODULE(schema_yin, LYS_IN_YIN, NULL, &mod);
728 assert_non_null(mod);
729 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YANG, 0));
730 assert_string_equal(printed, schema_yang);
731 free(printed);
732
733 /* test no segmentation fold due ignoring default value */
734 schema_yang = MODULE_CREATE_YANG("PRINT2", "list user {"
735 "key uid;"
736 "leaf uid{type int32; default \"25\";}"
737 "leaf name{type string;}"
738 "leaf group{type string;}"
739 "}");
740
741 UTEST_ADD_MODULE(schema_yang, LYS_IN_YANG, NULL, &mod);
742 assert_non_null(mod);
743 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0));
744 free(printed);
745}
746
747static void
748test_xml(void **state)
749{
750 struct lyd_node *tree;
751 const char *data, *schema;
752 struct lyd_node_inner *list_tree;
753 struct lyd_node_term *list_leaf;
754
755 schema = MODULE_CREATE_YANG("T0", "list user {"
756 "key uid;"
757 "unique \"name group\";"
758 "leaf uid{type uint32;}"
759 "leaf name{type string;}"
760 "leaf group{type string;}"
761 "}");
762 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
763
764 /* add data */
765 data =
766 "<user xmlns=\"urn:tests:T0\">"
767 " <uid>0</uid>"
768 " <name>Tomáš Novák</name>"
769 " <group>User</group>"
770 "</user>"
771 "<user xmlns=\"urn:tests:T0\">"
772 " <uid>1</uid>"
773 " <name>Martin Novák</name>"
774 " <group>User</group>"
775 "</user>";
776 /* check first item */
777 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
778 list_tree = (void *)tree;
779 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
780 list_leaf = (void *) list_tree->child;
781 assert_string_equal(list_leaf->schema->name, "uid");
782 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
783 list_leaf = (void *) list_leaf->next;
784 assert_string_equal(list_leaf->schema->name, "name");
785 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák");
786 list_leaf = (void *) list_leaf->next;
787 assert_string_equal(list_leaf->schema->name, "group");
788 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
789 /* check second item */
790 list_tree = (void *) list_tree->next;
791 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
792 list_leaf = (void *) list_tree->child;
793 assert_string_equal(list_leaf->schema->name, "uid");
794 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1);
795 list_leaf = (void *) list_leaf->next;
796 assert_string_equal(list_leaf->schema->name, "name");
797 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Martin Novák");
798 list_leaf = (void *) list_leaf->next;
799 assert_string_equal(list_leaf->schema->name, "group");
800 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
801 lyd_free_all(tree);
802
803 /* add data */
804 data =
805 "<user xmlns=\"urn:tests:T0\">"
806 " <uid>0</uid>"
807 " <name>Tomáš Novák</name>"
808 " <group>User</group>"
809 "</user>"
810 "<user xmlns=\"urn:tests:T0\">"
811 " <uid>1</uid>"
812 " <name>Tomáš Novák</name>"
813 " <group>Admin</group>"
814 "</user>";
815 /* check first item */
816 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
817 list_tree = (void *)tree;
818 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
819 list_leaf = (void *) list_tree->child;
820 assert_string_equal(list_leaf->schema->name, "uid");
821 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
822 list_leaf = (void *) list_leaf->next;
823 assert_string_equal(list_leaf->schema->name, "name");
824 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák");
825 list_leaf = (void *) list_leaf->next;
826 assert_string_equal(list_leaf->schema->name, "group");
827 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
828 /* check second item */
829 list_tree = (void *) list_tree->next;
830 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
831 list_leaf = (void *) list_tree->child;
832 assert_string_equal(list_leaf->schema->name, "uid");
833 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1);
834 list_leaf = (void *) list_leaf->next;
835 assert_string_equal(list_leaf->schema->name, "name");
836 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák");
837 list_leaf = (void *) list_leaf->next;
838 assert_string_equal(list_leaf->schema->name, "group");
839 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin");
840 lyd_free_all(tree);
841
842 data =
843 "<user xmlns=\"urn:tests:T0\">"
844 " <uid>0</uid>"
845 " <name>Tomáš Novák</name>"
846 " <group>User</group>"
847 "</user>"
848 "<user xmlns=\"urn:tests:T0\">"
849 " <uid>0</uid>"
850 " <name>Tomáš Novák</name>"
851 " <group>Admin</group>"
852 "</user>";
853 /* check first item */
854 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
855 assert_null(tree);
856 CHECK_LOG_CTX("Duplicate instance of \"user\".",
857 "Schema location /T0:user, data location /T0:user[uid='0'].");
858
859 data =
860 "<user xmlns=\"urn:tests:T0\">"
861 " <uid>0</uid>"
862 " <name>Tomáš Novák</name>"
863 " <group>User</group>"
864 "</user>"
865 "<user xmlns=\"urn:tests:T0\">"
866 " <uid>1</uid>"
867 " <name>Tomáš Novák</name>"
868 " <group>User</group>"
869 "</user>";
870 /* check first item */
871 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
872 assert_null(tree);
873 CHECK_LOG_CTX("Unique data leaf(s) \"name group\" not satisfied in \"/T0:user[uid='0']\" and \"/T0:user[uid='1']\".",
874 "Schema location /T0:user, data location /T0:user[uid='1'].");
875
876 /* double key */
877 schema = MODULE_CREATE_YANG("T1", "list user {"
878 "key \"uid group\";"
879 "leaf uid{type uint32;}"
880 "leaf name{type string;}"
881 "leaf group{type string;}"
882 "}");
883 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
884 data =
885 "<user xmlns=\"urn:tests:T1\">"
886 " <uid>0</uid>"
887 " <name>Tomáš Novák</name>"
888 " <group>User</group>"
889 "</user>"
890 "<user xmlns=\"urn:tests:T1\">"
891 " <uid>0</uid>"
892 " <name>Tomáš Novák</name>"
893 " <group>Admin</group>"
894 "</user>";
895 /* check first item */
896 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
897 list_tree = (void *)tree;
898 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
899 list_leaf = (void *) list_tree->child;
900 assert_string_equal(list_leaf->schema->name, "uid");
901 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
902 list_leaf = (void *) list_leaf->next;
903 assert_string_equal(list_leaf->schema->name, "group");
904 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "User");
905 list_leaf = (void *) list_leaf->next;
906 assert_string_equal(list_leaf->schema->name, "name");
907 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Tomáš Novák");
908 /* check second item */
909 list_tree = (void *) list_tree->next;
910 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
911 list_leaf = (void *) list_tree->child;
912 assert_string_equal(list_leaf->schema->name, "uid");
913 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
914 list_leaf = (void *) list_leaf->next;
915 assert_string_equal(list_leaf->schema->name, "group");
916 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Admin");
917 list_leaf = (void *) list_leaf->next;
918 assert_string_equal(list_leaf->schema->name, "name");
919 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Tomáš Novák");
920 lyd_free_all(tree);
921
922 data =
923 "<user xmlns=\"urn:tests:T1\">"
924 " <uid>0</uid>"
925 " <name>Tomáš Novák</name>"
926 " <group>User</group>"
927 "</user>"
928 "<user xmlns=\"urn:tests:T1\">"
929 " <uid>0</uid>"
930 " <name>Tomáš Novák</name>"
931 " <group>User</group>"
932 "</user>";
933 /* check first item */
934 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
935 assert_null(tree);
936 CHECK_LOG_CTX("Duplicate instance of \"user\".",
937 "Schema location /T1:user, data location /T1:user[uid='0'][group='User'].");
938
939 /* min elements max elements */
940 schema = MODULE_CREATE_YANG("T2",
941 "list user {"
942 " key uid;"
943 " min-elements 3;"
944 " max-elements 5;"
945 " leaf uid{type uint32;}"
946 " leaf name{type string;}"
947 " leaf group{type string;}"
948 "}");
949 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
950 data =
951 "<user xmlns=\"urn:tests:T2\">"
952 " <uid>0</uid>"
953 " <name>Tomáš Novák</name>"
954 " <group>User</group>"
955 "</user>"
956 "<user xmlns=\"urn:tests:T2\">"
957 " <uid>1</uid>"
958 " <name>Tomáš Novák</name>"
959 " <group>Admin</group>"
960 "</user>"
961 "<user xmlns=\"urn:tests:T2\">"
962 " <uid>2</uid>"
963 " <name>Tomáš Jak</name>"
964 " <group>Admin</group>"
965 "</user>";
966 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
967 list_tree = (void *)tree;
968 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
969 list_leaf = (void *) list_tree->child;
970 assert_string_equal(list_leaf->schema->name, "uid");
971 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
972 list_leaf = (void *) list_leaf->next;
973 assert_string_equal(list_leaf->schema->name, "name");
974 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák");
975 list_leaf = (void *) list_leaf->next;
976 assert_string_equal(list_leaf->schema->name, "group");
977 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
978 /* check second item */
979 list_tree = (void *) list_tree->next;
980 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
981 list_leaf = (void *) list_tree->child;
982 assert_string_equal(list_leaf->schema->name, "uid");
983 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1);
984 list_leaf = (void *) list_leaf->next;
985 assert_string_equal(list_leaf->schema->name, "name");
986 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák");
987 list_leaf = (void *) list_leaf->next;
988 assert_string_equal(list_leaf->schema->name, "group");
989 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin");
990 /* check third item */
991 list_tree = (void *) list_tree->next;
992 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
993 list_leaf = (void *) list_tree->child;
994 assert_string_equal(list_leaf->schema->name, "uid");
995 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "2", 2);
996 list_leaf = (void *) list_leaf->next;
997 assert_string_equal(list_leaf->schema->name, "name");
998 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Jak");
999 list_leaf = (void *) list_leaf->next;
1000 assert_string_equal(list_leaf->schema->name, "group");
1001 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin");
1002 lyd_free_all(tree);
1003
1004 data =
1005 "<user xmlns=\"urn:tests:T2\">"
1006 " <uid>0</uid>"
1007 " <name>Tomáš Novák</name>"
1008 " <group>User</group>"
1009 "</user>"
1010 "<user xmlns=\"urn:tests:T2\">"
1011 " <uid>1</uid>"
1012 " <name>Tomáš Novák</name>"
1013 " <group>Admin</group>"
1014 "</user>"
1015 "<user xmlns=\"urn:tests:T2\">"
1016 " <uid>2</uid>"
1017 " <name>Tomáš Novák</name>"
1018 " <group>Admin</group>"
1019 "</user>"
1020 "<user xmlns=\"urn:tests:T2\">"
1021 " <uid>3</uid>"
1022 " <name>Tomáš Novák</name>"
1023 " <group>Admin</group>"
1024 "</user>"
1025 "<user xmlns=\"urn:tests:T2\">"
1026 " <uid>4</uid>"
1027 " <name>Tomáš Novák</name>"
1028 " <group>Admin</group>"
1029 "</user>";
1030 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1031 list_tree = (void *)tree;
1032 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1033 list_tree = (void *) list_tree->next;
1034 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1035 list_tree = (void *) list_tree->next;
1036 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1037 list_tree = (void *) list_tree->next;
1038 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1039 list_tree = (void *) list_tree->next;
1040 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
1041 lyd_free_all(tree);
1042
1043 /* check wrong number of items */
1044 data =
1045 "<user xmlns=\"urn:tests:T2\">"
1046 " <uid>0</uid>"
1047 " <name>Tomáš Novák</name>"
1048 " <group>User</group>"
1049 "</user>"
1050 "<user xmlns=\"urn:tests:T2\">"
1051 " <uid>1</uid>"
1052 " <name>Tomáš Novák</name>"
1053 " <group>Admin</group>"
1054 "</user>";
1055 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1056 assert_null(tree);
1057 CHECK_LOG_CTX("Too few \"user\" instances.",
1058 "Schema location /T2:user.");
1059
1060 data =
1061 "<user xmlns=\"urn:tests:T2\">"
1062 " <uid>0</uid>"
1063 " <name>Tomáš Novák</name>"
1064 " <group>User</group>"
1065 "</user>"
1066 "<user xmlns=\"urn:tests:T2\">"
1067 " <uid>1</uid>"
1068 " <name>Tomáš Novák</name>"
1069 " <group>Admin</group>"
1070 "</user>"
1071 "<user xmlns=\"urn:tests:T2\">"
1072 " <uid>2</uid>"
1073 " <name>Tomáš Novák</name>"
1074 " <group>Admin</group>"
1075 "</user>"
1076 "<user xmlns=\"urn:tests:T2\">"
1077 " <uid>3</uid>"
1078 " <name>Tomáš Novák</name>"
1079 " <group>Admin</group>"
1080 "</user>"
1081 "<user xmlns=\"urn:tests:T2\">"
1082 " <uid>4</uid>"
1083 " <name>Tomáš Novák</name>"
1084 " <group>Admin</group>"
1085 "</user>"
1086 "<user xmlns=\"urn:tests:T2\">"
1087 " <uid>5</uid>"
1088 " <name>Tomáš Novák</name>"
1089 " <group>Admin</group>"
1090 "</user>";
1091 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1092 assert_null(tree);
1093 CHECK_LOG_CTX("Too many \"user\" instances.",
1094 "Schema location /T2:user, data location /T2:user[uid='5'].");
1095
1096 /* empty list */
1097 schema = MODULE_CREATE_YANG("T_EMPTY_LIST",
1098 "container user_list {"
1099 " list user {"
1100 " key uid;"
1101 " unique \"name group\";"
1102 " leaf uid{type uint32;}"
1103 " leaf name{type string;}"
1104 " leaf group{type string;}"
1105 "}"
1106 "}");
1107 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1108
1109 /* empty list */
1110 data = "<user_list xmlns=\"urn:tests:T_EMPTY_LIST\"/>";
1111 /* check first item */
1112 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1113 list_tree = (void *)tree;
1114 CHECK_LYD_NODE_INNER(list_tree, 0, 0, 0, 1, 0, 0, 0, 1);
1115 lyd_free_all(tree);
1116}
1117
1118static void
1119test_json(void **state)
1120{
1121 struct lyd_node *tree;
1122 const char *data, *schema;
1123 struct lyd_node_inner *list_tree;
1124 struct lyd_node_term *list_leaf;
1125
1126 schema = MODULE_CREATE_YANG("T0", "list user {"
1127 "key uid;"
1128 "unique \"name group\";"
1129 "leaf uid{type uint32;}"
1130 "leaf name{type string;}"
1131 "leaf group{type string;}"
1132 "}");
1133 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1134
1135 /* add data */
1136 data =
1137 "{\"T0:user\": ["
1138 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1139 " {\"uid\":1, \"name\":\"Martin Novák\", \"group\":\"User\"}"
1140 "]}";
1141
1142 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1143 list_tree = (void *)tree;
1144 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1145 list_leaf = (void *) list_tree->child;
1146 assert_string_equal(list_leaf->schema->name, "uid");
1147 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
1148 list_leaf = (void *) list_leaf->next;
1149 assert_string_equal(list_leaf->schema->name, "name");
1150 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Jan Kuba");
1151 list_leaf = (void *) list_leaf->next;
1152 assert_string_equal(list_leaf->schema->name, "group");
1153 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
1154 /* check second item */
1155 list_tree = (void *) list_tree->next;
1156 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
1157 list_leaf = (void *) list_tree->child;
1158 assert_string_equal(list_leaf->schema->name, "uid");
1159 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1);
1160 list_leaf = (void *) list_leaf->next;
1161 assert_string_equal(list_leaf->schema->name, "name");
1162 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Martin Novák");
1163 list_leaf = (void *) list_leaf->next;
1164 assert_string_equal(list_leaf->schema->name, "group");
1165 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
1166 lyd_free_all(tree);
1167
1168 /* Unique */
1169 data =
1170 "{\"T0:user\": ["
1171 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1172 " {\"uid\":1, \"name\":\"Jan Kuba\", \"group\":\"Admin\"}"
1173 "]}";
1174
1175 /* check first item */
1176 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1177 list_tree = (void *)tree;
1178 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1179 list_leaf = (void *) list_tree->child;
1180 assert_string_equal(list_leaf->schema->name, "uid");
1181 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
1182 list_leaf = (void *) list_leaf->next;
1183 assert_string_equal(list_leaf->schema->name, "name");
1184 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Jan Kuba");
1185 list_leaf = (void *) list_leaf->next;
1186 assert_string_equal(list_leaf->schema->name, "group");
1187 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
1188 /* check second item */
1189 list_tree = (void *) list_tree->next;
1190 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
1191 list_leaf = (void *) list_tree->child;
1192 assert_string_equal(list_leaf->schema->name, "uid");
1193 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1);
1194 list_leaf = (void *) list_leaf->next;
1195 assert_string_equal(list_leaf->schema->name, "name");
1196 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Jan Kuba");
1197 list_leaf = (void *) list_leaf->next;
1198 assert_string_equal(list_leaf->schema->name, "group");
1199 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin");
1200 lyd_free_all(tree);
1201
1202 data =
1203 "{\"T0:user\": ["
1204 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1205 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"Admin\"}"
1206 "]}";
1207 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1208 assert_null(tree);
1209 CHECK_LOG_CTX("Duplicate instance of \"user\".",
1210 "Schema location /T0:user, data location /T0:user[uid='0'], line number 1.");
1211
1212 data =
1213 "{\"T0:user\": ["
1214 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1215 " {\"uid\":1, \"name\":\"Jan Kuba\", \"group\":\"User\"}"
1216 "]}";
1217 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1218 assert_null(tree);
1219 CHECK_LOG_CTX("Unique data leaf(s) \"name group\" not satisfied in \"/T0:user[uid='0']\" and \"/T0:user[uid='1']\".",
1220 "Schema location /T0:user, data location /T0:user[uid='1'], line number 1.");
1221
1222 /* double key */
1223 schema = MODULE_CREATE_YANG("T1", "list user {"
1224 "key \"uid group\";"
1225 "leaf uid{type uint32;}"
1226 "leaf name{type string;}"
1227 "leaf group{type string;}"
1228 "}");
1229 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1230 data =
1231 "{\"T1:user\": ["
1232 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1233 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"Admin\"}"
1234 "]}";
1235 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1236 list_tree = (void *)tree;
1237 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1238 list_leaf = (void *) list_tree->child;
1239 assert_string_equal(list_leaf->schema->name, "uid");
1240 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
1241 list_leaf = (void *) list_leaf->next;
1242 assert_string_equal(list_leaf->schema->name, "group");
1243 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "User");
1244 list_leaf = (void *) list_leaf->next;
1245 assert_string_equal(list_leaf->schema->name, "name");
1246 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Jan Kuba");
1247 /* check second item */
1248 list_tree = (void *) list_tree->next;
1249 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
1250 list_leaf = (void *) list_tree->child;
1251 assert_string_equal(list_leaf->schema->name, "uid");
1252 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
1253 list_leaf = (void *) list_leaf->next;
1254 assert_string_equal(list_leaf->schema->name, "group");
1255 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Admin");
1256 list_leaf = (void *) list_leaf->next;
1257 assert_string_equal(list_leaf->schema->name, "name");
1258 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Jan Kuba");
1259 lyd_free_all(tree);
1260
1261 data =
1262 "{\"T1:user\": ["
1263 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1264 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}"
1265 "]}";
1266 /* check first item */
1267 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1268 assert_null(tree);
1269 CHECK_LOG_CTX("Duplicate instance of \"user\".",
1270 "Schema location /T1:user, data location /T1:user[uid='0'][group='User'], line number 1.");
1271
1272 /* min elements max elements */
1273 schema = MODULE_CREATE_YANG("T2",
1274 "list user {"
1275 " key uid;"
1276 " min-elements 3;"
1277 " max-elements 5;"
1278 " leaf uid{type uint32;}"
1279 " leaf name{type string;}"
1280 " leaf group{type string;}"
1281 "}");
1282 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1283 data =
1284 "{\"T2:user\": ["
1285 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1286 " {\"uid\":1, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1287 " {\"uid\":2, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}"
1288 "]}";
1289
1290 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1291 list_tree = (void *)tree;
1292 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1293 list_leaf = (void *) list_tree->child;
1294 assert_string_equal(list_leaf->schema->name, "uid");
1295 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
1296 list_leaf = (void *) list_leaf->next;
1297 assert_string_equal(list_leaf->schema->name, "name");
1298 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Jan Kuba");
1299 list_leaf = (void *) list_leaf->next;
1300 assert_string_equal(list_leaf->schema->name, "group");
1301 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
1302 /* check second item */
1303 list_tree = (void *) list_tree->next;
1304 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1305 list_leaf = (void *) list_tree->child;
1306 assert_string_equal(list_leaf->schema->name, "uid");
1307 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1);
1308 list_leaf = (void *) list_leaf->next;
1309 assert_string_equal(list_leaf->schema->name, "name");
1310 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Antonín Kuba");
1311 list_leaf = (void *) list_leaf->next;
1312 assert_string_equal(list_leaf->schema->name, "group");
1313 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
1314 /* check third item */
1315 list_tree = (void *) list_tree->next;
1316 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
1317 list_leaf = (void *) list_tree->child;
1318 assert_string_equal(list_leaf->schema->name, "uid");
1319 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "2", 2);
1320 list_leaf = (void *) list_leaf->next;
1321 assert_string_equal(list_leaf->schema->name, "name");
1322 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák");
1323 list_leaf = (void *) list_leaf->next;
1324 assert_string_equal(list_leaf->schema->name, "group");
1325 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin");
1326 lyd_free_all(tree);
1327
1328 data =
1329 "{\"T2:user\": ["
1330 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1331 " {\"uid\":1, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1332 " {\"uid\":2, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1333 " {\"uid\":3, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1334 " {\"uid\":4, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}"
1335 "]}";
1336 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1337 list_tree = (void *)tree;
1338 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1339 list_tree = (void *) list_tree->next;
1340 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1341 list_tree = (void *) list_tree->next;
1342 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1343 list_tree = (void *) list_tree->next;
1344 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1345 list_tree = (void *) list_tree->next;
1346 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
1347 lyd_free_all(tree);
1348
1349 /* check wrong number of items */
1350 data =
1351 "{\"T2:user\": ["
1352 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1353 " {\"uid\":4, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}"
1354 "]}";
1355 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1356 assert_null(tree);
1357 CHECK_LOG_CTX("Too few \"user\" instances.",
1358 "Schema location /T2:user, line number 1.");
1359
1360 data =
1361 "{\"T2:user\": ["
1362 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1363 " {\"uid\":1, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1364 " {\"uid\":2, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1365 " {\"uid\":3, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1366 " {\"uid\":4, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"},"
1367 " {\"uid\":5, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}"
1368 "]}";
1369 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1370 assert_null(tree);
1371 CHECK_LOG_CTX("Too many \"user\" instances.",
1372 "Schema location /T2:user, data location /T2:user[uid='5'], line number 1.");
1373
1374 schema = MODULE_CREATE_YANG("T_EMPTY_LIST",
1375 "container user_list {"
1376 " list user {"
1377 " key uid;"
1378 " unique \"name group\";"
1379 " leaf uid{type uint32;}"
1380 " leaf name{type string;}"
1381 " leaf group{type string;}"
1382 "}"
1383 "}");
1384 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1385
1386 /* empty list */
1387 data =
1388 "{\"T_EMPTY_LIST:user_list\": {}"
1389 "}";
1390
1391 /* check first item */
1392 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1393 list_tree = (void *)tree;
1394 CHECK_LYD_NODE_INNER(list_tree, 0, 0, 0, 1, 0, 0, 0, 1);
1395 lyd_free_all(tree);
1396}
1397
1398static void
1399test_diff(void **state)
1400{
1401 struct lyd_node *tree;
1402 const char *data, *schema;
1403 struct lyd_node_inner *list_tree;
1404 struct lyd_node_term *list_leaf;
1405
1406 struct lyd_node *model_1, *model_2;
1407 struct lyd_node *diff;
1408 const char *expected_string;
1409 const char *data_1;
1410 const char *data_2;
1411 const char *diff_expected;
1412
1413 schema = MODULE_CREATE_YANG("T0", "list user {"
1414 "key uid;"
1415 "unique \"name group\";"
1416 "leaf uid{type uint32;}"
1417 "leaf name{type string;}"
1418 "leaf group{type string;}"
1419 "}");
1420 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1421
1422 /* delete item */
1423 data_1 =
1424 "<user xmlns=\"urn:tests:T0\">"
1425 " <uid>0</uid>"
1426 " <name>Tomáš Novák</name>"
1427 " <group>User</group>"
1428 "</user>"
1429 "<user xmlns=\"urn:tests:T0\">"
1430 " <uid>1</uid>"
1431 " <name>Martin Novák</name>"
1432 " <group>User</group>"
1433 "</user>";
1434
1435 data_2 =
1436 "<user xmlns=\"urn:tests:T0\">"
1437 " <uid>0</uid>"
1438 " <name>Tomáš Novák</name>"
1439 " <group>User</group>"
1440 "</user>";
1441
1442 diff_expected =
1443 "<user xmlns=\"urn:tests:T0\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\""
1444 " yang:operation=\"delete\">"
1445 "<uid>1</uid>"
1446 "<name>Martin Novák</name>"
1447 "<group>User</group>"
1448 "</user>";
1449 CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1);
1450 CHECK_PARSE_LYD_PARAM(data_2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1451 assert_int_equal(LY_SUCCESS, lyd_diff_siblings(model_1, model_2, 0, &diff));
1452 assert_non_null(diff);
1453 CHECK_LYD_STRING_PARAM(diff, diff_expected, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
1454 assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff));
1455 CHECK_LYD(model_1, model_2);
1456 lyd_free_all(model_1);
1457 lyd_free_all(model_2);
1458 lyd_free_all(diff);
1459
1460 /* add item */
1461 data_1 =
1462 "<user xmlns=\"urn:tests:T0\">"
1463 " <uid>0</uid>"
1464 " <name>Tomáš Novák</name>"
1465 " <group>User</group>"
1466 "</user>";
1467
1468 data_2 =
1469 "<user xmlns=\"urn:tests:T0\">"
1470 " <uid>0</uid>"
1471 " <name>Tomáš Novák</name>"
1472 " <group>User</group>"
1473 "</user>"
1474 "<user xmlns=\"urn:tests:T0\">"
1475 " <uid>1</uid>"
1476 " <name>Martin Novák</name>"
1477 " <group>User</group>"
1478 "</user>";
1479
1480 diff_expected =
1481 "<user xmlns=\"urn:tests:T0\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\""
1482 " yang:operation=\"create\">"
1483 "<uid>1</uid><name>Martin Novák</name><group>User</group>"
1484 "</user>";
1485 CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1);
1486 CHECK_PARSE_LYD_PARAM(data_2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1487 assert_int_equal(LY_SUCCESS, lyd_diff_siblings(model_1, model_2, 0, &diff));
1488 assert_non_null(diff);
1489 CHECK_LYD_STRING_PARAM(diff, diff_expected, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
1490 assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff));
1491 CHECK_LYD(model_1, model_2);
1492 lyd_free_all(model_1);
1493 lyd_free_all(model_2);
1494 lyd_free_all(diff);
1495
1496 /* diff one */
1497 data_1 =
1498 "<user xmlns=\"urn:tests:T0\">"
1499 " <uid>0</uid>"
1500 " <name>Tomáš Novák</name>"
1501 " <group>User</group>"
1502 "</user>"
1503 "<user xmlns=\"urn:tests:T0\">"
1504 " <uid>1</uid>"
1505 " <name>Martin Novák</name>"
1506 " <group>User</group>"
1507 "</user>";
1508
1509 data_2 =
1510 "<user xmlns=\"urn:tests:T0\">"
1511 " <uid>0</uid>"
1512 " <name>Tomáš Novák</name>"
1513 " <group>Admin</group>"
1514 "</user>"
1515 "<user xmlns=\"urn:tests:T0\">"
1516 " <uid>1</uid>"
1517 " <name>Martin Novák</name>"
1518 " <group>User</group>"
1519 "</user>";
1520
1521 diff_expected =
1522 "<user xmlns=\"urn:tests:T0\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\""
1523 " yang:operation=\"none\">"
1524 "<uid>0</uid>"
1525 "<group yang:operation=\"replace\" yang:orig-default=\"false\""
1526 " yang:orig-value=\"User\">Admin</group></user>";
1527 CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1);
1528 CHECK_PARSE_LYD_PARAM(data_2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1529 assert_int_equal(LY_SUCCESS, lyd_diff_siblings(model_1, model_2, 0, &diff));
1530 assert_non_null(diff);
1531 CHECK_LYD_STRING_PARAM(diff, diff_expected, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
1532 assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff));
1533 CHECK_LYD(model_1, model_2);
1534 lyd_free_all(model_1);
1535 lyd_free_all(model_2);
1536 lyd_free_all(diff);
1537
1538 /* diff same */
1539 data_1 =
1540 "<user xmlns=\"urn:tests:T0\">"
1541 " <uid>0</uid>"
1542 " <name>Tomáš Novák</name>"
1543 " <group>User</group>"
1544 "</user>"
1545 "<user xmlns=\"urn:tests:T0\">"
1546 " <uid>1</uid>"
1547 " <name>Martin Novák</name>"
1548 " <group>User</group>"
1549 "</user>";
1550
1551 data_2 =
1552 "<user xmlns=\"urn:tests:T0\">"
1553 " <uid>0</uid>"
1554 " <name>Tomáš Novák</name>"
1555 " <group>User</group>"
1556 "</user>"
1557 "<user xmlns=\"urn:tests:T0\">"
1558 " <uid>1</uid>"
1559 " <name>Martin Novák</name>"
1560 " <group>User</group>"
1561 "</user>";
1562
1563 CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1);
1564 CHECK_PARSE_LYD_PARAM(data_2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1565 assert_int_equal(LY_SUCCESS, lyd_diff_siblings(model_1, model_2, 0, &diff));
1566 assert_null(diff);
1567 assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff));
1568 CHECK_LYD(model_1, model_2);
1569 lyd_free_all(model_1);
1570 lyd_free_all(model_2);
1571 lyd_free_all(diff);
1572
1573 /* key changing */
1574 diff_expected =
1575 "<user xmlns=\"urn:tests:T0\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\""
1576 " yang:operation=\"none\">"
1577 "<uid>1</uid>"
1578 "<uid yang:operation=\"replace\" yang:orig-default=\"false\""
1579 " yang:orig-value=\"1\">0</uid></user>";
1580 CHECK_PARSE_LYD_PARAM(diff_expected, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, diff_expected);
1581}
1582
1583static void
1584test_print(void **state)
1585{
1586
1587 const char *schema;
1588 const char *expected_string;
1589
1590 schema = MODULE_CREATE_YANG("T0",
1591 "list user {"
1592 "key uid;"
1593 "leaf uid{type uint32;}"
1594 "leaf name{type string;}"
1595 "leaf group{type string; default \"User\";}"
1596 "}");
1597 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1598
1599 struct lyd_node *model_1;
1600 const char *data_1 =
1601 "<user xmlns=\"urn:tests:T0\">"
1602 " <uid>0</uid>"
1603 " <name>Tomáš Novák</name>"
1604 "</user>"
1605 "<user xmlns=\"urn:tests:T0\">"
1606 " <uid>1</uid>"
1607 " <name>Martin Novák</name>"
1608 " <group>Admin</group>"
1609 "</user>";
1610
1611 LYD_TREE_CREATE(data_1, model_1);
1612
1613 /* XML */
1614 expected_string =
1615 "<user xmlns=\"urn:tests:T0\">"
1616 "<uid>0</uid><name>Tomáš Novák</name>"
1617 "</user>"
1618 "<user xmlns=\"urn:tests:T0\">"
1619 "<uid>1</uid><name>Martin Novák</name><group>Admin</group>"
1620 "</user>";
1621 CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
1622
1623 /* JSON */
1624 expected_string = "{\"T0:user\":["
1625 "{\"uid\":0,\"name\":\"Tomáš Novák\"},"
1626 "{\"uid\":1,\"name\":\"Martin Novák\",\"group\":\"Admin\"}"
1627 "]}";
1628 CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_JSON, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
1629
1630 lyd_free_all(model_1);
1631}
1632
1633int
1634main(void)
1635{
1636 const struct CMUnitTest tests[] = {
1637 UTEST(test_schema_yang),
1638 UTEST(test_schema_yin),
1639 UTEST(test_schema_print),
1640
1641 UTEST(test_xml),
1642 UTEST(test_json),
1643 UTEST(test_diff),
1644 UTEST(test_print),
1645 };
1646
1647 return cmocka_run_group_tests(tests, NULL, NULL);
1648}