blob: 4400b5da25e91a2279c25d878c9837f2599239aa [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 *
Michal Vaskod4525672023-06-20 09:15:42 +02007 * Copyright (c) 2020 - 2023 CESNET, z.s.p.o.
Michal Vaskoe893ddd2020-06-23 13:35:20 +02008 *
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
Michal Vasko58d89e92023-05-23 09:56:19 +020020#define CHECK_PARSE_LYD(INPUT, OUTPUT) \
21 CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, OUTPUT)
Radek Iša56ca9e42020-09-08 18:42:00 +020022
Michal Vasko58d89e92023-05-23 09:56:19 +020023#define CHECK_LYD_STRING(INPUT, TEXT) \
24 CHECK_LYD_STRING_PARAM(INPUT, TEXT, LYD_XML, LYD_PRINT_WITHSIBLINGS)
Radek Iša56ca9e42020-09-08 18:42:00 +020025
Michal Vasko58d89e92023-05-23 09:56:19 +020026#define CHECK_PARSE_LYD_DIFF(INPUT_1, INPUT_2, OUT_DIFF) \
27 assert_int_equal(LY_SUCCESS, lyd_diff_siblings(INPUT_1, INPUT_2, 0, &OUT_DIFF));\
28 assert_non_null(OUT_DIFF)
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"
Michal Vaskod4525672023-06-20 09:15:42 +0200120 ""
121 " container cont {\n"
122 " leaf l3 {\n"
123 " type string;\n"
124 " }\n"
125 " }\n"
Michal Vaskoe78faec2021-04-08 17:24:43 +0200126 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200127 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200128 " leaf-list dllist {\n"
129 " type uint8;\n"
130 " default \"1\";\n"
131 " default \"2\";\n"
132 " default \"3\";\n"
133 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200134 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200135 " list list {\n"
136 " key \"name\";\n"
137 " leaf name {\n"
138 " type string;\n"
139 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200140 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200141 " leaf value {\n"
142 " type int32;\n"
143 " default \"42\";\n"
144 " }\n"
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100145 " list list2 {\n"
146 " key \"name2\";\n"
147 " leaf name2 {\n"
148 " type string;\n"
149 " }\n"
150 " leaf value2 {\n"
151 " type int32;\n"
152 " }\n"
153 " }\n"
154 " }\n";
155const char *schema2 =
Radek Iša56ca9e42020-09-08 18:42:00 +0200156 " choice select {\n"
157 " default \"a\";\n"
158 " case a {\n"
159 " choice a {\n"
160 " leaf a1 {\n"
161 " type int32;\n"
162 " default \"42\";\n"
163 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200164 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200165 " leaf a2 {\n"
166 " type int32;\n"
167 " default \"24\";\n"
168 " }\n"
169 " }\n"
170 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200171 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200172 " leaf b {\n"
173 " type string;\n"
174 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200175 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200176 " container c {\n"
177 " presence \"\";\n"
178 " leaf x {\n"
179 " type int32;\n"
180 " default \"42\";\n"
181 " }\n"
182 " }\n"
183 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200184 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200185 " choice select2 {\n"
186 " default \"s2b\";\n"
187 " leaf s2a {\n"
188 " type int32;\n"
189 " default \"42\";\n"
190 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200191 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200192 " case s2b {\n"
193 " choice s2b {\n"
194 " default \"b1\";\n"
195 " case b1 {\n"
196 " leaf b1_1 {\n"
197 " type int32;\n"
198 " default \"42\";\n"
199 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200200 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200201 " leaf b1_2 {\n"
202 " type string;\n"
203 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200204 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200205 " leaf b1_status {\n"
206 " type int32;\n"
207 " default \"42\";\n"
208 " config false;\n"
209 " }\n"
210 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200211 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200212 " leaf b2 {\n"
213 " type int32;\n"
214 " default \"42\";\n"
215 " }\n"
216 " }\n"
217 " }\n"
218 " }\n"
Michal Vaskoe78faec2021-04-08 17:24:43 +0200219 " list kl {\n"
220 " config \"false\";\n"
221 " leaf l1 {\n"
222 " type string;\n"
223 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200224 ""
Michal Vaskoe78faec2021-04-08 17:24:43 +0200225 " leaf l2 {\n"
226 " type int32;\n"
227 " }\n"
228 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200229 ""
Michal Vaskoe78faec2021-04-08 17:24:43 +0200230 " leaf-list kll {\n"
231 " config \"false\";\n"
232 " type string;\n"
233 " }\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200234 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200235 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200236 " container hidden {\n"
237 " leaf foo {\n"
238 " type int32;\n"
239 " default \"42\";\n"
240 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200241 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200242 " leaf baz {\n"
243 " type int32;\n"
244 " default \"42\";\n"
245 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200246 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200247 " leaf papa {\n"
248 " type int32;\n"
249 " default \"42\";\n"
250 " config false;\n"
251 " }\n"
252 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200253 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200254 " rpc rpc1 {\n"
255 " input {\n"
256 " leaf inleaf1 {\n"
257 " type string;\n"
258 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200259 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200260 " leaf inleaf2 {\n"
261 " type string;\n"
262 " default \"def1\";\n"
263 " }\n"
264 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200265 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200266 " output {\n"
267 " leaf outleaf1 {\n"
268 " type string;\n"
269 " default \"def2\";\n"
270 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200271 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200272 " leaf outleaf2 {\n"
273 " type string;\n"
274 " }\n"
275 " }\n"
276 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200277 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200278 " notification notif {\n"
279 " leaf ntfleaf1 {\n"
280 " type string;\n"
281 " default \"def3\";\n"
282 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200283 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200284 " leaf ntfleaf2 {\n"
285 " type string;\n"
286 " }\n"
287 " }\n"
288 "}\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200289
290static int
Radek Iša56ca9e42020-09-08 18:42:00 +0200291setup(void **state)
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200292{
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100293 char *schema;
294
Radek Iša56ca9e42020-09-08 18:42:00 +0200295 UTEST_SETUP;
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100296
297 /* create one schema, longer than 4095 chars */
298 schema = malloc(strlen(schema1) + strlen(schema2) + 1);
299 strcpy(schema, schema1);
300 strcat(schema, schema2);
301
Radek Iša56ca9e42020-09-08 18:42:00 +0200302 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100303 free(schema);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200304
305 return 0;
306}
307
308static void
309test_invalid(void **state)
310{
Radek Iša56ca9e42020-09-08 18:42:00 +0200311 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200312 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
313
Radek Iša56ca9e42020-09-08 18:42:00 +0200314 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200315
Radek Iša56ca9e42020-09-08 18:42:00 +0200316 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200317
Radek Iša56ca9e42020-09-08 18:42:00 +0200318 struct lyd_node *diff = NULL;
319
320 assert_int_equal(lyd_diff_siblings(model_1, lyd_child(model_1), 0, &diff), LY_EINVAL);
Michal Vasko62af3692023-02-09 14:00:09 +0100321 CHECK_LOG_CTX("Invalid arguments - cannot create diff for unrelated data (lyd_diff()).", NULL);
322
Michal Vasko3a41dff2020-07-15 14:30:28 +0200323 assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, NULL), LY_EINVAL);
Radek Iša56ca9e42020-09-08 18:42:00 +0200324
325 lyd_free_all(model_1);
326 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200327}
328
329static void
330test_same(void **state)
331{
Radek Iša56ca9e42020-09-08 18:42:00 +0200332 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100333 const char *xml =
334 "<nacm xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-acm\">\n"
335 " <enable-nacm>true</enable-nacm>\n"
336 " <read-default>permit</read-default>\n"
337 " <write-default>deny</write-default>\n"
338 " <exec-default>permit</exec-default>\n"
339 " <enable-external-groups>true</enable-external-groups>\n"
340 "</nacm><df xmlns=\"urn:libyang:tests:defaults\">\n"
341 " <foo>42</foo><b1_1>42</b1_1>\n"
342 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">\n"
343 " <foo>42</foo><baz>42</baz></hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200344
Radek Iša56ca9e42020-09-08 18:42:00 +0200345 struct lyd_node *model_1;
346 struct lyd_node *model_2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200347
Radek Iša56ca9e42020-09-08 18:42:00 +0200348 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
349 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-acm", "2018-02-14", NULL));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200350
Radek Iša56ca9e42020-09-08 18:42:00 +0200351 CHECK_PARSE_LYD(xml, model_1);
352 CHECK_PARSE_LYD(xml, model_2);
353
354 struct lyd_node *diff = NULL;
355
356 assert_int_equal(lyd_diff_siblings(model_1, model_2, 0, &diff), LY_SUCCESS);
357 assert_null(diff);
358 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
359 CHECK_LYD(model_1, model_2);
360
361 lyd_free_all(model_1);
362 lyd_free_all(model_2);
363 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200364}
365
366static void
367test_empty1(void **state)
368{
Radek Iša56ca9e42020-09-08 18:42:00 +0200369 (void) state;
370 const char *xml_in =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100371 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
372 " <foo>42</foo>\n"
373 " <b1_1>42</b1_1>\n"
374 "</df>\n"
375 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
376 " <foo>42</foo>\n"
377 " <baz>42</baz>\n"
378 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200379
Radek Iša56ca9e42020-09-08 18:42:00 +0200380 struct lyd_node *model_1 = NULL;
381 struct lyd_node *model_2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200382
Radek Iša56ca9e42020-09-08 18:42:00 +0200383 CHECK_PARSE_LYD(xml_in, model_2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200384
Radek Iša56ca9e42020-09-08 18:42:00 +0200385 struct lyd_node *diff;
386
387 CHECK_PARSE_LYD_DIFF(model_1, model_2, diff);
388 CHECK_LYD_STRING(diff,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100389 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
390 " <foo>42</foo>\n"
391 " <b1_1>42</b1_1>\n"
392 "</df>\n"
393 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
394 " <foo>42</foo>\n"
395 " <baz>42</baz>\n"
396 "</hidden>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200397 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
398 CHECK_LYD(model_1, model_2);
399
400 lyd_free_all(model_1);
401 lyd_free_all(model_2);
402 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200403}
404
405static void
406test_empty2(void **state)
407{
Radek Iša56ca9e42020-09-08 18:42:00 +0200408 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100409 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
410 " <foo>42</foo>\n"
411 " <b1_1>42</b1_1>\n"
412 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">\n"
413 " <foo>42</foo>\n"
414 " <baz>42</baz>\n"
415 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200416
Radek Iša56ca9e42020-09-08 18:42:00 +0200417 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200418
Radek Iša56ca9e42020-09-08 18:42:00 +0200419 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200420
Radek Iša56ca9e42020-09-08 18:42:00 +0200421 struct lyd_node *diff;
422
423 CHECK_PARSE_LYD_DIFF(model_1, NULL, diff);
424 CHECK_LYD_STRING(diff,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100425 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
426 " <foo>42</foo>\n"
427 " <b1_1>42</b1_1>\n"
428 "</df>\n"
429 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
430 " <foo>42</foo>\n"
431 " <baz>42</baz>\n"
432 "</hidden>\n");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200433
Radek Iša56ca9e42020-09-08 18:42:00 +0200434 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
435 assert_ptr_equal(model_1, NULL);
436
437 lyd_free_all(diff);
438 lyd_free_all(model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200439}
440
441static void
442test_empty_nested(void **state)
443{
Radek Iša56ca9e42020-09-08 18:42:00 +0200444 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200445 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
446
Radek Iša56ca9e42020-09-08 18:42:00 +0200447 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200448
Radek Iša56ca9e42020-09-08 18:42:00 +0200449 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200450
Radek Iša56ca9e42020-09-08 18:42:00 +0200451 struct lyd_node *diff = NULL;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200452
Radek Iša56ca9e42020-09-08 18:42:00 +0200453 assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, &diff), LY_SUCCESS);
454 assert_null(diff);
455
456 struct lyd_node *diff1;
457
458 CHECK_PARSE_LYD_DIFF(NULL, lyd_child(model_1), diff1);
459 CHECK_LYD_STRING(diff1,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100460 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
461 " <foo yang:operation=\"create\">42</foo>\n"
462 "</df>\n");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200463
Radek Iša56ca9e42020-09-08 18:42:00 +0200464 struct lyd_node *diff2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200465
Radek Iša56ca9e42020-09-08 18:42:00 +0200466 CHECK_PARSE_LYD_DIFF(lyd_child(model_1), NULL, diff2);
467 CHECK_LYD_STRING(diff2,
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=\"delete\">42</foo>\n"
470 "</df>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200471
472 lyd_free_all(model_1);
473 lyd_free_all(diff1);
474 lyd_free_all(diff2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200475}
476
477static void
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100478test_delete_merge(void **state)
479{
480 (void) state;
481 struct lyd_node *diff1, *diff2;
482 const char *xml1 =
483 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
484 " <list>\n"
485 " <name>a</name>\n"
486 " <list2 yang:operation=\"delete\">\n"
487 " <name2>a</name2>\n"
488 " </list2>\n"
489 " </list>\n"
490 "</df>\n";
491 const char *xml2 =
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 " </list>\n"
496 "</df>\n";
497 const char *xml_merge =
498 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
499 " <list yang:operation=\"delete\">\n"
500 " <name>a</name>\n"
501 " <list2 yang:operation=\"delete\">\n"
502 " <name2>a</name2>\n"
503 " </list2>\n"
504 " </list>\n"
505 "</df>\n";
506
507 CHECK_PARSE_LYD(xml1, diff1);
508 CHECK_PARSE_LYD(xml2, diff2);
509
510 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);
511 CHECK_LYD_STRING(diff1, xml_merge);
512
513 lyd_free_all(diff1);
514 lyd_free_all(diff2);
515}
516
517static void
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200518test_leaf(void **state)
519{
Radek Iša56ca9e42020-09-08 18:42:00 +0200520 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200521 const char *xml1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100522 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
523 " <foo>42</foo>\n"
524 "</df>\n"
525 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
526 " <foo>42</foo>\n"
527 " <baz>42</baz>\n"
528 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200529 const char *xml2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100530 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
531 " <foo>41</foo>\n"
532 " <b1_1>42</b1_1>\n"
533 "</df>\n";
Michal Vaskoe6323f62020-07-09 15:49:02 +0200534 const char *xml3 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100535 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
536 " <foo>40</foo>\n"
537 "</df>\n"
538 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
539 " <foo>40</foo>\n"
540 "</hidden>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200541 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100542 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
543 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"42\">41</foo>\n"
544 " <b1_1 yang:operation=\"create\">42</b1_1>\n"
545 "</df>\n"
546 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
547 " <foo>42</foo>\n"
548 " <baz>42</baz>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200549 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200550
Radek Iša56ca9e42020-09-08 18:42:00 +0200551 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 +0100552 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"41\">40</foo>\n"
553 " <b1_1 yang:operation=\"delete\">42</b1_1>\n"
554 "</df>\n"
555 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
556 " <foo>40</foo>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200557 "</hidden>\n";
Michal Vaskoe6323f62020-07-09 15:49:02 +0200558
Radek Iša56ca9e42020-09-08 18:42:00 +0200559 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100560 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
561 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"42\">40</foo>\n"
562 "</df>\n"
563 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
564 " <foo yang:operation=\"replace\" yang:orig-value=\"42\" yang:orig-default=\"false\">40</foo>\n"
565 " <baz yang:operation=\"delete\">42</baz>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200566 "</hidden>\n";
567
568 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200569}
570
571static void
572test_list(void **state)
573{
Radek Iša56ca9e42020-09-08 18:42:00 +0200574 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100575 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
576 " <list>\n"
577 " <name>a</name>\n"
578 " <value>1</value>\n"
579 " </list>\n"
580 " <list>\n"
581 " <name>b</name>\n"
582 " <value>2</value>\n"
583 " </list>\n"
584 "</df>\n";
585 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
586 " <list>\n"
587 " <name>b</name>\n"
588 " <value>-2</value>\n"
589 " </list>\n"
590 " <list>\n"
591 " <name>c</name>\n"
592 " <value>3</value>\n"
593 " </list>\n"
594 "</df>\n";
595 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
596 " <list>\n"
597 " <name>b</name>\n"
598 " <value>-2</value>\n"
599 " </list>\n"
600 " <list>\n"
601 " <name>a</name>\n"
602 " <value>2</value>\n"
603 " </list>\n"
604 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200605
Radek Iša56ca9e42020-09-08 18:42:00 +0200606 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100607 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
608 " <list yang:operation=\"delete\">\n"
609 " <name>a</name>\n"
610 " <value>1</value>\n"
611 " </list>\n"
612 " <list yang:operation=\"none\">\n"
613 " <name>b</name>\n"
614 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\">-2</value>\n"
615 " </list>\n"
616 " <list yang:operation=\"create\">\n"
617 " <name>c</name>\n"
618 " <value>3</value>\n"
619 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200620 "</df>\n";
621 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100622 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
623 " <list yang:operation=\"delete\">\n"
624 " <name>c</name>\n"
625 " <value>3</value>\n"
626 " </list>\n"
627 " <list yang:operation=\"create\">\n"
628 " <name>a</name>\n"
629 " <value>2</value>\n"
630 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200631 "</df>\n";
632 const char *out_merge =
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 " <list yang:operation=\"none\">\n"
635 " <name>a</name>\n"
636 " <value yang:operation=\"replace\" yang:orig-value=\"1\" yang:orig-default=\"false\">2</value>\n"
637 " </list>\n"
638 " <list yang:operation=\"none\">\n"
639 " <name>b</name>\n"
640 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\">-2</value>\n"
641 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200642 "</df>\n";
643
644 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200645}
646
647static void
Michal Vasko58d89e92023-05-23 09:56:19 +0200648test_nested_list(void **state)
649{
650 struct lyd_node *data1, *data2, *diff;
651 const char *xml1, *xml2;
652
653 (void) state;
654
655 xml1 =
656 "<df xmlns=\"urn:libyang:tests:defaults\">"
657 " <list>"
658 " <name>n1</name>"
659 " <value>25</value>"
660 " <list2>"
661 " <name2>n22</name2>"
662 " <value2>26</value2>"
663 " </list2>"
664 " </list>"
665 " <list>"
666 " <name>n2</name>"
667 " <value>25</value>"
668 " <list2>"
669 " <name2>n22</name2>"
670 " <value2>26</value2>"
671 " </list2>"
672 " </list>"
673 " <list>"
674 " <name>n3</name>"
675 " <value>25</value>"
676 " <list2>"
677 " <name2>n22</name2>"
678 " <value2>26</value2>"
679 " </list2>"
680 " </list>"
681 " <list>"
682 " <name>n4</name>"
683 " <value>25</value>"
684 " <list2>"
685 " <name2>n22</name2>"
686 " <value2>26</value2>"
687 " </list2>"
688 " </list>"
689 " <list>"
690 " <name>n0</name>"
691 " <value>26</value>"
692 " <list2>"
693 " <name2>n22</name2>"
694 " <value2>26</value2>"
695 " </list2>"
696 " <list2>"
697 " <name2>n23</name2>"
698 " <value2>26</value2>"
699 " </list2>"
700 " </list>"
701 "</df>";
702 xml2 =
703 "<df xmlns=\"urn:libyang:tests:defaults\">"
704 " <list>"
705 " <name>n0</name>"
706 " <value>30</value>"
707 " <list2>"
708 " <name2>n23</name2>"
709 " <value2>26</value2>"
710 " </list2>"
711 " </list>"
712 "</df>";
713
714 CHECK_PARSE_LYD(xml1, data1);
715 CHECK_PARSE_LYD(xml2, data2);
716 CHECK_PARSE_LYD_DIFF(data1, data2, diff);
717
718 CHECK_LYD_STRING(diff,
719 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
720 " <list yang:operation=\"delete\">\n"
721 " <name>n1</name>\n"
722 " <value>25</value>\n"
723 " <list2>\n"
724 " <name2>n22</name2>\n"
725 " <value2>26</value2>\n"
726 " </list2>\n"
727 " </list>\n"
728 " <list yang:operation=\"delete\">\n"
729 " <name>n2</name>\n"
730 " <value>25</value>\n"
731 " <list2>\n"
732 " <name2>n22</name2>\n"
733 " <value2>26</value2>\n"
734 " </list2>\n"
735 " </list>\n"
736 " <list yang:operation=\"delete\">\n"
737 " <name>n3</name>\n"
738 " <value>25</value>\n"
739 " <list2>\n"
740 " <name2>n22</name2>\n"
741 " <value2>26</value2>\n"
742 " </list2>\n"
743 " </list>\n"
744 " <list yang:operation=\"delete\">\n"
745 " <name>n4</name>\n"
746 " <value>25</value>\n"
747 " <list2>\n"
748 " <name2>n22</name2>\n"
749 " <value2>26</value2>\n"
750 " </list2>\n"
751 " </list>\n"
752 " <list yang:operation=\"none\">\n"
753 " <name>n0</name>\n"
754 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"26\">30</value>\n"
755 " <list2 yang:operation=\"delete\">\n"
756 " <name2>n22</name2>\n"
757 " <value2>26</value2>\n"
758 " </list2>\n"
759 " </list>\n"
760 "</df>\n");
761
762 lyd_free_all(data1);
763 lyd_free_all(data2);
764 lyd_free_all(diff);
765}
766
767static void
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200768test_userord_llist(void **state)
769{
Radek Iša56ca9e42020-09-08 18:42:00 +0200770 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100771 const char *xml1 =
772 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
773 " <llist>1</llist>\n"
774 " <llist>2</llist>\n"
775 " <llist>3</llist>\n"
776 " <llist>4</llist>\n"
777 " <llist>5</llist>\n"
778 "</df>\n";
779 const char *xml2 =
780 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
781 " <llist>1</llist>\n"
782 " <llist>4</llist>\n"
783 " <llist>3</llist>\n"
784 " <llist>2</llist>\n"
785 " <llist>5</llist>\n"
786 "</df>\n";
787 const char *xml3 =
788 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
789 " <llist>5</llist>\n"
790 " <llist>4</llist>\n"
791 " <llist>3</llist>\n"
792 " <llist>2</llist>\n"
793 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200794
Radek Iša56ca9e42020-09-08 18:42:00 +0200795 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100796 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
797 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>\n"
798 " <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 +0200799 "</df>\n";
800 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100801 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
802 " <llist yang:operation=\"delete\" yang:orig-value=\"\">1</llist>\n"
803 " <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 +0200804 "</df>\n";
805 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100806 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
807 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>\n"
808 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\" yang:value=\"4\">3</llist>\n"
809 " <llist yang:orig-value=\"\" yang:operation=\"delete\">1</llist>\n"
810 " <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 +0200811 "</df>\n";
812
813 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200814}
815
816static void
817test_userord_llist2(void **state)
818{
Radek Iša56ca9e42020-09-08 18:42:00 +0200819 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100820 const char *xml1 =
821 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
822 " <llist>1</llist>\n"
823 " <list><name>a</name><value>1</value></list>\n"
824 " <llist>2</llist>\n"
825 " <llist>3</llist>\n"
826 " <llist>4</llist>\n"
827 "</df>\n";
828 const char *xml2 =
829 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
830 " <llist>1</llist>\n"
831 " <list><name>a</name><value>1</value></list>\n"
832 " <llist>2</llist>\n"
833 " <llist>4</llist>\n"
834 " <llist>3</llist>\n"
835 "</df>\n";
836 const char *xml3 =
837 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
838 " <llist>4</llist>\n"
839 " <llist>1</llist>\n"
840 " <list><name>a</name><value>1</value></list>\n"
841 " <llist>3</llist>\n"
842 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200843
Radek Iša56ca9e42020-09-08 18:42:00 +0200844 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100845 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
846 " <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 +0200847 "</df>\n";
848 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100849 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
850 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
851 " <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 +0200852 "</df>\n";
853 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100854 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
855 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\">4</llist>\n"
856 " <llist yang:orig-value=\"1\" yang:operation=\"delete\">2</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200857 "</df>\n";
858
859 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200860}
861
862static void
863test_userord_mix(void **state)
864{
Radek Iša56ca9e42020-09-08 18:42:00 +0200865 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100866 const char *xml1 =
867 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
868 " <llist>1</llist>\n"
869 " <llist>2</llist>\n"
870 " <llist>3</llist>\n"
871 "</df>\n";
872 const char *xml2 =
873 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
874 " <llist>3</llist>\n"
875 " <llist>1</llist>\n"
876 "</df>\n";
877 const char *xml3 =
878 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
879 " <llist>1</llist>\n"
880 " <llist>4</llist>\n"
881 " <llist>3</llist>\n"
882 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200883
Radek Iša56ca9e42020-09-08 18:42:00 +0200884 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100885 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
886 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
887 " <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 +0200888 "</df>\n";
889 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100890 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
891 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\">1</llist>\n"
892 " <llist yang:operation=\"create\" yang:value=\"1\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200893 "</df>\n";
894 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100895 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
896 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
897 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\" yang:value=\"\">3</llist>\n"
898 " <llist yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\" yang:operation=\"replace\">1</llist>\n"
899 " <llist yang:value=\"1\" yang:operation=\"create\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200900 "</df>\n";
901
902 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200903}
904
905static void
Michal Vaskoe78faec2021-04-08 17:24:43 +0200906test_userord_list(void **state)
907{
908 (void) state;
909 const char *xml1 =
910 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
911 " <ul>\n"
912 " <l1>a</l1>\n"
913 " <l2>1</l2>\n"
914 " </ul>\n"
915 " <ul>\n"
916 " <l1>b</l1>\n"
917 " <l2>2</l2>\n"
918 " </ul>\n"
919 " <ul>\n"
920 " <l1>c</l1>\n"
921 " <l2>3</l2>\n"
922 " </ul>\n"
923 "</df>\n";
924 const char *xml2 =
925 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
926 " <ul>\n"
927 " <l1>a</l1>\n"
928 " <l2>11</l2>\n"
929 " </ul>\n"
930 " <ul>\n"
931 " <l1>c</l1>\n"
932 " <l2>3</l2>\n"
933 " </ul>\n"
934 "</df>\n";
935 const char *xml3 =
936 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
937 " <ul>\n"
938 " <l1>c</l1>\n"
939 " <l2>33</l2>\n"
940 " </ul>\n"
941 " <ul>\n"
942 " <l1>b</l1>\n"
943 " <l2>2</l2>\n"
944 " </ul>\n"
945 "</df>\n";
946
947 const char *out_diff_1 =
948 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
949 " <ul>\n"
950 " <l1>a</l1>\n"
951 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\">11</l2>\n"
952 " </ul>\n"
953 " <ul yang:operation=\"delete\" yang:orig-key=\"[l1='a']\">\n"
954 " <l1>b</l1>\n"
955 " <l2>2</l2>\n"
956 " </ul>\n"
957 "</df>\n";
958 const char *out_diff_2 =
959 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
960 " <ul yang:operation=\"delete\" yang:orig-key=\"\">\n"
961 " <l1>a</l1>\n"
962 " <l2>11</l2>\n"
963 " </ul>\n"
964 " <ul yang:operation=\"none\">\n"
965 " <l1>c</l1>\n"
966 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\">33</l2>\n"
967 " </ul>\n"
968 " <ul yang:operation=\"create\" yang:key=\"[l1='c']\">\n"
969 " <l1>b</l1>\n"
970 " <l2>2</l2>\n"
971 " </ul>\n"
972 "</df>\n";
973 const char *out_merge =
974 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
975 " <ul yang:operation=\"delete\">\n"
976 " <l1>a</l1>\n"
977 " <l2 yang:operation=\"delete\">1</l2>\n"
978 " </ul>\n"
979 " <ul yang:orig-key=\"[l1='a']\" yang:operation=\"replace\" yang:key=\"[l1='c']\">\n"
980 " <l1>b</l1>\n"
981 " </ul>\n"
982 " <ul yang:operation=\"none\">\n"
983 " <l1>c</l1>\n"
984 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\">33</l2>\n"
985 " </ul>\n"
986 "</df>\n";
987
988 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
989}
990
991static void
Michal Vasko5da938a2022-03-01 09:19:02 +0100992test_userord_list2(void **state)
993{
994 (void) state;
995 const char *xml1 =
996 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
997 " <ul>\n"
998 " <l1>d</l1>\n"
999 " <l2>4</l2>\n"
1000 " </ul>\n"
1001 "</df>\n";
1002 const char *xml2 =
1003 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1004 " <ul>\n"
1005 " <l1>c</l1>\n"
1006 " <l2>3</l2>\n"
1007 " </ul>\n"
1008 " <ul>\n"
1009 " <l1>d</l1>\n"
1010 " <l2>4</l2>\n"
1011 " </ul>\n"
1012 "</df>\n";
1013 const char *xml3 =
1014 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1015 " <ul>\n"
1016 " <l1>a</l1>\n"
1017 " <l2>1</l2>\n"
1018 " </ul>\n"
1019 " <ul>\n"
1020 " <l1>b</l1>\n"
1021 " <l2>2</l2>\n"
1022 " </ul>\n"
1023 " <ul>\n"
1024 " <l1>c</l1>\n"
1025 " <l2>3</l2>\n"
1026 " </ul>\n"
1027 " <ul>\n"
1028 " <l1>d</l1>\n"
1029 " <l2>4</l2>\n"
1030 " </ul>\n"
1031 "</df>\n";
1032
1033 const char *out_diff_1 =
1034 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1035 " <ul yang:operation=\"create\" yang:key=\"\">\n"
1036 " <l1>c</l1>\n"
1037 " <l2>3</l2>\n"
1038 " </ul>\n"
1039 "</df>\n";
1040 const char *out_diff_2 =
1041 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1042 " <ul yang:operation=\"create\" yang:key=\"\">\n"
1043 " <l1>a</l1>\n"
1044 " <l2>1</l2>\n"
1045 " </ul>\n"
1046 " <ul yang:operation=\"create\" yang:key=\"[l1='a']\">\n"
1047 " <l1>b</l1>\n"
1048 " <l2>2</l2>\n"
1049 " </ul>\n"
1050 "</df>\n";
1051 const char *out_merge =
1052 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1053 " <ul yang:operation=\"create\" yang:key=\"\">\n"
1054 " <l1>c</l1>\n"
1055 " <l2>3</l2>\n"
1056 " </ul>\n"
1057 " <ul yang:key=\"\" yang:operation=\"create\">\n"
1058 " <l1>a</l1>\n"
1059 " <l2>1</l2>\n"
1060 " </ul>\n"
1061 " <ul yang:key=\"[l1='a']\" yang:operation=\"create\">\n"
1062 " <l1>b</l1>\n"
1063 " <l2>2</l2>\n"
1064 " </ul>\n"
1065 "</df>\n";
1066
1067 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
1068}
1069
1070static void
Michal Vaskofb51a842023-06-20 08:50:24 +02001071test_userord_list3(void **state)
1072{
1073 (void) state;
1074 const char *xml1 =
1075 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1076 " <ul>\n"
1077 " <l1>a</l1>\n"
1078 " <l2>1</l2>\n"
1079 " </ul>\n"
1080 " <ul>\n"
1081 " <l1>b</l1>\n"
1082 " <l2>2</l2>\n"
1083 " </ul>\n"
1084 " <ul>\n"
1085 " <l1>c</l1>\n"
Michal Vaskod4525672023-06-20 09:15:42 +02001086 " <cont>\n"
1087 " <l3>val1</l3>\n"
1088 " </cont>\n"
Michal Vaskofb51a842023-06-20 08:50:24 +02001089 " </ul>\n"
1090 " <ul>\n"
1091 " <l1>d</l1>\n"
1092 " <l2>4</l2>\n"
1093 " </ul>\n"
1094 "</df>\n";
1095 const char *xml2 =
1096 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1097 " <ul>\n"
1098 " <l1>c</l1>\n"
1099 " <l2>3</l2>\n"
Michal Vaskod4525672023-06-20 09:15:42 +02001100 " <cont>\n"
1101 " <l3>val2</l3>\n"
1102 " </cont>\n"
Michal Vaskofb51a842023-06-20 08:50:24 +02001103 " </ul>\n"
1104 " <ul>\n"
1105 " <l1>a</l1>\n"
1106 " <l2>1</l2>\n"
1107 " </ul>\n"
1108 " <ul>\n"
1109 " <l1>d</l1>\n"
1110 " <l2>44</l2>\n"
1111 " </ul>\n"
1112 " <ul>\n"
1113 " <l1>b</l1>\n"
1114 " <l2>2</l2>\n"
1115 " </ul>\n"
1116 "</df>\n";
1117 const char *xml3 =
1118 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1119 " <ul>\n"
1120 " <l1>a</l1>\n"
1121 " </ul>\n"
1122 " <ul>\n"
1123 " <l1>c</l1>\n"
1124 " <l2>3</l2>\n"
Michal Vaskod4525672023-06-20 09:15:42 +02001125 " <cont>\n"
1126 " <l3>val2</l3>\n"
1127 " </cont>\n"
Michal Vaskofb51a842023-06-20 08:50:24 +02001128 " </ul>\n"
1129 " <ul>\n"
1130 " <l1>d</l1>\n"
1131 " <l2>44</l2>\n"
1132 " </ul>\n"
1133 " <ul>\n"
1134 " <l1>b</l1>\n"
1135 " <l2>2</l2>\n"
1136 " </ul>\n"
1137 "</df>\n";
1138
1139 const char *out_diff_1 =
1140 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1141 " <ul yang:operation=\"replace\" yang:key=\"\" yang:orig-key=\"[l1='b']\">\n"
1142 " <l1>c</l1>\n"
1143 " <l2 yang:operation=\"create\">3</l2>\n"
Michal Vaskod4525672023-06-20 09:15:42 +02001144 " <cont yang:operation=\"none\">\n"
1145 " <l3 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"val1\">val2</l3>\n"
1146 " </cont>\n"
Michal Vaskofb51a842023-06-20 08:50:24 +02001147 " </ul>\n"
1148 " <ul yang:operation=\"replace\" yang:key=\"[l1='a']\" yang:orig-key=\"[l1='b']\">\n"
1149 " <l1>d</l1>\n"
1150 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"4\">44</l2>\n"
1151 " </ul>\n"
1152 "</df>\n";
1153 const char *out_diff_2 =
1154 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1155 " <ul yang:operation=\"replace\" yang:key=\"\" yang:orig-key=\"[l1='c']\">\n"
1156 " <l1>a</l1>\n"
1157 " <l2 yang:operation=\"delete\">1</l2>\n"
1158 " </ul>\n"
1159 "</df>\n";
1160 const char *out_merge =
1161 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1162 " <ul yang:operation=\"replace\" yang:key=\"\" yang:orig-key=\"[l1='b']\">\n"
1163 " <l1>c</l1>\n"
1164 " <l2 yang:operation=\"create\">3</l2>\n"
Michal Vaskod4525672023-06-20 09:15:42 +02001165 " <cont yang:operation=\"none\">\n"
1166 " <l3 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"val1\">val2</l3>\n"
1167 " </cont>\n"
Michal Vaskofb51a842023-06-20 08:50:24 +02001168 " </ul>\n"
1169 " <ul yang:operation=\"replace\" yang:key=\"[l1='a']\" yang:orig-key=\"[l1='b']\">\n"
1170 " <l1>d</l1>\n"
1171 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"4\">44</l2>\n"
1172 " </ul>\n"
1173 " <ul yang:key=\"\" yang:orig-key=\"[l1='c']\" yang:operation=\"replace\">\n"
1174 " <l1>a</l1>\n"
1175 " <l2 yang:operation=\"delete\">1</l2>\n"
1176 " </ul>\n"
1177 "</df>\n";
1178
1179 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
1180}
1181
1182static void
Michal Vaskoe78faec2021-04-08 17:24:43 +02001183test_keyless_list(void **state)
1184{
1185 (void) state;
1186 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1187 " <kl>\n"
1188 " <l1>a</l1>\n"
1189 " <l2>1</l2>\n"
1190 " </kl>\n"
1191 " <kl>\n"
1192 " <l1>b</l1>\n"
1193 " <l2>2</l2>\n"
1194 " </kl>\n"
1195 " <kl>\n"
1196 " <l1>c</l1>\n"
1197 " <l2>3</l2>\n"
1198 " </kl>\n"
1199 "</df>\n";
1200 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1201 " <kl>\n"
1202 " <l1>b</l1>\n"
1203 " <l2>2</l2>\n"
1204 " </kl>\n"
1205 " <kl>\n"
1206 " <l1>a</l1>\n"
1207 " <l2>1</l2>\n"
1208 " </kl>\n"
1209 " <kl>\n"
1210 " <l1>a</l1>\n"
1211 " <l2>1</l2>\n"
1212 " </kl>\n"
1213 "</df>\n";
1214 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1215 " <kl>\n"
1216 " <l1>c</l1>\n"
1217 " </kl>\n"
1218 " <kl>\n"
1219 " <l2>4</l2>\n"
1220 " </kl>\n"
1221 " <kl>\n"
1222 " <l1>e</l1>\n"
1223 " <l2>5</l2>\n"
1224 " </kl>\n"
1225 " <kl>\n"
1226 " <l1>f</l1>\n"
1227 " <l2>6</l2>\n"
1228 " </kl>\n"
1229 "</df>\n";
1230
1231 const char *out_diff_1 =
1232 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1233 " <kl yang:operation=\"delete\" yang:orig-position=\"2\">\n"
1234 " <l1>c</l1>\n"
1235 " <l2>3</l2>\n"
1236 " </kl>\n"
1237 " <kl yang:operation=\"replace\" yang:position=\"\" yang:orig-position=\"1\">\n"
1238 " <l1>b</l1>\n"
1239 " <l2>2</l2>\n"
1240 " </kl>\n"
1241 " <kl yang:operation=\"create\" yang:position=\"2\">\n"
1242 " <l1>a</l1>\n"
1243 " <l2>1</l2>\n"
1244 " </kl>\n"
1245 "</df>\n";
1246 const char *out_diff_2 =
1247 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1248 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
1249 " <l1>b</l1>\n"
1250 " <l2>2</l2>\n"
1251 " </kl>\n"
1252 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
1253 " <l1>a</l1>\n"
1254 " <l2>1</l2>\n"
1255 " </kl>\n"
1256 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
1257 " <l1>a</l1>\n"
1258 " <l2>1</l2>\n"
1259 " </kl>\n"
1260 " <kl yang:operation=\"create\" yang:position=\"\">\n"
1261 " <l1>c</l1>\n"
1262 " </kl>\n"
1263 " <kl yang:operation=\"create\" yang:position=\"1\">\n"
1264 " <l2>4</l2>\n"
1265 " </kl>\n"
1266 " <kl yang:operation=\"create\" yang:position=\"2\">\n"
1267 " <l1>e</l1>\n"
1268 " <l2>5</l2>\n"
1269 " </kl>\n"
1270 " <kl yang:operation=\"create\" yang:position=\"3\">\n"
1271 " <l1>f</l1>\n"
1272 " <l2>6</l2>\n"
1273 " </kl>\n"
1274 "</df>\n";
1275 const char *out_merge =
1276 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1277 " <kl yang:operation=\"delete\" yang:orig-position=\"2\">\n"
1278 " <l1>c</l1>\n"
1279 " <l2>3</l2>\n"
1280 " </kl>\n"
1281 " <kl yang:orig-position=\"1\" yang:operation=\"delete\">\n"
1282 " <l1>b</l1>\n"
1283 " <l2>2</l2>\n"
1284 " </kl>\n"
1285 " <kl yang:orig-position=\"\" yang:operation=\"delete\">\n"
1286 " <l1>a</l1>\n"
1287 " <l2>1</l2>\n"
1288 " </kl>\n"
1289 " <kl yang:position=\"\" yang:operation=\"create\">\n"
1290 " <l1>c</l1>\n"
1291 " </kl>\n"
1292 " <kl yang:position=\"1\" yang:operation=\"create\">\n"
1293 " <l2>4</l2>\n"
1294 " </kl>\n"
1295 " <kl yang:position=\"2\" yang:operation=\"create\">\n"
1296 " <l1>e</l1>\n"
1297 " <l2>5</l2>\n"
1298 " </kl>\n"
1299 " <kl yang:position=\"3\" yang:operation=\"create\">\n"
1300 " <l1>f</l1>\n"
1301 " <l2>6</l2>\n"
1302 " </kl>\n"
1303 "</df>\n";
1304
1305 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
1306}
1307
1308static void
1309test_state_llist(void **state)
1310{
1311 (void) state;
1312 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1313 " <kll>a</kll>\n"
1314 " <kll>b</kll>\n"
1315 " <kll>c</kll>\n"
1316 "</df>\n";
1317 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1318 " <kll>b</kll>\n"
1319 " <kll>c</kll>\n"
1320 " <kll>a</kll>\n"
1321 " <kll>a</kll>\n"
1322 " <kll>a</kll>\n"
1323 "</df>\n";
1324 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1325 " <kll>a</kll>\n"
1326 " <kll>d</kll>\n"
1327 " <kll>a</kll>\n"
1328 "</df>\n";
1329
1330 const char *out_diff_1 =
1331 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1332 " <kll yang:operation=\"replace\" yang:orig-default=\"false\" yang:position=\"\" yang:orig-position=\"1\">b</kll>\n"
1333 " <kll yang:operation=\"replace\" yang:orig-default=\"false\" yang:position=\"1\" yang:orig-position=\"2\">c</kll>\n"
1334 " <kll yang:operation=\"create\" yang:position=\"3\">a</kll>\n"
1335 " <kll yang:operation=\"create\" yang:position=\"4\">a</kll>\n"
1336 "</df>\n";
1337 const char *out_diff_2 =
1338 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1339 " <kll yang:operation=\"delete\" yang:orig-position=\"\">b</kll>\n"
1340 " <kll yang:operation=\"delete\" yang:orig-position=\"\">c</kll>\n"
1341 " <kll yang:operation=\"delete\" yang:orig-position=\"2\">a</kll>\n"
1342 " <kll yang:operation=\"create\" yang:position=\"1\">d</kll>\n"
1343 "</df>\n";
1344 const char *out_merge =
1345 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1346 " <kll yang:orig-default=\"false\" yang:orig-position=\"1\" yang:operation=\"delete\">b</kll>\n"
1347 " <kll yang:orig-default=\"false\" yang:orig-position=\"2\" yang:operation=\"delete\">c</kll>\n"
1348 " <kll yang:operation=\"create\" yang:position=\"4\">a</kll>\n"
1349 " <kll yang:position=\"1\" yang:operation=\"create\">d</kll>\n"
1350 "</df>\n";
1351
1352 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
1353}
1354
1355static void
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001356test_wd(void **state)
1357{
Radek Iša56ca9e42020-09-08 18:42:00 +02001358 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001359 const struct lys_module *mod;
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001360 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1361 " <foo>41</foo>\n"
1362 " <dllist>4</dllist>\n"
1363 "</df>\n";
1364 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1365 " <foo>42</foo>\n"
1366 " <dllist>4</dllist>\n"
1367 " <dllist>1</dllist>\n"
1368 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001369
Radek Iša56ca9e42020-09-08 18:42:00 +02001370 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "defaults");
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001371 assert_non_null(mod);
1372
Radek Iša56ca9e42020-09-08 18:42:00 +02001373 struct lyd_node *model_1 = NULL;
1374
1375 assert_int_equal(lyd_validate_module(&model_1, mod, 0, NULL), LY_SUCCESS);
1376 assert_ptr_not_equal(model_1, NULL);
1377
1378 struct lyd_node *model_2;
1379 struct lyd_node *model_3;
1380
1381 CHECK_PARSE_LYD_PARAM(xml2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1382 CHECK_PARSE_LYD_PARAM(xml3, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_3);
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001383
Michal Vaskoe6323f62020-07-09 15:49:02 +02001384 /* diff1 */
Radek Iša56ca9e42020-09-08 18:42:00 +02001385 struct lyd_node *diff1 = NULL;
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001386
Radek Iša56ca9e42020-09-08 18:42:00 +02001387 assert_int_equal(lyd_diff_siblings(model_1, model_2, LYD_DIFF_DEFAULTS, &diff1), LY_SUCCESS);
1388 assert_non_null(diff1);
1389
1390 const char *diff1_out_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001391 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1392 " <foo yang:operation=\"replace\" yang:orig-default=\"true\" yang:orig-value=\"42\">41</foo>\n"
1393 " <dllist yang:operation=\"delete\">1</dllist>\n"
1394 " <dllist yang:operation=\"delete\">2</dllist>\n"
1395 " <dllist yang:operation=\"delete\">3</dllist>\n"
1396 " <dllist yang:operation=\"create\">4</dllist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001397 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001398
Radek Iša56ca9e42020-09-08 18:42:00 +02001399 CHECK_LYD_STRING_PARAM(diff1, diff1_out_1, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
1400 assert_int_equal(lyd_diff_apply_all(&model_1, diff1), LY_SUCCESS);
1401 CHECK_LYD(model_1, model_2);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001402
1403 /* diff2 */
Radek Iša56ca9e42020-09-08 18:42:00 +02001404 struct lyd_node *diff2;
Michal Vaskoe6323f62020-07-09 15:49:02 +02001405
Radek Iša56ca9e42020-09-08 18:42:00 +02001406 assert_int_equal(lyd_diff_siblings(model_2, model_3, LYD_DIFF_DEFAULTS, &diff2), LY_SUCCESS);
1407 assert_non_null(diff2);
1408 CHECK_LYD_STRING(diff2,
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001409 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1410 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"41\">42</foo>\n"
1411 " <dllist yang:operation=\"create\">1</dllist>\n"
1412 "</df>\n");
Michal Vaskoe6323f62020-07-09 15:49:02 +02001413
Radek Iša56ca9e42020-09-08 18:42:00 +02001414 assert_int_equal(lyd_diff_apply_all(&model_2, diff2), LY_SUCCESS);
1415 CHECK_LYD(model_2, model_3);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001416
1417 /* merge */
Radek Iša56ca9e42020-09-08 18:42:00 +02001418 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001419
Radek Iša56ca9e42020-09-08 18:42:00 +02001420 const char *diff1_out_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001421 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1422 " <foo yang:orig-default=\"true\" yang:operation=\"none\">42</foo>\n"
1423 " <dllist yang:operation=\"none\" yang:orig-default=\"true\">1</dllist>\n"
1424 " <dllist yang:operation=\"delete\">2</dllist>\n"
1425 " <dllist yang:operation=\"delete\">3</dllist>\n"
1426 " <dllist yang:operation=\"create\">4</dllist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001427 "</df>\n";
1428
1429 CHECK_LYD_STRING_PARAM(diff1, diff1_out_2, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
1430
1431 lyd_free_all(model_1);
1432 lyd_free_all(model_2);
1433 lyd_free_all(model_3);
1434 lyd_free_all(diff1);
1435 lyd_free_all(diff2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001436}
1437
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001438int
1439main(void)
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001440{
1441 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +02001442 UTEST(test_invalid, setup),
1443 UTEST(test_same, setup),
1444 UTEST(test_empty1, setup),
1445 UTEST(test_empty2, setup),
1446 UTEST(test_empty_nested, setup),
Michal Vasko17d0c5c2021-11-01 11:31:11 +01001447 UTEST(test_delete_merge, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001448 UTEST(test_leaf, setup),
1449 UTEST(test_list, setup),
Michal Vasko58d89e92023-05-23 09:56:19 +02001450 UTEST(test_nested_list, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001451 UTEST(test_userord_llist, setup),
1452 UTEST(test_userord_llist2, setup),
1453 UTEST(test_userord_mix, setup),
Michal Vaskoe78faec2021-04-08 17:24:43 +02001454 UTEST(test_userord_list, setup),
Michal Vasko5da938a2022-03-01 09:19:02 +01001455 UTEST(test_userord_list2, setup),
Michal Vaskofb51a842023-06-20 08:50:24 +02001456 UTEST(test_userord_list3, setup),
Michal Vaskoe78faec2021-04-08 17:24:43 +02001457 UTEST(test_keyless_list, setup),
1458 UTEST(test_state_llist, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001459 UTEST(test_wd, setup),
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001460 };
1461
1462 return cmocka_run_group_tests(tests, NULL, NULL);
1463}