blob: f89c56ae4d5c3c225b9dfdc248b12d39063980da [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;
Michal Vasko4de7d072021-07-09 09:13:18 +020052 struct lys_module *mod;
Radek Išaa76902f2021-03-29 08:52:51 +020053 struct lysc_node_list *lysc_leaf;
54 struct lysc_node *lysc_node;
Radek Išaa76902f2021-03-29 08:52:51 +020055
56 schema = MODULE_CREATE_YANG("T0", "list user {"
57 "key uid;"
58 "unique name;"
59 "leaf uid{type int32;}"
60 "leaf name{type string;}"
61 "leaf group{type string;}"
62 "}");
63 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
64 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +020065 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +020066 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
67 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +020068 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +020069 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +020070 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +020071 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +020072 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +020073
74 schema = MODULE_CREATE_YANG("T1", "list user {"
75 "key uid;"
76 "container name{"
77 " leaf fist {type string;}"
78 " container second{leaf sub { type int32;}}"
79 "}"
80 "leaf uid{type int32;}"
81 "}");
82 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
83 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +020084 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +020085 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
86 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +020087 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +020088 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +020089 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "name", 0, LYS_CONTAINER, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +020090
91 schema = MODULE_CREATE_YANG("T2", "list grup {"
92 "key \"guid\";"
93 "leaf guid{type int32;}"
94 "list users{ key name; leaf name {type string;}}"
95 "}");
96 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
97 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +020098 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "grup", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +020099 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
100 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200101 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200102 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200103 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200104
105 /* restriction */
106 schema = MODULE_CREATE_YANG("T3", "list grup {"
107 "key guid;"
108 "min-elements 10;"
109 "max-elements 20;"
110 "leaf guid{type int32;}"
111 "list users{ key name; leaf name {type string;}}"
112 "}");
113 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
114 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200115 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_MAND_TRUE | LYS_ORDBY_SYSTEM, 1, \
116 "grup", 0, 0, 0, 0, 0, 1, 20, 10, 0, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200117 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200118 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200119 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200120 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200121
122 schema = MODULE_CREATE_YANG("T4", "list user {"
123 "key \"uid name\";"
124 "unique name;"
125 "leaf uid{type int32;}"
126 "leaf name{type string;}"
127 "leaf group{type string;}"
128 "}");
129 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
130 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200131 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200132 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
133 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200134 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200135 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200136 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE | LYS_KEY, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200137 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200138 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200139
140 schema = MODULE_CREATE_YANG("T5", "list rule {"
141 "key \"id\";"
142 "unique \"name\";"
143 "unique \"ip port\";"
144 "leaf id{type int32;}"
145 "leaf name{type string;}"
146 "leaf ip{type string;}"
147 "leaf port{type int16;}"
148 "}");
149 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
150 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200151 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "rule", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200152 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 2, 0);
153 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200154 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "id", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200155 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200156 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200157 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200158 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "ip", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200159 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200160 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200161
162 /* test error */
163 schema = MODULE_CREATE_YANG("TERR_0", "list user {"
164 "key uid;"
165 "min-elements 10;"
166 "max-elements -1;"
167 "leaf uid{type int32;}"
168 "leaf name{type string;}"
169 "leaf group{type string;}"
170 "}");
171 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200172 CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL,
173 "Invalid value \"-1\" of \"max-elements\".", "Line number 5.");
Radek Išaa76902f2021-03-29 08:52:51 +0200174
175 schema = MODULE_CREATE_YANG("TERR_0", "list user {"
176 "key uid;"
177 "min-elements 10;"
178 "max-elements 4294967298;"
179 "leaf uid{type int32;}"
180 "leaf name{type string;}"
181 "leaf group{type string;}"
182 "}");
183 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200184 CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL,
185 "Value \"4294967298\" is out of \"max-elements\" bounds.", "Line number 5.");
Radek Išaa76902f2021-03-29 08:52:51 +0200186
187 schema = MODULE_CREATE_YANG("TERR_0", "list user {"
188 "key uid;"
189 "min-elements 20;"
190 "max-elements 10;"
191 "leaf uid{type int32;}"
192 "leaf name{type string;}"
193 "leaf group{type string;}"
194 "}");
195 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200196 CHECK_LOG_CTX("List min-elements 20 is bigger than max-elements 10.", "/TERR_0:user");
Radek Išaa76902f2021-03-29 08:52:51 +0200197
198 schema = MODULE_CREATE_YANG("TERR_0", "list user {"
199 "key uid;"
200 "min-elements -1;"
201 "max-elements 20;"
202 "leaf uid{type int32;}"
203 "leaf name{type string;}"
204 "leaf group{type string;}"
205 "}");
206 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200207 CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL,
208 "Invalid value \"-1\" of \"min-elements\".", "Line number 5.");
Radek Išaa76902f2021-03-29 08:52:51 +0200209
210 schema = MODULE_CREATE_YANG("TERR_0", "list user {"
211 "key uid;"
212 "key name;"
213 "leaf uid{type int32;}"
214 "leaf name{type string;}"
215 "leaf group{type string;}"
216 "}");
217 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200218 CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL,
219 "Duplicate keyword \"key\".", "Line number 5.");
Radek Išaa76902f2021-03-29 08:52:51 +0200220
221 schema = MODULE_CREATE_YANG("T6", "list user {"
222 "config false;"
223 "leaf uid{type int32;}"
224 "leaf name{type string;}"
225 "leaf group{type string;}"
226 "}");
227 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
228 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200229 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_USER | LYS_KEYLESS | LYS_SET_CONFIG, \
230 1, "user", 0, 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200231 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200232 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200233 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200234 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200235 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200236 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200237
238 schema = MODULE_CREATE_YANG("T7", "list user {"
239 "key uid;"
240 "unique name;"
241 "ordered-by user;"
242 "leaf uid{type int32;}"
243 "leaf name{type string;}"
244 "leaf group{type string;}"
245 "}");
246 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
247 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200248 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_USER, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200249 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
250 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200251 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200252 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200253 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200254 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200255 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200256
257 schema = MODULE_CREATE_YANG("T8", "list user {"
258 "key uid;"
259 "unique name;"
260 "ordered-by system;"
261 "leaf uid{type int32;}"
262 "leaf name{type string;}"
263 "leaf group{type string;}"
264 "}");
265 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
266 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200267 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200268 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
269 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200270 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200271 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200272 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200273 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200274 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200275
276 schema = MODULE_CREATE_YANG("TERROR0", "list user {"
277 "key uid;"
278 "unique name;"
279 "ordered-by systeme;"
280 "leaf uid{type int32;}"
281 "leaf name{type string;}"
282 "leaf group{type string;}"
283 "}");
284 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200285 CHECK_LOG_CTX("Parsing module \"TERROR0\" failed.", NULL,
286 "Invalid value \"systeme\" of \"ordered-by\".", "Line number 5.");
Radek Išaa76902f2021-03-29 08:52:51 +0200287
288 schema = MODULE_CREATE_YANG("TERROR0", "list \"\" {"
289 "key uid;"
290 "unique name;"
291 "ordered-by system;"
292 "leaf uid{type int32;}"
293 "leaf name{type string;}"
294 "leaf group{type string;}"
295 "}");
296 UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200297 CHECK_LOG_CTX("Parsing module \"TERROR0\" failed.", NULL,
298 "Statement argument is required.", "Line number 5.");
Radek Išaa76902f2021-03-29 08:52:51 +0200299
300 schema = MODULE_CREATE_YANG("T9", "list user {"
301 "key uid;"
302 "unique name;"
303 "ordered-by system;"
304 "leaf uid{type int32;}"
305 "leaf name{type string;}"
306 "leaf group{type string; default \"abcd\";}"
307 "}");
308 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
309 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200310 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200311 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
312 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200313 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200314 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200315 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200316 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200317 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200318
319 schema = MODULE_CREATE_YANG("T10", "list user {"
320 "key uid;"
321 "leaf uid{type int32; default \"25\";}"
322 "leaf name{type string;}"
323 "leaf group{type string;}"
324 "}");
325 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
326 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200327 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200328 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
329 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200330 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY | LYS_SET_DFLT, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200331 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200332 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200333 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200334 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200335
336 schema = MODULE_CREATE_YANG("T11",
337 "typedef my_type {"
338 " type int8; default \"25\";"
339 "}"
340 "list user {"
341 " key uid;"
342 " leaf uid{type my_type;}"
343 " leaf name{type string;}"
344 " leaf group{type string;}"
345 "}");
346 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
347 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200348 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200349 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
350 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200351 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200352 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200353 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200354 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200355 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200356
357}
358
359static void
360test_schema_yin(void **state)
361{
362 const char *schema;
Michal Vasko4de7d072021-07-09 09:13:18 +0200363 struct lys_module *mod;
Radek Išaa76902f2021-03-29 08:52:51 +0200364 struct lysc_node_list *lysc_leaf;
365 struct lysc_node *lysc_node;
Radek Išaa76902f2021-03-29 08:52:51 +0200366
367 schema = MODULE_CREATE_YIN("T0", "<list name=\"user\">"
368 " <key value=\"uid\"/>"
369 " <unique tag=\"name\"/>"
370 " <leaf name=\"uid\"><type name=\"int32\"/></leaf>"
371 " <leaf name=\"name\"><type name=\"string\"/></leaf>"
372 " <leaf name=\"group\"><type name=\"string\"/></leaf>"
373 "</list>");
374 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
375 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200376 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200377 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
378 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200379 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200380 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200381 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200382 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200383 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200384
385 schema = MODULE_CREATE_YIN("T00", "<list name=\"user\">"
386 " <key value=\"u&lt;id\"/>"
387 " <leaf name=\"uid\"><type name=\"int32\"/></leaf>"
388 " <leaf name=\"name\"><type name=\"string\"/></leaf>"
389 " <leaf name=\"group\"><type name=\"string\"/></leaf>"
390 "</list>");
391 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200392 CHECK_LOG_CTX("The list's key \"u<id\" not found.", "/T00:user");
Radek Išaa76902f2021-03-29 08:52:51 +0200393
394 schema = MODULE_CREATE_YIN("T1", "<list name=\"user\"> "
395 " <key value=\"uid\"/>"
396 " <container name=\"name\">"
397 " <leaf name=\"fist\"> <type name=\"string\"/> </leaf>"
398 " <container name=\"second\">"
399 " <leaf name=\"sub\"> <type name=\"int32\"/></leaf>"
400 " </container>"
401 " </container>"
402 " <leaf name=\"uid\"> <type name=\"int32\"/></leaf>"
403 "</list>");
404 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
405 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200406 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200407 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
408 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200409 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200410 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200411 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "name", 0, LYS_CONTAINER, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200412
413 schema = MODULE_CREATE_YIN("T2", "<list name=\"grup\">"
414 "<key value=\"guid\"/>"
415 "<leaf name=\"guid\"> <type name=\"int32\"/> </leaf>"
416 "<list name=\"users\">"
417 " <key value=\"name\"/>"
418 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
419 "</list>"
420 "</list>");
421 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
422 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200423 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "grup", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200424 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
425 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200426 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200427 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200428 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200429
430 /* restriction */
431 schema = MODULE_CREATE_YIN("T3",
432 "<list name = \"grup\">"
433 " <key value=\"guid\"/>"
434 " <min-elements value=\"10\"/>"
435 " <max-elements value=\"20\"/>"
436 " <leaf name=\"guid\"> <type name=\"int32\"/> </leaf>"
437 " <list name=\"users\"> <key value=\"name\"/>"
438 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
439 " </list>"
440 "</list>");
441 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
442 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200443 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_MAND_TRUE | LYS_ORDBY_SYSTEM, 1, "grup", \
444 0, 0, 0, 0, 0, 1, 20, 10, 0, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200445 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200446 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200447 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200448 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200449
Radek Išabe8a6532021-03-29 08:54:22 +0200450 schema = MODULE_CREATE_YIN("T4",
Radek Išaa76902f2021-03-29 08:52:51 +0200451 "<list name=\"user\">"
452 " <key value=\"uid name\"/>"
453 " <unique tag=\"name\"/>"
454 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
455 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
456 " <leaf name=\"group\"> <type name=\"string\"/> </leaf>"
457 "</list>");
458 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
459 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200460 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200461 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
462 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200463 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200464 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200465 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE | LYS_KEY, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200466 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200467 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200468
469 schema = MODULE_CREATE_YIN("T5",
470 "<list name=\"rule\">"
471 " <key value=\"id\"/>"
472 " <unique tag=\"name\"/>"
473 " <unique tag=\"ip port\"/>"
474 " <leaf name=\"id\"> <type name=\"int32\"/></leaf>"
475 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
476 " <leaf name=\"ip\"> <type name=\"string\"/> </leaf>"
477 " <leaf name=\"port\"> <type name=\"int16\"/> </leaf>"
478 "</list>");
479 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
480 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200481 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "rule", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200482 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 2, 0);
483 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200484 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "id", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200485 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200486 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200487 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200488 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "ip", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200489 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200490 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200491
492 /* test error */
493 schema = MODULE_CREATE_YIN("TERR_0",
494 "<list name=\"user\">"
495 " <key value=\"uid\"/>"
496 " <min-elements value=\"10\"/>"
497 " <max-elements value=\"-1\"/>"
498 " <leaf name=\"uid\"> <type name=\"int32\"> </leaf>"
499 "</list>");
500 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200501 CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL,
Michal Vasko4fd91922021-09-15 08:51:06 +0200502 "Invalid value \"-1\" of \"value\" attribute in \"max-elements\" element.", "Line number 8.");
Radek Išaa76902f2021-03-29 08:52:51 +0200503
504 schema = MODULE_CREATE_YIN("TERR_0",
505 "<list name=\"user\">"
506 " <key value=\"uid\"/>"
507 " <min-elements value=\"10\"/>"
508 " <max-elements value=\"4294967298\"/>"
509 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
510 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
511 " <leaf name=\"group\"> <type name=\"string\"/> </leaf>"
512 "</list>");
513 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200514 CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL,
Michal Vasko4fd91922021-09-15 08:51:06 +0200515 "Value \"4294967298\" of \"value\" attribute in \"max-elements\" element is out of bounds.", "Line number 8.");
Radek Išaa76902f2021-03-29 08:52:51 +0200516
517 schema = MODULE_CREATE_YIN("TERR_0",
518 "<list name=\"user\">"
519 " <key value=\"uid\"/>"
520 " <min-elements value=\"20\"/>"
521 " <max-elements value=\"10\"/>"
522 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
523 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
524 " <leaf name=\"group\"> <type name=\"string\"/> </leaf>"
525 "</list>");
526 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200527 CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL,
Michal Vasko4fd91922021-09-15 08:51:06 +0200528 "Invalid combination of min-elements and max-elements: min value 20 is bigger than the max value 10.", "Line number 8.");
Radek Išaa76902f2021-03-29 08:52:51 +0200529
530 schema = MODULE_CREATE_YIN("TERR_0",
531 "<list name=\"user\">"
532 " <key value=\"uid\"/>"
533 " <min-elements value=\"-1\"/>"
534 " <max-elements value=\"20\"/>"
535 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
536 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
537 " <leaf name=\"group\"> <type name=\"string\"/> </leaf>"
538 "</list>");
539 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200540 CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL,
Michal Vasko4fd91922021-09-15 08:51:06 +0200541 "Value \"-1\" of \"value\" attribute in \"min-elements\" element is out of bounds.", "Line number 8.");
Radek Išaa76902f2021-03-29 08:52:51 +0200542
543 schema = MODULE_CREATE_YIN("TERR_0",
544 "<list name=\"user\">"
545 " <key value=\"uid\"/>"
546 " <key value=\"name\"/>"
547 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
548 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
549 " <leaf name=\"group\"> <type name=\"string\"/> </leaf>"
550 "</list>");
551 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200552 CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL,
Michal Vasko4fd91922021-09-15 08:51:06 +0200553 "Redefinition of \"key\" sub-element in \"list\" element.", "Line number 8.");
Radek Išaa76902f2021-03-29 08:52:51 +0200554
555 schema = MODULE_CREATE_YIN("T6",
556 "<list name=\"user\">"
557 " <config value=\"false\"/>"
558 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
559 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
560 " <leaf name=\"group\"><type name=\"string\"/> </leaf>"
561 "</list>");
562 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
563 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200564 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_USER | LYS_KEYLESS | LYS_SET_CONFIG, \
565 1, "user", 0, 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200566 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200567 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200568 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200569 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200570 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200571 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200572
573 schema = MODULE_CREATE_YIN("T7",
574 "<list name=\"user\">"
575 " <key value=\"uid\"/>"
576 " <unique tag=\"name\"/>"
577 " <ordered-by value=\"user\"/>"
578 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
579 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
580 " <leaf name=\"group\"><type name=\"string\"/> </leaf>"
581 "</list>");
582 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
583 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200584 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_USER, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200585 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
586 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200587 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200588 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200589 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200590 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200591 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200592
593 schema = MODULE_CREATE_YIN("T8",
594 "<list name=\"user\">"
595 " <key value=\"uid\"/>"
596 " <unique tag=\"name\"/>"
597 " <ordered-by value=\"system\"/>"
598 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
599 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
600 " <leaf name=\"group\"><type name=\"string\"/> </leaf>"
601 "</list>");
602 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
603 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200604 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200605 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
606 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200607 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200608 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200609 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200610 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200611 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200612
613 schema = MODULE_CREATE_YIN("TERROR0",
614 "<list name=\"user\">"
615 " <key value=\"uid\"/>"
616 " <unique tag=\"name\"/>"
617 " <ordered-by value=\"systeme\"/>"
618 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
619 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
620 " <leaf name=\"group\"><type name=\"string\"/> </leaf>"
621 "</list>");
622 UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200623 CHECK_LOG_CTX("Parsing module \"TERROR0\" failed.", NULL,
624 "Invalid value \"systeme\" of \"value\" attribute in \"ordered-by\" element. Valid values are \"system\" and \"user\".",
Michal Vasko4fd91922021-09-15 08:51:06 +0200625 "Line number 8.");
Radek Išaa76902f2021-03-29 08:52:51 +0200626
627 schema = MODULE_CREATE_YIN("T_DEFS1",
628 "<list name=\"user\">"
629 " <key value=\"uid\"/>"
630 " <unique tag=\"name\"/>"
631 " <ordered-by value=\"system\"/>"
632 " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>"
633 " <leaf name=\"name\"> <type name=\"string\"/> </leaf>"
634 " <leaf name=\"group\"><type name=\"string\"/> <default value=\"ath\"/> </leaf>"
635 "</list>");
636 UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
637 lysc_leaf = (void *)mod->compiled->data;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200638 CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
Radek Išaa76902f2021-03-29 08:52:51 +0200639 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
640 lysc_node = lysc_leaf->child;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200641 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200642 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200643 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200644 lysc_node = lysc_node->next;
Michal Vaskoe78faec2021-04-08 17:24:43 +0200645 CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
Radek Išaa76902f2021-03-29 08:52:51 +0200646
647}
648
649static void
650test_schema_print(void **state)
651{
652 const char *schema_yang, *schema_yin;
653 char *printed;
Michal Vasko4de7d072021-07-09 09:13:18 +0200654 struct lys_module *mod;
Radek Išaa76902f2021-03-29 08:52:51 +0200655
656 /* test print yang to yin */
657 schema_yang = MODULE_CREATE_YANG("PRINT0",
658 "list user {"
659 " min-elements 10;"
660 " max-elements 20;"
661 " key \"uid name\";"
662 " unique name;"
663 " leaf uid{type int32;}"
664 " leaf name{type string;}"
665 " leaf group{type string;}"
666 "}");
667 schema_yin = MODULE_CREATE_YIN("PRINT0",
668 " <list name=\"user\">\n"
669 " <key value=\"uid name\"/>\n"
670 " <unique tag=\"name\"/>\n"
671 " <min-elements value=\"10\"/>\n"
672 " <max-elements value=\"20\"/>\n"
673 " <leaf name=\"uid\">\n"
674 " <type name=\"int32\"/>\n"
675 " </leaf>\n"
676 " <leaf name=\"name\">\n"
677 " <type name=\"string\"/>\n"
678 " </leaf>\n"
679 " <leaf name=\"group\">\n"
680 " <type name=\"string\"/>\n"
681 " </leaf>\n"
682 " </list>\n");
683
684 UTEST_ADD_MODULE(schema_yang, LYS_IN_YANG, NULL, &mod);
685 assert_non_null(mod);
686 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0));
687 assert_string_equal(printed, schema_yin);
688 free(printed);
689
690 /* test print yin to yang */
691 schema_yang = MODULE_CREATE_YANG("PRINT1",
Radek Krejciaa14a0c2020-09-04 11:16:47 +0200692 "\n"
Radek Išaa76902f2021-03-29 08:52:51 +0200693 " list user {\n"
694 " key \"uid name\";\n"
695 " unique \"name\";\n"
696 " min-elements 10;\n"
697 " max-elements 20;\n"
698 " leaf uid {\n"
699 " type int32;\n"
700 " }\n"
701 " leaf name {\n"
702 " type string;\n"
703 " }\n"
704 " leaf group {\n"
705 " type string;\n"
706 " }\n"
707 " }\n");
708 schema_yin = MODULE_CREATE_YIN("PRINT1",
709 " <list name=\"user\">\n"
710 " <key value=\"uid name\"/>\n"
711 " <unique tag=\"name\"/>\n"
712 " <min-elements value=\"10\"/>\n"
713 " <max-elements value=\"20\"/>\n"
714 " <leaf name=\"uid\">\n"
715 " <type name=\"int32\"/>\n"
716 " </leaf>\n"
717 " <leaf name=\"name\">\n"
718 " <type name=\"string\"/>\n"
719 " </leaf>\n"
720 " <leaf name=\"group\">\n"
721 " <type name=\"string\"/>\n"
722 " </leaf>\n"
723 " </list>\n");
724
725 UTEST_ADD_MODULE(schema_yin, LYS_IN_YIN, NULL, &mod);
726 assert_non_null(mod);
727 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YANG, 0));
728 assert_string_equal(printed, schema_yang);
729 free(printed);
730
731 /* test no segmentation fold due ignoring default value */
732 schema_yang = MODULE_CREATE_YANG("PRINT2", "list user {"
733 "key uid;"
734 "leaf uid{type int32; default \"25\";}"
735 "leaf name{type string;}"
736 "leaf group{type string;}"
737 "}");
738
739 UTEST_ADD_MODULE(schema_yang, LYS_IN_YANG, NULL, &mod);
740 assert_non_null(mod);
741 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0));
742 free(printed);
743}
744
745static void
746test_xml(void **state)
747{
748 struct lyd_node *tree;
749 const char *data, *schema;
750 struct lyd_node_inner *list_tree;
751 struct lyd_node_term *list_leaf;
752
753 schema = MODULE_CREATE_YANG("T0", "list user {"
754 "key uid;"
755 "unique \"name group\";"
756 "leaf uid{type uint32;}"
757 "leaf name{type string;}"
758 "leaf group{type string;}"
759 "}");
760 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
761
762 /* add data */
763 data =
764 "<user xmlns=\"urn:tests:T0\">"
765 " <uid>0</uid>"
766 " <name>Tomáš Novák</name>"
767 " <group>User</group>"
768 "</user>"
769 "<user xmlns=\"urn:tests:T0\">"
770 " <uid>1</uid>"
771 " <name>Martin Novák</name>"
772 " <group>User</group>"
773 "</user>";
774 /* check first item */
775 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
776 list_tree = (void *)tree;
777 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
778 list_leaf = (void *) list_tree->child;
779 assert_string_equal(list_leaf->schema->name, "uid");
780 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
781 list_leaf = (void *) list_leaf->next;
782 assert_string_equal(list_leaf->schema->name, "name");
783 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák");
784 list_leaf = (void *) list_leaf->next;
785 assert_string_equal(list_leaf->schema->name, "group");
786 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
787 /* check second item */
788 list_tree = (void *) list_tree->next;
789 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
790 list_leaf = (void *) list_tree->child;
791 assert_string_equal(list_leaf->schema->name, "uid");
792 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1);
793 list_leaf = (void *) list_leaf->next;
794 assert_string_equal(list_leaf->schema->name, "name");
795 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Martin Novák");
796 list_leaf = (void *) list_leaf->next;
797 assert_string_equal(list_leaf->schema->name, "group");
798 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
799 lyd_free_all(tree);
800
801 /* add data */
802 data =
803 "<user xmlns=\"urn:tests:T0\">"
804 " <uid>0</uid>"
805 " <name>Tomáš Novák</name>"
806 " <group>User</group>"
807 "</user>"
808 "<user xmlns=\"urn:tests:T0\">"
809 " <uid>1</uid>"
810 " <name>Tomáš Novák</name>"
811 " <group>Admin</group>"
812 "</user>";
813 /* check first item */
814 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
815 list_tree = (void *)tree;
816 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
817 list_leaf = (void *) list_tree->child;
818 assert_string_equal(list_leaf->schema->name, "uid");
819 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
820 list_leaf = (void *) list_leaf->next;
821 assert_string_equal(list_leaf->schema->name, "name");
822 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák");
823 list_leaf = (void *) list_leaf->next;
824 assert_string_equal(list_leaf->schema->name, "group");
825 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
826 /* check second item */
827 list_tree = (void *) list_tree->next;
828 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
829 list_leaf = (void *) list_tree->child;
830 assert_string_equal(list_leaf->schema->name, "uid");
831 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1);
832 list_leaf = (void *) list_leaf->next;
833 assert_string_equal(list_leaf->schema->name, "name");
834 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák");
835 list_leaf = (void *) list_leaf->next;
836 assert_string_equal(list_leaf->schema->name, "group");
837 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin");
838 lyd_free_all(tree);
839
840 data =
841 "<user xmlns=\"urn:tests:T0\">"
842 " <uid>0</uid>"
843 " <name>Tomáš Novák</name>"
844 " <group>User</group>"
845 "</user>"
846 "<user xmlns=\"urn:tests:T0\">"
847 " <uid>0</uid>"
848 " <name>Tomáš Novák</name>"
849 " <group>Admin</group>"
850 "</user>";
851 /* check first item */
852 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
853 assert_null(tree);
854 CHECK_LOG_CTX("Duplicate instance of \"user\".",
Michal Vaskodbf3e652022-10-21 08:46:25 +0200855 "Data location \"/T0:user[uid='0']\".");
Radek Išaa76902f2021-03-29 08:52:51 +0200856
857 data =
858 "<user xmlns=\"urn:tests:T0\">"
859 " <uid>0</uid>"
860 " <name>Tomáš Novák</name>"
861 " <group>User</group>"
862 "</user>"
863 "<user xmlns=\"urn:tests:T0\">"
864 " <uid>1</uid>"
865 " <name>Tomáš Novák</name>"
866 " <group>User</group>"
867 "</user>";
868 /* check first item */
869 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
870 assert_null(tree);
871 CHECK_LOG_CTX("Unique data leaf(s) \"name group\" not satisfied in \"/T0:user[uid='0']\" and \"/T0:user[uid='1']\".",
Michal Vaskodbf3e652022-10-21 08:46:25 +0200872 "Data location \"/T0:user[uid='1']\".");
Radek Išaa76902f2021-03-29 08:52:51 +0200873
874 /* double key */
875 schema = MODULE_CREATE_YANG("T1", "list user {"
876 "key \"uid group\";"
877 "leaf uid{type uint32;}"
878 "leaf name{type string;}"
879 "leaf group{type string;}"
880 "}");
881 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
882 data =
883 "<user xmlns=\"urn:tests:T1\">"
884 " <uid>0</uid>"
885 " <name>Tomáš Novák</name>"
886 " <group>User</group>"
887 "</user>"
888 "<user xmlns=\"urn:tests:T1\">"
889 " <uid>0</uid>"
890 " <name>Tomáš Novák</name>"
891 " <group>Admin</group>"
892 "</user>";
893 /* check first item */
894 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
895 list_tree = (void *)tree;
896 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
897 list_leaf = (void *) list_tree->child;
898 assert_string_equal(list_leaf->schema->name, "uid");
899 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
900 list_leaf = (void *) list_leaf->next;
901 assert_string_equal(list_leaf->schema->name, "group");
902 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "User");
903 list_leaf = (void *) list_leaf->next;
904 assert_string_equal(list_leaf->schema->name, "name");
905 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Tomáš Novák");
906 /* check second item */
907 list_tree = (void *) list_tree->next;
908 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
909 list_leaf = (void *) list_tree->child;
910 assert_string_equal(list_leaf->schema->name, "uid");
911 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
912 list_leaf = (void *) list_leaf->next;
913 assert_string_equal(list_leaf->schema->name, "group");
914 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Admin");
915 list_leaf = (void *) list_leaf->next;
916 assert_string_equal(list_leaf->schema->name, "name");
917 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Tomáš Novák");
918 lyd_free_all(tree);
919
920 data =
921 "<user xmlns=\"urn:tests:T1\">"
922 " <uid>0</uid>"
923 " <name>Tomáš Novák</name>"
924 " <group>User</group>"
925 "</user>"
926 "<user xmlns=\"urn:tests:T1\">"
927 " <uid>0</uid>"
928 " <name>Tomáš Novák</name>"
929 " <group>User</group>"
930 "</user>";
931 /* check first item */
932 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
933 assert_null(tree);
934 CHECK_LOG_CTX("Duplicate instance of \"user\".",
Michal Vaskodbf3e652022-10-21 08:46:25 +0200935 "Data location \"/T1:user[uid='0'][group='User']\".");
Radek Išaa76902f2021-03-29 08:52:51 +0200936
937 /* min elements max elements */
938 schema = MODULE_CREATE_YANG("T2",
939 "list user {"
940 " key uid;"
941 " min-elements 3;"
942 " max-elements 5;"
943 " leaf uid{type uint32;}"
944 " leaf name{type string;}"
945 " leaf group{type string;}"
946 "}");
947 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
948 data =
949 "<user xmlns=\"urn:tests:T2\">"
950 " <uid>0</uid>"
951 " <name>Tomáš Novák</name>"
952 " <group>User</group>"
953 "</user>"
954 "<user xmlns=\"urn:tests:T2\">"
955 " <uid>1</uid>"
956 " <name>Tomáš Novák</name>"
957 " <group>Admin</group>"
958 "</user>"
959 "<user xmlns=\"urn:tests:T2\">"
960 " <uid>2</uid>"
961 " <name>Tomáš Jak</name>"
962 " <group>Admin</group>"
963 "</user>";
964 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
965 list_tree = (void *)tree;
966 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
967 list_leaf = (void *) list_tree->child;
968 assert_string_equal(list_leaf->schema->name, "uid");
969 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
970 list_leaf = (void *) list_leaf->next;
971 assert_string_equal(list_leaf->schema->name, "name");
972 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák");
973 list_leaf = (void *) list_leaf->next;
974 assert_string_equal(list_leaf->schema->name, "group");
975 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
976 /* check second item */
977 list_tree = (void *) list_tree->next;
978 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
979 list_leaf = (void *) list_tree->child;
980 assert_string_equal(list_leaf->schema->name, "uid");
981 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1);
982 list_leaf = (void *) list_leaf->next;
983 assert_string_equal(list_leaf->schema->name, "name");
984 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák");
985 list_leaf = (void *) list_leaf->next;
986 assert_string_equal(list_leaf->schema->name, "group");
987 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin");
988 /* check third item */
989 list_tree = (void *) list_tree->next;
990 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
991 list_leaf = (void *) list_tree->child;
992 assert_string_equal(list_leaf->schema->name, "uid");
993 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "2", 2);
994 list_leaf = (void *) list_leaf->next;
995 assert_string_equal(list_leaf->schema->name, "name");
996 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Jak");
997 list_leaf = (void *) list_leaf->next;
998 assert_string_equal(list_leaf->schema->name, "group");
999 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin");
1000 lyd_free_all(tree);
1001
1002 data =
1003 "<user xmlns=\"urn:tests:T2\">"
1004 " <uid>0</uid>"
1005 " <name>Tomáš Novák</name>"
1006 " <group>User</group>"
1007 "</user>"
1008 "<user xmlns=\"urn:tests:T2\">"
1009 " <uid>1</uid>"
1010 " <name>Tomáš Novák</name>"
1011 " <group>Admin</group>"
1012 "</user>"
1013 "<user xmlns=\"urn:tests:T2\">"
1014 " <uid>2</uid>"
1015 " <name>Tomáš Novák</name>"
1016 " <group>Admin</group>"
1017 "</user>"
1018 "<user xmlns=\"urn:tests:T2\">"
1019 " <uid>3</uid>"
1020 " <name>Tomáš Novák</name>"
1021 " <group>Admin</group>"
1022 "</user>"
1023 "<user xmlns=\"urn:tests:T2\">"
1024 " <uid>4</uid>"
1025 " <name>Tomáš Novák</name>"
1026 " <group>Admin</group>"
1027 "</user>";
1028 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1029 list_tree = (void *)tree;
1030 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1031 list_tree = (void *) list_tree->next;
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, 0, 0, 0, 1);
1039 lyd_free_all(tree);
1040
1041 /* check wrong number of items */
1042 data =
1043 "<user xmlns=\"urn:tests:T2\">"
1044 " <uid>0</uid>"
1045 " <name>Tomáš Novák</name>"
1046 " <group>User</group>"
1047 "</user>"
1048 "<user xmlns=\"urn:tests:T2\">"
1049 " <uid>1</uid>"
1050 " <name>Tomáš Novák</name>"
1051 " <group>Admin</group>"
1052 "</user>";
1053 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1054 assert_null(tree);
1055 CHECK_LOG_CTX("Too few \"user\" instances.",
Michal Vasko959f8d82022-06-16 07:51:50 +02001056 "Schema location \"/T2:user\".");
Radek Išaa76902f2021-03-29 08:52:51 +02001057
1058 data =
1059 "<user xmlns=\"urn:tests:T2\">"
1060 " <uid>0</uid>"
1061 " <name>Tomáš Novák</name>"
1062 " <group>User</group>"
1063 "</user>"
1064 "<user xmlns=\"urn:tests:T2\">"
1065 " <uid>1</uid>"
1066 " <name>Tomáš Novák</name>"
1067 " <group>Admin</group>"
1068 "</user>"
1069 "<user xmlns=\"urn:tests:T2\">"
1070 " <uid>2</uid>"
1071 " <name>Tomáš Novák</name>"
1072 " <group>Admin</group>"
1073 "</user>"
1074 "<user xmlns=\"urn:tests:T2\">"
1075 " <uid>3</uid>"
1076 " <name>Tomáš Novák</name>"
1077 " <group>Admin</group>"
1078 "</user>"
1079 "<user xmlns=\"urn:tests:T2\">"
1080 " <uid>4</uid>"
1081 " <name>Tomáš Novák</name>"
1082 " <group>Admin</group>"
1083 "</user>"
1084 "<user xmlns=\"urn:tests:T2\">"
1085 " <uid>5</uid>"
1086 " <name>Tomáš Novák</name>"
1087 " <group>Admin</group>"
1088 "</user>";
1089 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1090 assert_null(tree);
1091 CHECK_LOG_CTX("Too many \"user\" instances.",
Michal Vaskodbf3e652022-10-21 08:46:25 +02001092 "Data location \"/T2:user[uid='5']\".");
Radek Išaa76902f2021-03-29 08:52:51 +02001093
1094 /* empty list */
1095 schema = MODULE_CREATE_YANG("T_EMPTY_LIST",
1096 "container user_list {"
1097 " list user {"
1098 " key uid;"
1099 " unique \"name group\";"
1100 " leaf uid{type uint32;}"
1101 " leaf name{type string;}"
1102 " leaf group{type string;}"
1103 "}"
1104 "}");
1105 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1106
1107 /* empty list */
1108 data = "<user_list xmlns=\"urn:tests:T_EMPTY_LIST\"/>";
1109 /* check first item */
1110 CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1111 list_tree = (void *)tree;
1112 CHECK_LYD_NODE_INNER(list_tree, 0, 0, 0, 1, 0, 0, 0, 1);
1113 lyd_free_all(tree);
1114}
1115
1116static void
1117test_json(void **state)
1118{
1119 struct lyd_node *tree;
1120 const char *data, *schema;
1121 struct lyd_node_inner *list_tree;
1122 struct lyd_node_term *list_leaf;
1123
1124 schema = MODULE_CREATE_YANG("T0", "list user {"
1125 "key uid;"
1126 "unique \"name group\";"
1127 "leaf uid{type uint32;}"
1128 "leaf name{type string;}"
1129 "leaf group{type string;}"
1130 "}");
1131 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1132
1133 /* add data */
1134 data =
1135 "{\"T0:user\": ["
1136 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1137 " {\"uid\":1, \"name\":\"Martin Novák\", \"group\":\"User\"}"
1138 "]}";
1139
1140 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1141 list_tree = (void *)tree;
1142 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1143 list_leaf = (void *) list_tree->child;
1144 assert_string_equal(list_leaf->schema->name, "uid");
1145 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
1146 list_leaf = (void *) list_leaf->next;
1147 assert_string_equal(list_leaf->schema->name, "name");
1148 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Jan Kuba");
1149 list_leaf = (void *) list_leaf->next;
1150 assert_string_equal(list_leaf->schema->name, "group");
1151 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
1152 /* check second item */
1153 list_tree = (void *) list_tree->next;
1154 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
1155 list_leaf = (void *) list_tree->child;
1156 assert_string_equal(list_leaf->schema->name, "uid");
1157 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1);
1158 list_leaf = (void *) list_leaf->next;
1159 assert_string_equal(list_leaf->schema->name, "name");
1160 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Martin Novák");
1161 list_leaf = (void *) list_leaf->next;
1162 assert_string_equal(list_leaf->schema->name, "group");
1163 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
1164 lyd_free_all(tree);
1165
1166 /* Unique */
1167 data =
1168 "{\"T0:user\": ["
1169 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1170 " {\"uid\":1, \"name\":\"Jan Kuba\", \"group\":\"Admin\"}"
1171 "]}";
1172
1173 /* check first item */
1174 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1175 list_tree = (void *)tree;
1176 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1177 list_leaf = (void *) list_tree->child;
1178 assert_string_equal(list_leaf->schema->name, "uid");
1179 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
1180 list_leaf = (void *) list_leaf->next;
1181 assert_string_equal(list_leaf->schema->name, "name");
1182 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Jan Kuba");
1183 list_leaf = (void *) list_leaf->next;
1184 assert_string_equal(list_leaf->schema->name, "group");
1185 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
1186 /* check second item */
1187 list_tree = (void *) list_tree->next;
1188 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
1189 list_leaf = (void *) list_tree->child;
1190 assert_string_equal(list_leaf->schema->name, "uid");
1191 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1);
1192 list_leaf = (void *) list_leaf->next;
1193 assert_string_equal(list_leaf->schema->name, "name");
1194 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Jan Kuba");
1195 list_leaf = (void *) list_leaf->next;
1196 assert_string_equal(list_leaf->schema->name, "group");
1197 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin");
1198 lyd_free_all(tree);
1199
1200 data =
1201 "{\"T0:user\": ["
1202 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1203 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"Admin\"}"
1204 "]}";
1205 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1206 assert_null(tree);
1207 CHECK_LOG_CTX("Duplicate instance of \"user\".",
Michal Vaskodbf3e652022-10-21 08:46:25 +02001208 "Data location \"/T0:user[uid='0']\", line number 1.");
Radek Išaa76902f2021-03-29 08:52:51 +02001209
1210 data =
1211 "{\"T0:user\": ["
1212 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1213 " {\"uid\":1, \"name\":\"Jan Kuba\", \"group\":\"User\"}"
1214 "]}";
1215 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1216 assert_null(tree);
1217 CHECK_LOG_CTX("Unique data leaf(s) \"name group\" not satisfied in \"/T0:user[uid='0']\" and \"/T0:user[uid='1']\".",
Michal Vaskodbf3e652022-10-21 08:46:25 +02001218 "Data location \"/T0:user[uid='1']\", line number 1.");
Radek Išaa76902f2021-03-29 08:52:51 +02001219
1220 /* double key */
1221 schema = MODULE_CREATE_YANG("T1", "list user {"
1222 "key \"uid group\";"
1223 "leaf uid{type uint32;}"
1224 "leaf name{type string;}"
1225 "leaf group{type string;}"
1226 "}");
1227 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1228 data =
1229 "{\"T1:user\": ["
1230 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1231 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"Admin\"}"
1232 "]}";
1233 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1234 list_tree = (void *)tree;
1235 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1236 list_leaf = (void *) list_tree->child;
1237 assert_string_equal(list_leaf->schema->name, "uid");
1238 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
1239 list_leaf = (void *) list_leaf->next;
1240 assert_string_equal(list_leaf->schema->name, "group");
1241 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "User");
1242 list_leaf = (void *) list_leaf->next;
1243 assert_string_equal(list_leaf->schema->name, "name");
1244 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Jan Kuba");
1245 /* check second item */
1246 list_tree = (void *) list_tree->next;
1247 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
1248 list_leaf = (void *) list_tree->child;
1249 assert_string_equal(list_leaf->schema->name, "uid");
1250 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
1251 list_leaf = (void *) list_leaf->next;
1252 assert_string_equal(list_leaf->schema->name, "group");
1253 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Admin");
1254 list_leaf = (void *) list_leaf->next;
1255 assert_string_equal(list_leaf->schema->name, "name");
1256 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Jan Kuba");
1257 lyd_free_all(tree);
1258
1259 data =
1260 "{\"T1:user\": ["
1261 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1262 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}"
1263 "]}";
1264 /* check first item */
1265 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1266 assert_null(tree);
1267 CHECK_LOG_CTX("Duplicate instance of \"user\".",
Michal Vaskodbf3e652022-10-21 08:46:25 +02001268 "Data location \"/T1:user[uid='0'][group='User']\", line number 1.");
Radek Išaa76902f2021-03-29 08:52:51 +02001269
1270 /* min elements max elements */
1271 schema = MODULE_CREATE_YANG("T2",
1272 "list user {"
1273 " key uid;"
1274 " min-elements 3;"
1275 " max-elements 5;"
1276 " leaf uid{type uint32;}"
1277 " leaf name{type string;}"
1278 " leaf group{type string;}"
1279 "}");
1280 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1281 data =
1282 "{\"T2:user\": ["
1283 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1284 " {\"uid\":1, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1285 " {\"uid\":2, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}"
1286 "]}";
1287
1288 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1289 list_tree = (void *)tree;
1290 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1291 list_leaf = (void *) list_tree->child;
1292 assert_string_equal(list_leaf->schema->name, "uid");
1293 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0);
1294 list_leaf = (void *) list_leaf->next;
1295 assert_string_equal(list_leaf->schema->name, "name");
1296 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Jan Kuba");
1297 list_leaf = (void *) list_leaf->next;
1298 assert_string_equal(list_leaf->schema->name, "group");
1299 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
1300 /* check second item */
1301 list_tree = (void *) list_tree->next;
1302 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1303 list_leaf = (void *) list_tree->child;
1304 assert_string_equal(list_leaf->schema->name, "uid");
1305 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1);
1306 list_leaf = (void *) list_leaf->next;
1307 assert_string_equal(list_leaf->schema->name, "name");
1308 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Antonín Kuba");
1309 list_leaf = (void *) list_leaf->next;
1310 assert_string_equal(list_leaf->schema->name, "group");
1311 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User");
1312 /* check third item */
1313 list_tree = (void *) list_tree->next;
1314 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1);
1315 list_leaf = (void *) list_tree->child;
1316 assert_string_equal(list_leaf->schema->name, "uid");
1317 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "2", 2);
1318 list_leaf = (void *) list_leaf->next;
1319 assert_string_equal(list_leaf->schema->name, "name");
1320 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák");
1321 list_leaf = (void *) list_leaf->next;
1322 assert_string_equal(list_leaf->schema->name, "group");
1323 CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin");
1324 lyd_free_all(tree);
1325
1326 data =
1327 "{\"T2:user\": ["
1328 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1329 " {\"uid\":1, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1330 " {\"uid\":2, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1331 " {\"uid\":3, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1332 " {\"uid\":4, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}"
1333 "]}";
1334 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1335 list_tree = (void *)tree;
1336 CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1);
1337 list_tree = (void *) list_tree->next;
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, 0, 0, 0, 1);
1345 lyd_free_all(tree);
1346
1347 /* check wrong number of items */
1348 data =
1349 "{\"T2:user\": ["
1350 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1351 " {\"uid\":4, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}"
1352 "]}";
1353 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1354 assert_null(tree);
1355 CHECK_LOG_CTX("Too few \"user\" instances.",
Michal Vasko959f8d82022-06-16 07:51:50 +02001356 "Schema location \"/T2:user\", line number 1.");
Radek Išaa76902f2021-03-29 08:52:51 +02001357
1358 data =
1359 "{\"T2:user\": ["
1360 " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"},"
1361 " {\"uid\":1, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1362 " {\"uid\":2, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1363 " {\"uid\":3, \"name\":\"Antonín Kuba\", \"group\":\"User\"},"
1364 " {\"uid\":4, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"},"
1365 " {\"uid\":5, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}"
1366 "]}";
1367 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
1368 assert_null(tree);
1369 CHECK_LOG_CTX("Too many \"user\" instances.",
Michal Vaskodbf3e652022-10-21 08:46:25 +02001370 "Data location \"/T2:user[uid='5']\", line number 1.");
Radek Išaa76902f2021-03-29 08:52:51 +02001371
1372 schema = MODULE_CREATE_YANG("T_EMPTY_LIST",
1373 "container user_list {"
1374 " list user {"
1375 " key uid;"
1376 " unique \"name group\";"
1377 " leaf uid{type uint32;}"
1378 " leaf name{type string;}"
1379 " leaf group{type string;}"
1380 "}"
1381 "}");
1382 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1383
1384 /* empty list */
1385 data =
1386 "{\"T_EMPTY_LIST:user_list\": {}"
1387 "}";
1388
1389 /* check first item */
1390 CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
1391 list_tree = (void *)tree;
1392 CHECK_LYD_NODE_INNER(list_tree, 0, 0, 0, 1, 0, 0, 0, 1);
1393 lyd_free_all(tree);
1394}
1395
1396static void
1397test_diff(void **state)
1398{
Radek Krejciaa0b1db2021-04-01 15:26:53 +02001399 const char *schema;
Radek Išaa76902f2021-03-29 08:52:51 +02001400 struct lyd_node *model_1, *model_2;
1401 struct lyd_node *diff;
Radek Išaa76902f2021-03-29 08:52:51 +02001402 const char *data_1;
1403 const char *data_2;
1404 const char *diff_expected;
1405
1406 schema = MODULE_CREATE_YANG("T0", "list user {"
1407 "key uid;"
1408 "unique \"name group\";"
1409 "leaf uid{type uint32;}"
1410 "leaf name{type string;}"
1411 "leaf group{type string;}"
1412 "}");
1413 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1414
1415 /* delete item */
1416 data_1 =
1417 "<user xmlns=\"urn:tests:T0\">"
1418 " <uid>0</uid>"
1419 " <name>Tomáš Novák</name>"
1420 " <group>User</group>"
1421 "</user>"
1422 "<user xmlns=\"urn:tests:T0\">"
1423 " <uid>1</uid>"
1424 " <name>Martin Novák</name>"
1425 " <group>User</group>"
1426 "</user>";
1427
1428 data_2 =
1429 "<user xmlns=\"urn:tests:T0\">"
1430 " <uid>0</uid>"
1431 " <name>Tomáš Novák</name>"
1432 " <group>User</group>"
1433 "</user>";
1434
1435 diff_expected =
1436 "<user xmlns=\"urn:tests:T0\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\""
1437 " yang:operation=\"delete\">"
1438 "<uid>1</uid>"
1439 "<name>Martin Novák</name>"
1440 "<group>User</group>"
1441 "</user>";
1442 CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1);
1443 CHECK_PARSE_LYD_PARAM(data_2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1444 assert_int_equal(LY_SUCCESS, lyd_diff_siblings(model_1, model_2, 0, &diff));
1445 assert_non_null(diff);
1446 CHECK_LYD_STRING_PARAM(diff, diff_expected, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
1447 assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff));
1448 CHECK_LYD(model_1, model_2);
1449 lyd_free_all(model_1);
1450 lyd_free_all(model_2);
1451 lyd_free_all(diff);
1452
1453 /* add item */
1454 data_1 =
1455 "<user xmlns=\"urn:tests:T0\">"
1456 " <uid>0</uid>"
1457 " <name>Tomáš Novák</name>"
1458 " <group>User</group>"
1459 "</user>";
1460
1461 data_2 =
1462 "<user xmlns=\"urn:tests:T0\">"
1463 " <uid>0</uid>"
1464 " <name>Tomáš Novák</name>"
1465 " <group>User</group>"
1466 "</user>"
1467 "<user xmlns=\"urn:tests:T0\">"
1468 " <uid>1</uid>"
1469 " <name>Martin Novák</name>"
1470 " <group>User</group>"
1471 "</user>";
1472
1473 diff_expected =
1474 "<user xmlns=\"urn:tests:T0\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\""
1475 " yang:operation=\"create\">"
1476 "<uid>1</uid><name>Martin Novák</name><group>User</group>"
1477 "</user>";
1478 CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1);
1479 CHECK_PARSE_LYD_PARAM(data_2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1480 assert_int_equal(LY_SUCCESS, lyd_diff_siblings(model_1, model_2, 0, &diff));
1481 assert_non_null(diff);
1482 CHECK_LYD_STRING_PARAM(diff, diff_expected, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
1483 assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff));
1484 CHECK_LYD(model_1, model_2);
1485 lyd_free_all(model_1);
1486 lyd_free_all(model_2);
1487 lyd_free_all(diff);
1488
1489 /* diff one */
1490 data_1 =
1491 "<user xmlns=\"urn:tests:T0\">"
1492 " <uid>0</uid>"
1493 " <name>Tomáš Novák</name>"
1494 " <group>User</group>"
1495 "</user>"
1496 "<user xmlns=\"urn:tests:T0\">"
1497 " <uid>1</uid>"
1498 " <name>Martin Novák</name>"
1499 " <group>User</group>"
1500 "</user>";
1501
1502 data_2 =
1503 "<user xmlns=\"urn:tests:T0\">"
1504 " <uid>0</uid>"
1505 " <name>Tomáš Novák</name>"
1506 " <group>Admin</group>"
1507 "</user>"
1508 "<user xmlns=\"urn:tests:T0\">"
1509 " <uid>1</uid>"
1510 " <name>Martin Novák</name>"
1511 " <group>User</group>"
1512 "</user>";
1513
1514 diff_expected =
1515 "<user xmlns=\"urn:tests:T0\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\""
1516 " yang:operation=\"none\">"
1517 "<uid>0</uid>"
1518 "<group yang:operation=\"replace\" yang:orig-default=\"false\""
1519 " yang:orig-value=\"User\">Admin</group></user>";
1520 CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1);
1521 CHECK_PARSE_LYD_PARAM(data_2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1522 assert_int_equal(LY_SUCCESS, lyd_diff_siblings(model_1, model_2, 0, &diff));
1523 assert_non_null(diff);
1524 CHECK_LYD_STRING_PARAM(diff, diff_expected, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
1525 assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff));
1526 CHECK_LYD(model_1, model_2);
1527 lyd_free_all(model_1);
1528 lyd_free_all(model_2);
1529 lyd_free_all(diff);
1530
1531 /* diff same */
1532 data_1 =
1533 "<user xmlns=\"urn:tests:T0\">"
1534 " <uid>0</uid>"
1535 " <name>Tomáš Novák</name>"
1536 " <group>User</group>"
1537 "</user>"
1538 "<user xmlns=\"urn:tests:T0\">"
1539 " <uid>1</uid>"
1540 " <name>Martin Novák</name>"
1541 " <group>User</group>"
1542 "</user>";
1543
1544 data_2 =
1545 "<user xmlns=\"urn:tests:T0\">"
1546 " <uid>0</uid>"
1547 " <name>Tomáš Novák</name>"
1548 " <group>User</group>"
1549 "</user>"
1550 "<user xmlns=\"urn:tests:T0\">"
1551 " <uid>1</uid>"
1552 " <name>Martin Novák</name>"
1553 " <group>User</group>"
1554 "</user>";
1555
1556 CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1);
1557 CHECK_PARSE_LYD_PARAM(data_2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1558 assert_int_equal(LY_SUCCESS, lyd_diff_siblings(model_1, model_2, 0, &diff));
1559 assert_null(diff);
1560 assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff));
1561 CHECK_LYD(model_1, model_2);
1562 lyd_free_all(model_1);
1563 lyd_free_all(model_2);
1564 lyd_free_all(diff);
Radek Išaa76902f2021-03-29 08:52:51 +02001565}
1566
1567static void
1568test_print(void **state)
1569{
1570
1571 const char *schema;
1572 const char *expected_string;
1573
1574 schema = MODULE_CREATE_YANG("T0",
1575 "list user {"
1576 "key uid;"
1577 "leaf uid{type uint32;}"
1578 "leaf name{type string;}"
1579 "leaf group{type string; default \"User\";}"
1580 "}");
1581 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
1582
1583 struct lyd_node *model_1;
1584 const char *data_1 =
1585 "<user xmlns=\"urn:tests:T0\">"
1586 " <uid>0</uid>"
1587 " <name>Tomáš Novák</name>"
1588 "</user>"
1589 "<user xmlns=\"urn:tests:T0\">"
1590 " <uid>1</uid>"
1591 " <name>Martin Novák</name>"
1592 " <group>Admin</group>"
1593 "</user>";
1594
1595 LYD_TREE_CREATE(data_1, model_1);
1596
1597 /* XML */
1598 expected_string =
1599 "<user xmlns=\"urn:tests:T0\">"
1600 "<uid>0</uid><name>Tomáš Novák</name>"
1601 "</user>"
1602 "<user xmlns=\"urn:tests:T0\">"
1603 "<uid>1</uid><name>Martin Novák</name><group>Admin</group>"
1604 "</user>";
1605 CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
1606
1607 /* JSON */
1608 expected_string = "{\"T0:user\":["
1609 "{\"uid\":0,\"name\":\"Tomáš Novák\"},"
1610 "{\"uid\":1,\"name\":\"Martin Novák\",\"group\":\"Admin\"}"
1611 "]}";
1612 CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_JSON, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
1613
1614 lyd_free_all(model_1);
1615}
1616
1617int
1618main(void)
1619{
1620 const struct CMUnitTest tests[] = {
1621 UTEST(test_schema_yang),
1622 UTEST(test_schema_yin),
1623 UTEST(test_schema_print),
1624
1625 UTEST(test_xml),
1626 UTEST(test_json),
1627 UTEST(test_diff),
1628 UTEST(test_print),
1629 };
1630
1631 return cmocka_run_group_tests(tests, NULL, NULL);
1632}