blob: 20df92a5373eafc3169c349b9c6ed5069491d2d2 [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 */
14
Michal Vasko4490d312020-06-16 13:08:55 +020015#include "libyang.h"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010016#include "utests.h"
Michal Vasko4490d312020-06-16 13:08:55 +020017
18struct state {
19 struct ly_ctx *ctx;
20 struct lyd_node *source;
21 struct lyd_node *target;
22 struct lyd_node *result;
23};
24
25static int
26setup_dflt(void **state)
27{
28 struct state *st;
29
30 (*state) = st = calloc(1, sizeof *st);
31 if (!st) {
32 fprintf(stderr, "Memory allocation error.\n");
33 return -1;
34 }
35
36 /* libyang context */
37 if (ly_ctx_new(NULL, 0, &st->ctx)) {
38 fprintf(stderr, "Failed to create context.\n");
39 goto error;
40 }
41
42 return 0;
43
44error:
45 ly_ctx_destroy(st->ctx, NULL);
46 free(st);
47 (*state) = NULL;
48
49 return -1;
50}
51
52static int
53teardown_dflt(void **state)
54{
55 struct state *st = (*state);
56
57 lyd_free_siblings(st->target);
58 lyd_free_siblings(st->source);
59 lyd_free_siblings(st->result);
60 ly_ctx_destroy(st->ctx, NULL);
61 free(st);
62 (*state) = NULL;
63
64 return 0;
65}
66
67static void
68test_batch(void **state)
69{
70 struct state *st = (*state);
Michal Vasko4490d312020-06-16 13:08:55 +020071 uint32_t i;
72 char *str;
73
74 const char *start =
Radek Krejcib4ac5a92020-11-23 17:54:33 +010075 "<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 " <conformance-type>implement</conformance-type>\n"
80 " </module>\n"
81 "</modules-state>\n";
Michal Vasko4490d312020-06-16 13:08:55 +020082 const char *data[] = {
Radek Krejcib4ac5a92020-11-23 17:54:33 +010083 "<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 " <conformance-type>implement</conformance-type>\n"
88 " </module>\n"
89 "</modules-state>\n",
90 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
91 " <module>\n"
92 " <name>ietf-netconf-acm</name>\n"
93 " <revision>2012-02-22</revision>\n"
94 " <conformance-type>implement</conformance-type>\n"
95 " </module>\n"
96 "</modules-state>\n",
97 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
98 " <module>\n"
99 " <name>ietf-netconf</name>\n"
100 " <revision>2011-06-01</revision>\n"
101 " <conformance-type>implement</conformance-type>\n"
102 " </module>\n"
103 "</modules-state>\n",
104 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
105 " <module>\n"
106 " <name>ietf-netconf-monitoring</name>\n"
107 " <revision>2010-10-04</revision>\n"
108 " <conformance-type>implement</conformance-type>\n"
109 " </module>\n"
110 "</modules-state>\n",
111 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
112 " <module>\n"
113 " <name>ietf-netconf-with-defaults</name>\n"
114 " <revision>2011-06-01</revision>\n"
115 " <conformance-type>implement</conformance-type>\n"
116 " </module>\n"
117 "</modules-state>\n",
118 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
119 " <module>\n"
120 " <name>yang</name>\n"
121 " <revision>2016-02-11</revision>\n"
122 " <namespace>urn:ietf:params:xml:ns:yang:1</namespace>\n"
123 " <conformance-type>implement</conformance-type>\n"
124 " </module>\n"
125 "</modules-state>\n",
126 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
127 " <module>\n"
128 " <name>ietf-yang-library</name>\n"
129 " <revision>2016-02-01</revision>\n"
130 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>\n"
131 " <conformance-type>implement</conformance-type>\n"
132 " </module>\n"
133 "</modules-state>\n",
134 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
135 " <module>\n"
136 " <name>ietf-netconf-acm</name>\n"
137 " <revision>2012-02-22</revision>\n"
138 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>\n"
139 " <conformance-type>implement</conformance-type>\n"
140 " </module>\n"
141 "</modules-state>\n",
142 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
143 " <module>\n"
144 " <name>ietf-netconf</name>\n"
145 " <revision>2011-06-01</revision>\n"
146 " <namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>\n"
147 " <feature>writable-running</feature>\n"
148 " <feature>candidate</feature>\n"
149 " <feature>rollback-on-error</feature>\n"
150 " <feature>validate</feature>\n"
151 " <feature>startup</feature>\n"
152 " <feature>xpath</feature>\n"
153 " <conformance-type>implement</conformance-type>\n"
154 " </module>\n"
155 "</modules-state>\n",
156 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
157 " <module>\n"
158 " <name>ietf-netconf-monitoring</name>\n"
159 " <revision>2010-10-04</revision>\n"
160 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</namespace>\n"
161 " <conformance-type>implement</conformance-type>\n"
162 " </module>\n"
163 "</modules-state>\n",
164 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
165 " <module>\n"
166 " <name>ietf-netconf-with-defaults</name>\n"
167 " <revision>2011-06-01</revision>\n"
168 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults</namespace>\n"
169 " <conformance-type>implement</conformance-type>\n"
170 " </module>\n"
171 "</modules-state>\n"
Michal Vasko4490d312020-06-16 13:08:55 +0200172 };
173 const char *output_template =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100174 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
175 " <module>\n"
176 " <name>yang</name>\n"
177 " <revision>2016-02-11</revision>\n"
178 " <namespace>urn:ietf:params:xml:ns:yang:1</namespace>\n"
179 " <conformance-type>implement</conformance-type>\n"
180 " </module>\n"
181 " <module>\n"
182 " <name>ietf-yang-library</name>\n"
183 " <revision>2016-02-01</revision>\n"
184 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>\n"
185 " <conformance-type>implement</conformance-type>\n"
186 " </module>\n"
187 " <module>\n"
188 " <name>ietf-netconf-acm</name>\n"
189 " <revision>2012-02-22</revision>\n"
190 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>\n"
191 " <conformance-type>implement</conformance-type>\n"
192 " </module>\n"
193 " <module>\n"
194 " <name>ietf-netconf</name>\n"
195 " <revision>2011-06-01</revision>\n"
196 " <namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>\n"
197 " <feature>writable-running</feature>\n"
198 " <feature>candidate</feature>\n"
199 " <feature>rollback-on-error</feature>\n"
200 " <feature>validate</feature>\n"
201 " <feature>startup</feature>\n"
202 " <feature>xpath</feature>\n"
203 " <conformance-type>implement</conformance-type>\n"
204 " </module>\n"
205 " <module>\n"
206 " <name>ietf-netconf-monitoring</name>\n"
207 " <revision>2010-10-04</revision>\n"
208 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</namespace>\n"
209 " <conformance-type>implement</conformance-type>\n"
210 " </module>\n"
211 " <module>\n"
212 " <name>ietf-netconf-with-defaults</name>\n"
213 " <revision>2011-06-01</revision>\n"
214 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults</namespace>\n"
215 " <conformance-type>implement</conformance-type>\n"
216 " </module>\n"
217 "</modules-state>\n";
Radek Krejci7931b192020-06-25 17:05:03 +0200218 struct ly_in *in = NULL;
Michal Vasko4490d312020-06-16 13:08:55 +0200219
Radek Krejci7931b192020-06-25 17:05:03 +0200220 assert_int_equal(LY_SUCCESS, ly_in_new_memory(start, &in));
221 assert_int_equal(LY_SUCCESS, lyd_parse_data(st->ctx, in, LYD_XML, LYD_PARSE_ONLY, 0, &st->target));
Michal Vasko4490d312020-06-16 13:08:55 +0200222 assert_non_null(st->target);
223
224 for (i = 0; i < 11; ++i) {
Radek Krejci7931b192020-06-25 17:05:03 +0200225 ly_in_memory(in, data[i]);
226 assert_int_equal(LY_SUCCESS, lyd_parse_data(st->ctx, in, LYD_XML, LYD_PARSE_ONLY, 0, &st->source));
Michal Vasko4490d312020-06-16 13:08:55 +0200227 assert_non_null(st->source);
228
Michal Vasko3a41dff2020-07-15 14:30:28 +0200229 assert_int_equal(LY_SUCCESS, lyd_merge_siblings(&st->target, st->source, LYD_MERGE_DESTRUCT));
Michal Vasko4490d312020-06-16 13:08:55 +0200230 st->source = NULL;
231 }
232
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100233 lyd_print_mem(&str, st->target, LYD_XML, 0);
Michal Vasko4490d312020-06-16 13:08:55 +0200234 assert_string_equal(str, output_template);
Radek Krejci7931b192020-06-25 17:05:03 +0200235
236 ly_in_free(in, 0);
Michal Vasko4490d312020-06-16 13:08:55 +0200237 free(str);
238}
239
240static void
241test_leaf(void **state)
242{
243 struct state *st = (*state);
244 const char *sch = "module x {"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100245 " namespace urn:x;"
246 " prefix x;"
247 " container A {"
248 " leaf f1 {type string;}"
249 " container B {"
250 " leaf f2 {type string;}"
251 " }"
252 " }"
253 " }";
Michal Vasko4490d312020-06-16 13:08:55 +0200254 const char *trg = "<A xmlns=\"urn:x\"> <f1>block</f1> </A>";
255 const char *src = "<A xmlns=\"urn:x\"> <f1>aa</f1> <B> <f2>bb</f2> </B> </A>";
256 const char *result = "<A xmlns=\"urn:x\"><f1>aa</f1><B><f2>bb</f2></B></A>";
257 char *printed = NULL;
258
Michal Vasko3a41dff2020-07-15 14:30:28 +0200259 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200260
Radek Krejci7931b192020-06-25 17:05:03 +0200261 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, src, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->source));
Michal Vasko4490d312020-06-16 13:08:55 +0200262 assert_non_null(st->source);
263
Radek Krejci7931b192020-06-25 17:05:03 +0200264 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, trg, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->target));
Michal Vasko4490d312020-06-16 13:08:55 +0200265 assert_non_null(st->target);
266
267 /* merge them */
Michal Vasko3a41dff2020-07-15 14:30:28 +0200268 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
269 assert_int_equal(lyd_validate_all(&st->target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200270
271 /* check the result */
Radek Krejci52f65552020-09-01 17:03:35 +0200272 lyd_print_mem(&printed, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
Michal Vasko4490d312020-06-16 13:08:55 +0200273 assert_string_equal(printed, result);
274 free(printed);
275}
276
277static void
278test_container(void **state)
279{
280 struct state *st = (*state);
281 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100282 "module A {\n"
283 " namespace \"aa:A\";\n"
284 " prefix A;\n"
285 " container A {\n"
286 " leaf f1 {type string;}\n"
287 " container B {\n"
288 " leaf f2 {type string;}\n"
289 " }\n"
290 " container C {\n"
291 " leaf f3 {type string;}\n"
292 " }\n"
293 " }\n"
294 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200295
296 const char *trg = "<A xmlns=\"aa:A\"> <B> <f2>aaa</f2> </B> </A>";
297 const char *src = "<A xmlns=\"aa:A\"> <C> <f3>bbb</f3> </C> </A>";
298 const char *result = "<A xmlns=\"aa:A\"><B><f2>aaa</f2></B><C><f3>bbb</f3></C></A>";
299 char *printed = NULL;
300
Michal Vasko3a41dff2020-07-15 14:30:28 +0200301 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200302
Radek Krejci7931b192020-06-25 17:05:03 +0200303 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, src, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->source));
Michal Vasko4490d312020-06-16 13:08:55 +0200304 assert_non_null(st->source);
305
Radek Krejci7931b192020-06-25 17:05:03 +0200306 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, trg, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->target));
Michal Vasko4490d312020-06-16 13:08:55 +0200307 assert_non_null(st->target);
308
309 /* merge them */
Michal Vasko3a41dff2020-07-15 14:30:28 +0200310 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
311 assert_int_equal(lyd_validate_all(&st->target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200312
313 /* check the result */
Radek Krejci52f65552020-09-01 17:03:35 +0200314 lyd_print_mem(&printed, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
Michal Vasko4490d312020-06-16 13:08:55 +0200315 assert_string_equal(printed, result);
316 free(printed);
317}
318
319static void
320test_list(void **state)
321{
322 struct state *st = (*state);
323 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100324 "module merge {\n"
325 " namespace \"http://test/merge\";\n"
326 " prefix merge;\n"
327 "\n"
328 " container inner1 {\n"
329 " list b-list1 {\n"
330 " key p1;\n"
331 " leaf p1 {\n"
332 " type uint8;\n"
333 " }\n"
334 " leaf p2 {\n"
335 " type string;\n"
336 " }\n"
337 " leaf p3 {\n"
338 " type boolean;\n"
339 " default false;\n"
340 " }\n"
341 " }\n"
342 " }\n"
343 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200344
345 const char *trg =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100346 "<inner1 xmlns=\"http://test/merge\">\n"
347 " <b-list1>\n"
348 " <p1>1</p1>\n"
349 " <p2>a</p2>\n"
350 " <p3>true</p3>\n"
351 " </b-list1>\n"
352 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200353 const char *src =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100354 "<inner1 xmlns=\"http://test/merge\">\n"
355 " <b-list1>\n"
356 " <p1>1</p1>\n"
357 " <p2>b</p2>\n"
358 " </b-list1>\n"
359 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200360 const char *result =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100361 "<inner1 xmlns=\"http://test/merge\">\n"
362 " <b-list1>\n"
363 " <p1>1</p1>\n"
364 " <p2>b</p2>\n"
365 " <p3>true</p3>\n"
366 " </b-list1>\n"
367 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200368 char *printed = NULL;
369
Michal Vasko3a41dff2020-07-15 14:30:28 +0200370 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200371
Radek Krejci7931b192020-06-25 17:05:03 +0200372 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, src, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->source));
Michal Vasko4490d312020-06-16 13:08:55 +0200373 assert_non_null(st->source);
374
Radek Krejci7931b192020-06-25 17:05:03 +0200375 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, trg, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->target));
Michal Vasko4490d312020-06-16 13:08:55 +0200376 assert_non_null(st->target);
377
378 /* merge them */
Michal Vasko3a41dff2020-07-15 14:30:28 +0200379 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
380 assert_int_equal(lyd_validate_all(&st->target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200381
382 /* check the result */
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100383 lyd_print_mem(&printed, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vasko4490d312020-06-16 13:08:55 +0200384 assert_string_equal(printed, result);
385 free(printed);
386}
387
388static void
389test_list2(void **state)
390{
391 struct state *st = (*state);
392 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100393 "module merge {\n"
394 " namespace \"http://test/merge\";\n"
395 " prefix merge;\n"
396 "\n"
397 " container inner1 {\n"
398 " list b-list1 {\n"
399 " key p1;\n"
400 " leaf p1 {\n"
401 " type uint8;\n"
402 " }\n"
403 " leaf p2 {\n"
404 " type string;\n"
405 " }\n"
406 " container inner2 {\n"
407 " leaf p3 {\n"
408 " type boolean;\n"
409 " default false;\n"
410 " }\n"
411 " leaf p4 {\n"
412 " type string;\n"
413 " }\n"
414 " }\n"
415 " }\n"
416 " }\n"
417 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200418
419 const char *trg =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100420 "<inner1 xmlns=\"http://test/merge\">\n"
421 " <b-list1>\n"
422 " <p1>1</p1>\n"
423 " <p2>a</p2>\n"
424 " <inner2>\n"
425 " <p4>val</p4>\n"
426 " </inner2>\n"
427 " </b-list1>\n"
428 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200429 const char *src =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100430 "<inner1 xmlns=\"http://test/merge\">\n"
431 " <b-list1>\n"
432 " <p1>1</p1>\n"
433 " <p2>b</p2>\n"
434 " </b-list1>\n"
435 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200436 const char *result =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100437 "<inner1 xmlns=\"http://test/merge\">\n"
438 " <b-list1>\n"
439 " <p1>1</p1>\n"
440 " <p2>b</p2>\n"
441 " <inner2>\n"
442 " <p4>val</p4>\n"
443 " </inner2>\n"
444 " </b-list1>\n"
445 "</inner1>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200446 char *printed = NULL;
447
Michal Vasko3a41dff2020-07-15 14:30:28 +0200448 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200449
Radek Krejci7931b192020-06-25 17:05:03 +0200450 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, src, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->source));
Michal Vasko4490d312020-06-16 13:08:55 +0200451 assert_non_null(st->source);
452
Radek Krejci7931b192020-06-25 17:05:03 +0200453 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, trg, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->target));
Michal Vasko4490d312020-06-16 13:08:55 +0200454 assert_non_null(st->target);
455
456 /* merge them */
Michal Vasko3a41dff2020-07-15 14:30:28 +0200457 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
458 assert_int_equal(lyd_validate_all(&st->target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200459
460 /* check the result */
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100461 lyd_print_mem(&printed, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vasko4490d312020-06-16 13:08:55 +0200462 assert_string_equal(printed, result);
463 free(printed);
464}
465
466static void
467test_case(void **state)
468{
469 struct state *st = (*state);
470 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100471 "module merge {\n"
472 " namespace \"http://test/merge\";\n"
473 " prefix merge;\n"
474 " container cont {\n"
475 " choice ch {\n"
476 " container inner {\n"
477 " leaf p1 {\n"
478 " type string;\n"
479 " }\n"
480 " }\n"
481 " case c2 {\n"
482 " leaf p1 {\n"
483 " type string;\n"
484 " }\n"
485 " }\n"
486 " }\n"
487 " }\n"
488 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200489
490 const char *trg =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100491 "<cont xmlns=\"http://test/merge\">\n"
492 " <inner>\n"
493 " <p1>1</p1>\n"
494 " </inner>\n"
495 "</cont>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200496 const char *src =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100497 "<cont xmlns=\"http://test/merge\">\n"
498 " <p1>1</p1>\n"
499 "</cont>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200500 const char *result =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100501 "<cont xmlns=\"http://test/merge\">\n"
502 " <p1>1</p1>\n"
503 "</cont>\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200504 char *printed = NULL;
505
Michal Vasko3a41dff2020-07-15 14:30:28 +0200506 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200507
Radek Krejci7931b192020-06-25 17:05:03 +0200508 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, src, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->source));
Michal Vasko4490d312020-06-16 13:08:55 +0200509 assert_non_null(st->source);
510
Radek Krejci7931b192020-06-25 17:05:03 +0200511 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, trg, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->target));
Michal Vasko4490d312020-06-16 13:08:55 +0200512 assert_non_null(st->target);
513
514 /* merge them */
Michal Vasko3a41dff2020-07-15 14:30:28 +0200515 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
516 assert_int_equal(lyd_validate_all(&st->target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200517
518 /* check the result */
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100519 lyd_print_mem(&printed, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vasko4490d312020-06-16 13:08:55 +0200520 assert_string_equal(printed, result);
521 free(printed);
522}
523
524static void
525test_dflt(void **state)
526{
527 struct state *st = (*state);
Michal Vasko4490d312020-06-16 13:08:55 +0200528 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100529 "module merge-dflt {\n"
530 " namespace \"urn:merge-dflt\";\n"
531 " prefix md;\n"
532 " container top {\n"
533 " leaf a {\n"
534 " type string;\n"
535 " }\n"
536 " leaf b {\n"
537 " type string;\n"
538 " }\n"
539 " leaf c {\n"
540 " type string;\n"
541 " default \"c_dflt\";\n"
542 " }\n"
543 " }\n"
544 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200545
Michal Vasko3a41dff2020-07-15 14:30:28 +0200546 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200547
Michal Vasko3a41dff2020-07-15 14:30:28 +0200548 assert_int_equal(lyd_new_path(NULL, st->ctx, "/merge-dflt:top/c", "c_dflt", 0, &st->target), LY_SUCCESS);
549 assert_int_equal(lyd_validate_all(&(st->target), NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200550
Michal Vasko3a41dff2020-07-15 14:30:28 +0200551 assert_int_equal(lyd_new_path(NULL, st->ctx, "/merge-dflt:top/a", "a_val", 0, &st->source), LY_SUCCESS);
552 assert_int_equal(lyd_new_path(st->source, st->ctx, "/merge-dflt:top/b", "b_val", 0, NULL), LY_SUCCESS);
553 assert_int_equal(lyd_validate_all(&(st->source), NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200554
Michal Vasko3a41dff2020-07-15 14:30:28 +0200555 assert_int_equal(lyd_merge_siblings(&st->target, st->source, LYD_MERGE_DESTRUCT | LYD_MERGE_DEFAULTS), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200556 st->source = NULL;
557
558 /* c should be replaced and now be default */
Radek Krejcia1c1e542020-09-29 16:06:52 +0200559 assert_string_equal(lyd_child(st->target)->prev->schema->name, "c");
560 assert_true(lyd_child(st->target)->prev->flags & LYD_DEFAULT);
Michal Vasko4490d312020-06-16 13:08:55 +0200561}
562
563static void
564test_dflt2(void **state)
565{
566 struct state *st = (*state);
Michal Vasko4490d312020-06-16 13:08:55 +0200567 const char *sch =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100568 "module merge-dflt {\n"
569 " namespace \"urn:merge-dflt\";\n"
570 " prefix md;\n"
571 " container top {\n"
572 " leaf a {\n"
573 " type string;\n"
574 " }\n"
575 " leaf b {\n"
576 " type string;\n"
577 " }\n"
578 " leaf c {\n"
579 " type string;\n"
580 " default \"c_dflt\";\n"
581 " }\n"
582 " }\n"
583 "}\n";
Michal Vasko4490d312020-06-16 13:08:55 +0200584
Michal Vasko3a41dff2020-07-15 14:30:28 +0200585 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200586
Michal Vasko3a41dff2020-07-15 14:30:28 +0200587 assert_int_equal(lyd_new_path(NULL, st->ctx, "/merge-dflt:top/c", "c_dflt", 0, &st->target), LY_SUCCESS);
588 assert_int_equal(lyd_validate_all(&(st->target), NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200589
Michal Vasko3a41dff2020-07-15 14:30:28 +0200590 assert_int_equal(lyd_new_path(NULL, st->ctx, "/merge-dflt:top/a", "a_val", 0, &st->source), LY_SUCCESS);
591 assert_int_equal(lyd_new_path(st->source, st->ctx, "/merge-dflt:top/b", "b_val", 0, NULL), LY_SUCCESS);
592 assert_int_equal(lyd_validate_all(&(st->source), NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200593
Michal Vasko3a41dff2020-07-15 14:30:28 +0200594 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200595
596 /* c should not be replaced, so c remains not default */
Radek Krejcia1c1e542020-09-29 16:06:52 +0200597 assert_false(lyd_child(st->target)->flags & LYD_DEFAULT);
Michal Vasko4490d312020-06-16 13:08:55 +0200598}
599
600static void
601test_leafrefs(void **state)
602{
603 struct state *st = (*state);
604 const char *sch = "module x {"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100605 " namespace urn:x;"
606 " prefix x;"
607 " list l {"
608 " key n;"
609 " leaf n { type string; }"
610 " leaf t { type string; }"
611 " leaf r { type leafref { path '/l/n'; } }}}";
Michal Vasko4490d312020-06-16 13:08:55 +0200612 const char *trg = "<l xmlns=\"urn:x\"><n>a</n></l>"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100613 "<l xmlns=\"urn:x\"><n>b</n><r>a</r></l>";
Michal Vasko4490d312020-06-16 13:08:55 +0200614 const char *src = "<l xmlns=\"urn:x\"><n>c</n><r>a</r></l>"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100615 "<l xmlns=\"urn:x\"><n>a</n><t>*</t></l>";
Michal Vasko4490d312020-06-16 13:08:55 +0200616 const char *res = "<l xmlns=\"urn:x\"><n>a</n><t>*</t></l>"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100617 "<l xmlns=\"urn:x\"><n>b</n><r>a</r></l>"
618 "<l xmlns=\"urn:x\"><n>c</n><r>a</r></l>";
Michal Vasko4490d312020-06-16 13:08:55 +0200619 char *prt = NULL;
620
Michal Vasko3a41dff2020-07-15 14:30:28 +0200621 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200622
Radek Krejci7931b192020-06-25 17:05:03 +0200623 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, src, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->source));
Michal Vasko4490d312020-06-16 13:08:55 +0200624 assert_non_null(st->source);
625
Radek Krejci7931b192020-06-25 17:05:03 +0200626 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, trg, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->target));
627 assert_non_null(st->target);
628
Michal Vasko3a41dff2020-07-15 14:30:28 +0200629 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200630
Radek Krejci52f65552020-09-01 17:03:35 +0200631 lyd_print_mem(&prt, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
Michal Vasko4490d312020-06-16 13:08:55 +0200632 assert_string_equal(prt, res);
633 free(prt);
634}
635
636int
637main(void)
638{
639 const struct CMUnitTest tests[] = {
640 cmocka_unit_test_setup_teardown(test_batch, setup_dflt, teardown_dflt),
641 cmocka_unit_test_setup_teardown(test_leaf, setup_dflt, teardown_dflt),
642 cmocka_unit_test_setup_teardown(test_container, setup_dflt, teardown_dflt),
643 cmocka_unit_test_setup_teardown(test_list, setup_dflt, teardown_dflt),
644 cmocka_unit_test_setup_teardown(test_list2, setup_dflt, teardown_dflt),
645 cmocka_unit_test_setup_teardown(test_case, setup_dflt, teardown_dflt),
646 cmocka_unit_test_setup_teardown(test_dflt, setup_dflt, teardown_dflt),
647 cmocka_unit_test_setup_teardown(test_dflt2, setup_dflt, teardown_dflt),
648 cmocka_unit_test_setup_teardown(test_leafrefs, setup_dflt, teardown_dflt),
649 };
650
651 return cmocka_run_group_tests(tests, NULL, NULL);
652}