blob: 95e2f865d0c764ccb75753f58a3d66d3f9ce4ea5 [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
15#include <stdarg.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <setjmp.h>
20#include <cmocka.h>
21
22#include "libyang.h"
23
24struct state {
25 struct ly_ctx *ctx;
26 struct lyd_node *source;
27 struct lyd_node *target;
28 struct lyd_node *result;
29};
30
31static int
32setup_dflt(void **state)
33{
34 struct state *st;
35
36 (*state) = st = calloc(1, sizeof *st);
37 if (!st) {
38 fprintf(stderr, "Memory allocation error.\n");
39 return -1;
40 }
41
42 /* libyang context */
43 if (ly_ctx_new(NULL, 0, &st->ctx)) {
44 fprintf(stderr, "Failed to create context.\n");
45 goto error;
46 }
47
48 return 0;
49
50error:
51 ly_ctx_destroy(st->ctx, NULL);
52 free(st);
53 (*state) = NULL;
54
55 return -1;
56}
57
58static int
59teardown_dflt(void **state)
60{
61 struct state *st = (*state);
62
63 lyd_free_siblings(st->target);
64 lyd_free_siblings(st->source);
65 lyd_free_siblings(st->result);
66 ly_ctx_destroy(st->ctx, NULL);
67 free(st);
68 (*state) = NULL;
69
70 return 0;
71}
72
73static void
74test_batch(void **state)
75{
76 struct state *st = (*state);
Michal Vasko4490d312020-06-16 13:08:55 +020077 uint32_t i;
78 char *str;
79
80 const char *start =
81 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
82 "<module>"
83 "<name>yang</name>"
84 "<revision>2016-02-11</revision>"
85 "<conformance-type>implement</conformance-type>"
86 "</module>"
87 "</modules-state>";
88 const char *data[] = {
89 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
90 "<module>"
91 "<name>ietf-yang-library</name>"
92 "<revision>2016-02-01</revision>"
93 "<conformance-type>implement</conformance-type>"
94 "</module>"
95 "</modules-state>"
96 ,
97 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
98 "<module>"
99 "<name>ietf-netconf-acm</name>"
100 "<revision>2012-02-22</revision>"
101 "<conformance-type>implement</conformance-type>"
102 "</module>"
103 "</modules-state>"
104 ,
105 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
106 "<module>"
107 "<name>ietf-netconf</name>"
108 "<revision>2011-06-01</revision>"
109 "<conformance-type>implement</conformance-type>"
110 "</module>"
111 "</modules-state>"
112 ,
113 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
114 "<module>"
115 "<name>ietf-netconf-monitoring</name>"
116 "<revision>2010-10-04</revision>"
117 "<conformance-type>implement</conformance-type>"
118 "</module>"
119 "</modules-state>"
120 ,
121 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
122 "<module>"
123 "<name>ietf-netconf-with-defaults</name>"
124 "<revision>2011-06-01</revision>"
125 "<conformance-type>implement</conformance-type>"
126 "</module>"
127 "</modules-state>"
128 ,
129 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
130 "<module>"
131 "<name>yang</name>"
132 "<revision>2016-02-11</revision>"
133 "<namespace>urn:ietf:params:xml:ns:yang:1</namespace>"
134 "<conformance-type>implement</conformance-type>"
135 "</module>"
136 "</modules-state>"
137 ,
138 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
139 "<module>"
140 "<name>ietf-yang-library</name>"
141 "<revision>2016-02-01</revision>"
142 "<namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>"
143 "<conformance-type>implement</conformance-type>"
144 "</module>"
145 "</modules-state>"
146 ,
147 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
148 "<module>"
149 "<name>ietf-netconf-acm</name>"
150 "<revision>2012-02-22</revision>"
151 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>"
152 "<conformance-type>implement</conformance-type>"
153 "</module>"
154 "</modules-state>"
155 ,
156 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
157 "<module>"
158 "<name>ietf-netconf</name>"
159 "<revision>2011-06-01</revision>"
160 "<namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>"
161 "<feature>writable-running</feature>"
162 "<feature>candidate</feature>"
163 "<feature>rollback-on-error</feature>"
164 "<feature>validate</feature>"
165 "<feature>startup</feature>"
166 "<feature>xpath</feature>"
167 "<conformance-type>implement</conformance-type>"
168 "</module>"
169 "</modules-state>"
170 ,
171 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
172 "<module>"
173 "<name>ietf-netconf-monitoring</name>"
174 "<revision>2010-10-04</revision>"
175 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</namespace>"
176 "<conformance-type>implement</conformance-type>"
177 "</module>"
178 "</modules-state>"
179 ,
180 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
181 "<module>"
182 "<name>ietf-netconf-with-defaults</name>"
183 "<revision>2011-06-01</revision>"
184 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults</namespace>"
185 "<conformance-type>implement</conformance-type>"
186 "</module>"
187 "</modules-state>"
188 };
189 const char *output_template =
190 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
191 "<module>"
192 "<name>yang</name>"
193 "<revision>2016-02-11</revision>"
Michal Vasko4490d312020-06-16 13:08:55 +0200194 "<namespace>urn:ietf:params:xml:ns:yang:1</namespace>"
Michal Vaskob104f112020-07-17 09:54:54 +0200195 "<conformance-type>implement</conformance-type>"
Michal Vasko4490d312020-06-16 13:08:55 +0200196 "</module>"
197 "<module>"
198 "<name>ietf-yang-library</name>"
199 "<revision>2016-02-01</revision>"
Michal Vasko4490d312020-06-16 13:08:55 +0200200 "<namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>"
Michal Vaskob104f112020-07-17 09:54:54 +0200201 "<conformance-type>implement</conformance-type>"
Michal Vasko4490d312020-06-16 13:08:55 +0200202 "</module>"
203 "<module>"
204 "<name>ietf-netconf-acm</name>"
205 "<revision>2012-02-22</revision>"
Michal Vasko4490d312020-06-16 13:08:55 +0200206 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>"
Michal Vaskob104f112020-07-17 09:54:54 +0200207 "<conformance-type>implement</conformance-type>"
Michal Vasko4490d312020-06-16 13:08:55 +0200208 "</module>"
209 "<module>"
210 "<name>ietf-netconf</name>"
211 "<revision>2011-06-01</revision>"
Michal Vasko4490d312020-06-16 13:08:55 +0200212 "<namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>"
213 "<feature>writable-running</feature>"
214 "<feature>candidate</feature>"
215 "<feature>rollback-on-error</feature>"
216 "<feature>validate</feature>"
217 "<feature>startup</feature>"
218 "<feature>xpath</feature>"
Michal Vaskob104f112020-07-17 09:54:54 +0200219 "<conformance-type>implement</conformance-type>"
Michal Vasko4490d312020-06-16 13:08:55 +0200220 "</module>"
221 "<module>"
222 "<name>ietf-netconf-monitoring</name>"
223 "<revision>2010-10-04</revision>"
Michal Vasko4490d312020-06-16 13:08:55 +0200224 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</namespace>"
Michal Vaskob104f112020-07-17 09:54:54 +0200225 "<conformance-type>implement</conformance-type>"
Michal Vasko4490d312020-06-16 13:08:55 +0200226 "</module>"
227 "<module>"
228 "<name>ietf-netconf-with-defaults</name>"
229 "<revision>2011-06-01</revision>"
Michal Vasko4490d312020-06-16 13:08:55 +0200230 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults</namespace>"
Michal Vaskob104f112020-07-17 09:54:54 +0200231 "<conformance-type>implement</conformance-type>"
Michal Vasko4490d312020-06-16 13:08:55 +0200232 "</module>"
233 "</modules-state>";
Radek Krejci7931b192020-06-25 17:05:03 +0200234 struct ly_in *in = NULL;
Michal Vasko4490d312020-06-16 13:08:55 +0200235
Radek Krejci7931b192020-06-25 17:05:03 +0200236 assert_int_equal(LY_SUCCESS, ly_in_new_memory(start, &in));
237 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 +0200238 assert_non_null(st->target);
239
240 for (i = 0; i < 11; ++i) {
Radek Krejci7931b192020-06-25 17:05:03 +0200241 ly_in_memory(in, data[i]);
242 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 +0200243 assert_non_null(st->source);
244
Michal Vasko3a41dff2020-07-15 14:30:28 +0200245 assert_int_equal(LY_SUCCESS, lyd_merge_siblings(&st->target, st->source, LYD_MERGE_DESTRUCT));
Michal Vasko4490d312020-06-16 13:08:55 +0200246 st->source = NULL;
247 }
248
249 lyd_print_mem(&str, st->target, LYD_XML, 0);
250 assert_string_equal(str, output_template);
Radek Krejci7931b192020-06-25 17:05:03 +0200251
252 ly_in_free(in, 0);
Michal Vasko4490d312020-06-16 13:08:55 +0200253 free(str);
254}
255
256static void
257test_leaf(void **state)
258{
259 struct state *st = (*state);
260 const char *sch = "module x {"
261 " namespace urn:x;"
262 " prefix x;"
263 " container A {"
264 " leaf f1 {type string;}"
265 " container B {"
266 " leaf f2 {type string;}"
267 " }"
268 " }"
269 " }";
270 const char *trg = "<A xmlns=\"urn:x\"> <f1>block</f1> </A>";
271 const char *src = "<A xmlns=\"urn:x\"> <f1>aa</f1> <B> <f2>bb</f2> </B> </A>";
272 const char *result = "<A xmlns=\"urn:x\"><f1>aa</f1><B><f2>bb</f2></B></A>";
273 char *printed = NULL;
274
Michal Vasko3a41dff2020-07-15 14:30:28 +0200275 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200276
Radek Krejci7931b192020-06-25 17:05:03 +0200277 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 +0200278 assert_non_null(st->source);
279
Radek Krejci7931b192020-06-25 17:05:03 +0200280 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 +0200281 assert_non_null(st->target);
282
283 /* merge them */
Michal Vasko3a41dff2020-07-15 14:30:28 +0200284 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
285 assert_int_equal(lyd_validate_all(&st->target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200286
287 /* check the result */
Radek Krejci7931b192020-06-25 17:05:03 +0200288 lyd_print_mem(&printed, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vasko4490d312020-06-16 13:08:55 +0200289 assert_string_equal(printed, result);
290 free(printed);
291}
292
293static void
294test_container(void **state)
295{
296 struct state *st = (*state);
297 const char *sch =
298 "module A {"
299 "namespace \"aa:A\";"
300 "prefix A;"
301 "container A {"
302 "leaf f1 {type string;}"
303 "container B {"
304 "leaf f2 {type string;}"
305 "}"
306 "container C {"
307 "leaf f3 {type string;}"
308 "}"
309 "}"
310 "}";
311
312 const char *trg = "<A xmlns=\"aa:A\"> <B> <f2>aaa</f2> </B> </A>";
313 const char *src = "<A xmlns=\"aa:A\"> <C> <f3>bbb</f3> </C> </A>";
314 const char *result = "<A xmlns=\"aa:A\"><B><f2>aaa</f2></B><C><f3>bbb</f3></C></A>";
315 char *printed = NULL;
316
Michal Vasko3a41dff2020-07-15 14:30:28 +0200317 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200318
Radek Krejci7931b192020-06-25 17:05:03 +0200319 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 +0200320 assert_non_null(st->source);
321
Radek Krejci7931b192020-06-25 17:05:03 +0200322 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 +0200323 assert_non_null(st->target);
324
325 /* merge them */
Michal Vasko3a41dff2020-07-15 14:30:28 +0200326 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
327 assert_int_equal(lyd_validate_all(&st->target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200328
329 /* check the result */
Radek Krejci7931b192020-06-25 17:05:03 +0200330 lyd_print_mem(&printed, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vasko4490d312020-06-16 13:08:55 +0200331 assert_string_equal(printed, result);
332 free(printed);
333}
334
335static void
336test_list(void **state)
337{
338 struct state *st = (*state);
339 const char *sch =
340 "module merge {"
341 "namespace \"http://test/merge\";"
342 "prefix merge;"
343
344 "container inner1 {"
345 "list b-list1 {"
346 "key p1;"
347 "leaf p1 {"
348 "type uint8;"
349 "}"
350 "leaf p2 {"
351 "type string;"
352 "}"
353 "leaf p3 {"
354 "type boolean;"
355 "default false;"
356 "}"
357 "}"
358 "}"
359 "}";
360
361
362 const char *trg =
363 "<inner1 xmlns=\"http://test/merge\">"
364 "<b-list1>"
365 "<p1>1</p1>"
366 "<p2>a</p2>"
367 "<p3>true</p3>"
368 "</b-list1>"
369 "</inner1>";
370 const char *src =
371 "<inner1 xmlns=\"http://test/merge\">"
372 "<b-list1>"
373 "<p1>1</p1>"
374 "<p2>b</p2>"
375 "</b-list1>"
376 "</inner1>";
377 const char *result =
378 "<inner1 xmlns=\"http://test/merge\">"
379 "<b-list1>"
380 "<p1>1</p1>"
381 "<p2>b</p2>"
382 "<p3>true</p3>"
383 "</b-list1>"
384 "</inner1>";
385 char *printed = NULL;
386
Michal Vasko3a41dff2020-07-15 14:30:28 +0200387 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200388
Radek Krejci7931b192020-06-25 17:05:03 +0200389 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 +0200390 assert_non_null(st->source);
391
Radek Krejci7931b192020-06-25 17:05:03 +0200392 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 +0200393 assert_non_null(st->target);
394
395 /* merge them */
Michal Vasko3a41dff2020-07-15 14:30:28 +0200396 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
397 assert_int_equal(lyd_validate_all(&st->target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200398
399 /* check the result */
Radek Krejci7931b192020-06-25 17:05:03 +0200400 lyd_print_mem(&printed, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vasko4490d312020-06-16 13:08:55 +0200401 assert_string_equal(printed, result);
402 free(printed);
403}
404
405static void
406test_list2(void **state)
407{
408 struct state *st = (*state);
409 const char *sch =
410 "module merge {"
411 "namespace \"http://test/merge\";"
412 "prefix merge;"
413
414 "container inner1 {"
415 "list b-list1 {"
416 "key p1;"
417 "leaf p1 {"
418 "type uint8;"
419 "}"
420 "leaf p2 {"
421 "type string;"
422 "}"
423 "container inner2 {"
424 "leaf p3 {"
425 "type boolean;"
426 "default false;"
427 "}"
428 "leaf p4 {"
429 "type string;"
430 "}"
431 "}"
432 "}"
433 "}"
434 "}";
435
436
437 const char *trg =
438 "<inner1 xmlns=\"http://test/merge\">"
439 "<b-list1>"
440 "<p1>1</p1>"
441 "<p2>a</p2>"
442 "<inner2>"
443 "<p4>val</p4>"
444 "</inner2>"
445 "</b-list1>"
446 "</inner1>";
447 const char *src =
448 "<inner1 xmlns=\"http://test/merge\">"
449 "<b-list1>"
450 "<p1>1</p1>"
451 "<p2>b</p2>"
452 "</b-list1>"
453 "</inner1>";
454 const char *result =
455 "<inner1 xmlns=\"http://test/merge\">"
456 "<b-list1>"
457 "<p1>1</p1>"
458 "<p2>b</p2>"
459 "<inner2>"
460 "<p4>val</p4>"
461 "</inner2>"
462 "</b-list1>"
463 "</inner1>";
464 char *printed = NULL;
465
Michal Vasko3a41dff2020-07-15 14:30:28 +0200466 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200467
Radek Krejci7931b192020-06-25 17:05:03 +0200468 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 +0200469 assert_non_null(st->source);
470
Radek Krejci7931b192020-06-25 17:05:03 +0200471 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 +0200472 assert_non_null(st->target);
473
474 /* merge them */
Michal Vasko3a41dff2020-07-15 14:30:28 +0200475 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
476 assert_int_equal(lyd_validate_all(&st->target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200477
478 /* check the result */
Radek Krejci7931b192020-06-25 17:05:03 +0200479 lyd_print_mem(&printed, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vasko4490d312020-06-16 13:08:55 +0200480 assert_string_equal(printed, result);
481 free(printed);
482}
483
484static void
485test_case(void **state)
486{
487 struct state *st = (*state);
488 const char *sch =
489 "module merge {"
490 "namespace \"http://test/merge\";"
491 "prefix merge;"
492 "container cont {"
493 "choice ch {"
494 "container inner {"
495 "leaf p1 {"
496 "type string;"
497 "}"
498 "}"
499 "case c2 {"
500 "leaf p1 {"
501 "type string;"
502 "}"
503 "}"
504 "}"
505 "}"
506 "}";
507
508 const char *trg =
509 "<cont xmlns=\"http://test/merge\">"
510 "<inner>"
511 "<p1>1</p1>"
512 "</inner>"
513 "</cont>";
514 const char *src =
515 "<cont xmlns=\"http://test/merge\">"
516 "<p1>1</p1>"
517 "</cont>";
518 const char *result =
519 "<cont xmlns=\"http://test/merge\">"
520 "<p1>1</p1>"
521 "</cont>";
522 char *printed = NULL;
523
Michal Vasko3a41dff2020-07-15 14:30:28 +0200524 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200525
Radek Krejci7931b192020-06-25 17:05:03 +0200526 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 +0200527 assert_non_null(st->source);
528
Radek Krejci7931b192020-06-25 17:05:03 +0200529 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 +0200530 assert_non_null(st->target);
531
532 /* merge them */
Michal Vasko3a41dff2020-07-15 14:30:28 +0200533 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
534 assert_int_equal(lyd_validate_all(&st->target, NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200535
536 /* check the result */
Radek Krejci7931b192020-06-25 17:05:03 +0200537 lyd_print_mem(&printed, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vasko4490d312020-06-16 13:08:55 +0200538 assert_string_equal(printed, result);
539 free(printed);
540}
541
542static void
543test_dflt(void **state)
544{
545 struct state *st = (*state);
Michal Vasko4490d312020-06-16 13:08:55 +0200546 const char *sch =
547 "module merge-dflt {"
548 "namespace \"urn:merge-dflt\";"
549 "prefix md;"
550 "container top {"
551 "leaf a {"
552 "type string;"
553 "}"
554 "leaf b {"
555 "type string;"
556 "}"
557 "leaf c {"
558 "type string;"
559 "default \"c_dflt\";"
560 "}"
561 "}"
562 "}";
563
Michal Vasko3a41dff2020-07-15 14:30:28 +0200564 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200565
Michal Vasko3a41dff2020-07-15 14:30:28 +0200566 assert_int_equal(lyd_new_path(NULL, st->ctx, "/merge-dflt:top/c", "c_dflt", 0, &st->target), LY_SUCCESS);
567 assert_int_equal(lyd_validate_all(&(st->target), NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200568
Michal Vasko3a41dff2020-07-15 14:30:28 +0200569 assert_int_equal(lyd_new_path(NULL, st->ctx, "/merge-dflt:top/a", "a_val", 0, &st->source), LY_SUCCESS);
570 assert_int_equal(lyd_new_path(st->source, st->ctx, "/merge-dflt:top/b", "b_val", 0, NULL), LY_SUCCESS);
571 assert_int_equal(lyd_validate_all(&(st->source), NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200572
Michal Vasko3a41dff2020-07-15 14:30:28 +0200573 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 +0200574 st->source = NULL;
575
576 /* c should be replaced and now be default */
Michal Vaskob104f112020-07-17 09:54:54 +0200577 assert_string_equal(lyd_node_children(st->target, 0)->prev->schema->name, "c");
578 assert_true(lyd_node_children(st->target, 0)->prev->flags & LYD_DEFAULT);
Michal Vasko4490d312020-06-16 13:08:55 +0200579}
580
581static void
582test_dflt2(void **state)
583{
584 struct state *st = (*state);
Michal Vasko4490d312020-06-16 13:08:55 +0200585 const char *sch =
586 "module merge-dflt {"
587 "namespace \"urn:merge-dflt\";"
588 "prefix md;"
589 "container top {"
590 "leaf a {"
591 "type string;"
592 "}"
593 "leaf b {"
594 "type string;"
595 "}"
596 "leaf c {"
597 "type string;"
598 "default \"c_dflt\";"
599 "}"
600 "}"
601 "}";
602
Michal Vasko3a41dff2020-07-15 14:30:28 +0200603 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200604
Michal Vasko3a41dff2020-07-15 14:30:28 +0200605 assert_int_equal(lyd_new_path(NULL, st->ctx, "/merge-dflt:top/c", "c_dflt", 0, &st->target), LY_SUCCESS);
606 assert_int_equal(lyd_validate_all(&(st->target), NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200607
Michal Vasko3a41dff2020-07-15 14:30:28 +0200608 assert_int_equal(lyd_new_path(NULL, st->ctx, "/merge-dflt:top/a", "a_val", 0, &st->source), LY_SUCCESS);
609 assert_int_equal(lyd_new_path(st->source, st->ctx, "/merge-dflt:top/b", "b_val", 0, NULL), LY_SUCCESS);
610 assert_int_equal(lyd_validate_all(&(st->source), NULL, LYD_VALIDATE_PRESENT, NULL), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200611
Michal Vasko3a41dff2020-07-15 14:30:28 +0200612 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200613
614 /* c should not be replaced, so c remains not default */
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200615 assert_false(lyd_node_children(st->target, 0)->flags & LYD_DEFAULT);
Michal Vasko4490d312020-06-16 13:08:55 +0200616}
617
618static void
619test_leafrefs(void **state)
620{
621 struct state *st = (*state);
622 const char *sch = "module x {"
623 " namespace urn:x;"
624 " prefix x;"
625 " list l {"
626 " key n;"
627 " leaf n { type string; }"
628 " leaf t { type string; }"
629 " leaf r { type leafref { path '/l/n'; } }}}";
630 const char *trg = "<l xmlns=\"urn:x\"><n>a</n></l>"
631 "<l xmlns=\"urn:x\"><n>b</n><r>a</r></l>";
632 const char *src = "<l xmlns=\"urn:x\"><n>c</n><r>a</r></l>"
633 "<l xmlns=\"urn:x\"><n>a</n><t>*</t></l>";
634 const char *res = "<l xmlns=\"urn:x\"><n>a</n><t>*</t></l>"
635 "<l xmlns=\"urn:x\"><n>b</n><r>a</r></l>"
636 "<l xmlns=\"urn:x\"><n>c</n><r>a</r></l>";
637 char *prt = NULL;
638
Michal Vasko3a41dff2020-07-15 14:30:28 +0200639 assert_int_equal(LY_SUCCESS, lys_parse_mem(st->ctx, sch, LYS_IN_YANG, NULL));
Michal Vasko4490d312020-06-16 13:08:55 +0200640
Radek Krejci7931b192020-06-25 17:05:03 +0200641 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 +0200642 assert_non_null(st->source);
643
Radek Krejci7931b192020-06-25 17:05:03 +0200644 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, trg, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->target));
645 assert_non_null(st->target);
646
Michal Vasko3a41dff2020-07-15 14:30:28 +0200647 assert_int_equal(lyd_merge_siblings(&st->target, st->source, 0), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200648
Radek Krejci7931b192020-06-25 17:05:03 +0200649 lyd_print_mem(&prt, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vasko4490d312020-06-16 13:08:55 +0200650 assert_string_equal(prt, res);
651 free(prt);
652}
653
654int
655main(void)
656{
657 const struct CMUnitTest tests[] = {
658 cmocka_unit_test_setup_teardown(test_batch, setup_dflt, teardown_dflt),
659 cmocka_unit_test_setup_teardown(test_leaf, setup_dflt, teardown_dflt),
660 cmocka_unit_test_setup_teardown(test_container, setup_dflt, teardown_dflt),
661 cmocka_unit_test_setup_teardown(test_list, setup_dflt, teardown_dflt),
662 cmocka_unit_test_setup_teardown(test_list2, setup_dflt, teardown_dflt),
663 cmocka_unit_test_setup_teardown(test_case, setup_dflt, teardown_dflt),
664 cmocka_unit_test_setup_teardown(test_dflt, setup_dflt, teardown_dflt),
665 cmocka_unit_test_setup_teardown(test_dflt2, setup_dflt, teardown_dflt),
666 cmocka_unit_test_setup_teardown(test_leafrefs, setup_dflt, teardown_dflt),
667 };
668
669 return cmocka_run_group_tests(tests, NULL, NULL);
670}