blob: a84c3f6dc7eab29780720ae863fdff32236477e7 [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) \
Michal Vasko5da938a2022-03-01 09:19:02 +010021 CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, MODEL)
Radek Iša56ca9e42020-09-08 18:42:00 +020022
23#define CHECK_LYD_STRING(IN_MODEL, TEXT) \
Michal Vasko5da938a2022-03-01 09:19:02 +010024 CHECK_LYD_STRING_PARAM(IN_MODEL, TEXT, LYD_XML, LYD_PRINT_WITHSIBLINGS)
Radek Iša56ca9e42020-09-08 18:42:00 +020025
26#define CHECK_PARSE_LYD_DIFF(INPUT_1, INPUT_2, OUT_MODEL) \
Michal Vasko5da938a2022-03-01 09:19:02 +010027 assert_int_equal(LY_SUCCESS, lyd_diff_siblings(INPUT_1, INPUT_2, 0, &OUT_MODEL));\
28 assert_non_null(OUT_MODEL)
Radek Iša56ca9e42020-09-08 18:42:00 +020029
Michal Vasko5da938a2022-03-01 09:19:02 +010030#define TEST_DIFF_3(XML1, XML2, XML3, DIFF1, DIFF2, MERGE) \
31 { \
32 struct lyd_node *data1;\
33 struct lyd_node *data2;\
34 struct lyd_node *data3;\
Michal Vasko2bf4af42023-01-04 12:08:38 +010035 /*create*/\
Michal Vasko5da938a2022-03-01 09:19:02 +010036 CHECK_PARSE_LYD(XML1, data1);\
37 CHECK_PARSE_LYD(XML2, data2);\
38 CHECK_PARSE_LYD(XML3, data3);\
Michal Vasko2bf4af42023-01-04 12:08:38 +010039 /* diff1 */ \
Michal Vasko5da938a2022-03-01 09:19:02 +010040 struct lyd_node *diff1;\
41 CHECK_PARSE_LYD_DIFF(data1, data2, diff1); \
42 CHECK_LYD_STRING(diff1, DIFF1); \
43 assert_int_equal(lyd_diff_apply_all(&data1, diff1), LY_SUCCESS); \
44 CHECK_LYD(data1, data2); \
Michal Vasko2bf4af42023-01-04 12:08:38 +010045 /* diff2 */ \
Michal Vasko5da938a2022-03-01 09:19:02 +010046 struct lyd_node *diff2;\
47 CHECK_PARSE_LYD_DIFF(data2, data3, diff2); \
48 CHECK_LYD_STRING(diff2, DIFF2); \
49 assert_int_equal(lyd_diff_apply_all(&data2, diff2), LY_SUCCESS);\
50 CHECK_LYD(data2, data3);\
Michal Vasko2bf4af42023-01-04 12:08:38 +010051 /* merge */ \
Michal Vasko5da938a2022-03-01 09:19:02 +010052 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);\
53 CHECK_LYD_STRING(diff1, MERGE); \
Michal Vasko2bf4af42023-01-04 12:08:38 +010054 /* cleanup */ \
Michal Vasko5da938a2022-03-01 09:19:02 +010055 lyd_free_all(data1);\
56 lyd_free_all(data2);\
57 lyd_free_all(data3);\
58 lyd_free_all(diff1);\
59 lyd_free_all(diff2);\
60 }
Radek Iša56ca9e42020-09-08 18:42:00 +020061
Michal Vasko17d0c5c2021-11-01 11:31:11 +010062const char *schema1 =
Radek Iša56ca9e42020-09-08 18:42:00 +020063 "module defaults {\n"
64 " yang-version 1.1;\n"
65 " namespace \"urn:libyang:tests:defaults\";\n"
66 " prefix df;\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020067 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020068 " feature unhide;\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020069 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020070 " typedef defint32 {\n"
71 " type int32;\n"
72 " default \"42\";\n"
73 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020074 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020075 " leaf hiddenleaf {\n"
76 " if-feature \"unhide\";\n"
77 " type int32;\n"
78 " default \"42\";\n"
79 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020080 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020081 " container df {\n"
82 " leaf foo {\n"
83 " type defint32;\n"
84 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020085 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020086 " leaf hiddenleaf {\n"
87 " if-feature \"unhide\";\n"
88 " type int32;\n"
89 " default \"42\";\n"
90 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020091 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020092 " container bar {\n"
93 " presence \"\";\n"
94 " leaf hi {\n"
95 " type int32;\n"
96 " default \"42\";\n"
97 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020098 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020099 " leaf ho {\n"
100 " type int32;\n"
101 " mandatory true;\n"
102 " }\n"
103 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200104 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200105 " leaf-list llist {\n"
106 " type defint32;\n"
107 " ordered-by user;\n"
108 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200109 ""
Michal Vaskoe78faec2021-04-08 17:24:43 +0200110 " list ul {\n"
111 " key \"l1\";\n"
112 " ordered-by user;\n"
113 " leaf l1 {\n"
114 " type string;\n"
115 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200116 ""
Michal Vaskoe78faec2021-04-08 17:24:43 +0200117 " leaf l2 {\n"
118 " type int32;\n"
119 " }\n"
120 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200121 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200122 " leaf-list dllist {\n"
123 " type uint8;\n"
124 " default \"1\";\n"
125 " default \"2\";\n"
126 " default \"3\";\n"
127 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200128 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200129 " list list {\n"
130 " key \"name\";\n"
131 " leaf name {\n"
132 " type string;\n"
133 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200134 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200135 " leaf value {\n"
136 " type int32;\n"
137 " default \"42\";\n"
138 " }\n"
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100139 " list list2 {\n"
140 " key \"name2\";\n"
141 " leaf name2 {\n"
142 " type string;\n"
143 " }\n"
144 " leaf value2 {\n"
145 " type int32;\n"
146 " }\n"
147 " }\n"
148 " }\n";
149const char *schema2 =
Radek Iša56ca9e42020-09-08 18:42:00 +0200150 " choice select {\n"
151 " default \"a\";\n"
152 " case a {\n"
153 " choice a {\n"
154 " leaf a1 {\n"
155 " type int32;\n"
156 " default \"42\";\n"
157 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200158 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200159 " leaf a2 {\n"
160 " type int32;\n"
161 " default \"24\";\n"
162 " }\n"
163 " }\n"
164 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200165 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200166 " leaf b {\n"
167 " type string;\n"
168 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200169 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200170 " container c {\n"
171 " presence \"\";\n"
172 " leaf x {\n"
173 " type int32;\n"
174 " default \"42\";\n"
175 " }\n"
176 " }\n"
177 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200178 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200179 " choice select2 {\n"
180 " default \"s2b\";\n"
181 " leaf s2a {\n"
182 " type int32;\n"
183 " default \"42\";\n"
184 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200185 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200186 " case s2b {\n"
187 " choice s2b {\n"
188 " default \"b1\";\n"
189 " case b1 {\n"
190 " leaf b1_1 {\n"
191 " type int32;\n"
192 " default \"42\";\n"
193 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200194 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200195 " leaf b1_2 {\n"
196 " type string;\n"
197 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200198 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200199 " leaf b1_status {\n"
200 " type int32;\n"
201 " default \"42\";\n"
202 " config false;\n"
203 " }\n"
204 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200205 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200206 " leaf b2 {\n"
207 " type int32;\n"
208 " default \"42\";\n"
209 " }\n"
210 " }\n"
211 " }\n"
212 " }\n"
Michal Vaskoe78faec2021-04-08 17:24:43 +0200213 " list kl {\n"
214 " config \"false\";\n"
215 " leaf l1 {\n"
216 " type string;\n"
217 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200218 ""
Michal Vaskoe78faec2021-04-08 17:24:43 +0200219 " leaf l2 {\n"
220 " type int32;\n"
221 " }\n"
222 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200223 ""
Michal Vaskoe78faec2021-04-08 17:24:43 +0200224 " leaf-list kll {\n"
225 " config \"false\";\n"
226 " type string;\n"
227 " }\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200228 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200229 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200230 " container hidden {\n"
231 " leaf foo {\n"
232 " type int32;\n"
233 " default \"42\";\n"
234 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200235 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200236 " leaf baz {\n"
237 " type int32;\n"
238 " default \"42\";\n"
239 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200240 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200241 " leaf papa {\n"
242 " type int32;\n"
243 " default \"42\";\n"
244 " config false;\n"
245 " }\n"
246 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200247 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200248 " rpc rpc1 {\n"
249 " input {\n"
250 " leaf inleaf1 {\n"
251 " type string;\n"
252 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200253 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200254 " leaf inleaf2 {\n"
255 " type string;\n"
256 " default \"def1\";\n"
257 " }\n"
258 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200259 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200260 " output {\n"
261 " leaf outleaf1 {\n"
262 " type string;\n"
263 " default \"def2\";\n"
264 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200265 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200266 " leaf outleaf2 {\n"
267 " type string;\n"
268 " }\n"
269 " }\n"
270 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200271 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200272 " notification notif {\n"
273 " leaf ntfleaf1 {\n"
274 " type string;\n"
275 " default \"def3\";\n"
276 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200277 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200278 " leaf ntfleaf2 {\n"
279 " type string;\n"
280 " }\n"
281 " }\n"
282 "}\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200283
284static int
Radek Iša56ca9e42020-09-08 18:42:00 +0200285setup(void **state)
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200286{
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100287 char *schema;
288
Radek Iša56ca9e42020-09-08 18:42:00 +0200289 UTEST_SETUP;
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100290
291 /* create one schema, longer than 4095 chars */
292 schema = malloc(strlen(schema1) + strlen(schema2) + 1);
293 strcpy(schema, schema1);
294 strcat(schema, schema2);
295
Radek Iša56ca9e42020-09-08 18:42:00 +0200296 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100297 free(schema);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200298
299 return 0;
300}
301
302static void
303test_invalid(void **state)
304{
Radek Iša56ca9e42020-09-08 18:42:00 +0200305 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200306 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
307
Radek Iša56ca9e42020-09-08 18:42:00 +0200308 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200309
Radek Iša56ca9e42020-09-08 18:42:00 +0200310 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200311
Radek Iša56ca9e42020-09-08 18:42:00 +0200312 struct lyd_node *diff = NULL;
313
314 assert_int_equal(lyd_diff_siblings(model_1, lyd_child(model_1), 0, &diff), LY_EINVAL);
Michal Vasko62af3692023-02-09 14:00:09 +0100315 CHECK_LOG_CTX("Invalid arguments - cannot create diff for unrelated data (lyd_diff()).", NULL);
316
Michal Vasko3a41dff2020-07-15 14:30:28 +0200317 assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, NULL), LY_EINVAL);
Radek Iša56ca9e42020-09-08 18:42:00 +0200318
319 lyd_free_all(model_1);
320 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200321}
322
323static void
324test_same(void **state)
325{
Radek Iša56ca9e42020-09-08 18:42:00 +0200326 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100327 const char *xml =
328 "<nacm xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-acm\">\n"
329 " <enable-nacm>true</enable-nacm>\n"
330 " <read-default>permit</read-default>\n"
331 " <write-default>deny</write-default>\n"
332 " <exec-default>permit</exec-default>\n"
333 " <enable-external-groups>true</enable-external-groups>\n"
334 "</nacm><df xmlns=\"urn:libyang:tests:defaults\">\n"
335 " <foo>42</foo><b1_1>42</b1_1>\n"
336 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">\n"
337 " <foo>42</foo><baz>42</baz></hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200338
Radek Iša56ca9e42020-09-08 18:42:00 +0200339 struct lyd_node *model_1;
340 struct lyd_node *model_2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200341
Radek Iša56ca9e42020-09-08 18:42:00 +0200342 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
343 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-acm", "2018-02-14", NULL));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200344
Radek Iša56ca9e42020-09-08 18:42:00 +0200345 CHECK_PARSE_LYD(xml, model_1);
346 CHECK_PARSE_LYD(xml, model_2);
347
348 struct lyd_node *diff = NULL;
349
350 assert_int_equal(lyd_diff_siblings(model_1, model_2, 0, &diff), LY_SUCCESS);
351 assert_null(diff);
352 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
353 CHECK_LYD(model_1, model_2);
354
355 lyd_free_all(model_1);
356 lyd_free_all(model_2);
357 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200358}
359
360static void
361test_empty1(void **state)
362{
Radek Iša56ca9e42020-09-08 18:42:00 +0200363 (void) state;
364 const char *xml_in =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100365 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
366 " <foo>42</foo>\n"
367 " <b1_1>42</b1_1>\n"
368 "</df>\n"
369 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
370 " <foo>42</foo>\n"
371 " <baz>42</baz>\n"
372 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200373
Radek Iša56ca9e42020-09-08 18:42:00 +0200374 struct lyd_node *model_1 = NULL;
375 struct lyd_node *model_2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200376
Radek Iša56ca9e42020-09-08 18:42:00 +0200377 CHECK_PARSE_LYD(xml_in, model_2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200378
Radek Iša56ca9e42020-09-08 18:42:00 +0200379 struct lyd_node *diff;
380
381 CHECK_PARSE_LYD_DIFF(model_1, model_2, diff);
382 CHECK_LYD_STRING(diff,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100383 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
384 " <foo>42</foo>\n"
385 " <b1_1>42</b1_1>\n"
386 "</df>\n"
387 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
388 " <foo>42</foo>\n"
389 " <baz>42</baz>\n"
390 "</hidden>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200391 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
392 CHECK_LYD(model_1, model_2);
393
394 lyd_free_all(model_1);
395 lyd_free_all(model_2);
396 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200397}
398
399static void
400test_empty2(void **state)
401{
Radek Iša56ca9e42020-09-08 18:42:00 +0200402 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100403 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
404 " <foo>42</foo>\n"
405 " <b1_1>42</b1_1>\n"
406 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">\n"
407 " <foo>42</foo>\n"
408 " <baz>42</baz>\n"
409 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200410
Radek Iša56ca9e42020-09-08 18:42:00 +0200411 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200412
Radek Iša56ca9e42020-09-08 18:42:00 +0200413 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200414
Radek Iša56ca9e42020-09-08 18:42:00 +0200415 struct lyd_node *diff;
416
417 CHECK_PARSE_LYD_DIFF(model_1, NULL, diff);
418 CHECK_LYD_STRING(diff,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100419 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
420 " <foo>42</foo>\n"
421 " <b1_1>42</b1_1>\n"
422 "</df>\n"
423 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
424 " <foo>42</foo>\n"
425 " <baz>42</baz>\n"
426 "</hidden>\n");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200427
Radek Iša56ca9e42020-09-08 18:42:00 +0200428 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
429 assert_ptr_equal(model_1, NULL);
430
431 lyd_free_all(diff);
432 lyd_free_all(model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200433}
434
435static void
436test_empty_nested(void **state)
437{
Radek Iša56ca9e42020-09-08 18:42:00 +0200438 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200439 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
440
Radek Iša56ca9e42020-09-08 18:42:00 +0200441 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200442
Radek Iša56ca9e42020-09-08 18:42:00 +0200443 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200444
Radek Iša56ca9e42020-09-08 18:42:00 +0200445 struct lyd_node *diff = NULL;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200446
Radek Iša56ca9e42020-09-08 18:42:00 +0200447 assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, &diff), LY_SUCCESS);
448 assert_null(diff);
449
450 struct lyd_node *diff1;
451
452 CHECK_PARSE_LYD_DIFF(NULL, lyd_child(model_1), diff1);
453 CHECK_LYD_STRING(diff1,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100454 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
455 " <foo yang:operation=\"create\">42</foo>\n"
456 "</df>\n");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200457
Radek Iša56ca9e42020-09-08 18:42:00 +0200458 struct lyd_node *diff2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200459
Radek Iša56ca9e42020-09-08 18:42:00 +0200460 CHECK_PARSE_LYD_DIFF(lyd_child(model_1), NULL, diff2);
461 CHECK_LYD_STRING(diff2,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100462 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
463 " <foo yang:operation=\"delete\">42</foo>\n"
464 "</df>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200465
466 lyd_free_all(model_1);
467 lyd_free_all(diff1);
468 lyd_free_all(diff2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200469}
470
471static void
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100472test_delete_merge(void **state)
473{
474 (void) state;
475 struct lyd_node *diff1, *diff2;
476 const char *xml1 =
477 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
478 " <list>\n"
479 " <name>a</name>\n"
480 " <list2 yang:operation=\"delete\">\n"
481 " <name2>a</name2>\n"
482 " </list2>\n"
483 " </list>\n"
484 "</df>\n";
485 const char *xml2 =
486 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
487 " <list yang:operation=\"delete\">\n"
488 " <name>a</name>\n"
489 " </list>\n"
490 "</df>\n";
491 const char *xml_merge =
492 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
493 " <list yang:operation=\"delete\">\n"
494 " <name>a</name>\n"
495 " <list2 yang:operation=\"delete\">\n"
496 " <name2>a</name2>\n"
497 " </list2>\n"
498 " </list>\n"
499 "</df>\n";
500
501 CHECK_PARSE_LYD(xml1, diff1);
502 CHECK_PARSE_LYD(xml2, diff2);
503
504 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);
505 CHECK_LYD_STRING(diff1, xml_merge);
506
507 lyd_free_all(diff1);
508 lyd_free_all(diff2);
509}
510
511static void
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200512test_leaf(void **state)
513{
Radek Iša56ca9e42020-09-08 18:42:00 +0200514 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200515 const char *xml1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100516 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
517 " <foo>42</foo>\n"
518 "</df>\n"
519 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
520 " <foo>42</foo>\n"
521 " <baz>42</baz>\n"
522 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200523 const char *xml2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100524 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
525 " <foo>41</foo>\n"
526 " <b1_1>42</b1_1>\n"
527 "</df>\n";
Michal Vaskoe6323f62020-07-09 15:49:02 +0200528 const char *xml3 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100529 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
530 " <foo>40</foo>\n"
531 "</df>\n"
532 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
533 " <foo>40</foo>\n"
534 "</hidden>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200535 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100536 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
537 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"42\">41</foo>\n"
538 " <b1_1 yang:operation=\"create\">42</b1_1>\n"
539 "</df>\n"
540 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
541 " <foo>42</foo>\n"
542 " <baz>42</baz>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200543 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200544
Radek Iša56ca9e42020-09-08 18:42:00 +0200545 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 +0100546 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"41\">40</foo>\n"
547 " <b1_1 yang:operation=\"delete\">42</b1_1>\n"
548 "</df>\n"
549 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
550 " <foo>40</foo>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200551 "</hidden>\n";
Michal Vaskoe6323f62020-07-09 15:49:02 +0200552
Radek Iša56ca9e42020-09-08 18:42:00 +0200553 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100554 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
555 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"42\">40</foo>\n"
556 "</df>\n"
557 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
558 " <foo yang:operation=\"replace\" yang:orig-value=\"42\" yang:orig-default=\"false\">40</foo>\n"
559 " <baz yang:operation=\"delete\">42</baz>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200560 "</hidden>\n";
561
562 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200563}
564
565static void
566test_list(void **state)
567{
Radek Iša56ca9e42020-09-08 18:42:00 +0200568 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100569 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
570 " <list>\n"
571 " <name>a</name>\n"
572 " <value>1</value>\n"
573 " </list>\n"
574 " <list>\n"
575 " <name>b</name>\n"
576 " <value>2</value>\n"
577 " </list>\n"
578 "</df>\n";
579 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
580 " <list>\n"
581 " <name>b</name>\n"
582 " <value>-2</value>\n"
583 " </list>\n"
584 " <list>\n"
585 " <name>c</name>\n"
586 " <value>3</value>\n"
587 " </list>\n"
588 "</df>\n";
589 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
590 " <list>\n"
591 " <name>b</name>\n"
592 " <value>-2</value>\n"
593 " </list>\n"
594 " <list>\n"
595 " <name>a</name>\n"
596 " <value>2</value>\n"
597 " </list>\n"
598 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200599
Radek Iša56ca9e42020-09-08 18:42:00 +0200600 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100601 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
602 " <list yang:operation=\"delete\">\n"
603 " <name>a</name>\n"
604 " <value>1</value>\n"
605 " </list>\n"
606 " <list yang:operation=\"none\">\n"
607 " <name>b</name>\n"
608 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\">-2</value>\n"
609 " </list>\n"
610 " <list yang:operation=\"create\">\n"
611 " <name>c</name>\n"
612 " <value>3</value>\n"
613 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200614 "</df>\n";
615 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100616 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
617 " <list yang:operation=\"delete\">\n"
618 " <name>c</name>\n"
619 " <value>3</value>\n"
620 " </list>\n"
621 " <list yang:operation=\"create\">\n"
622 " <name>a</name>\n"
623 " <value>2</value>\n"
624 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200625 "</df>\n";
626 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100627 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
628 " <list yang:operation=\"none\">\n"
629 " <name>a</name>\n"
630 " <value yang:operation=\"replace\" yang:orig-value=\"1\" yang:orig-default=\"false\">2</value>\n"
631 " </list>\n"
632 " <list yang:operation=\"none\">\n"
633 " <name>b</name>\n"
634 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\">-2</value>\n"
635 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200636 "</df>\n";
637
638 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200639}
640
641static void
642test_userord_llist(void **state)
643{
Radek Iša56ca9e42020-09-08 18:42:00 +0200644 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100645 const char *xml1 =
646 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
647 " <llist>1</llist>\n"
648 " <llist>2</llist>\n"
649 " <llist>3</llist>\n"
650 " <llist>4</llist>\n"
651 " <llist>5</llist>\n"
652 "</df>\n";
653 const char *xml2 =
654 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
655 " <llist>1</llist>\n"
656 " <llist>4</llist>\n"
657 " <llist>3</llist>\n"
658 " <llist>2</llist>\n"
659 " <llist>5</llist>\n"
660 "</df>\n";
661 const char *xml3 =
662 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
663 " <llist>5</llist>\n"
664 " <llist>4</llist>\n"
665 " <llist>3</llist>\n"
666 " <llist>2</llist>\n"
667 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200668
Radek Iša56ca9e42020-09-08 18:42:00 +0200669 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100670 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
671 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>\n"
672 " <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 +0200673 "</df>\n";
674 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100675 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
676 " <llist yang:operation=\"delete\" yang:orig-value=\"\">1</llist>\n"
677 " <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 +0200678 "</df>\n";
679 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100680 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
681 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>\n"
682 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\" yang:value=\"4\">3</llist>\n"
683 " <llist yang:orig-value=\"\" yang:operation=\"delete\">1</llist>\n"
684 " <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 +0200685 "</df>\n";
686
687 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200688}
689
690static void
691test_userord_llist2(void **state)
692{
Radek Iša56ca9e42020-09-08 18:42:00 +0200693 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100694 const char *xml1 =
695 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
696 " <llist>1</llist>\n"
697 " <list><name>a</name><value>1</value></list>\n"
698 " <llist>2</llist>\n"
699 " <llist>3</llist>\n"
700 " <llist>4</llist>\n"
701 "</df>\n";
702 const char *xml2 =
703 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
704 " <llist>1</llist>\n"
705 " <list><name>a</name><value>1</value></list>\n"
706 " <llist>2</llist>\n"
707 " <llist>4</llist>\n"
708 " <llist>3</llist>\n"
709 "</df>\n";
710 const char *xml3 =
711 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
712 " <llist>4</llist>\n"
713 " <llist>1</llist>\n"
714 " <list><name>a</name><value>1</value></list>\n"
715 " <llist>3</llist>\n"
716 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200717
Radek Iša56ca9e42020-09-08 18:42:00 +0200718 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100719 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
720 " <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 +0200721 "</df>\n";
722 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100723 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
724 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
725 " <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 +0200726 "</df>\n";
727 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100728 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
729 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\">4</llist>\n"
730 " <llist yang:orig-value=\"1\" yang:operation=\"delete\">2</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200731 "</df>\n";
732
733 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200734}
735
736static void
737test_userord_mix(void **state)
738{
Radek Iša56ca9e42020-09-08 18:42:00 +0200739 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100740 const char *xml1 =
741 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
742 " <llist>1</llist>\n"
743 " <llist>2</llist>\n"
744 " <llist>3</llist>\n"
745 "</df>\n";
746 const char *xml2 =
747 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
748 " <llist>3</llist>\n"
749 " <llist>1</llist>\n"
750 "</df>\n";
751 const char *xml3 =
752 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
753 " <llist>1</llist>\n"
754 " <llist>4</llist>\n"
755 " <llist>3</llist>\n"
756 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200757
Radek Iša56ca9e42020-09-08 18:42:00 +0200758 const char *out_diff_1 =
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 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
761 " <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 +0200762 "</df>\n";
763 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100764 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
765 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\">1</llist>\n"
766 " <llist yang:operation=\"create\" yang:value=\"1\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200767 "</df>\n";
768 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100769 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
770 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
771 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\" yang:value=\"\">3</llist>\n"
772 " <llist yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\" yang:operation=\"replace\">1</llist>\n"
773 " <llist yang:value=\"1\" yang:operation=\"create\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200774 "</df>\n";
775
776 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200777}
778
779static void
Michal Vaskoe78faec2021-04-08 17:24:43 +0200780test_userord_list(void **state)
781{
782 (void) state;
783 const char *xml1 =
784 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
785 " <ul>\n"
786 " <l1>a</l1>\n"
787 " <l2>1</l2>\n"
788 " </ul>\n"
789 " <ul>\n"
790 " <l1>b</l1>\n"
791 " <l2>2</l2>\n"
792 " </ul>\n"
793 " <ul>\n"
794 " <l1>c</l1>\n"
795 " <l2>3</l2>\n"
796 " </ul>\n"
797 "</df>\n";
798 const char *xml2 =
799 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
800 " <ul>\n"
801 " <l1>a</l1>\n"
802 " <l2>11</l2>\n"
803 " </ul>\n"
804 " <ul>\n"
805 " <l1>c</l1>\n"
806 " <l2>3</l2>\n"
807 " </ul>\n"
808 "</df>\n";
809 const char *xml3 =
810 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
811 " <ul>\n"
812 " <l1>c</l1>\n"
813 " <l2>33</l2>\n"
814 " </ul>\n"
815 " <ul>\n"
816 " <l1>b</l1>\n"
817 " <l2>2</l2>\n"
818 " </ul>\n"
819 "</df>\n";
820
821 const char *out_diff_1 =
822 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
823 " <ul>\n"
824 " <l1>a</l1>\n"
825 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\">11</l2>\n"
826 " </ul>\n"
827 " <ul yang:operation=\"delete\" yang:orig-key=\"[l1='a']\">\n"
828 " <l1>b</l1>\n"
829 " <l2>2</l2>\n"
830 " </ul>\n"
831 "</df>\n";
832 const char *out_diff_2 =
833 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
834 " <ul yang:operation=\"delete\" yang:orig-key=\"\">\n"
835 " <l1>a</l1>\n"
836 " <l2>11</l2>\n"
837 " </ul>\n"
838 " <ul yang:operation=\"none\">\n"
839 " <l1>c</l1>\n"
840 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\">33</l2>\n"
841 " </ul>\n"
842 " <ul yang:operation=\"create\" yang:key=\"[l1='c']\">\n"
843 " <l1>b</l1>\n"
844 " <l2>2</l2>\n"
845 " </ul>\n"
846 "</df>\n";
847 const char *out_merge =
848 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
849 " <ul yang:operation=\"delete\">\n"
850 " <l1>a</l1>\n"
851 " <l2 yang:operation=\"delete\">1</l2>\n"
852 " </ul>\n"
853 " <ul yang:orig-key=\"[l1='a']\" yang:operation=\"replace\" yang:key=\"[l1='c']\">\n"
854 " <l1>b</l1>\n"
855 " </ul>\n"
856 " <ul yang:operation=\"none\">\n"
857 " <l1>c</l1>\n"
858 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\">33</l2>\n"
859 " </ul>\n"
860 "</df>\n";
861
862 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
863}
864
865static void
Michal Vasko5da938a2022-03-01 09:19:02 +0100866test_userord_list2(void **state)
867{
868 (void) state;
869 const char *xml1 =
870 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
871 " <ul>\n"
872 " <l1>d</l1>\n"
873 " <l2>4</l2>\n"
874 " </ul>\n"
875 "</df>\n";
876 const char *xml2 =
877 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
878 " <ul>\n"
879 " <l1>c</l1>\n"
880 " <l2>3</l2>\n"
881 " </ul>\n"
882 " <ul>\n"
883 " <l1>d</l1>\n"
884 " <l2>4</l2>\n"
885 " </ul>\n"
886 "</df>\n";
887 const char *xml3 =
888 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
889 " <ul>\n"
890 " <l1>a</l1>\n"
891 " <l2>1</l2>\n"
892 " </ul>\n"
893 " <ul>\n"
894 " <l1>b</l1>\n"
895 " <l2>2</l2>\n"
896 " </ul>\n"
897 " <ul>\n"
898 " <l1>c</l1>\n"
899 " <l2>3</l2>\n"
900 " </ul>\n"
901 " <ul>\n"
902 " <l1>d</l1>\n"
903 " <l2>4</l2>\n"
904 " </ul>\n"
905 "</df>\n";
906
907 const char *out_diff_1 =
908 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
909 " <ul yang:operation=\"create\" yang:key=\"\">\n"
910 " <l1>c</l1>\n"
911 " <l2>3</l2>\n"
912 " </ul>\n"
913 "</df>\n";
914 const char *out_diff_2 =
915 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
916 " <ul yang:operation=\"create\" yang:key=\"\">\n"
917 " <l1>a</l1>\n"
918 " <l2>1</l2>\n"
919 " </ul>\n"
920 " <ul yang:operation=\"create\" yang:key=\"[l1='a']\">\n"
921 " <l1>b</l1>\n"
922 " <l2>2</l2>\n"
923 " </ul>\n"
924 "</df>\n";
925 const char *out_merge =
926 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
927 " <ul yang:operation=\"create\" yang:key=\"\">\n"
928 " <l1>c</l1>\n"
929 " <l2>3</l2>\n"
930 " </ul>\n"
931 " <ul yang:key=\"\" yang:operation=\"create\">\n"
932 " <l1>a</l1>\n"
933 " <l2>1</l2>\n"
934 " </ul>\n"
935 " <ul yang:key=\"[l1='a']\" yang:operation=\"create\">\n"
936 " <l1>b</l1>\n"
937 " <l2>2</l2>\n"
938 " </ul>\n"
939 "</df>\n";
940
941 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
942}
943
944static void
Michal Vaskoe78faec2021-04-08 17:24:43 +0200945test_keyless_list(void **state)
946{
947 (void) state;
948 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
949 " <kl>\n"
950 " <l1>a</l1>\n"
951 " <l2>1</l2>\n"
952 " </kl>\n"
953 " <kl>\n"
954 " <l1>b</l1>\n"
955 " <l2>2</l2>\n"
956 " </kl>\n"
957 " <kl>\n"
958 " <l1>c</l1>\n"
959 " <l2>3</l2>\n"
960 " </kl>\n"
961 "</df>\n";
962 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
963 " <kl>\n"
964 " <l1>b</l1>\n"
965 " <l2>2</l2>\n"
966 " </kl>\n"
967 " <kl>\n"
968 " <l1>a</l1>\n"
969 " <l2>1</l2>\n"
970 " </kl>\n"
971 " <kl>\n"
972 " <l1>a</l1>\n"
973 " <l2>1</l2>\n"
974 " </kl>\n"
975 "</df>\n";
976 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
977 " <kl>\n"
978 " <l1>c</l1>\n"
979 " </kl>\n"
980 " <kl>\n"
981 " <l2>4</l2>\n"
982 " </kl>\n"
983 " <kl>\n"
984 " <l1>e</l1>\n"
985 " <l2>5</l2>\n"
986 " </kl>\n"
987 " <kl>\n"
988 " <l1>f</l1>\n"
989 " <l2>6</l2>\n"
990 " </kl>\n"
991 "</df>\n";
992
993 const char *out_diff_1 =
994 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
995 " <kl yang:operation=\"delete\" yang:orig-position=\"2\">\n"
996 " <l1>c</l1>\n"
997 " <l2>3</l2>\n"
998 " </kl>\n"
999 " <kl yang:operation=\"replace\" yang:position=\"\" yang:orig-position=\"1\">\n"
1000 " <l1>b</l1>\n"
1001 " <l2>2</l2>\n"
1002 " </kl>\n"
1003 " <kl yang:operation=\"create\" yang:position=\"2\">\n"
1004 " <l1>a</l1>\n"
1005 " <l2>1</l2>\n"
1006 " </kl>\n"
1007 "</df>\n";
1008 const char *out_diff_2 =
1009 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1010 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
1011 " <l1>b</l1>\n"
1012 " <l2>2</l2>\n"
1013 " </kl>\n"
1014 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
1015 " <l1>a</l1>\n"
1016 " <l2>1</l2>\n"
1017 " </kl>\n"
1018 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
1019 " <l1>a</l1>\n"
1020 " <l2>1</l2>\n"
1021 " </kl>\n"
1022 " <kl yang:operation=\"create\" yang:position=\"\">\n"
1023 " <l1>c</l1>\n"
1024 " </kl>\n"
1025 " <kl yang:operation=\"create\" yang:position=\"1\">\n"
1026 " <l2>4</l2>\n"
1027 " </kl>\n"
1028 " <kl yang:operation=\"create\" yang:position=\"2\">\n"
1029 " <l1>e</l1>\n"
1030 " <l2>5</l2>\n"
1031 " </kl>\n"
1032 " <kl yang:operation=\"create\" yang:position=\"3\">\n"
1033 " <l1>f</l1>\n"
1034 " <l2>6</l2>\n"
1035 " </kl>\n"
1036 "</df>\n";
1037 const char *out_merge =
1038 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1039 " <kl yang:operation=\"delete\" yang:orig-position=\"2\">\n"
1040 " <l1>c</l1>\n"
1041 " <l2>3</l2>\n"
1042 " </kl>\n"
1043 " <kl yang:orig-position=\"1\" yang:operation=\"delete\">\n"
1044 " <l1>b</l1>\n"
1045 " <l2>2</l2>\n"
1046 " </kl>\n"
1047 " <kl yang:orig-position=\"\" yang:operation=\"delete\">\n"
1048 " <l1>a</l1>\n"
1049 " <l2>1</l2>\n"
1050 " </kl>\n"
1051 " <kl yang:position=\"\" yang:operation=\"create\">\n"
1052 " <l1>c</l1>\n"
1053 " </kl>\n"
1054 " <kl yang:position=\"1\" yang:operation=\"create\">\n"
1055 " <l2>4</l2>\n"
1056 " </kl>\n"
1057 " <kl yang:position=\"2\" yang:operation=\"create\">\n"
1058 " <l1>e</l1>\n"
1059 " <l2>5</l2>\n"
1060 " </kl>\n"
1061 " <kl yang:position=\"3\" yang:operation=\"create\">\n"
1062 " <l1>f</l1>\n"
1063 " <l2>6</l2>\n"
1064 " </kl>\n"
1065 "</df>\n";
1066
1067 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
1068}
1069
1070static void
1071test_state_llist(void **state)
1072{
1073 (void) state;
1074 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1075 " <kll>a</kll>\n"
1076 " <kll>b</kll>\n"
1077 " <kll>c</kll>\n"
1078 "</df>\n";
1079 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1080 " <kll>b</kll>\n"
1081 " <kll>c</kll>\n"
1082 " <kll>a</kll>\n"
1083 " <kll>a</kll>\n"
1084 " <kll>a</kll>\n"
1085 "</df>\n";
1086 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1087 " <kll>a</kll>\n"
1088 " <kll>d</kll>\n"
1089 " <kll>a</kll>\n"
1090 "</df>\n";
1091
1092 const char *out_diff_1 =
1093 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1094 " <kll yang:operation=\"replace\" yang:orig-default=\"false\" yang:position=\"\" yang:orig-position=\"1\">b</kll>\n"
1095 " <kll yang:operation=\"replace\" yang:orig-default=\"false\" yang:position=\"1\" yang:orig-position=\"2\">c</kll>\n"
1096 " <kll yang:operation=\"create\" yang:position=\"3\">a</kll>\n"
1097 " <kll yang:operation=\"create\" yang:position=\"4\">a</kll>\n"
1098 "</df>\n";
1099 const char *out_diff_2 =
1100 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1101 " <kll yang:operation=\"delete\" yang:orig-position=\"\">b</kll>\n"
1102 " <kll yang:operation=\"delete\" yang:orig-position=\"\">c</kll>\n"
1103 " <kll yang:operation=\"delete\" yang:orig-position=\"2\">a</kll>\n"
1104 " <kll yang:operation=\"create\" yang:position=\"1\">d</kll>\n"
1105 "</df>\n";
1106 const char *out_merge =
1107 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1108 " <kll yang:orig-default=\"false\" yang:orig-position=\"1\" yang:operation=\"delete\">b</kll>\n"
1109 " <kll yang:orig-default=\"false\" yang:orig-position=\"2\" yang:operation=\"delete\">c</kll>\n"
1110 " <kll yang:operation=\"create\" yang:position=\"4\">a</kll>\n"
1111 " <kll yang:position=\"1\" yang:operation=\"create\">d</kll>\n"
1112 "</df>\n";
1113
1114 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
1115}
1116
1117static void
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001118test_wd(void **state)
1119{
Radek Iša56ca9e42020-09-08 18:42:00 +02001120 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001121 const struct lys_module *mod;
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001122 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1123 " <foo>41</foo>\n"
1124 " <dllist>4</dllist>\n"
1125 "</df>\n";
1126 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1127 " <foo>42</foo>\n"
1128 " <dllist>4</dllist>\n"
1129 " <dllist>1</dllist>\n"
1130 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001131
Radek Iša56ca9e42020-09-08 18:42:00 +02001132 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "defaults");
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001133 assert_non_null(mod);
1134
Radek Iša56ca9e42020-09-08 18:42:00 +02001135 struct lyd_node *model_1 = NULL;
1136
1137 assert_int_equal(lyd_validate_module(&model_1, mod, 0, NULL), LY_SUCCESS);
1138 assert_ptr_not_equal(model_1, NULL);
1139
1140 struct lyd_node *model_2;
1141 struct lyd_node *model_3;
1142
1143 CHECK_PARSE_LYD_PARAM(xml2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1144 CHECK_PARSE_LYD_PARAM(xml3, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_3);
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001145
Michal Vaskoe6323f62020-07-09 15:49:02 +02001146 /* diff1 */
Radek Iša56ca9e42020-09-08 18:42:00 +02001147 struct lyd_node *diff1 = NULL;
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001148
Radek Iša56ca9e42020-09-08 18:42:00 +02001149 assert_int_equal(lyd_diff_siblings(model_1, model_2, LYD_DIFF_DEFAULTS, &diff1), LY_SUCCESS);
1150 assert_non_null(diff1);
1151
1152 const char *diff1_out_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001153 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1154 " <foo yang:operation=\"replace\" yang:orig-default=\"true\" yang:orig-value=\"42\">41</foo>\n"
1155 " <dllist yang:operation=\"delete\">1</dllist>\n"
1156 " <dllist yang:operation=\"delete\">2</dllist>\n"
1157 " <dllist yang:operation=\"delete\">3</dllist>\n"
1158 " <dllist yang:operation=\"create\">4</dllist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001159 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001160
Radek Iša56ca9e42020-09-08 18:42:00 +02001161 CHECK_LYD_STRING_PARAM(diff1, diff1_out_1, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
1162 assert_int_equal(lyd_diff_apply_all(&model_1, diff1), LY_SUCCESS);
1163 CHECK_LYD(model_1, model_2);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001164
1165 /* diff2 */
Radek Iša56ca9e42020-09-08 18:42:00 +02001166 struct lyd_node *diff2;
Michal Vaskoe6323f62020-07-09 15:49:02 +02001167
Radek Iša56ca9e42020-09-08 18:42:00 +02001168 assert_int_equal(lyd_diff_siblings(model_2, model_3, LYD_DIFF_DEFAULTS, &diff2), LY_SUCCESS);
1169 assert_non_null(diff2);
1170 CHECK_LYD_STRING(diff2,
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001171 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1172 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"41\">42</foo>\n"
1173 " <dllist yang:operation=\"create\">1</dllist>\n"
1174 "</df>\n");
Michal Vaskoe6323f62020-07-09 15:49:02 +02001175
Radek Iša56ca9e42020-09-08 18:42:00 +02001176 assert_int_equal(lyd_diff_apply_all(&model_2, diff2), LY_SUCCESS);
1177 CHECK_LYD(model_2, model_3);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001178
1179 /* merge */
Radek Iša56ca9e42020-09-08 18:42:00 +02001180 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001181
Radek Iša56ca9e42020-09-08 18:42:00 +02001182 const char *diff1_out_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001183 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1184 " <foo yang:orig-default=\"true\" yang:operation=\"none\">42</foo>\n"
1185 " <dllist yang:operation=\"none\" yang:orig-default=\"true\">1</dllist>\n"
1186 " <dllist yang:operation=\"delete\">2</dllist>\n"
1187 " <dllist yang:operation=\"delete\">3</dllist>\n"
1188 " <dllist yang:operation=\"create\">4</dllist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001189 "</df>\n";
1190
1191 CHECK_LYD_STRING_PARAM(diff1, diff1_out_2, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
1192
1193 lyd_free_all(model_1);
1194 lyd_free_all(model_2);
1195 lyd_free_all(model_3);
1196 lyd_free_all(diff1);
1197 lyd_free_all(diff2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001198}
1199
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001200int
1201main(void)
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001202{
1203 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +02001204 UTEST(test_invalid, setup),
1205 UTEST(test_same, setup),
1206 UTEST(test_empty1, setup),
1207 UTEST(test_empty2, setup),
1208 UTEST(test_empty_nested, setup),
Michal Vasko17d0c5c2021-11-01 11:31:11 +01001209 UTEST(test_delete_merge, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001210 UTEST(test_leaf, setup),
1211 UTEST(test_list, setup),
1212 UTEST(test_userord_llist, setup),
1213 UTEST(test_userord_llist2, setup),
1214 UTEST(test_userord_mix, setup),
Michal Vaskoe78faec2021-04-08 17:24:43 +02001215 UTEST(test_userord_list, setup),
Michal Vasko5da938a2022-03-01 09:19:02 +01001216 UTEST(test_userord_list2, setup),
Michal Vaskoe78faec2021-04-08 17:24:43 +02001217 UTEST(test_keyless_list, setup),
1218 UTEST(test_state_llist, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001219 UTEST(test_wd, setup),
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001220 };
1221
1222 return cmocka_run_group_tests(tests, NULL, NULL);
1223}