blob: 6964764db6d69eca8e9bdedd7692024132767095 [file] [log] [blame]
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001/**
2 * @file test_diff.c
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @author Michal Vasko <mvasko@cesnet.cz>
5 * @brief tests for lyd_diff()
6 *
7 * Copyright (c) 2020 CESNET, z.s.p.o.
8 *
9 * This source code is licensed under BSD 3-Clause License (the "License").
10 * You may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * https://opensource.org/licenses/BSD-3-Clause
14 */
Radek Iša56ca9e42020-09-08 18:42:00 +020015#define _UTEST_MAIN_
Radek Krejcib4ac5a92020-11-23 17:54:33 +010016#include "utests.h"
Michal Vaskoe893ddd2020-06-23 13:35:20 +020017
Radek Iša56ca9e42020-09-08 18:42:00 +020018#include "libyang.h"
19
20#define CHECK_PARSE_LYD(INPUT, MODEL) \
21 CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, MODEL)
22
23#define CHECK_LYD_STRING(IN_MODEL, TEXT) \
24 CHECK_LYD_STRING_PARAM(IN_MODEL, TEXT, LYD_XML, LYD_PRINT_WITHSIBLINGS)
25
26#define CHECK_PARSE_LYD_DIFF(INPUT_1, INPUT_2, OUT_MODEL) \
27 assert_int_equal(LY_SUCCESS, lyd_diff_siblings(INPUT_1, INPUT_2, 0, &OUT_MODEL));\
28 assert_non_null(OUT_MODEL)
29
30#define TEST_DIFF_3(XML_1, XML_2, XML_3, DIFF_1, DIFF_2, MERGE) \
31 { \
32 /*decladation*/\
33 struct lyd_node *model_1;\
34 struct lyd_node *model_2;\
35 struct lyd_node *model_3;\
36 /*create*/\
37 CHECK_PARSE_LYD(XML_1, model_1);\
38 CHECK_PARSE_LYD(XML_2, model_2);\
39 CHECK_PARSE_LYD(XML_3, model_3);\
40 /* diff1 */ \
41 struct lyd_node * diff1;\
42 CHECK_PARSE_LYD_DIFF(model_1, model_2, diff1); \
43 CHECK_LYD_STRING(diff1, DIFF_1); \
44 assert_int_equal(lyd_diff_apply_all(&model_1, diff1), LY_SUCCESS); \
45 CHECK_LYD(model_1, model_2); \
46 /* diff2 */ \
47 struct lyd_node * diff2;\
48 CHECK_PARSE_LYD_DIFF(model_2, model_3, diff2); \
49 CHECK_LYD_STRING(diff2, DIFF_2); \
50 assert_int_equal(lyd_diff_apply_all(&model_2, diff2), LY_SUCCESS);\
51 CHECK_LYD(model_2, model_3);\
52 /* merge */ \
53 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);\
54 CHECK_LYD_STRING(diff1, MERGE); \
55 /* CREAR ENV */ \
56 lyd_free_all(model_1);\
57 lyd_free_all(model_2);\
58 lyd_free_all(model_3);\
59 lyd_free_all(diff1);\
60 lyd_free_all(diff2);\
61 }
62
63const char *schema =
64 "module defaults {\n"
65 " yang-version 1.1;\n"
66 " namespace \"urn:libyang:tests:defaults\";\n"
67 " prefix df;\n"
68 "\n"
69 " feature unhide;\n"
70 "\n"
71 " typedef defint32 {\n"
72 " type int32;\n"
73 " default \"42\";\n"
74 " }\n"
75 "\n"
76 " leaf hiddenleaf {\n"
77 " if-feature \"unhide\";\n"
78 " type int32;\n"
79 " default \"42\";\n"
80 " }\n"
81 "\n"
82 " container df {\n"
83 " leaf foo {\n"
84 " type defint32;\n"
85 " }\n"
86 "\n"
87 " leaf hiddenleaf {\n"
88 " if-feature \"unhide\";\n"
89 " type int32;\n"
90 " default \"42\";\n"
91 " }\n"
92 "\n"
93 " container bar {\n"
94 " presence \"\";\n"
95 " leaf hi {\n"
96 " type int32;\n"
97 " default \"42\";\n"
98 " }\n"
99 "\n"
100 " leaf ho {\n"
101 " type int32;\n"
102 " mandatory true;\n"
103 " }\n"
104 " }\n"
105 "\n"
106 " leaf-list llist {\n"
107 " type defint32;\n"
108 " ordered-by user;\n"
109 " }\n"
110 "\n"
111 " leaf-list dllist {\n"
112 " type uint8;\n"
113 " default \"1\";\n"
114 " default \"2\";\n"
115 " default \"3\";\n"
116 " }\n"
117 "\n"
118 " list list {\n"
119 " key \"name\";\n"
120 " leaf name {\n"
121 " type string;\n"
122 " }\n"
123 "\n"
124 " leaf value {\n"
125 " type int32;\n"
126 " default \"42\";\n"
127 " }\n"
128 " }\n"
129 "\n"
130 " choice select {\n"
131 " default \"a\";\n"
132 " case a {\n"
133 " choice a {\n"
134 " leaf a1 {\n"
135 " type int32;\n"
136 " default \"42\";\n"
137 " }\n"
138 "\n"
139 " leaf a2 {\n"
140 " type int32;\n"
141 " default \"24\";\n"
142 " }\n"
143 " }\n"
144 " }\n"
145 "\n"
146 " leaf b {\n"
147 " type string;\n"
148 " }\n"
149 "\n"
150 " container c {\n"
151 " presence \"\";\n"
152 " leaf x {\n"
153 " type int32;\n"
154 " default \"42\";\n"
155 " }\n"
156 " }\n"
157 " }\n"
158 "\n"
159 " choice select2 {\n"
160 " default \"s2b\";\n"
161 " leaf s2a {\n"
162 " type int32;\n"
163 " default \"42\";\n"
164 " }\n"
165 "\n"
166 " case s2b {\n"
167 " choice s2b {\n"
168 " default \"b1\";\n"
169 " case b1 {\n"
170 " leaf b1_1 {\n"
171 " type int32;\n"
172 " default \"42\";\n"
173 " }\n"
174 "\n"
175 " leaf b1_2 {\n"
176 " type string;\n"
177 " }\n"
178 "\n"
179 " leaf b1_status {\n"
180 " type int32;\n"
181 " default \"42\";\n"
182 " config false;\n"
183 " }\n"
184 " }\n"
185 "\n"
186 " leaf b2 {\n"
187 " type int32;\n"
188 " default \"42\";\n"
189 " }\n"
190 " }\n"
191 " }\n"
192 " }\n"
193 " }\n"
194 "\n"
195 " container hidden {\n"
196 " leaf foo {\n"
197 " type int32;\n"
198 " default \"42\";\n"
199 " }\n"
200 "\n"
201 " leaf baz {\n"
202 " type int32;\n"
203 " default \"42\";\n"
204 " }\n"
205 "\n"
206 " leaf papa {\n"
207 " type int32;\n"
208 " default \"42\";\n"
209 " config false;\n"
210 " }\n"
211 " }\n"
212 "\n"
213 " rpc rpc1 {\n"
214 " input {\n"
215 " leaf inleaf1 {\n"
216 " type string;\n"
217 " }\n"
218 "\n"
219 " leaf inleaf2 {\n"
220 " type string;\n"
221 " default \"def1\";\n"
222 " }\n"
223 " }\n"
224 "\n"
225 " output {\n"
226 " leaf outleaf1 {\n"
227 " type string;\n"
228 " default \"def2\";\n"
229 " }\n"
230 "\n"
231 " leaf outleaf2 {\n"
232 " type string;\n"
233 " }\n"
234 " }\n"
235 " }\n"
236 "\n"
237 " notification notif {\n"
238 " leaf ntfleaf1 {\n"
239 " type string;\n"
240 " default \"def3\";\n"
241 " }\n"
242 "\n"
243 " leaf ntfleaf2 {\n"
244 " type string;\n"
245 " }\n"
246 " }\n"
247 "}\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200248
249static int
Radek Iša56ca9e42020-09-08 18:42:00 +0200250setup(void **state)
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200251{
Radek Iša56ca9e42020-09-08 18:42:00 +0200252 UTEST_SETUP;
253 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200254
255 return 0;
256}
257
258static void
259test_invalid(void **state)
260{
Radek Iša56ca9e42020-09-08 18:42:00 +0200261 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200262 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
263
Radek Iša56ca9e42020-09-08 18:42:00 +0200264 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200265
Radek Iša56ca9e42020-09-08 18:42:00 +0200266 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200267
Radek Iša56ca9e42020-09-08 18:42:00 +0200268 struct lyd_node *diff = NULL;
269
270 assert_int_equal(lyd_diff_siblings(model_1, lyd_child(model_1), 0, &diff), LY_EINVAL);
Michal Vasko3a41dff2020-07-15 14:30:28 +0200271 assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, NULL), LY_EINVAL);
Radek Iša56ca9e42020-09-08 18:42:00 +0200272
273 lyd_free_all(model_1);
274 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200275}
276
277static void
278test_same(void **state)
279{
Radek Iša56ca9e42020-09-08 18:42:00 +0200280 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100281 const char *xml =
282 "<nacm xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-acm\">\n"
283 " <enable-nacm>true</enable-nacm>\n"
284 " <read-default>permit</read-default>\n"
285 " <write-default>deny</write-default>\n"
286 " <exec-default>permit</exec-default>\n"
287 " <enable-external-groups>true</enable-external-groups>\n"
288 "</nacm><df xmlns=\"urn:libyang:tests:defaults\">\n"
289 " <foo>42</foo><b1_1>42</b1_1>\n"
290 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">\n"
291 " <foo>42</foo><baz>42</baz></hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200292
Radek Iša56ca9e42020-09-08 18:42:00 +0200293 struct lyd_node *model_1;
294 struct lyd_node *model_2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200295
Radek Iša56ca9e42020-09-08 18:42:00 +0200296 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
297 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-acm", "2018-02-14", NULL));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200298
Radek Iša56ca9e42020-09-08 18:42:00 +0200299 CHECK_PARSE_LYD(xml, model_1);
300 CHECK_PARSE_LYD(xml, model_2);
301
302 struct lyd_node *diff = NULL;
303
304 assert_int_equal(lyd_diff_siblings(model_1, model_2, 0, &diff), LY_SUCCESS);
305 assert_null(diff);
306 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
307 CHECK_LYD(model_1, model_2);
308
309 lyd_free_all(model_1);
310 lyd_free_all(model_2);
311 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200312}
313
314static void
315test_empty1(void **state)
316{
Radek Iša56ca9e42020-09-08 18:42:00 +0200317 (void) state;
318 const char *xml_in =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100319 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
320 " <foo>42</foo>\n"
321 " <b1_1>42</b1_1>\n"
322 "</df>\n"
323 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
324 " <foo>42</foo>\n"
325 " <baz>42</baz>\n"
326 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200327
Radek Iša56ca9e42020-09-08 18:42:00 +0200328 struct lyd_node *model_1 = NULL;
329 struct lyd_node *model_2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200330
Radek Iša56ca9e42020-09-08 18:42:00 +0200331 CHECK_PARSE_LYD(xml_in, model_2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200332
Radek Iša56ca9e42020-09-08 18:42:00 +0200333 struct lyd_node *diff;
334
335 CHECK_PARSE_LYD_DIFF(model_1, model_2, diff);
336 CHECK_LYD_STRING(diff,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100337 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
338 " <foo>42</foo>\n"
339 " <b1_1>42</b1_1>\n"
340 "</df>\n"
341 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
342 " <foo>42</foo>\n"
343 " <baz>42</baz>\n"
344 "</hidden>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200345 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
346 CHECK_LYD(model_1, model_2);
347
348 lyd_free_all(model_1);
349 lyd_free_all(model_2);
350 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200351}
352
353static void
354test_empty2(void **state)
355{
Radek Iša56ca9e42020-09-08 18:42:00 +0200356 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100357 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
358 " <foo>42</foo>\n"
359 " <b1_1>42</b1_1>\n"
360 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">\n"
361 " <foo>42</foo>\n"
362 " <baz>42</baz>\n"
363 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200364
Radek Iša56ca9e42020-09-08 18:42:00 +0200365 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200366
Radek Iša56ca9e42020-09-08 18:42:00 +0200367 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200368
Radek Iša56ca9e42020-09-08 18:42:00 +0200369 struct lyd_node *diff;
370
371 CHECK_PARSE_LYD_DIFF(model_1, NULL, diff);
372 CHECK_LYD_STRING(diff,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100373 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
374 " <foo>42</foo>\n"
375 " <b1_1>42</b1_1>\n"
376 "</df>\n"
377 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
378 " <foo>42</foo>\n"
379 " <baz>42</baz>\n"
380 "</hidden>\n");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200381
Radek Iša56ca9e42020-09-08 18:42:00 +0200382 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
383 assert_ptr_equal(model_1, NULL);
384
385 lyd_free_all(diff);
386 lyd_free_all(model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200387}
388
389static void
390test_empty_nested(void **state)
391{
Radek Iša56ca9e42020-09-08 18:42:00 +0200392 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200393 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
394
Radek Iša56ca9e42020-09-08 18:42:00 +0200395 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200396
Radek Iša56ca9e42020-09-08 18:42:00 +0200397 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200398
Radek Iša56ca9e42020-09-08 18:42:00 +0200399 struct lyd_node *diff = NULL;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200400
Radek Iša56ca9e42020-09-08 18:42:00 +0200401 assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, &diff), LY_SUCCESS);
402 assert_null(diff);
403
404 struct lyd_node *diff1;
405
406 CHECK_PARSE_LYD_DIFF(NULL, lyd_child(model_1), diff1);
407 CHECK_LYD_STRING(diff1,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100408 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
409 " <foo yang:operation=\"create\">42</foo>\n"
410 "</df>\n");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200411
Radek Iša56ca9e42020-09-08 18:42:00 +0200412 struct lyd_node *diff2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200413
Radek Iša56ca9e42020-09-08 18:42:00 +0200414 CHECK_PARSE_LYD_DIFF(lyd_child(model_1), NULL, diff2);
415 CHECK_LYD_STRING(diff2,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100416 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
417 " <foo yang:operation=\"delete\">42</foo>\n"
418 "</df>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200419
420 lyd_free_all(model_1);
421 lyd_free_all(diff1);
422 lyd_free_all(diff2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200423}
424
425static void
426test_leaf(void **state)
427{
Radek Iša56ca9e42020-09-08 18:42:00 +0200428 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200429 const char *xml1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100430 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
431 " <foo>42</foo>\n"
432 "</df>\n"
433 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
434 " <foo>42</foo>\n"
435 " <baz>42</baz>\n"
436 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200437 const char *xml2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100438 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
439 " <foo>41</foo>\n"
440 " <b1_1>42</b1_1>\n"
441 "</df>\n";
Michal Vaskoe6323f62020-07-09 15:49:02 +0200442 const char *xml3 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100443 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
444 " <foo>40</foo>\n"
445 "</df>\n"
446 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
447 " <foo>40</foo>\n"
448 "</hidden>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200449 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100450 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
451 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"42\">41</foo>\n"
452 " <b1_1 yang:operation=\"create\">42</b1_1>\n"
453 "</df>\n"
454 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
455 " <foo>42</foo>\n"
456 " <baz>42</baz>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200457 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200458
Radek Iša56ca9e42020-09-08 18:42:00 +0200459 const char *out_diff_2 = "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100460 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"41\">40</foo>\n"
461 " <b1_1 yang:operation=\"delete\">42</b1_1>\n"
462 "</df>\n"
463 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
464 " <foo>40</foo>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200465 "</hidden>\n";
Michal Vaskoe6323f62020-07-09 15:49:02 +0200466
Radek Iša56ca9e42020-09-08 18:42:00 +0200467 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100468 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
469 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"42\">40</foo>\n"
470 "</df>\n"
471 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
472 " <foo yang:operation=\"replace\" yang:orig-value=\"42\" yang:orig-default=\"false\">40</foo>\n"
473 " <baz yang:operation=\"delete\">42</baz>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200474 "</hidden>\n";
475
476 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200477}
478
479static void
480test_list(void **state)
481{
Radek Iša56ca9e42020-09-08 18:42:00 +0200482 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100483 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
484 " <list>\n"
485 " <name>a</name>\n"
486 " <value>1</value>\n"
487 " </list>\n"
488 " <list>\n"
489 " <name>b</name>\n"
490 " <value>2</value>\n"
491 " </list>\n"
492 "</df>\n";
493 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
494 " <list>\n"
495 " <name>b</name>\n"
496 " <value>-2</value>\n"
497 " </list>\n"
498 " <list>\n"
499 " <name>c</name>\n"
500 " <value>3</value>\n"
501 " </list>\n"
502 "</df>\n";
503 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
504 " <list>\n"
505 " <name>b</name>\n"
506 " <value>-2</value>\n"
507 " </list>\n"
508 " <list>\n"
509 " <name>a</name>\n"
510 " <value>2</value>\n"
511 " </list>\n"
512 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200513
Radek Iša56ca9e42020-09-08 18:42:00 +0200514 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100515 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
516 " <list yang:operation=\"delete\">\n"
517 " <name>a</name>\n"
518 " <value>1</value>\n"
519 " </list>\n"
520 " <list yang:operation=\"none\">\n"
521 " <name>b</name>\n"
522 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\">-2</value>\n"
523 " </list>\n"
524 " <list yang:operation=\"create\">\n"
525 " <name>c</name>\n"
526 " <value>3</value>\n"
527 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200528 "</df>\n";
529 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100530 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
531 " <list yang:operation=\"delete\">\n"
532 " <name>c</name>\n"
533 " <value>3</value>\n"
534 " </list>\n"
535 " <list yang:operation=\"create\">\n"
536 " <name>a</name>\n"
537 " <value>2</value>\n"
538 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200539 "</df>\n";
540 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100541 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
542 " <list yang:operation=\"none\">\n"
543 " <name>a</name>\n"
544 " <value yang:operation=\"replace\" yang:orig-value=\"1\" yang:orig-default=\"false\">2</value>\n"
545 " </list>\n"
546 " <list yang:operation=\"none\">\n"
547 " <name>b</name>\n"
548 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\">-2</value>\n"
549 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200550 "</df>\n";
551
552 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200553}
554
555static void
556test_userord_llist(void **state)
557{
Radek Iša56ca9e42020-09-08 18:42:00 +0200558 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100559 const char *xml1 =
560 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
561 " <llist>1</llist>\n"
562 " <llist>2</llist>\n"
563 " <llist>3</llist>\n"
564 " <llist>4</llist>\n"
565 " <llist>5</llist>\n"
566 "</df>\n";
567 const char *xml2 =
568 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
569 " <llist>1</llist>\n"
570 " <llist>4</llist>\n"
571 " <llist>3</llist>\n"
572 " <llist>2</llist>\n"
573 " <llist>5</llist>\n"
574 "</df>\n";
575 const char *xml3 =
576 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
577 " <llist>5</llist>\n"
578 " <llist>4</llist>\n"
579 " <llist>3</llist>\n"
580 " <llist>2</llist>\n"
581 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200582
Radek Iša56ca9e42020-09-08 18:42:00 +0200583 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100584 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
585 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>\n"
586 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\" yang:value=\"4\">3</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200587 "</df>\n";
588 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100589 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
590 " <llist yang:operation=\"delete\" yang:orig-value=\"\">1</llist>\n"
591 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\" yang:value=\"\">5</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200592 "</df>\n";
593 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100594 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
595 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>\n"
596 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\" yang:value=\"4\">3</llist>\n"
597 " <llist yang:orig-value=\"\" yang:operation=\"delete\">1</llist>\n"
598 " <llist yang:orig-default=\"false\" yang:orig-value=\"2\" yang:value=\"\" yang:operation=\"replace\">5</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200599 "</df>\n";
600
601 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200602}
603
604static void
605test_userord_llist2(void **state)
606{
Radek Iša56ca9e42020-09-08 18:42:00 +0200607 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100608 const char *xml1 =
609 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
610 " <llist>1</llist>\n"
611 " <list><name>a</name><value>1</value></list>\n"
612 " <llist>2</llist>\n"
613 " <llist>3</llist>\n"
614 " <llist>4</llist>\n"
615 "</df>\n";
616 const char *xml2 =
617 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
618 " <llist>1</llist>\n"
619 " <list><name>a</name><value>1</value></list>\n"
620 " <llist>2</llist>\n"
621 " <llist>4</llist>\n"
622 " <llist>3</llist>\n"
623 "</df>\n";
624 const char *xml3 =
625 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
626 " <llist>4</llist>\n"
627 " <llist>1</llist>\n"
628 " <list><name>a</name><value>1</value></list>\n"
629 " <llist>3</llist>\n"
630 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200631
Radek Iša56ca9e42020-09-08 18:42:00 +0200632 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100633 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
634 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"2\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200635 "</df>\n";
636 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100637 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
638 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
639 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\" yang:value=\"\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200640 "</df>\n";
641 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100642 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
643 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\">4</llist>\n"
644 " <llist yang:orig-value=\"1\" yang:operation=\"delete\">2</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200645 "</df>\n";
646
647 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200648}
649
650static void
651test_userord_mix(void **state)
652{
Radek Iša56ca9e42020-09-08 18:42:00 +0200653 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100654 const char *xml1 =
655 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
656 " <llist>1</llist>\n"
657 " <llist>2</llist>\n"
658 " <llist>3</llist>\n"
659 "</df>\n";
660 const char *xml2 =
661 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
662 " <llist>3</llist>\n"
663 " <llist>1</llist>\n"
664 "</df>\n";
665 const char *xml3 =
666 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
667 " <llist>1</llist>\n"
668 " <llist>4</llist>\n"
669 " <llist>3</llist>\n"
670 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200671
Radek Iša56ca9e42020-09-08 18:42:00 +0200672 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100673 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
674 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
675 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\" yang:value=\"\">3</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200676 "</df>\n";
677 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100678 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
679 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\">1</llist>\n"
680 " <llist yang:operation=\"create\" yang:value=\"1\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200681 "</df>\n";
682 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100683 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
684 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
685 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\" yang:value=\"\">3</llist>\n"
686 " <llist yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\" yang:operation=\"replace\">1</llist>\n"
687 " <llist yang:value=\"1\" yang:operation=\"create\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200688 "</df>\n";
689
690 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200691}
692
693static void
694test_wd(void **state)
695{
Radek Iša56ca9e42020-09-08 18:42:00 +0200696 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200697 const struct lys_module *mod;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100698 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
699 " <foo>41</foo>\n"
700 " <dllist>4</dllist>\n"
701 "</df>\n";
702 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
703 " <foo>42</foo>\n"
704 " <dllist>4</dllist>\n"
705 " <dllist>1</dllist>\n"
706 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200707
Radek Iša56ca9e42020-09-08 18:42:00 +0200708 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "defaults");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200709 assert_non_null(mod);
710
Radek Iša56ca9e42020-09-08 18:42:00 +0200711 struct lyd_node *model_1 = NULL;
712
713 assert_int_equal(lyd_validate_module(&model_1, mod, 0, NULL), LY_SUCCESS);
714 assert_ptr_not_equal(model_1, NULL);
715
716 struct lyd_node *model_2;
717 struct lyd_node *model_3;
718
719 CHECK_PARSE_LYD_PARAM(xml2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
720 CHECK_PARSE_LYD_PARAM(xml3, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_3);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200721
Michal Vaskoe6323f62020-07-09 15:49:02 +0200722 /* diff1 */
Radek Iša56ca9e42020-09-08 18:42:00 +0200723 struct lyd_node *diff1 = NULL;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200724
Radek Iša56ca9e42020-09-08 18:42:00 +0200725 assert_int_equal(lyd_diff_siblings(model_1, model_2, LYD_DIFF_DEFAULTS, &diff1), LY_SUCCESS);
726 assert_non_null(diff1);
727
728 const char *diff1_out_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100729 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
730 " <foo yang:operation=\"replace\" yang:orig-default=\"true\" yang:orig-value=\"42\">41</foo>\n"
731 " <dllist yang:operation=\"delete\">1</dllist>\n"
732 " <dllist yang:operation=\"delete\">2</dllist>\n"
733 " <dllist yang:operation=\"delete\">3</dllist>\n"
734 " <dllist yang:operation=\"create\">4</dllist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200735 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200736
Radek Iša56ca9e42020-09-08 18:42:00 +0200737 CHECK_LYD_STRING_PARAM(diff1, diff1_out_1, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
738 assert_int_equal(lyd_diff_apply_all(&model_1, diff1), LY_SUCCESS);
739 CHECK_LYD(model_1, model_2);
Michal Vaskoe6323f62020-07-09 15:49:02 +0200740
741 /* diff2 */
Radek Iša56ca9e42020-09-08 18:42:00 +0200742 struct lyd_node *diff2;
Michal Vaskoe6323f62020-07-09 15:49:02 +0200743
Radek Iša56ca9e42020-09-08 18:42:00 +0200744 assert_int_equal(lyd_diff_siblings(model_2, model_3, LYD_DIFF_DEFAULTS, &diff2), LY_SUCCESS);
745 assert_non_null(diff2);
746 CHECK_LYD_STRING(diff2,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100747 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
748 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"41\">42</foo>\n"
749 " <dllist yang:operation=\"create\">1</dllist>\n"
750 "</df>\n");
Michal Vaskoe6323f62020-07-09 15:49:02 +0200751
Radek Iša56ca9e42020-09-08 18:42:00 +0200752 assert_int_equal(lyd_diff_apply_all(&model_2, diff2), LY_SUCCESS);
753 CHECK_LYD(model_2, model_3);
Michal Vaskoe6323f62020-07-09 15:49:02 +0200754
755 /* merge */
Radek Iša56ca9e42020-09-08 18:42:00 +0200756 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);
Michal Vaskoe6323f62020-07-09 15:49:02 +0200757
Radek Iša56ca9e42020-09-08 18:42:00 +0200758 const char *diff1_out_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100759 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
760 " <foo yang:orig-default=\"true\" yang:operation=\"none\">42</foo>\n"
761 " <dllist yang:operation=\"none\" yang:orig-default=\"true\">1</dllist>\n"
762 " <dllist yang:operation=\"delete\">2</dllist>\n"
763 " <dllist yang:operation=\"delete\">3</dllist>\n"
764 " <dllist yang:operation=\"create\">4</dllist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200765 "</df>\n";
766
767 CHECK_LYD_STRING_PARAM(diff1, diff1_out_2, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
768
769 lyd_free_all(model_1);
770 lyd_free_all(model_2);
771 lyd_free_all(model_3);
772 lyd_free_all(diff1);
773 lyd_free_all(diff2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200774}
775
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100776int
777main(void)
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200778{
779 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200780 UTEST(test_invalid, setup),
781 UTEST(test_same, setup),
782 UTEST(test_empty1, setup),
783 UTEST(test_empty2, setup),
784 UTEST(test_empty_nested, setup),
785 UTEST(test_leaf, setup),
786 UTEST(test_list, setup),
787 UTEST(test_userord_llist, setup),
788 UTEST(test_userord_llist2, setup),
789 UTEST(test_userord_mix, setup),
790 UTEST(test_wd, setup),
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200791 };
792
793 return cmocka_run_group_tests(tests, NULL, NULL);
794}