blob: 0c77cea93a685019bfb9facd8954977d0240b9e5 [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>"
194 "<conformance-type>implement</conformance-type>"
195 "<namespace>urn:ietf:params:xml:ns:yang:1</namespace>"
196 "</module>"
197 "<module>"
198 "<name>ietf-yang-library</name>"
199 "<revision>2016-02-01</revision>"
200 "<conformance-type>implement</conformance-type>"
201 "<namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>"
202 "</module>"
203 "<module>"
204 "<name>ietf-netconf-acm</name>"
205 "<revision>2012-02-22</revision>"
206 "<conformance-type>implement</conformance-type>"
207 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>"
208 "</module>"
209 "<module>"
210 "<name>ietf-netconf</name>"
211 "<revision>2011-06-01</revision>"
212 "<conformance-type>implement</conformance-type>"
213 "<namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>"
214 "<feature>writable-running</feature>"
215 "<feature>candidate</feature>"
216 "<feature>rollback-on-error</feature>"
217 "<feature>validate</feature>"
218 "<feature>startup</feature>"
219 "<feature>xpath</feature>"
220 "</module>"
221 "<module>"
222 "<name>ietf-netconf-monitoring</name>"
223 "<revision>2010-10-04</revision>"
224 "<conformance-type>implement</conformance-type>"
225 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</namespace>"
226 "</module>"
227 "<module>"
228 "<name>ietf-netconf-with-defaults</name>"
229 "<revision>2011-06-01</revision>"
230 "<conformance-type>implement</conformance-type>"
231 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults</namespace>"
232 "</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
Radek Krejci7931b192020-06-25 17:05:03 +0200245 assert_int_equal(LY_SUCCESS, lyd_merge(&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
275 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
276
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 */
284 assert_int_equal(lyd_merge(&st->target, st->source, 0), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200285 assert_int_equal(lyd_validate(&st->target, NULL, LYD_VALIDATE_PRESENT), 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
317 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
318
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 */
326 assert_int_equal(lyd_merge(&st->target, st->source, 0), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200327 assert_int_equal(lyd_validate(&st->target, NULL, LYD_VALIDATE_PRESENT), 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
387 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
388
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 */
396 assert_int_equal(lyd_merge(&st->target, st->source, LYD_MERGE_EXPLICIT), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200397 assert_int_equal(lyd_validate(&st->target, NULL, LYD_VALIDATE_PRESENT), 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
466 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
467
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 */
475 assert_int_equal(lyd_merge(&st->target, st->source, LYD_MERGE_EXPLICIT), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200476 assert_int_equal(lyd_validate(&st->target, NULL, LYD_VALIDATE_PRESENT), 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
524 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
525
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 */
533 assert_int_equal(lyd_merge(&st->target, st->source, 0), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200534 assert_int_equal(lyd_validate(&st->target, NULL, LYD_VALIDATE_PRESENT), 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);
546 struct lyd_node *tmp;
547 const char *sch =
548 "module merge-dflt {"
549 "namespace \"urn:merge-dflt\";"
550 "prefix md;"
551 "container top {"
552 "leaf a {"
553 "type string;"
554 "}"
555 "leaf b {"
556 "type string;"
557 "}"
558 "leaf c {"
559 "type string;"
560 "default \"c_dflt\";"
561 "}"
562 "}"
563 "}";
564
565 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
566
567 st->target = lyd_new_path(NULL, st->ctx, "/merge-dflt:top/c", "c_dflt", 0);
568 assert_non_null(st->target);
Radek Krejci7931b192020-06-25 17:05:03 +0200569 assert_int_equal(lyd_validate(&(st->target), NULL, LYD_VALIDATE_PRESENT), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200570
571 st->source = lyd_new_path(NULL, st->ctx, "/merge-dflt:top/a", "a_val", 0);
572 assert_non_null(st->source);
573 tmp = lyd_new_path(st->source, st->ctx, "/merge-dflt:top/b", "b_val", 0);
574 assert_non_null(tmp);
Radek Krejci7931b192020-06-25 17:05:03 +0200575 assert_int_equal(lyd_validate(&(st->source), NULL, LYD_VALIDATE_PRESENT), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200576
577 assert_int_equal(lyd_merge(&st->target, st->source, LYD_MERGE_DESTRUCT), LY_SUCCESS);
578 st->source = NULL;
579
580 /* c should be replaced and now be default */
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200581 assert_true(lyd_node_children(st->target, 0)->flags & LYD_DEFAULT);
Michal Vasko4490d312020-06-16 13:08:55 +0200582}
583
584static void
585test_dflt2(void **state)
586{
587 struct state *st = (*state);
588 struct lyd_node *tmp;
589 const char *sch =
590 "module merge-dflt {"
591 "namespace \"urn:merge-dflt\";"
592 "prefix md;"
593 "container top {"
594 "leaf a {"
595 "type string;"
596 "}"
597 "leaf b {"
598 "type string;"
599 "}"
600 "leaf c {"
601 "type string;"
602 "default \"c_dflt\";"
603 "}"
604 "}"
605 "}";
606
607 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
608
609 st->target = lyd_new_path(NULL, st->ctx, "/merge-dflt:top/c", "c_dflt", 0);
610 assert_non_null(st->target);
Radek Krejci7931b192020-06-25 17:05:03 +0200611 assert_int_equal(lyd_validate(&(st->target), NULL, LYD_VALIDATE_PRESENT), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200612
613 st->source = lyd_new_path(NULL, st->ctx, "/merge-dflt:top/a", "a_val", 0);
614 assert_non_null(st->source);
615 tmp = lyd_new_path(st->source, st->ctx, "/merge-dflt:top/b", "b_val", 0);
616 assert_non_null(tmp);
Radek Krejci7931b192020-06-25 17:05:03 +0200617 assert_int_equal(lyd_validate(&(st->source), NULL, LYD_VALIDATE_PRESENT), LY_SUCCESS);
Michal Vasko4490d312020-06-16 13:08:55 +0200618
619 assert_int_equal(lyd_merge(&st->target, st->source, LYD_MERGE_EXPLICIT), LY_SUCCESS);
620
621 /* c should not be replaced, so c remains not default */
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200622 assert_false(lyd_node_children(st->target, 0)->flags & LYD_DEFAULT);
Michal Vasko4490d312020-06-16 13:08:55 +0200623}
624
625static void
626test_leafrefs(void **state)
627{
628 struct state *st = (*state);
629 const char *sch = "module x {"
630 " namespace urn:x;"
631 " prefix x;"
632 " list l {"
633 " key n;"
634 " leaf n { type string; }"
635 " leaf t { type string; }"
636 " leaf r { type leafref { path '/l/n'; } }}}";
637 const char *trg = "<l xmlns=\"urn:x\"><n>a</n></l>"
638 "<l xmlns=\"urn:x\"><n>b</n><r>a</r></l>";
639 const char *src = "<l xmlns=\"urn:x\"><n>c</n><r>a</r></l>"
640 "<l xmlns=\"urn:x\"><n>a</n><t>*</t></l>";
641 const char *res = "<l xmlns=\"urn:x\"><n>a</n><t>*</t></l>"
642 "<l xmlns=\"urn:x\"><n>b</n><r>a</r></l>"
643 "<l xmlns=\"urn:x\"><n>c</n><r>a</r></l>";
644 char *prt = NULL;
645
646 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
647
Radek Krejci7931b192020-06-25 17:05:03 +0200648 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 +0200649 assert_non_null(st->source);
650
Radek Krejci7931b192020-06-25 17:05:03 +0200651 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, trg, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->target));
652 assert_non_null(st->target);
653
Michal Vasko4490d312020-06-16 13:08:55 +0200654 assert_int_equal(lyd_merge(&st->target, st->source, LYD_MERGE_DESTRUCT), LY_SUCCESS);
655 st->source = NULL;
656
Radek Krejci7931b192020-06-25 17:05:03 +0200657 lyd_print_mem(&prt, st->target, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vasko4490d312020-06-16 13:08:55 +0200658 assert_string_equal(prt, res);
659 free(prt);
660}
661
662int
663main(void)
664{
665 const struct CMUnitTest tests[] = {
666 cmocka_unit_test_setup_teardown(test_batch, setup_dflt, teardown_dflt),
667 cmocka_unit_test_setup_teardown(test_leaf, setup_dflt, teardown_dflt),
668 cmocka_unit_test_setup_teardown(test_container, setup_dflt, teardown_dflt),
669 cmocka_unit_test_setup_teardown(test_list, setup_dflt, teardown_dflt),
670 cmocka_unit_test_setup_teardown(test_list2, setup_dflt, teardown_dflt),
671 cmocka_unit_test_setup_teardown(test_case, setup_dflt, teardown_dflt),
672 cmocka_unit_test_setup_teardown(test_dflt, setup_dflt, teardown_dflt),
673 cmocka_unit_test_setup_teardown(test_dflt2, setup_dflt, teardown_dflt),
674 cmocka_unit_test_setup_teardown(test_leafrefs, setup_dflt, teardown_dflt),
675 };
676
677 return cmocka_run_group_tests(tests, NULL, NULL);
678}