blob: b0d510474e458a610e52c3bff193bd9f71dd098b [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;\
Radek Iša56ca9e42020-09-08 18:42:00 +020035 /*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);\
Radek Iša56ca9e42020-09-08 18:42:00 +020039 /* 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); \
Radek Iša56ca9e42020-09-08 18:42:00 +020045 /* 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);\
Radek Iša56ca9e42020-09-08 18:42:00 +020051 /* 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); \
54 /* cleanup */ \
55 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 Vasko3a41dff2020-07-15 14:30:28 +0200315 assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, NULL), LY_EINVAL);
Radek Iša56ca9e42020-09-08 18:42:00 +0200316
317 lyd_free_all(model_1);
318 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200319}
320
321static void
322test_same(void **state)
323{
Radek Iša56ca9e42020-09-08 18:42:00 +0200324 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100325 const char *xml =
326 "<nacm xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-acm\">\n"
327 " <enable-nacm>true</enable-nacm>\n"
328 " <read-default>permit</read-default>\n"
329 " <write-default>deny</write-default>\n"
330 " <exec-default>permit</exec-default>\n"
331 " <enable-external-groups>true</enable-external-groups>\n"
332 "</nacm><df xmlns=\"urn:libyang:tests:defaults\">\n"
333 " <foo>42</foo><b1_1>42</b1_1>\n"
334 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">\n"
335 " <foo>42</foo><baz>42</baz></hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200336
Radek Iša56ca9e42020-09-08 18:42:00 +0200337 struct lyd_node *model_1;
338 struct lyd_node *model_2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200339
Radek Iša56ca9e42020-09-08 18:42:00 +0200340 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
341 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-acm", "2018-02-14", NULL));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200342
Radek Iša56ca9e42020-09-08 18:42:00 +0200343 CHECK_PARSE_LYD(xml, model_1);
344 CHECK_PARSE_LYD(xml, model_2);
345
346 struct lyd_node *diff = NULL;
347
348 assert_int_equal(lyd_diff_siblings(model_1, model_2, 0, &diff), LY_SUCCESS);
349 assert_null(diff);
350 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
351 CHECK_LYD(model_1, model_2);
352
353 lyd_free_all(model_1);
354 lyd_free_all(model_2);
355 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200356}
357
358static void
359test_empty1(void **state)
360{
Radek Iša56ca9e42020-09-08 18:42:00 +0200361 (void) state;
362 const char *xml_in =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100363 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
364 " <foo>42</foo>\n"
365 " <b1_1>42</b1_1>\n"
366 "</df>\n"
367 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
368 " <foo>42</foo>\n"
369 " <baz>42</baz>\n"
370 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200371
Radek Iša56ca9e42020-09-08 18:42:00 +0200372 struct lyd_node *model_1 = NULL;
373 struct lyd_node *model_2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200374
Radek Iša56ca9e42020-09-08 18:42:00 +0200375 CHECK_PARSE_LYD(xml_in, model_2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200376
Radek Iša56ca9e42020-09-08 18:42:00 +0200377 struct lyd_node *diff;
378
379 CHECK_PARSE_LYD_DIFF(model_1, model_2, diff);
380 CHECK_LYD_STRING(diff,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100381 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
382 " <foo>42</foo>\n"
383 " <b1_1>42</b1_1>\n"
384 "</df>\n"
385 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
386 " <foo>42</foo>\n"
387 " <baz>42</baz>\n"
388 "</hidden>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200389 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
390 CHECK_LYD(model_1, model_2);
391
392 lyd_free_all(model_1);
393 lyd_free_all(model_2);
394 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200395}
396
397static void
398test_empty2(void **state)
399{
Radek Iša56ca9e42020-09-08 18:42:00 +0200400 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100401 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
402 " <foo>42</foo>\n"
403 " <b1_1>42</b1_1>\n"
404 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">\n"
405 " <foo>42</foo>\n"
406 " <baz>42</baz>\n"
407 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200408
Radek Iša56ca9e42020-09-08 18:42:00 +0200409 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200410
Radek Iša56ca9e42020-09-08 18:42:00 +0200411 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200412
Radek Iša56ca9e42020-09-08 18:42:00 +0200413 struct lyd_node *diff;
414
415 CHECK_PARSE_LYD_DIFF(model_1, NULL, diff);
416 CHECK_LYD_STRING(diff,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100417 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
418 " <foo>42</foo>\n"
419 " <b1_1>42</b1_1>\n"
420 "</df>\n"
421 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
422 " <foo>42</foo>\n"
423 " <baz>42</baz>\n"
424 "</hidden>\n");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200425
Radek Iša56ca9e42020-09-08 18:42:00 +0200426 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
427 assert_ptr_equal(model_1, NULL);
428
429 lyd_free_all(diff);
430 lyd_free_all(model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200431}
432
433static void
434test_empty_nested(void **state)
435{
Radek Iša56ca9e42020-09-08 18:42:00 +0200436 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200437 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
438
Radek Iša56ca9e42020-09-08 18:42:00 +0200439 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200440
Radek Iša56ca9e42020-09-08 18:42:00 +0200441 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200442
Radek Iša56ca9e42020-09-08 18:42:00 +0200443 struct lyd_node *diff = NULL;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200444
Radek Iša56ca9e42020-09-08 18:42:00 +0200445 assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, &diff), LY_SUCCESS);
446 assert_null(diff);
447
448 struct lyd_node *diff1;
449
450 CHECK_PARSE_LYD_DIFF(NULL, lyd_child(model_1), diff1);
451 CHECK_LYD_STRING(diff1,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100452 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
453 " <foo yang:operation=\"create\">42</foo>\n"
454 "</df>\n");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200455
Radek Iša56ca9e42020-09-08 18:42:00 +0200456 struct lyd_node *diff2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200457
Radek Iša56ca9e42020-09-08 18:42:00 +0200458 CHECK_PARSE_LYD_DIFF(lyd_child(model_1), NULL, diff2);
459 CHECK_LYD_STRING(diff2,
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=\"delete\">42</foo>\n"
462 "</df>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200463
464 lyd_free_all(model_1);
465 lyd_free_all(diff1);
466 lyd_free_all(diff2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200467}
468
469static void
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100470test_delete_merge(void **state)
471{
472 (void) state;
473 struct lyd_node *diff1, *diff2;
474 const char *xml1 =
475 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
476 " <list>\n"
477 " <name>a</name>\n"
478 " <list2 yang:operation=\"delete\">\n"
479 " <name2>a</name2>\n"
480 " </list2>\n"
481 " </list>\n"
482 "</df>\n";
483 const char *xml2 =
484 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
485 " <list yang:operation=\"delete\">\n"
486 " <name>a</name>\n"
487 " </list>\n"
488 "</df>\n";
489 const char *xml_merge =
490 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
491 " <list yang:operation=\"delete\">\n"
492 " <name>a</name>\n"
493 " <list2 yang:operation=\"delete\">\n"
494 " <name2>a</name2>\n"
495 " </list2>\n"
496 " </list>\n"
497 "</df>\n";
498
499 CHECK_PARSE_LYD(xml1, diff1);
500 CHECK_PARSE_LYD(xml2, diff2);
501
502 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);
503 CHECK_LYD_STRING(diff1, xml_merge);
504
505 lyd_free_all(diff1);
506 lyd_free_all(diff2);
507}
508
509static void
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200510test_leaf(void **state)
511{
Radek Iša56ca9e42020-09-08 18:42:00 +0200512 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200513 const char *xml1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100514 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
515 " <foo>42</foo>\n"
516 "</df>\n"
517 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
518 " <foo>42</foo>\n"
519 " <baz>42</baz>\n"
520 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200521 const char *xml2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100522 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
523 " <foo>41</foo>\n"
524 " <b1_1>42</b1_1>\n"
525 "</df>\n";
Michal Vaskoe6323f62020-07-09 15:49:02 +0200526 const char *xml3 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100527 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
528 " <foo>40</foo>\n"
529 "</df>\n"
530 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
531 " <foo>40</foo>\n"
532 "</hidden>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200533 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100534 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
535 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"42\">41</foo>\n"
536 " <b1_1 yang:operation=\"create\">42</b1_1>\n"
537 "</df>\n"
538 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
539 " <foo>42</foo>\n"
540 " <baz>42</baz>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200541 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200542
Radek Iša56ca9e42020-09-08 18:42:00 +0200543 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 +0100544 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"41\">40</foo>\n"
545 " <b1_1 yang:operation=\"delete\">42</b1_1>\n"
546 "</df>\n"
547 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
548 " <foo>40</foo>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200549 "</hidden>\n";
Michal Vaskoe6323f62020-07-09 15:49:02 +0200550
Radek Iša56ca9e42020-09-08 18:42:00 +0200551 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100552 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
553 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"42\">40</foo>\n"
554 "</df>\n"
555 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
556 " <foo yang:operation=\"replace\" yang:orig-value=\"42\" yang:orig-default=\"false\">40</foo>\n"
557 " <baz yang:operation=\"delete\">42</baz>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200558 "</hidden>\n";
559
560 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200561}
562
563static void
564test_list(void **state)
565{
Radek Iša56ca9e42020-09-08 18:42:00 +0200566 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100567 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
568 " <list>\n"
569 " <name>a</name>\n"
570 " <value>1</value>\n"
571 " </list>\n"
572 " <list>\n"
573 " <name>b</name>\n"
574 " <value>2</value>\n"
575 " </list>\n"
576 "</df>\n";
577 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
578 " <list>\n"
579 " <name>b</name>\n"
580 " <value>-2</value>\n"
581 " </list>\n"
582 " <list>\n"
583 " <name>c</name>\n"
584 " <value>3</value>\n"
585 " </list>\n"
586 "</df>\n";
587 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
588 " <list>\n"
589 " <name>b</name>\n"
590 " <value>-2</value>\n"
591 " </list>\n"
592 " <list>\n"
593 " <name>a</name>\n"
594 " <value>2</value>\n"
595 " </list>\n"
596 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200597
Radek Iša56ca9e42020-09-08 18:42:00 +0200598 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100599 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
600 " <list yang:operation=\"delete\">\n"
601 " <name>a</name>\n"
602 " <value>1</value>\n"
603 " </list>\n"
604 " <list yang:operation=\"none\">\n"
605 " <name>b</name>\n"
606 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\">-2</value>\n"
607 " </list>\n"
608 " <list yang:operation=\"create\">\n"
609 " <name>c</name>\n"
610 " <value>3</value>\n"
611 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200612 "</df>\n";
613 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100614 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
615 " <list yang:operation=\"delete\">\n"
616 " <name>c</name>\n"
617 " <value>3</value>\n"
618 " </list>\n"
619 " <list yang:operation=\"create\">\n"
620 " <name>a</name>\n"
621 " <value>2</value>\n"
622 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200623 "</df>\n";
624 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100625 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
626 " <list yang:operation=\"none\">\n"
627 " <name>a</name>\n"
628 " <value yang:operation=\"replace\" yang:orig-value=\"1\" yang:orig-default=\"false\">2</value>\n"
629 " </list>\n"
630 " <list yang:operation=\"none\">\n"
631 " <name>b</name>\n"
632 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\">-2</value>\n"
633 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200634 "</df>\n";
635
636 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200637}
638
639static void
640test_userord_llist(void **state)
641{
Radek Iša56ca9e42020-09-08 18:42:00 +0200642 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100643 const char *xml1 =
644 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
645 " <llist>1</llist>\n"
646 " <llist>2</llist>\n"
647 " <llist>3</llist>\n"
648 " <llist>4</llist>\n"
649 " <llist>5</llist>\n"
650 "</df>\n";
651 const char *xml2 =
652 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
653 " <llist>1</llist>\n"
654 " <llist>4</llist>\n"
655 " <llist>3</llist>\n"
656 " <llist>2</llist>\n"
657 " <llist>5</llist>\n"
658 "</df>\n";
659 const char *xml3 =
660 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
661 " <llist>5</llist>\n"
662 " <llist>4</llist>\n"
663 " <llist>3</llist>\n"
664 " <llist>2</llist>\n"
665 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200666
Radek Iša56ca9e42020-09-08 18:42:00 +0200667 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100668 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
669 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>\n"
670 " <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 +0200671 "</df>\n";
672 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100673 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
674 " <llist yang:operation=\"delete\" yang:orig-value=\"\">1</llist>\n"
675 " <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 +0200676 "</df>\n";
677 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100678 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
679 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>\n"
680 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\" yang:value=\"4\">3</llist>\n"
681 " <llist yang:orig-value=\"\" yang:operation=\"delete\">1</llist>\n"
682 " <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 +0200683 "</df>\n";
684
685 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200686}
687
688static void
689test_userord_llist2(void **state)
690{
Radek Iša56ca9e42020-09-08 18:42:00 +0200691 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100692 const char *xml1 =
693 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
694 " <llist>1</llist>\n"
695 " <list><name>a</name><value>1</value></list>\n"
696 " <llist>2</llist>\n"
697 " <llist>3</llist>\n"
698 " <llist>4</llist>\n"
699 "</df>\n";
700 const char *xml2 =
701 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
702 " <llist>1</llist>\n"
703 " <list><name>a</name><value>1</value></list>\n"
704 " <llist>2</llist>\n"
705 " <llist>4</llist>\n"
706 " <llist>3</llist>\n"
707 "</df>\n";
708 const char *xml3 =
709 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
710 " <llist>4</llist>\n"
711 " <llist>1</llist>\n"
712 " <list><name>a</name><value>1</value></list>\n"
713 " <llist>3</llist>\n"
714 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200715
Radek Iša56ca9e42020-09-08 18:42:00 +0200716 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100717 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
718 " <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 +0200719 "</df>\n";
720 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100721 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
722 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
723 " <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 +0200724 "</df>\n";
725 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100726 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
727 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\">4</llist>\n"
728 " <llist yang:orig-value=\"1\" yang:operation=\"delete\">2</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200729 "</df>\n";
730
731 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200732}
733
734static void
735test_userord_mix(void **state)
736{
Radek Iša56ca9e42020-09-08 18:42:00 +0200737 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100738 const char *xml1 =
739 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
740 " <llist>1</llist>\n"
741 " <llist>2</llist>\n"
742 " <llist>3</llist>\n"
743 "</df>\n";
744 const char *xml2 =
745 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
746 " <llist>3</llist>\n"
747 " <llist>1</llist>\n"
748 "</df>\n";
749 const char *xml3 =
750 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
751 " <llist>1</llist>\n"
752 " <llist>4</llist>\n"
753 " <llist>3</llist>\n"
754 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200755
Radek Iša56ca9e42020-09-08 18:42:00 +0200756 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100757 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
758 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
759 " <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 +0200760 "</df>\n";
761 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100762 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
763 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\">1</llist>\n"
764 " <llist yang:operation=\"create\" yang:value=\"1\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200765 "</df>\n";
766 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100767 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
768 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
769 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\" yang:value=\"\">3</llist>\n"
770 " <llist yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\" yang:operation=\"replace\">1</llist>\n"
771 " <llist yang:value=\"1\" yang:operation=\"create\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200772 "</df>\n";
773
774 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200775}
776
777static void
Michal Vaskoe78faec2021-04-08 17:24:43 +0200778test_userord_list(void **state)
779{
780 (void) state;
781 const char *xml1 =
782 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
783 " <ul>\n"
784 " <l1>a</l1>\n"
785 " <l2>1</l2>\n"
786 " </ul>\n"
787 " <ul>\n"
788 " <l1>b</l1>\n"
789 " <l2>2</l2>\n"
790 " </ul>\n"
791 " <ul>\n"
792 " <l1>c</l1>\n"
793 " <l2>3</l2>\n"
794 " </ul>\n"
795 "</df>\n";
796 const char *xml2 =
797 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
798 " <ul>\n"
799 " <l1>a</l1>\n"
800 " <l2>11</l2>\n"
801 " </ul>\n"
802 " <ul>\n"
803 " <l1>c</l1>\n"
804 " <l2>3</l2>\n"
805 " </ul>\n"
806 "</df>\n";
807 const char *xml3 =
808 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
809 " <ul>\n"
810 " <l1>c</l1>\n"
811 " <l2>33</l2>\n"
812 " </ul>\n"
813 " <ul>\n"
814 " <l1>b</l1>\n"
815 " <l2>2</l2>\n"
816 " </ul>\n"
817 "</df>\n";
818
819 const char *out_diff_1 =
820 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
821 " <ul>\n"
822 " <l1>a</l1>\n"
823 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\">11</l2>\n"
824 " </ul>\n"
825 " <ul yang:operation=\"delete\" yang:orig-key=\"[l1='a']\">\n"
826 " <l1>b</l1>\n"
827 " <l2>2</l2>\n"
828 " </ul>\n"
829 "</df>\n";
830 const char *out_diff_2 =
831 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
832 " <ul yang:operation=\"delete\" yang:orig-key=\"\">\n"
833 " <l1>a</l1>\n"
834 " <l2>11</l2>\n"
835 " </ul>\n"
836 " <ul yang:operation=\"none\">\n"
837 " <l1>c</l1>\n"
838 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\">33</l2>\n"
839 " </ul>\n"
840 " <ul yang:operation=\"create\" yang:key=\"[l1='c']\">\n"
841 " <l1>b</l1>\n"
842 " <l2>2</l2>\n"
843 " </ul>\n"
844 "</df>\n";
845 const char *out_merge =
846 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
847 " <ul yang:operation=\"delete\">\n"
848 " <l1>a</l1>\n"
849 " <l2 yang:operation=\"delete\">1</l2>\n"
850 " </ul>\n"
851 " <ul yang:orig-key=\"[l1='a']\" yang:operation=\"replace\" yang:key=\"[l1='c']\">\n"
852 " <l1>b</l1>\n"
853 " </ul>\n"
854 " <ul yang:operation=\"none\">\n"
855 " <l1>c</l1>\n"
856 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\">33</l2>\n"
857 " </ul>\n"
858 "</df>\n";
859
860 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
861}
862
863static void
Michal Vasko5da938a2022-03-01 09:19:02 +0100864test_userord_list2(void **state)
865{
866 (void) state;
867 const char *xml1 =
868 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
869 " <ul>\n"
870 " <l1>d</l1>\n"
871 " <l2>4</l2>\n"
872 " </ul>\n"
873 "</df>\n";
874 const char *xml2 =
875 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
876 " <ul>\n"
877 " <l1>c</l1>\n"
878 " <l2>3</l2>\n"
879 " </ul>\n"
880 " <ul>\n"
881 " <l1>d</l1>\n"
882 " <l2>4</l2>\n"
883 " </ul>\n"
884 "</df>\n";
885 const char *xml3 =
886 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
887 " <ul>\n"
888 " <l1>a</l1>\n"
889 " <l2>1</l2>\n"
890 " </ul>\n"
891 " <ul>\n"
892 " <l1>b</l1>\n"
893 " <l2>2</l2>\n"
894 " </ul>\n"
895 " <ul>\n"
896 " <l1>c</l1>\n"
897 " <l2>3</l2>\n"
898 " </ul>\n"
899 " <ul>\n"
900 " <l1>d</l1>\n"
901 " <l2>4</l2>\n"
902 " </ul>\n"
903 "</df>\n";
904
905 const char *out_diff_1 =
906 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
907 " <ul yang:operation=\"create\" yang:key=\"\">\n"
908 " <l1>c</l1>\n"
909 " <l2>3</l2>\n"
910 " </ul>\n"
911 "</df>\n";
912 const char *out_diff_2 =
913 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
914 " <ul yang:operation=\"create\" yang:key=\"\">\n"
915 " <l1>a</l1>\n"
916 " <l2>1</l2>\n"
917 " </ul>\n"
918 " <ul yang:operation=\"create\" yang:key=\"[l1='a']\">\n"
919 " <l1>b</l1>\n"
920 " <l2>2</l2>\n"
921 " </ul>\n"
922 "</df>\n";
923 const char *out_merge =
924 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
925 " <ul yang:operation=\"create\" yang:key=\"\">\n"
926 " <l1>c</l1>\n"
927 " <l2>3</l2>\n"
928 " </ul>\n"
929 " <ul yang:key=\"\" yang:operation=\"create\">\n"
930 " <l1>a</l1>\n"
931 " <l2>1</l2>\n"
932 " </ul>\n"
933 " <ul yang:key=\"[l1='a']\" yang:operation=\"create\">\n"
934 " <l1>b</l1>\n"
935 " <l2>2</l2>\n"
936 " </ul>\n"
937 "</df>\n";
938
939 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
940}
941
942static void
Michal Vaskoe78faec2021-04-08 17:24:43 +0200943test_keyless_list(void **state)
944{
945 (void) state;
946 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
947 " <kl>\n"
948 " <l1>a</l1>\n"
949 " <l2>1</l2>\n"
950 " </kl>\n"
951 " <kl>\n"
952 " <l1>b</l1>\n"
953 " <l2>2</l2>\n"
954 " </kl>\n"
955 " <kl>\n"
956 " <l1>c</l1>\n"
957 " <l2>3</l2>\n"
958 " </kl>\n"
959 "</df>\n";
960 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
961 " <kl>\n"
962 " <l1>b</l1>\n"
963 " <l2>2</l2>\n"
964 " </kl>\n"
965 " <kl>\n"
966 " <l1>a</l1>\n"
967 " <l2>1</l2>\n"
968 " </kl>\n"
969 " <kl>\n"
970 " <l1>a</l1>\n"
971 " <l2>1</l2>\n"
972 " </kl>\n"
973 "</df>\n";
974 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
975 " <kl>\n"
976 " <l1>c</l1>\n"
977 " </kl>\n"
978 " <kl>\n"
979 " <l2>4</l2>\n"
980 " </kl>\n"
981 " <kl>\n"
982 " <l1>e</l1>\n"
983 " <l2>5</l2>\n"
984 " </kl>\n"
985 " <kl>\n"
986 " <l1>f</l1>\n"
987 " <l2>6</l2>\n"
988 " </kl>\n"
989 "</df>\n";
990
991 const char *out_diff_1 =
992 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
993 " <kl yang:operation=\"delete\" yang:orig-position=\"2\">\n"
994 " <l1>c</l1>\n"
995 " <l2>3</l2>\n"
996 " </kl>\n"
997 " <kl yang:operation=\"replace\" yang:position=\"\" yang:orig-position=\"1\">\n"
998 " <l1>b</l1>\n"
999 " <l2>2</l2>\n"
1000 " </kl>\n"
1001 " <kl yang:operation=\"create\" yang:position=\"2\">\n"
1002 " <l1>a</l1>\n"
1003 " <l2>1</l2>\n"
1004 " </kl>\n"
1005 "</df>\n";
1006 const char *out_diff_2 =
1007 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1008 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
1009 " <l1>b</l1>\n"
1010 " <l2>2</l2>\n"
1011 " </kl>\n"
1012 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
1013 " <l1>a</l1>\n"
1014 " <l2>1</l2>\n"
1015 " </kl>\n"
1016 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
1017 " <l1>a</l1>\n"
1018 " <l2>1</l2>\n"
1019 " </kl>\n"
1020 " <kl yang:operation=\"create\" yang:position=\"\">\n"
1021 " <l1>c</l1>\n"
1022 " </kl>\n"
1023 " <kl yang:operation=\"create\" yang:position=\"1\">\n"
1024 " <l2>4</l2>\n"
1025 " </kl>\n"
1026 " <kl yang:operation=\"create\" yang:position=\"2\">\n"
1027 " <l1>e</l1>\n"
1028 " <l2>5</l2>\n"
1029 " </kl>\n"
1030 " <kl yang:operation=\"create\" yang:position=\"3\">\n"
1031 " <l1>f</l1>\n"
1032 " <l2>6</l2>\n"
1033 " </kl>\n"
1034 "</df>\n";
1035 const char *out_merge =
1036 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1037 " <kl yang:operation=\"delete\" yang:orig-position=\"2\">\n"
1038 " <l1>c</l1>\n"
1039 " <l2>3</l2>\n"
1040 " </kl>\n"
1041 " <kl yang:orig-position=\"1\" yang:operation=\"delete\">\n"
1042 " <l1>b</l1>\n"
1043 " <l2>2</l2>\n"
1044 " </kl>\n"
1045 " <kl yang:orig-position=\"\" yang:operation=\"delete\">\n"
1046 " <l1>a</l1>\n"
1047 " <l2>1</l2>\n"
1048 " </kl>\n"
1049 " <kl yang:position=\"\" yang:operation=\"create\">\n"
1050 " <l1>c</l1>\n"
1051 " </kl>\n"
1052 " <kl yang:position=\"1\" yang:operation=\"create\">\n"
1053 " <l2>4</l2>\n"
1054 " </kl>\n"
1055 " <kl yang:position=\"2\" yang:operation=\"create\">\n"
1056 " <l1>e</l1>\n"
1057 " <l2>5</l2>\n"
1058 " </kl>\n"
1059 " <kl yang:position=\"3\" yang:operation=\"create\">\n"
1060 " <l1>f</l1>\n"
1061 " <l2>6</l2>\n"
1062 " </kl>\n"
1063 "</df>\n";
1064
1065 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
1066}
1067
1068static void
1069test_state_llist(void **state)
1070{
1071 (void) state;
1072 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1073 " <kll>a</kll>\n"
1074 " <kll>b</kll>\n"
1075 " <kll>c</kll>\n"
1076 "</df>\n";
1077 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1078 " <kll>b</kll>\n"
1079 " <kll>c</kll>\n"
1080 " <kll>a</kll>\n"
1081 " <kll>a</kll>\n"
1082 " <kll>a</kll>\n"
1083 "</df>\n";
1084 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1085 " <kll>a</kll>\n"
1086 " <kll>d</kll>\n"
1087 " <kll>a</kll>\n"
1088 "</df>\n";
1089
1090 const char *out_diff_1 =
1091 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1092 " <kll yang:operation=\"replace\" yang:orig-default=\"false\" yang:position=\"\" yang:orig-position=\"1\">b</kll>\n"
1093 " <kll yang:operation=\"replace\" yang:orig-default=\"false\" yang:position=\"1\" yang:orig-position=\"2\">c</kll>\n"
1094 " <kll yang:operation=\"create\" yang:position=\"3\">a</kll>\n"
1095 " <kll yang:operation=\"create\" yang:position=\"4\">a</kll>\n"
1096 "</df>\n";
1097 const char *out_diff_2 =
1098 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1099 " <kll yang:operation=\"delete\" yang:orig-position=\"\">b</kll>\n"
1100 " <kll yang:operation=\"delete\" yang:orig-position=\"\">c</kll>\n"
1101 " <kll yang:operation=\"delete\" yang:orig-position=\"2\">a</kll>\n"
1102 " <kll yang:operation=\"create\" yang:position=\"1\">d</kll>\n"
1103 "</df>\n";
1104 const char *out_merge =
1105 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1106 " <kll yang:orig-default=\"false\" yang:orig-position=\"1\" yang:operation=\"delete\">b</kll>\n"
1107 " <kll yang:orig-default=\"false\" yang:orig-position=\"2\" yang:operation=\"delete\">c</kll>\n"
1108 " <kll yang:operation=\"create\" yang:position=\"4\">a</kll>\n"
1109 " <kll yang:position=\"1\" yang:operation=\"create\">d</kll>\n"
1110 "</df>\n";
1111
1112 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
1113}
1114
1115static void
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001116test_wd(void **state)
1117{
Radek Iša56ca9e42020-09-08 18:42:00 +02001118 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001119 const struct lys_module *mod;
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001120 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1121 " <foo>41</foo>\n"
1122 " <dllist>4</dllist>\n"
1123 "</df>\n";
1124 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1125 " <foo>42</foo>\n"
1126 " <dllist>4</dllist>\n"
1127 " <dllist>1</dllist>\n"
1128 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001129
Radek Iša56ca9e42020-09-08 18:42:00 +02001130 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "defaults");
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001131 assert_non_null(mod);
1132
Radek Iša56ca9e42020-09-08 18:42:00 +02001133 struct lyd_node *model_1 = NULL;
1134
1135 assert_int_equal(lyd_validate_module(&model_1, mod, 0, NULL), LY_SUCCESS);
1136 assert_ptr_not_equal(model_1, NULL);
1137
1138 struct lyd_node *model_2;
1139 struct lyd_node *model_3;
1140
1141 CHECK_PARSE_LYD_PARAM(xml2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1142 CHECK_PARSE_LYD_PARAM(xml3, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_3);
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001143
Michal Vaskoe6323f62020-07-09 15:49:02 +02001144 /* diff1 */
Radek Iša56ca9e42020-09-08 18:42:00 +02001145 struct lyd_node *diff1 = NULL;
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001146
Radek Iša56ca9e42020-09-08 18:42:00 +02001147 assert_int_equal(lyd_diff_siblings(model_1, model_2, LYD_DIFF_DEFAULTS, &diff1), LY_SUCCESS);
1148 assert_non_null(diff1);
1149
1150 const char *diff1_out_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001151 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1152 " <foo yang:operation=\"replace\" yang:orig-default=\"true\" yang:orig-value=\"42\">41</foo>\n"
1153 " <dllist yang:operation=\"delete\">1</dllist>\n"
1154 " <dllist yang:operation=\"delete\">2</dllist>\n"
1155 " <dllist yang:operation=\"delete\">3</dllist>\n"
1156 " <dllist yang:operation=\"create\">4</dllist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001157 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001158
Radek Iša56ca9e42020-09-08 18:42:00 +02001159 CHECK_LYD_STRING_PARAM(diff1, diff1_out_1, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
1160 assert_int_equal(lyd_diff_apply_all(&model_1, diff1), LY_SUCCESS);
1161 CHECK_LYD(model_1, model_2);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001162
1163 /* diff2 */
Radek Iša56ca9e42020-09-08 18:42:00 +02001164 struct lyd_node *diff2;
Michal Vaskoe6323f62020-07-09 15:49:02 +02001165
Radek Iša56ca9e42020-09-08 18:42:00 +02001166 assert_int_equal(lyd_diff_siblings(model_2, model_3, LYD_DIFF_DEFAULTS, &diff2), LY_SUCCESS);
1167 assert_non_null(diff2);
1168 CHECK_LYD_STRING(diff2,
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001169 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1170 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"41\">42</foo>\n"
1171 " <dllist yang:operation=\"create\">1</dllist>\n"
1172 "</df>\n");
Michal Vaskoe6323f62020-07-09 15:49:02 +02001173
Radek Iša56ca9e42020-09-08 18:42:00 +02001174 assert_int_equal(lyd_diff_apply_all(&model_2, diff2), LY_SUCCESS);
1175 CHECK_LYD(model_2, model_3);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001176
1177 /* merge */
Radek Iša56ca9e42020-09-08 18:42:00 +02001178 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001179
Radek Iša56ca9e42020-09-08 18:42:00 +02001180 const char *diff1_out_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001181 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1182 " <foo yang:orig-default=\"true\" yang:operation=\"none\">42</foo>\n"
1183 " <dllist yang:operation=\"none\" yang:orig-default=\"true\">1</dllist>\n"
1184 " <dllist yang:operation=\"delete\">2</dllist>\n"
1185 " <dllist yang:operation=\"delete\">3</dllist>\n"
1186 " <dllist yang:operation=\"create\">4</dllist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001187 "</df>\n";
1188
1189 CHECK_LYD_STRING_PARAM(diff1, diff1_out_2, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
1190
1191 lyd_free_all(model_1);
1192 lyd_free_all(model_2);
1193 lyd_free_all(model_3);
1194 lyd_free_all(diff1);
1195 lyd_free_all(diff2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001196}
1197
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001198int
1199main(void)
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001200{
1201 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +02001202 UTEST(test_invalid, setup),
1203 UTEST(test_same, setup),
1204 UTEST(test_empty1, setup),
1205 UTEST(test_empty2, setup),
1206 UTEST(test_empty_nested, setup),
Michal Vasko17d0c5c2021-11-01 11:31:11 +01001207 UTEST(test_delete_merge, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001208 UTEST(test_leaf, setup),
1209 UTEST(test_list, setup),
1210 UTEST(test_userord_llist, setup),
1211 UTEST(test_userord_llist2, setup),
1212 UTEST(test_userord_mix, setup),
Michal Vaskoe78faec2021-04-08 17:24:43 +02001213 UTEST(test_userord_list, setup),
Michal Vasko5da938a2022-03-01 09:19:02 +01001214 UTEST(test_userord_list2, setup),
Michal Vaskoe78faec2021-04-08 17:24:43 +02001215 UTEST(test_keyless_list, setup),
1216 UTEST(test_state_llist, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001217 UTEST(test_wd, setup),
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001218 };
1219
1220 return cmocka_run_group_tests(tests, NULL, NULL);
1221}