blob: 3e7b77237a956dd0f27aacc6db21e186e25b4e21 [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"
aPiecek14f72532024-02-20 14:20:39 +0100133 " <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"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100151 " <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;
Michal Vasko26bbb272022-08-02 14:54:33 +0200182
Radek Iša56ca9e42020-09-08 18:42:00 +0200183 CHECK_PARSE_LYD_PARAM(data[i], LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, source);
184 assert_int_equal(LY_SUCCESS, lyd_merge_siblings(&target, source, LYD_MERGE_DESTRUCT));
Michal Vasko4490d312020-06-16 13:08:55 +0200185 }
186
Radek Iša56ca9e42020-09-08 18:42:00 +0200187 LYD_TREE_CHECK_CHAR(target, output_template, 0);
Radek Krejci7931b192020-06-25 17:05:03 +0200188
Radek Iša56ca9e42020-09-08 18:42:00 +0200189 lyd_free_all(target);
Michal Vasko4490d312020-06-16 13:08:55 +0200190}
191
192static void
193test_leaf(void **state)
194{
Michal Vasko4490d312020-06-16 13:08:55 +0200195 const char *sch = "module x {"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100196 " namespace urn:x;"
197 " prefix x;"
198 " container A {"
199 " leaf f1 {type string;}"
200 " container B {"
201 " leaf f2 {type string;}"
202 " }"
203 " }"
204 " }";
Michal Vasko4490d312020-06-16 13:08:55 +0200205 const char *trg = "<A xmlns=\"urn:x\"> <f1>block</f1> </A>";
206 const char *src = "<A xmlns=\"urn:x\"> <f1>aa</f1> <B> <f2>bb</f2> </B> </A>";
207 const char *result = "<A xmlns=\"urn:x\"><f1>aa</f1><B><f2>bb</f2></B></A>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200208 struct lyd_node *source, *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200209
Radek Iša56ca9e42020-09-08 18:42:00 +0200210 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200211
Radek Iša56ca9e42020-09-08 18:42:00 +0200212 LYD_TREE_CREATE(src, source);
213 LYD_TREE_CREATE(trg, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200214
215 /* merge them */
Radek Iša56ca9e42020-09-08 18:42:00 +0200216 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
217 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200218
219 /* check the result */
Radek Iša56ca9e42020-09-08 18:42:00 +0200220 LYD_TREE_CHECK_CHAR(target, result, LYD_PRINT_SHRINK);
221
222 lyd_free_all(target);
223 lyd_free_all(source);
Michal Vasko4490d312020-06-16 13:08:55 +0200224}
225
226static void
227test_container(void **state)
228{
Michal Vasko4490d312020-06-16 13:08:55 +0200229 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100230 "module A {\n"
231 " namespace \"aa:A\";\n"
232 " prefix A;\n"
233 " container A {\n"
234 " leaf f1 {type string;}\n"
235 " container B {\n"
236 " leaf f2 {type string;}\n"
237 " }\n"
238 " container C {\n"
239 " leaf f3 {type string;}\n"
240 " }\n"
241 " }\n"
242 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200243
244 const char *trg = "<A xmlns=\"aa:A\"> <B> <f2>aaa</f2> </B> </A>";
245 const char *src = "<A xmlns=\"aa:A\"> <C> <f3>bbb</f3> </C> </A>";
246 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 +0200247 struct lyd_node *source, *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200248
Radek Iša56ca9e42020-09-08 18:42:00 +0200249 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200250
Radek Iša56ca9e42020-09-08 18:42:00 +0200251 LYD_TREE_CREATE(src, source);
252 LYD_TREE_CREATE(trg, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200253
254 /* merge them */
Radek Iša56ca9e42020-09-08 18:42:00 +0200255 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
256 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200257
258 /* check the result */
Radek Iša56ca9e42020-09-08 18:42:00 +0200259 LYD_TREE_CHECK_CHAR(target, result, LYD_PRINT_SHRINK);
260
261 /* destroy */
262 lyd_free_all(source);
263 lyd_free_all(target);
Michal Vasko4490d312020-06-16 13:08:55 +0200264}
265
266static void
267test_list(void **state)
268{
Michal Vasko4490d312020-06-16 13:08:55 +0200269 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100270 "module merge {\n"
271 " namespace \"http://test/merge\";\n"
272 " prefix merge;\n"
273 "\n"
274 " container inner1 {\n"
275 " list b-list1 {\n"
276 " key p1;\n"
277 " leaf p1 {\n"
278 " type uint8;\n"
279 " }\n"
280 " leaf p2 {\n"
281 " type string;\n"
282 " }\n"
283 " leaf p3 {\n"
284 " type boolean;\n"
285 " default false;\n"
286 " }\n"
287 " }\n"
288 " }\n"
289 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200290
291 const char *trg =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100292 "<inner1 xmlns=\"http://test/merge\">\n"
293 " <b-list1>\n"
294 " <p1>1</p1>\n"
295 " <p2>a</p2>\n"
296 " <p3>true</p3>\n"
297 " </b-list1>\n"
298 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200299 const char *src =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100300 "<inner1 xmlns=\"http://test/merge\">\n"
301 " <b-list1>\n"
302 " <p1>1</p1>\n"
303 " <p2>b</p2>\n"
304 " </b-list1>\n"
305 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200306 const char *result =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100307 "<inner1 xmlns=\"http://test/merge\">\n"
308 " <b-list1>\n"
309 " <p1>1</p1>\n"
310 " <p2>b</p2>\n"
311 " <p3>true</p3>\n"
312 " </b-list1>\n"
313 "</inner1>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200314 struct lyd_node *source, *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200315
Radek Iša56ca9e42020-09-08 18:42:00 +0200316 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200317
Radek Iša56ca9e42020-09-08 18:42:00 +0200318 LYD_TREE_CREATE(src, source);
319 LYD_TREE_CREATE(trg, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200320
321 /* merge them */
Radek Iša56ca9e42020-09-08 18:42:00 +0200322 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
323 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200324
325 /* check the result */
Radek Iša56ca9e42020-09-08 18:42:00 +0200326 LYD_TREE_CHECK_CHAR(target, result, 0);
327
328 lyd_free_all(target);
329 lyd_free_all(source);
Michal Vasko4490d312020-06-16 13:08:55 +0200330}
331
332static void
333test_list2(void **state)
334{
Michal Vasko4490d312020-06-16 13:08:55 +0200335 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100336 "module merge {\n"
337 " namespace \"http://test/merge\";\n"
338 " prefix merge;\n"
339 "\n"
340 " container inner1 {\n"
341 " list b-list1 {\n"
342 " key p1;\n"
343 " leaf p1 {\n"
344 " type uint8;\n"
345 " }\n"
346 " leaf p2 {\n"
347 " type string;\n"
348 " }\n"
349 " container inner2 {\n"
350 " leaf p3 {\n"
351 " type boolean;\n"
352 " default false;\n"
353 " }\n"
354 " leaf p4 {\n"
355 " type string;\n"
356 " }\n"
357 " }\n"
358 " }\n"
359 " }\n"
360 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200361
362 const char *trg =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100363 "<inner1 xmlns=\"http://test/merge\">\n"
364 " <b-list1>\n"
365 " <p1>1</p1>\n"
366 " <p2>a</p2>\n"
367 " <inner2>\n"
368 " <p4>val</p4>\n"
369 " </inner2>\n"
370 " </b-list1>\n"
371 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200372 const char *src =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100373 "<inner1 xmlns=\"http://test/merge\">\n"
374 " <b-list1>\n"
375 " <p1>1</p1>\n"
376 " <p2>b</p2>\n"
377 " </b-list1>\n"
378 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200379 const char *result =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100380 "<inner1 xmlns=\"http://test/merge\">\n"
381 " <b-list1>\n"
382 " <p1>1</p1>\n"
383 " <p2>b</p2>\n"
384 " <inner2>\n"
385 " <p4>val</p4>\n"
386 " </inner2>\n"
387 " </b-list1>\n"
388 "</inner1>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200389 struct lyd_node *source, *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200390
Radek Iša56ca9e42020-09-08 18:42:00 +0200391 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200392
Radek Iša56ca9e42020-09-08 18:42:00 +0200393 LYD_TREE_CREATE(src, source);
394 LYD_TREE_CREATE(trg, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200395
396 /* merge them */
Radek Iša56ca9e42020-09-08 18:42:00 +0200397 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
398 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200399
400 /* check the result */
Radek Iša56ca9e42020-09-08 18:42:00 +0200401 LYD_TREE_CHECK_CHAR(target, result, 0);
402
403 lyd_free_all(source);
404 lyd_free_all(target);
Michal Vasko4490d312020-06-16 13:08:55 +0200405}
406
407static void
Michal Vaskocd3f6172021-05-18 16:14:50 +0200408test_dup_inst_list(void **state)
409{
410 const char *sch =
411 "module merge {\n"
412 " namespace \"http://test/merge\";\n"
413 " prefix merge;\n"
414 "\n"
415 " container inner1 {\n"
416 " config false;\n"
417 " list b-list1 {\n"
418 " leaf p1 {\n"
419 " type uint8;\n"
420 " }\n"
421 " leaf p2 {\n"
422 " type string;\n"
423 " }\n"
424 " container inner2 {\n"
425 " leaf p4 {\n"
426 " type string;\n"
427 " }\n"
428 " }\n"
429 " }\n"
430 " }\n"
431 "}\n";
432
433 const char *trg =
434 "<inner1 xmlns=\"http://test/merge\">\n"
435 " <b-list1>\n"
436 " <p1>1</p1>\n"
437 " <p2>b</p2>\n"
438 " </b-list1>\n"
439 " <b-list1>\n"
440 " <p1>1</p1>\n"
441 " <p2>a</p2>\n"
442 " <inner2>\n"
443 " <p4>val</p4>\n"
444 " </inner2>\n"
445 " </b-list1>\n"
446 "</inner1>\n";
447 const char *src =
448 "<inner1 xmlns=\"http://test/merge\">\n"
449 " <b-list1>\n"
450 " <p1>1</p1>\n"
451 " <p2>b</p2>\n"
452 " </b-list1>\n"
453 " <b-list1>\n"
454 " <p1>2</p1>\n"
455 " <p2>a</p2>\n"
456 " </b-list1>\n"
457 "</inner1>\n";
458 const char *result =
459 "<inner1 xmlns=\"http://test/merge\">\n"
460 " <b-list1>\n"
461 " <p1>1</p1>\n"
462 " <p2>b</p2>\n"
463 " </b-list1>\n"
464 " <b-list1>\n"
465 " <p1>1</p1>\n"
466 " <p2>a</p2>\n"
467 " <inner2>\n"
468 " <p4>val</p4>\n"
469 " </inner2>\n"
470 " </b-list1>\n"
471 " <b-list1>\n"
472 " <p1>2</p1>\n"
473 " <p2>a</p2>\n"
474 " </b-list1>\n"
475 "</inner1>\n";
476 struct lyd_node *source, *target;
477
478 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
479
480 LYD_TREE_CREATE(src, source);
481 LYD_TREE_CREATE(trg, target);
482
483 /* merge them */
484 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
485 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
486
487 /* check the result */
488 LYD_TREE_CHECK_CHAR(target, result, 0);
489
490 lyd_free_all(source);
491 lyd_free_all(target);
492}
493
494static void
495test_dup_inst_llist(void **state)
496{
497 const char *sch =
498 "module merge {\n"
499 " namespace \"http://test/merge\";\n"
500 " prefix merge;\n"
501 "\n"
502 " container inner1 {\n"
503 " config false;\n"
504 " leaf-list b-llist1 {\n"
505 " type string;\n"
506 " }\n"
507 " }\n"
508 "}\n";
509
510 const char *trg =
511 "<inner1 xmlns=\"http://test/merge\">\n"
512 " <b-llist1>a</b-llist1>\n"
513 " <b-llist1>b</b-llist1>\n"
514 " <b-llist1>c</b-llist1>\n"
515 " <b-llist1>d</b-llist1>\n"
516 " <b-llist1>a</b-llist1>\n"
517 " <b-llist1>b</b-llist1>\n"
518 " <b-llist1>c</b-llist1>\n"
519 " <b-llist1>d</b-llist1>\n"
520 "</inner1>\n";
521 const char *src =
522 "<inner1 xmlns=\"http://test/merge\">\n"
523 " <b-llist1>d</b-llist1>\n"
524 " <b-llist1>c</b-llist1>\n"
525 " <b-llist1>b</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>a</b-llist1>\n"
530 " <b-llist1>f</b-llist1>\n"
531 " <b-llist1>f</b-llist1>\n"
532 "</inner1>\n";
533 const char *result =
534 "<inner1 xmlns=\"http://test/merge\">\n"
535 " <b-llist1>a</b-llist1>\n"
536 " <b-llist1>b</b-llist1>\n"
537 " <b-llist1>c</b-llist1>\n"
538 " <b-llist1>d</b-llist1>\n"
539 " <b-llist1>a</b-llist1>\n"
540 " <b-llist1>b</b-llist1>\n"
541 " <b-llist1>c</b-llist1>\n"
542 " <b-llist1>d</b-llist1>\n"
543 " <b-llist1>a</b-llist1>\n"
544 " <b-llist1>a</b-llist1>\n"
545 " <b-llist1>f</b-llist1>\n"
546 " <b-llist1>f</b-llist1>\n"
547 "</inner1>\n";
548 struct lyd_node *source, *target;
549
550 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
551
552 LYD_TREE_CREATE(src, source);
553 LYD_TREE_CREATE(trg, target);
554
555 /* merge them */
556 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
557 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
558
559 /* check the result */
560 LYD_TREE_CHECK_CHAR(target, result, 0);
561
562 lyd_free_all(source);
563 lyd_free_all(target);
564}
565
566static void
Michal Vasko4490d312020-06-16 13:08:55 +0200567test_case(void **state)
568{
Michal Vasko4490d312020-06-16 13:08:55 +0200569 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100570 "module merge {\n"
571 " namespace \"http://test/merge\";\n"
572 " prefix merge;\n"
573 " container cont {\n"
574 " choice ch {\n"
575 " container inner {\n"
576 " leaf p1 {\n"
577 " type string;\n"
578 " }\n"
579 " }\n"
580 " case c2 {\n"
581 " leaf p1 {\n"
582 " type string;\n"
583 " }\n"
584 " }\n"
585 " }\n"
586 " }\n"
587 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200588
589 const char *trg =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100590 "<cont xmlns=\"http://test/merge\">\n"
591 " <inner>\n"
592 " <p1>1</p1>\n"
593 " </inner>\n"
594 "</cont>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200595 const char *src =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100596 "<cont xmlns=\"http://test/merge\">\n"
597 " <p1>1</p1>\n"
598 "</cont>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200599 const char *result =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100600 "<cont xmlns=\"http://test/merge\">\n"
601 " <p1>1</p1>\n"
602 "</cont>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200603 struct lyd_node *source, *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200604
Radek Iša56ca9e42020-09-08 18:42:00 +0200605 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200606
Radek Iša56ca9e42020-09-08 18:42:00 +0200607 LYD_TREE_CREATE(src, source);
608 LYD_TREE_CREATE(trg, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200609
610 /* merge them */
Radek Iša56ca9e42020-09-08 18:42:00 +0200611 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
612 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200613
614 /* check the result */
Radek Iša56ca9e42020-09-08 18:42:00 +0200615 LYD_TREE_CHECK_CHAR(target, result, 0);
616
617 lyd_free_all(source);
618 lyd_free_all(target);
Michal Vasko4490d312020-06-16 13:08:55 +0200619}
620
621static void
622test_dflt(void **state)
623{
Michal Vasko4490d312020-06-16 13:08:55 +0200624 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100625 "module merge-dflt {\n"
626 " namespace \"urn:merge-dflt\";\n"
627 " prefix md;\n"
628 " container top {\n"
629 " leaf a {\n"
630 " type string;\n"
631 " }\n"
632 " leaf b {\n"
633 " type string;\n"
634 " }\n"
635 " leaf c {\n"
636 " type string;\n"
637 " default \"c_dflt\";\n"
638 " }\n"
639 " }\n"
640 "}\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200641 struct lyd_node *target = NULL;
642 struct lyd_node *source = NULL;
Michal Vasko4490d312020-06-16 13:08:55 +0200643
Radek Iša56ca9e42020-09-08 18:42:00 +0200644 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200645
Radek Iša56ca9e42020-09-08 18:42:00 +0200646 assert_int_equal(lyd_new_path(NULL, UTEST_LYCTX, "/merge-dflt:top/c", "c_dflt", 0, &target), LY_SUCCESS);
647 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200648
Radek Iša56ca9e42020-09-08 18:42:00 +0200649 assert_int_equal(lyd_new_path(NULL, UTEST_LYCTX, "/merge-dflt:top/a", "a_val", 0, &source), LY_SUCCESS);
650 assert_int_equal(lyd_new_path(source, UTEST_LYCTX, "/merge-dflt:top/b", "b_val", 0, NULL), LY_SUCCESS);
651 assert_int_equal(lyd_validate_all(&source, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200652
Radek Iša56ca9e42020-09-08 18:42:00 +0200653 assert_int_equal(lyd_merge_siblings(&target, source, LYD_MERGE_DESTRUCT | LYD_MERGE_DEFAULTS), LY_SUCCESS);
654 source = NULL;
Michal Vasko4490d312020-06-16 13:08:55 +0200655
656 /* c should be replaced and now be default */
Radek Iša56ca9e42020-09-08 18:42:00 +0200657 assert_string_equal(lyd_child(target)->prev->schema->name, "c");
658 assert_true(lyd_child(target)->prev->flags & LYD_DEFAULT);
659
660 lyd_free_all(target);
661 lyd_free_all(source);
Michal Vasko4490d312020-06-16 13:08:55 +0200662}
663
664static void
665test_dflt2(void **state)
666{
Michal Vasko4490d312020-06-16 13:08:55 +0200667 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100668 "module merge-dflt {\n"
669 " namespace \"urn:merge-dflt\";\n"
670 " prefix md;\n"
671 " container top {\n"
672 " leaf a {\n"
673 " type string;\n"
674 " }\n"
675 " leaf b {\n"
676 " type string;\n"
677 " }\n"
678 " leaf c {\n"
679 " type string;\n"
680 " default \"c_dflt\";\n"
681 " }\n"
682 " }\n"
683 "}\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200684 struct lyd_node *target;
685 struct lyd_node *source;
Michal Vasko4490d312020-06-16 13:08:55 +0200686
Radek Iša56ca9e42020-09-08 18:42:00 +0200687 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200688
Radek Iša56ca9e42020-09-08 18:42:00 +0200689 assert_int_equal(lyd_new_path(NULL, UTEST_LYCTX, "/merge-dflt:top/c", "c_dflt", 0, &target), LY_SUCCESS);
690 assert_int_equal(lyd_validate_all(&target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200691
Radek Iša56ca9e42020-09-08 18:42:00 +0200692 assert_int_equal(lyd_new_path(NULL, UTEST_LYCTX, "/merge-dflt:top/a", "a_val", 0, &source), LY_SUCCESS);
693 assert_int_equal(lyd_new_path(source, UTEST_LYCTX, "/merge-dflt:top/b", "b_val", 0, NULL), LY_SUCCESS);
694 assert_int_equal(lyd_validate_all(&source, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200695
Radek Iša56ca9e42020-09-08 18:42:00 +0200696 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200697
698 /* c should not be replaced, so c remains not default */
Radek Iša56ca9e42020-09-08 18:42:00 +0200699 assert_false(lyd_child(target)->flags & LYD_DEFAULT);
700
701 lyd_free_all(target);
702 lyd_free_all(source);
Michal Vasko4490d312020-06-16 13:08:55 +0200703}
704
705static void
706test_leafrefs(void **state)
707{
Michal Vasko4490d312020-06-16 13:08:55 +0200708 const char *sch = "module x {"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100709 " namespace urn:x;"
710 " prefix x;"
711 " list l {"
712 " key n;"
713 " leaf n { type string; }"
714 " leaf t { type string; }"
715 " leaf r { type leafref { path '/l/n'; } }}}";
Michal Vasko4490d312020-06-16 13:08:55 +0200716 const char *trg = "<l xmlns=\"urn:x\"><n>a</n></l>"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100717 "<l xmlns=\"urn:x\"><n>b</n><r>a</r></l>";
Michal Vasko4490d312020-06-16 13:08:55 +0200718 const char *src = "<l xmlns=\"urn:x\"><n>c</n><r>a</r></l>"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100719 "<l xmlns=\"urn:x\"><n>a</n><t>*</t></l>";
Michal Vasko4490d312020-06-16 13:08:55 +0200720 const char *res = "<l xmlns=\"urn:x\"><n>a</n><t>*</t></l>"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100721 "<l xmlns=\"urn:x\"><n>b</n><r>a</r></l>"
722 "<l xmlns=\"urn:x\"><n>c</n><r>a</r></l>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200723 struct lyd_node *source, *target;
Michal Vasko4490d312020-06-16 13:08:55 +0200724
Radek Iša56ca9e42020-09-08 18:42:00 +0200725 UTEST_ADD_MODULE(sch, LYS_IN_YANG, NULL, NULL);
Michal Vasko4490d312020-06-16 13:08:55 +0200726
Radek Iša56ca9e42020-09-08 18:42:00 +0200727 LYD_TREE_CREATE(src, source);
728 LYD_TREE_CREATE(trg, target);
Michal Vasko4490d312020-06-16 13:08:55 +0200729
Radek Iša56ca9e42020-09-08 18:42:00 +0200730 assert_int_equal(lyd_merge_siblings(&target, source, 0), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200731
Radek Iša56ca9e42020-09-08 18:42:00 +0200732 LYD_TREE_CHECK_CHAR(target, res, LYD_PRINT_SHRINK);
Michal Vasko4490d312020-06-16 13:08:55 +0200733
Radek Iša56ca9e42020-09-08 18:42:00 +0200734 lyd_free_all(source);
735 lyd_free_all(target);
Michal Vasko4490d312020-06-16 13:08:55 +0200736}
737
738int
739main(void)
740{
741 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200742 UTEST(test_batch),
743 UTEST(test_leaf),
744 UTEST(test_container),
745 UTEST(test_list),
746 UTEST(test_list2),
Michal Vaskocd3f6172021-05-18 16:14:50 +0200747 UTEST(test_dup_inst_list),
748 UTEST(test_dup_inst_llist),
Radek Iša56ca9e42020-09-08 18:42:00 +0200749 UTEST(test_case),
750 UTEST(test_dflt),
751 UTEST(test_dflt2),
752 UTEST(test_leafrefs),
Michal Vasko4490d312020-06-16 13:08:55 +0200753 };
754
755 return cmocka_run_group_tests(tests, NULL, NULL);
756}