blob: b932dd00131cd8c269b9894e6bd848dc4b36dba4 [file] [log] [blame]
Michal Vasko4490d312020-06-16 13:08:55 +02001/**
2 * @file test_merge.c
3 * @author Michal Vasko <mvasko@cesnet.cz>
4 * @brief tests for complex data merges.
5 *
6 * Copyright (c) 2020 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 */
Radek Iša56ca9e42020-09-08 18:42:00 +020014#define _UTEST_MAIN_
Radek Krejcib4ac5a92020-11-23 17:54:33 +010015#include "utests.h"
Michal Vasko4490d312020-06-16 13:08:55 +020016
Radek Iša56ca9e42020-09-08 18:42:00 +020017#include "libyang.h"
Michal Vasko4490d312020-06-16 13:08:55 +020018
Radek Iša56ca9e42020-09-08 18:42:00 +020019#define LYD_TREE_CREATE(INPUT, MODEL) \
20 CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, MODEL)
Michal Vasko4490d312020-06-16 13:08:55 +020021
Radek Iša56ca9e42020-09-08 18:42:00 +020022#define CONTEXT_CREATE \
23 CONTEXT_CREATE_PATH(NULL)
Michal Vasko4490d312020-06-16 13:08:55 +020024
Radek Iša56ca9e42020-09-08 18:42:00 +020025#define LYD_TREE_CHECK_CHAR(MODEL, TEXT, PARAMS) \
26 CHECK_LYD_STRING_PARAM(MODEL, TEXT, LYD_XML, LYD_PRINT_WITHSIBLINGS | PARAMS)
Michal Vasko4490d312020-06-16 13:08:55 +020027
28static void
29test_batch(void **state)
30{
Michal Vasko4490d312020-06-16 13:08:55 +020031 const char *start =
Radek Krejcib4ac5a92020-11-23 17:54:33 +010032 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
33 " <module>\n"
34 " <name>yang</name>\n"
35 " <revision>2016-02-11</revision>\n"
36 " <conformance-type>implement</conformance-type>\n"
37 " </module>\n"
38 "</modules-state>\n";
Michal Vasko4490d312020-06-16 13:08:55 +020039 const char *data[] = {
Radek Krejcib4ac5a92020-11-23 17:54:33 +010040 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
41 " <module>\n"
42 " <name>ietf-yang-library</name>\n"
43 " <revision>2016-02-01</revision>\n"
44 " <conformance-type>implement</conformance-type>\n"
45 " </module>\n"
46 "</modules-state>\n",
47 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
48 " <module>\n"
49 " <name>ietf-netconf-acm</name>\n"
50 " <revision>2012-02-22</revision>\n"
51 " <conformance-type>implement</conformance-type>\n"
52 " </module>\n"
53 "</modules-state>\n",
54 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
55 " <module>\n"
56 " <name>ietf-netconf</name>\n"
57 " <revision>2011-06-01</revision>\n"
58 " <conformance-type>implement</conformance-type>\n"
59 " </module>\n"
60 "</modules-state>\n",
61 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
62 " <module>\n"
63 " <name>ietf-netconf-monitoring</name>\n"
64 " <revision>2010-10-04</revision>\n"
65 " <conformance-type>implement</conformance-type>\n"
66 " </module>\n"
67 "</modules-state>\n",
68 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
69 " <module>\n"
70 " <name>ietf-netconf-with-defaults</name>\n"
71 " <revision>2011-06-01</revision>\n"
72 " <conformance-type>implement</conformance-type>\n"
73 " </module>\n"
74 "</modules-state>\n",
75 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
76 " <module>\n"
77 " <name>yang</name>\n"
78 " <revision>2016-02-11</revision>\n"
79 " <namespace>urn:ietf:params:xml:ns:yang:1</namespace>\n"
80 " <conformance-type>implement</conformance-type>\n"
81 " </module>\n"
82 "</modules-state>\n",
83 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
84 " <module>\n"
85 " <name>ietf-yang-library</name>\n"
86 " <revision>2016-02-01</revision>\n"
87 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>\n"
88 " <conformance-type>implement</conformance-type>\n"
89 " </module>\n"
90 "</modules-state>\n",
91 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
92 " <module>\n"
93 " <name>ietf-netconf-acm</name>\n"
94 " <revision>2012-02-22</revision>\n"
95 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>\n"
96 " <conformance-type>implement</conformance-type>\n"
97 " </module>\n"
98 "</modules-state>\n",
99 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
100 " <module>\n"
101 " <name>ietf-netconf</name>\n"
102 " <revision>2011-06-01</revision>\n"
103 " <namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>\n"
104 " <feature>writable-running</feature>\n"
105 " <feature>candidate</feature>\n"
106 " <feature>rollback-on-error</feature>\n"
107 " <feature>validate</feature>\n"
108 " <feature>startup</feature>\n"
109 " <feature>xpath</feature>\n"
110 " <conformance-type>implement</conformance-type>\n"
111 " </module>\n"
112 "</modules-state>\n",
113 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
114 " <module>\n"
115 " <name>ietf-netconf-monitoring</name>\n"
116 " <revision>2010-10-04</revision>\n"
117 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</namespace>\n"
118 " <conformance-type>implement</conformance-type>\n"
119 " </module>\n"
120 "</modules-state>\n",
121 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
122 " <module>\n"
123 " <name>ietf-netconf-with-defaults</name>\n"
124 " <revision>2011-06-01</revision>\n"
125 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults</namespace>\n"
126 " <conformance-type>implement</conformance-type>\n"
127 " </module>\n"
128 "</modules-state>\n"
Michal Vasko4490d312020-06-16 13:08:55 +0200129 };
130 const char *output_template =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100131 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
132 " <module>\n"
133 " <name>yang</name>\n"
134 " <revision>2016-02-11</revision>\n"
135 " <namespace>urn:ietf:params:xml:ns:yang:1</namespace>\n"
136 " <conformance-type>implement</conformance-type>\n"
137 " </module>\n"
138 " <module>\n"
139 " <name>ietf-yang-library</name>\n"
140 " <revision>2016-02-01</revision>\n"
141 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>\n"
142 " <conformance-type>implement</conformance-type>\n"
143 " </module>\n"
144 " <module>\n"
145 " <name>ietf-netconf-acm</name>\n"
146 " <revision>2012-02-22</revision>\n"
147 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>\n"
148 " <conformance-type>implement</conformance-type>\n"
149 " </module>\n"
150 " <module>\n"
151 " <name>ietf-netconf</name>\n"
152 " <revision>2011-06-01</revision>\n"
153 " <namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>\n"
154 " <feature>writable-running</feature>\n"
155 " <feature>candidate</feature>\n"
156 " <feature>rollback-on-error</feature>\n"
157 " <feature>validate</feature>\n"
158 " <feature>startup</feature>\n"
159 " <feature>xpath</feature>\n"
160 " <conformance-type>implement</conformance-type>\n"
161 " </module>\n"
162 " <module>\n"
163 " <name>ietf-netconf-monitoring</name>\n"
164 " <revision>2010-10-04</revision>\n"
165 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</namespace>\n"
166 " <conformance-type>implement</conformance-type>\n"
167 " </module>\n"
168 " <module>\n"
169 " <name>ietf-netconf-with-defaults</name>\n"
170 " <revision>2011-06-01</revision>\n"
171 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults</namespace>\n"
172 " <conformance-type>implement</conformance-type>\n"
173 " </module>\n"
174 "</modules-state>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200175
Radek Iša56ca9e42020-09-08 18:42:00 +0200176 struct lyd_node *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200177
Radek Iša56ca9e42020-09-08 18:42:00 +0200178 CHECK_PARSE_LYD_PARAM(start, LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200179
Radek Iša56ca9e42020-09-08 18:42:00 +0200180 for (int32_t i = 0; i < 11; ++i) {
181 struct lyd_node *source;
182 CHECK_PARSE_LYD_PARAM(data[i], LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, source);
183 assert_int_equal(LY_SUCCESS, lyd_merge_siblings(&target, source, LYD_MERGE_DESTRUCT));
Michal Vasko4490d312020-06-16 13:08:55 +0200184 }
185
Radek Iša56ca9e42020-09-08 18:42:00 +0200186 LYD_TREE_CHECK_CHAR(target, output_template, 0);
Radek Krejci7931b192020-06-25 17:05:03 +0200187
Radek Iša56ca9e42020-09-08 18:42:00 +0200188 lyd_free_all(target);
Michal Vasko4490d312020-06-16 13:08:55 +0200189}
190
191static void
192test_leaf(void **state)
193{
Michal Vasko4490d312020-06-16 13:08:55 +0200194 const char *sch = "module x {"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100195 " namespace urn:x;"
196 " prefix x;"
197 " container A {"
198 " leaf f1 {type string;}"
199 " container B {"
200 " leaf f2 {type string;}"
201 " }"
202 " }"
203 " }";
Michal Vasko4490d312020-06-16 13:08:55 +0200204 const char *trg = "<A xmlns=\"urn:x\"> <f1>block</f1> </A>";
205 const char *src = "<A xmlns=\"urn:x\"> <f1>aa</f1> <B> <f2>bb</f2> </B> </A>";
206 const char *result = "<A xmlns=\"urn:x\"><f1>aa</f1><B><f2>bb</f2></B></A>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200207 struct lyd_node *source, *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200208
Radek Iša56ca9e42020-09-08 18:42:00 +0200209 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200210
Radek Iša56ca9e42020-09-08 18:42:00 +0200211 LYD_TREE_CREATE(src, source);
212 LYD_TREE_CREATE(trg, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200213
214 /* merge them */
Radek Iša56ca9e42020-09-08 18:42:00 +0200215 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
216 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200217
218 /* check the result */
Radek Iša56ca9e42020-09-08 18:42:00 +0200219 LYD_TREE_CHECK_CHAR(target, result, LYD_PRINT_SHRINK);
220
221 lyd_free_all(target);
222 lyd_free_all(source);
Michal Vasko4490d312020-06-16 13:08:55 +0200223}
224
225static void
226test_container(void **state)
227{
Michal Vasko4490d312020-06-16 13:08:55 +0200228 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100229 "module A {\n"
230 " namespace \"aa:A\";\n"
231 " prefix A;\n"
232 " container A {\n"
233 " leaf f1 {type string;}\n"
234 " container B {\n"
235 " leaf f2 {type string;}\n"
236 " }\n"
237 " container C {\n"
238 " leaf f3 {type string;}\n"
239 " }\n"
240 " }\n"
241 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200242
243 const char *trg = "<A xmlns=\"aa:A\"> <B> <f2>aaa</f2> </B> </A>";
244 const char *src = "<A xmlns=\"aa:A\"> <C> <f3>bbb</f3> </C> </A>";
245 const char *result = "<A xmlns=\"aa:A\"><B><f2>aaa</f2></B><C><f3>bbb</f3></C></A>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200246 struct lyd_node *source, *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200247
Radek Iša56ca9e42020-09-08 18:42:00 +0200248 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200249
Radek Iša56ca9e42020-09-08 18:42:00 +0200250 LYD_TREE_CREATE(src, source);
251 LYD_TREE_CREATE(trg, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200252
253 /* merge them */
Radek Iša56ca9e42020-09-08 18:42:00 +0200254 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
255 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200256
257 /* check the result */
Radek Iša56ca9e42020-09-08 18:42:00 +0200258 LYD_TREE_CHECK_CHAR(target, result, LYD_PRINT_SHRINK);
259
260 /* destroy */
261 lyd_free_all(source);
262 lyd_free_all(target);
Michal Vasko4490d312020-06-16 13:08:55 +0200263}
264
265static void
266test_list(void **state)
267{
Michal Vasko4490d312020-06-16 13:08:55 +0200268 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100269 "module merge {\n"
270 " namespace \"http://test/merge\";\n"
271 " prefix merge;\n"
272 "\n"
273 " container inner1 {\n"
274 " list b-list1 {\n"
275 " key p1;\n"
276 " leaf p1 {\n"
277 " type uint8;\n"
278 " }\n"
279 " leaf p2 {\n"
280 " type string;\n"
281 " }\n"
282 " leaf p3 {\n"
283 " type boolean;\n"
284 " default false;\n"
285 " }\n"
286 " }\n"
287 " }\n"
288 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200289
290 const char *trg =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100291 "<inner1 xmlns=\"http://test/merge\">\n"
292 " <b-list1>\n"
293 " <p1>1</p1>\n"
294 " <p2>a</p2>\n"
295 " <p3>true</p3>\n"
296 " </b-list1>\n"
297 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200298 const char *src =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100299 "<inner1 xmlns=\"http://test/merge\">\n"
300 " <b-list1>\n"
301 " <p1>1</p1>\n"
302 " <p2>b</p2>\n"
303 " </b-list1>\n"
304 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200305 const char *result =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100306 "<inner1 xmlns=\"http://test/merge\">\n"
307 " <b-list1>\n"
308 " <p1>1</p1>\n"
309 " <p2>b</p2>\n"
310 " <p3>true</p3>\n"
311 " </b-list1>\n"
312 "</inner1>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200313 struct lyd_node *source, *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200314
Radek Iša56ca9e42020-09-08 18:42:00 +0200315 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200316
Radek Iša56ca9e42020-09-08 18:42:00 +0200317 LYD_TREE_CREATE(src, source);
318 LYD_TREE_CREATE(trg, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200319
320 /* merge them */
Radek Iša56ca9e42020-09-08 18:42:00 +0200321 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
322 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200323
324 /* check the result */
Radek Iša56ca9e42020-09-08 18:42:00 +0200325 LYD_TREE_CHECK_CHAR(target, result, 0);
326
327 lyd_free_all(target);
328 lyd_free_all(source);
Michal Vasko4490d312020-06-16 13:08:55 +0200329}
330
331static void
332test_list2(void **state)
333{
Michal Vasko4490d312020-06-16 13:08:55 +0200334 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100335 "module merge {\n"
336 " namespace \"http://test/merge\";\n"
337 " prefix merge;\n"
338 "\n"
339 " container inner1 {\n"
340 " list b-list1 {\n"
341 " key p1;\n"
342 " leaf p1 {\n"
343 " type uint8;\n"
344 " }\n"
345 " leaf p2 {\n"
346 " type string;\n"
347 " }\n"
348 " container inner2 {\n"
349 " leaf p3 {\n"
350 " type boolean;\n"
351 " default false;\n"
352 " }\n"
353 " leaf p4 {\n"
354 " type string;\n"
355 " }\n"
356 " }\n"
357 " }\n"
358 " }\n"
359 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200360
361 const char *trg =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100362 "<inner1 xmlns=\"http://test/merge\">\n"
363 " <b-list1>\n"
364 " <p1>1</p1>\n"
365 " <p2>a</p2>\n"
366 " <inner2>\n"
367 " <p4>val</p4>\n"
368 " </inner2>\n"
369 " </b-list1>\n"
370 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200371 const char *src =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100372 "<inner1 xmlns=\"http://test/merge\">\n"
373 " <b-list1>\n"
374 " <p1>1</p1>\n"
375 " <p2>b</p2>\n"
376 " </b-list1>\n"
377 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200378 const char *result =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100379 "<inner1 xmlns=\"http://test/merge\">\n"
380 " <b-list1>\n"
381 " <p1>1</p1>\n"
382 " <p2>b</p2>\n"
383 " <inner2>\n"
384 " <p4>val</p4>\n"
385 " </inner2>\n"
386 " </b-list1>\n"
387 "</inner1>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200388 struct lyd_node *source, *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200389
Radek Iša56ca9e42020-09-08 18:42:00 +0200390 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200391
Radek Iša56ca9e42020-09-08 18:42:00 +0200392 LYD_TREE_CREATE(src, source);
393 LYD_TREE_CREATE(trg, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200394
395 /* merge them */
Radek Iša56ca9e42020-09-08 18:42:00 +0200396 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
397 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200398
399 /* check the result */
Radek Iša56ca9e42020-09-08 18:42:00 +0200400 LYD_TREE_CHECK_CHAR(target, result, 0);
401
402 lyd_free_all(source);
403 lyd_free_all(target);
Michal Vasko4490d312020-06-16 13:08:55 +0200404}
405
406static void
Michal Vaskocd3f6172021-05-18 16:14:50 +0200407test_dup_inst_list(void **state)
408{
409 const char *sch =
410 "module merge {\n"
411 " namespace \"http://test/merge\";\n"
412 " prefix merge;\n"
413 "\n"
414 " container inner1 {\n"
415 " config false;\n"
416 " list b-list1 {\n"
417 " leaf p1 {\n"
418 " type uint8;\n"
419 " }\n"
420 " leaf p2 {\n"
421 " type string;\n"
422 " }\n"
423 " container inner2 {\n"
424 " leaf p4 {\n"
425 " type string;\n"
426 " }\n"
427 " }\n"
428 " }\n"
429 " }\n"
430 "}\n";
431
432 const char *trg =
433 "<inner1 xmlns=\"http://test/merge\">\n"
434 " <b-list1>\n"
435 " <p1>1</p1>\n"
436 " <p2>b</p2>\n"
437 " </b-list1>\n"
438 " <b-list1>\n"
439 " <p1>1</p1>\n"
440 " <p2>a</p2>\n"
441 " <inner2>\n"
442 " <p4>val</p4>\n"
443 " </inner2>\n"
444 " </b-list1>\n"
445 "</inner1>\n";
446 const char *src =
447 "<inner1 xmlns=\"http://test/merge\">\n"
448 " <b-list1>\n"
449 " <p1>1</p1>\n"
450 " <p2>b</p2>\n"
451 " </b-list1>\n"
452 " <b-list1>\n"
453 " <p1>2</p1>\n"
454 " <p2>a</p2>\n"
455 " </b-list1>\n"
456 "</inner1>\n";
457 const char *result =
458 "<inner1 xmlns=\"http://test/merge\">\n"
459 " <b-list1>\n"
460 " <p1>1</p1>\n"
461 " <p2>b</p2>\n"
462 " </b-list1>\n"
463 " <b-list1>\n"
464 " <p1>1</p1>\n"
465 " <p2>a</p2>\n"
466 " <inner2>\n"
467 " <p4>val</p4>\n"
468 " </inner2>\n"
469 " </b-list1>\n"
470 " <b-list1>\n"
471 " <p1>2</p1>\n"
472 " <p2>a</p2>\n"
473 " </b-list1>\n"
474 "</inner1>\n";
475 struct lyd_node *source, *target;
476
477 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
478
479 LYD_TREE_CREATE(src, source);
480 LYD_TREE_CREATE(trg, target);
481
482 /* merge them */
483 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
484 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
485
486 /* check the result */
487 LYD_TREE_CHECK_CHAR(target, result, 0);
488
489 lyd_free_all(source);
490 lyd_free_all(target);
491}
492
493static void
494test_dup_inst_llist(void **state)
495{
496 const char *sch =
497 "module merge {\n"
498 " namespace \"http://test/merge\";\n"
499 " prefix merge;\n"
500 "\n"
501 " container inner1 {\n"
502 " config false;\n"
503 " leaf-list b-llist1 {\n"
504 " type string;\n"
505 " }\n"
506 " }\n"
507 "}\n";
508
509 const char *trg =
510 "<inner1 xmlns=\"http://test/merge\">\n"
511 " <b-llist1>a</b-llist1>\n"
512 " <b-llist1>b</b-llist1>\n"
513 " <b-llist1>c</b-llist1>\n"
514 " <b-llist1>d</b-llist1>\n"
515 " <b-llist1>a</b-llist1>\n"
516 " <b-llist1>b</b-llist1>\n"
517 " <b-llist1>c</b-llist1>\n"
518 " <b-llist1>d</b-llist1>\n"
519 "</inner1>\n";
520 const char *src =
521 "<inner1 xmlns=\"http://test/merge\">\n"
522 " <b-llist1>d</b-llist1>\n"
523 " <b-llist1>c</b-llist1>\n"
524 " <b-llist1>b</b-llist1>\n"
525 " <b-llist1>a</b-llist1>\n"
526 " <b-llist1>a</b-llist1>\n"
527 " <b-llist1>a</b-llist1>\n"
528 " <b-llist1>a</b-llist1>\n"
529 " <b-llist1>f</b-llist1>\n"
530 " <b-llist1>f</b-llist1>\n"
531 "</inner1>\n";
532 const char *result =
533 "<inner1 xmlns=\"http://test/merge\">\n"
534 " <b-llist1>a</b-llist1>\n"
535 " <b-llist1>b</b-llist1>\n"
536 " <b-llist1>c</b-llist1>\n"
537 " <b-llist1>d</b-llist1>\n"
538 " <b-llist1>a</b-llist1>\n"
539 " <b-llist1>b</b-llist1>\n"
540 " <b-llist1>c</b-llist1>\n"
541 " <b-llist1>d</b-llist1>\n"
542 " <b-llist1>a</b-llist1>\n"
543 " <b-llist1>a</b-llist1>\n"
544 " <b-llist1>f</b-llist1>\n"
545 " <b-llist1>f</b-llist1>\n"
546 "</inner1>\n";
547 struct lyd_node *source, *target;
548
549 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
550
551 LYD_TREE_CREATE(src, source);
552 LYD_TREE_CREATE(trg, target);
553
554 /* merge them */
555 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
556 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
557
558 /* check the result */
559 LYD_TREE_CHECK_CHAR(target, result, 0);
560
561 lyd_free_all(source);
562 lyd_free_all(target);
563}
564
565static void
Michal Vasko4490d312020-06-16 13:08:55 +0200566test_case(void **state)
567{
Michal Vasko4490d312020-06-16 13:08:55 +0200568 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100569 "module merge {\n"
570 " namespace \"http://test/merge\";\n"
571 " prefix merge;\n"
572 " container cont {\n"
573 " choice ch {\n"
574 " container inner {\n"
575 " leaf p1 {\n"
576 " type string;\n"
577 " }\n"
578 " }\n"
579 " case c2 {\n"
580 " leaf p1 {\n"
581 " type string;\n"
582 " }\n"
583 " }\n"
584 " }\n"
585 " }\n"
586 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200587
588 const char *trg =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100589 "<cont xmlns=\"http://test/merge\">\n"
590 " <inner>\n"
591 " <p1>1</p1>\n"
592 " </inner>\n"
593 "</cont>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200594 const char *src =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100595 "<cont xmlns=\"http://test/merge\">\n"
596 " <p1>1</p1>\n"
597 "</cont>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200598 const char *result =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100599 "<cont xmlns=\"http://test/merge\">\n"
600 " <p1>1</p1>\n"
601 "</cont>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200602 struct lyd_node *source, *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200603
Radek Iša56ca9e42020-09-08 18:42:00 +0200604 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200605
Radek Iša56ca9e42020-09-08 18:42:00 +0200606 LYD_TREE_CREATE(src, source);
607 LYD_TREE_CREATE(trg, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200608
609 /* merge them */
Radek Iša56ca9e42020-09-08 18:42:00 +0200610 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
611 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200612
613 /* check the result */
Radek Iša56ca9e42020-09-08 18:42:00 +0200614 LYD_TREE_CHECK_CHAR(target, result, 0);
615
616 lyd_free_all(source);
617 lyd_free_all(target);
Michal Vasko4490d312020-06-16 13:08:55 +0200618}
619
620static void
621test_dflt(void **state)
622{
Michal Vasko4490d312020-06-16 13:08:55 +0200623 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100624 "module merge-dflt {\n"
625 " namespace \"urn:merge-dflt\";\n"
626 " prefix md;\n"
627 " container top {\n"
628 " leaf a {\n"
629 " type string;\n"
630 " }\n"
631 " leaf b {\n"
632 " type string;\n"
633 " }\n"
634 " leaf c {\n"
635 " type string;\n"
636 " default \"c_dflt\";\n"
637 " }\n"
638 " }\n"
639 "}\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200640 struct lyd_node *target = NULL;
641 struct lyd_node *source = NULL;
Michal Vasko4490d312020-06-16 13:08:55 +0200642
Radek Iša56ca9e42020-09-08 18:42:00 +0200643 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200644
Radek Iša56ca9e42020-09-08 18:42:00 +0200645 assert_int_equal(lyd_new_path(NULL, UTEST_LYCTX, "/merge-dflt:top/c", "c_dflt", 0, &target), LY_SUCCESS);
646 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200647
Radek Iša56ca9e42020-09-08 18:42:00 +0200648 assert_int_equal(lyd_new_path(NULL, UTEST_LYCTX, "/merge-dflt:top/a", "a_val", 0, &source), LY_SUCCESS);
649 assert_int_equal(lyd_new_path(source, UTEST_LYCTX, "/merge-dflt:top/b", "b_val", 0, NULL), LY_SUCCESS);
650 assert_int_equal(lyd_validate_all(&source, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200651
Radek Iša56ca9e42020-09-08 18:42:00 +0200652 assert_int_equal(lyd_merge_siblings(&target, source, LYD_MERGE_DESTRUCT | LYD_MERGE_DEFAULTS), LY_SUCCESS);
653 source = NULL;
Michal Vasko4490d312020-06-16 13:08:55 +0200654
655 /* c should be replaced and now be default */
Radek Iša56ca9e42020-09-08 18:42:00 +0200656 assert_string_equal(lyd_child(target)->prev->schema->name, "c");
657 assert_true(lyd_child(target)->prev->flags & LYD_DEFAULT);
658
659 lyd_free_all(target);
660 lyd_free_all(source);
Michal Vasko4490d312020-06-16 13:08:55 +0200661}
662
663static void
664test_dflt2(void **state)
665{
Michal Vasko4490d312020-06-16 13:08:55 +0200666 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100667 "module merge-dflt {\n"
668 " namespace \"urn:merge-dflt\";\n"
669 " prefix md;\n"
670 " container top {\n"
671 " leaf a {\n"
672 " type string;\n"
673 " }\n"
674 " leaf b {\n"
675 " type string;\n"
676 " }\n"
677 " leaf c {\n"
678 " type string;\n"
679 " default \"c_dflt\";\n"
680 " }\n"
681 " }\n"
682 "}\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200683 struct lyd_node *target;
684 struct lyd_node *source;
Michal Vasko4490d312020-06-16 13:08:55 +0200685
Radek Iša56ca9e42020-09-08 18:42:00 +0200686 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200687
Radek Iša56ca9e42020-09-08 18:42:00 +0200688 assert_int_equal(lyd_new_path(NULL, UTEST_LYCTX, "/merge-dflt:top/c", "c_dflt", 0, &target), LY_SUCCESS);
689 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200690
Radek Iša56ca9e42020-09-08 18:42:00 +0200691 assert_int_equal(lyd_new_path(NULL, UTEST_LYCTX, "/merge-dflt:top/a", "a_val", 0, &source), LY_SUCCESS);
692 assert_int_equal(lyd_new_path(source, UTEST_LYCTX, "/merge-dflt:top/b", "b_val", 0, NULL), LY_SUCCESS);
693 assert_int_equal(lyd_validate_all(&source, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200694
Radek Iša56ca9e42020-09-08 18:42:00 +0200695 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200696
697 /* c should not be replaced, so c remains not default */
Radek Iša56ca9e42020-09-08 18:42:00 +0200698 assert_false(lyd_child(target)->flags & LYD_DEFAULT);
699
700 lyd_free_all(target);
701 lyd_free_all(source);
Michal Vasko4490d312020-06-16 13:08:55 +0200702}
703
704static void
705test_leafrefs(void **state)
706{
Michal Vasko4490d312020-06-16 13:08:55 +0200707 const char *sch = "module x {"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100708 " namespace urn:x;"
709 " prefix x;"
710 " list l {"
711 " key n;"
712 " leaf n { type string; }"
713 " leaf t { type string; }"
714 " leaf r { type leafref { path '/l/n'; } }}}";
Michal Vasko4490d312020-06-16 13:08:55 +0200715 const char *trg = "<l xmlns=\"urn:x\"><n>a</n></l>"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100716 "<l xmlns=\"urn:x\"><n>b</n><r>a</r></l>";
Michal Vasko4490d312020-06-16 13:08:55 +0200717 const char *src = "<l xmlns=\"urn:x\"><n>c</n><r>a</r></l>"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100718 "<l xmlns=\"urn:x\"><n>a</n><t>*</t></l>";
Michal Vasko4490d312020-06-16 13:08:55 +0200719 const char *res = "<l xmlns=\"urn:x\"><n>a</n><t>*</t></l>"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100720 "<l xmlns=\"urn:x\"><n>b</n><r>a</r></l>"
721 "<l xmlns=\"urn:x\"><n>c</n><r>a</r></l>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200722 struct lyd_node *source, *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200723
Radek Iša56ca9e42020-09-08 18:42:00 +0200724 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200725
Radek Iša56ca9e42020-09-08 18:42:00 +0200726 LYD_TREE_CREATE(src, source);
727 LYD_TREE_CREATE(trg, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200728
Radek Iša56ca9e42020-09-08 18:42:00 +0200729 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200730
Radek Iša56ca9e42020-09-08 18:42:00 +0200731 LYD_TREE_CHECK_CHAR(target, res, LYD_PRINT_SHRINK);
Michal Vasko4490d312020-06-16 13:08:55 +0200732
Radek Iša56ca9e42020-09-08 18:42:00 +0200733 lyd_free_all(source);
734 lyd_free_all(target);
Michal Vasko4490d312020-06-16 13:08:55 +0200735}
736
737int
738main(void)
739{
740 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200741 UTEST(test_batch),
742 UTEST(test_leaf),
743 UTEST(test_container),
744 UTEST(test_list),
745 UTEST(test_list2),
Michal Vaskocd3f6172021-05-18 16:14:50 +0200746 UTEST(test_dup_inst_list),
747 UTEST(test_dup_inst_llist),
Radek Iša56ca9e42020-09-08 18:42:00 +0200748 UTEST(test_case),
749 UTEST(test_dflt),
750 UTEST(test_dflt2),
751 UTEST(test_leafrefs),
Michal Vasko4490d312020-06-16 13:08:55 +0200752 };
753
754 return cmocka_run_group_tests(tests, NULL, NULL);
755}