blob: 50954d7f307ad3c0e712336167895b78a034a8fe [file] [log] [blame]
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001/**
2 * @file test_diff.c
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @author Michal Vasko <mvasko@cesnet.cz>
5 * @brief tests for lyd_diff()
6 *
7 * Copyright (c) 2020 CESNET, z.s.p.o.
8 *
9 * This source code is licensed under BSD 3-Clause License (the "License").
10 * You may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * https://opensource.org/licenses/BSD-3-Clause
14 */
Radek Iša56ca9e42020-09-08 18:42:00 +020015#define _UTEST_MAIN_
Radek Krejcib4ac5a92020-11-23 17:54:33 +010016#include "utests.h"
Michal Vaskoe893ddd2020-06-23 13:35:20 +020017
Radek Iša56ca9e42020-09-08 18:42:00 +020018#include "libyang.h"
19
20#define CHECK_PARSE_LYD(INPUT, MODEL) \
21 CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, MODEL)
22
23#define CHECK_LYD_STRING(IN_MODEL, TEXT) \
24 CHECK_LYD_STRING_PARAM(IN_MODEL, TEXT, LYD_XML, LYD_PRINT_WITHSIBLINGS)
25
26#define CHECK_PARSE_LYD_DIFF(INPUT_1, INPUT_2, OUT_MODEL) \
27 assert_int_equal(LY_SUCCESS, lyd_diff_siblings(INPUT_1, INPUT_2, 0, &OUT_MODEL));\
28 assert_non_null(OUT_MODEL)
29
30#define TEST_DIFF_3(XML_1, XML_2, XML_3, DIFF_1, DIFF_2, MERGE) \
31 { \
32 /*decladation*/\
33 struct lyd_node *model_1;\
34 struct lyd_node *model_2;\
35 struct lyd_node *model_3;\
36 /*create*/\
37 CHECK_PARSE_LYD(XML_1, model_1);\
38 CHECK_PARSE_LYD(XML_2, model_2);\
39 CHECK_PARSE_LYD(XML_3, model_3);\
40 /* diff1 */ \
Michal Vaskoe78faec2021-04-08 17:24:43 +020041 struct lyd_node *diff1;\
Radek Iša56ca9e42020-09-08 18:42:00 +020042 CHECK_PARSE_LYD_DIFF(model_1, model_2, diff1); \
43 CHECK_LYD_STRING(diff1, DIFF_1); \
44 assert_int_equal(lyd_diff_apply_all(&model_1, diff1), LY_SUCCESS); \
45 CHECK_LYD(model_1, model_2); \
46 /* diff2 */ \
Michal Vaskoe78faec2021-04-08 17:24:43 +020047 struct lyd_node *diff2;\
Radek Iša56ca9e42020-09-08 18:42:00 +020048 CHECK_PARSE_LYD_DIFF(model_2, model_3, diff2); \
49 CHECK_LYD_STRING(diff2, DIFF_2); \
50 assert_int_equal(lyd_diff_apply_all(&model_2, diff2), LY_SUCCESS);\
51 CHECK_LYD(model_2, model_3);\
52 /* merge */ \
53 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);\
54 CHECK_LYD_STRING(diff1, MERGE); \
55 /* CREAR ENV */ \
56 lyd_free_all(model_1);\
57 lyd_free_all(model_2);\
58 lyd_free_all(model_3);\
59 lyd_free_all(diff1);\
60 lyd_free_all(diff2);\
61 }
62
Michal Vasko17d0c5c2021-11-01 11:31:11 +010063const char *schema1 =
Radek Iša56ca9e42020-09-08 18:42:00 +020064 "module defaults {\n"
65 " yang-version 1.1;\n"
66 " namespace \"urn:libyang:tests:defaults\";\n"
67 " prefix df;\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020068 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020069 " feature unhide;\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020070 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020071 " typedef defint32 {\n"
72 " type int32;\n"
73 " default \"42\";\n"
74 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020075 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020076 " leaf hiddenleaf {\n"
77 " if-feature \"unhide\";\n"
78 " type int32;\n"
79 " default \"42\";\n"
80 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020081 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020082 " container df {\n"
83 " leaf foo {\n"
84 " type defint32;\n"
85 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020086 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020087 " leaf hiddenleaf {\n"
88 " if-feature \"unhide\";\n"
89 " type int32;\n"
90 " default \"42\";\n"
91 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020092 ""
Radek Iša56ca9e42020-09-08 18:42:00 +020093 " container bar {\n"
94 " presence \"\";\n"
95 " leaf hi {\n"
96 " type int32;\n"
97 " default \"42\";\n"
98 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +020099 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200100 " leaf ho {\n"
101 " type int32;\n"
102 " mandatory true;\n"
103 " }\n"
104 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200105 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200106 " leaf-list llist {\n"
107 " type defint32;\n"
108 " ordered-by user;\n"
109 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200110 ""
Michal Vaskoe78faec2021-04-08 17:24:43 +0200111 " list ul {\n"
112 " key \"l1\";\n"
113 " ordered-by user;\n"
114 " leaf l1 {\n"
115 " type string;\n"
116 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200117 ""
Michal Vaskoe78faec2021-04-08 17:24:43 +0200118 " leaf l2 {\n"
119 " type int32;\n"
120 " }\n"
121 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200122 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200123 " leaf-list dllist {\n"
124 " type uint8;\n"
125 " default \"1\";\n"
126 " default \"2\";\n"
127 " default \"3\";\n"
128 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200129 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200130 " list list {\n"
131 " key \"name\";\n"
132 " leaf name {\n"
133 " type string;\n"
134 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200135 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200136 " leaf value {\n"
137 " type int32;\n"
138 " default \"42\";\n"
139 " }\n"
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100140 " list list2 {\n"
141 " key \"name2\";\n"
142 " leaf name2 {\n"
143 " type string;\n"
144 " }\n"
145 " leaf value2 {\n"
146 " type int32;\n"
147 " }\n"
148 " }\n"
149 " }\n";
150const char *schema2 =
Radek Iša56ca9e42020-09-08 18:42:00 +0200151 " choice select {\n"
152 " default \"a\";\n"
153 " case a {\n"
154 " choice a {\n"
155 " leaf a1 {\n"
156 " type int32;\n"
157 " default \"42\";\n"
158 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200159 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200160 " leaf a2 {\n"
161 " type int32;\n"
162 " default \"24\";\n"
163 " }\n"
164 " }\n"
165 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200166 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200167 " leaf b {\n"
168 " type string;\n"
169 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200170 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200171 " container c {\n"
172 " presence \"\";\n"
173 " leaf x {\n"
174 " type int32;\n"
175 " default \"42\";\n"
176 " }\n"
177 " }\n"
178 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200179 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200180 " choice select2 {\n"
181 " default \"s2b\";\n"
182 " leaf s2a {\n"
183 " type int32;\n"
184 " default \"42\";\n"
185 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200186 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200187 " case s2b {\n"
188 " choice s2b {\n"
189 " default \"b1\";\n"
190 " case b1 {\n"
191 " leaf b1_1 {\n"
192 " type int32;\n"
193 " default \"42\";\n"
194 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200195 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200196 " leaf b1_2 {\n"
197 " type string;\n"
198 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200199 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200200 " leaf b1_status {\n"
201 " type int32;\n"
202 " default \"42\";\n"
203 " config false;\n"
204 " }\n"
205 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200206 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200207 " leaf b2 {\n"
208 " type int32;\n"
209 " default \"42\";\n"
210 " }\n"
211 " }\n"
212 " }\n"
213 " }\n"
Michal Vaskoe78faec2021-04-08 17:24:43 +0200214 " list kl {\n"
215 " config \"false\";\n"
216 " leaf l1 {\n"
217 " type string;\n"
218 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200219 ""
Michal Vaskoe78faec2021-04-08 17:24:43 +0200220 " leaf l2 {\n"
221 " type int32;\n"
222 " }\n"
223 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200224 ""
Michal Vaskoe78faec2021-04-08 17:24:43 +0200225 " leaf-list kll {\n"
226 " config \"false\";\n"
227 " type string;\n"
228 " }\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200229 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200230 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200231 " container hidden {\n"
232 " leaf foo {\n"
233 " type int32;\n"
234 " default \"42\";\n"
235 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200236 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200237 " leaf baz {\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 papa {\n"
243 " type int32;\n"
244 " default \"42\";\n"
245 " config false;\n"
246 " }\n"
247 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200248 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200249 " rpc rpc1 {\n"
250 " input {\n"
251 " leaf inleaf1 {\n"
252 " type string;\n"
253 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200254 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200255 " leaf inleaf2 {\n"
256 " type string;\n"
257 " default \"def1\";\n"
258 " }\n"
259 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200260 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200261 " output {\n"
262 " leaf outleaf1 {\n"
263 " type string;\n"
264 " default \"def2\";\n"
265 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200266 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200267 " leaf outleaf2 {\n"
268 " type string;\n"
269 " }\n"
270 " }\n"
271 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200272 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200273 " notification notif {\n"
274 " leaf ntfleaf1 {\n"
275 " type string;\n"
276 " default \"def3\";\n"
277 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200278 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200279 " leaf ntfleaf2 {\n"
280 " type string;\n"
281 " }\n"
282 " }\n"
283 "}\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200284
285static int
Radek Iša56ca9e42020-09-08 18:42:00 +0200286setup(void **state)
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200287{
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100288 char *schema;
289
Radek Iša56ca9e42020-09-08 18:42:00 +0200290 UTEST_SETUP;
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100291
292 /* create one schema, longer than 4095 chars */
293 schema = malloc(strlen(schema1) + strlen(schema2) + 1);
294 strcpy(schema, schema1);
295 strcat(schema, schema2);
296
Radek Iša56ca9e42020-09-08 18:42:00 +0200297 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100298 free(schema);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200299
300 return 0;
301}
302
303static void
304test_invalid(void **state)
305{
Radek Iša56ca9e42020-09-08 18:42:00 +0200306 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200307 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
308
Radek Iša56ca9e42020-09-08 18:42:00 +0200309 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200310
Radek Iša56ca9e42020-09-08 18:42:00 +0200311 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200312
Radek Iša56ca9e42020-09-08 18:42:00 +0200313 struct lyd_node *diff = NULL;
314
315 assert_int_equal(lyd_diff_siblings(model_1, lyd_child(model_1), 0, &diff), LY_EINVAL);
Michal Vasko3a41dff2020-07-15 14:30:28 +0200316 assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, NULL), LY_EINVAL);
Radek Iša56ca9e42020-09-08 18:42:00 +0200317
318 lyd_free_all(model_1);
319 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200320}
321
322static void
323test_same(void **state)
324{
Radek Iša56ca9e42020-09-08 18:42:00 +0200325 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100326 const char *xml =
327 "<nacm xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-acm\">\n"
328 " <enable-nacm>true</enable-nacm>\n"
329 " <read-default>permit</read-default>\n"
330 " <write-default>deny</write-default>\n"
331 " <exec-default>permit</exec-default>\n"
332 " <enable-external-groups>true</enable-external-groups>\n"
333 "</nacm><df xmlns=\"urn:libyang:tests:defaults\">\n"
334 " <foo>42</foo><b1_1>42</b1_1>\n"
335 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">\n"
336 " <foo>42</foo><baz>42</baz></hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200337
Radek Iša56ca9e42020-09-08 18:42:00 +0200338 struct lyd_node *model_1;
339 struct lyd_node *model_2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200340
Radek Iša56ca9e42020-09-08 18:42:00 +0200341 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
342 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-acm", "2018-02-14", NULL));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200343
Radek Iša56ca9e42020-09-08 18:42:00 +0200344 CHECK_PARSE_LYD(xml, model_1);
345 CHECK_PARSE_LYD(xml, model_2);
346
347 struct lyd_node *diff = NULL;
348
349 assert_int_equal(lyd_diff_siblings(model_1, model_2, 0, &diff), LY_SUCCESS);
350 assert_null(diff);
351 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
352 CHECK_LYD(model_1, model_2);
353
354 lyd_free_all(model_1);
355 lyd_free_all(model_2);
356 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200357}
358
359static void
360test_empty1(void **state)
361{
Radek Iša56ca9e42020-09-08 18:42:00 +0200362 (void) state;
363 const char *xml_in =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100364 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
365 " <foo>42</foo>\n"
366 " <b1_1>42</b1_1>\n"
367 "</df>\n"
368 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
369 " <foo>42</foo>\n"
370 " <baz>42</baz>\n"
371 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200372
Radek Iša56ca9e42020-09-08 18:42:00 +0200373 struct lyd_node *model_1 = NULL;
374 struct lyd_node *model_2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200375
Radek Iša56ca9e42020-09-08 18:42:00 +0200376 CHECK_PARSE_LYD(xml_in, model_2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200377
Radek Iša56ca9e42020-09-08 18:42:00 +0200378 struct lyd_node *diff;
379
380 CHECK_PARSE_LYD_DIFF(model_1, model_2, diff);
381 CHECK_LYD_STRING(diff,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100382 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
383 " <foo>42</foo>\n"
384 " <b1_1>42</b1_1>\n"
385 "</df>\n"
386 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
387 " <foo>42</foo>\n"
388 " <baz>42</baz>\n"
389 "</hidden>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200390 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
391 CHECK_LYD(model_1, model_2);
392
393 lyd_free_all(model_1);
394 lyd_free_all(model_2);
395 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200396}
397
398static void
399test_empty2(void **state)
400{
Radek Iša56ca9e42020-09-08 18:42:00 +0200401 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100402 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
403 " <foo>42</foo>\n"
404 " <b1_1>42</b1_1>\n"
405 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">\n"
406 " <foo>42</foo>\n"
407 " <baz>42</baz>\n"
408 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200409
Radek Iša56ca9e42020-09-08 18:42:00 +0200410 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200411
Radek Iša56ca9e42020-09-08 18:42:00 +0200412 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200413
Radek Iša56ca9e42020-09-08 18:42:00 +0200414 struct lyd_node *diff;
415
416 CHECK_PARSE_LYD_DIFF(model_1, NULL, diff);
417 CHECK_LYD_STRING(diff,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100418 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
419 " <foo>42</foo>\n"
420 " <b1_1>42</b1_1>\n"
421 "</df>\n"
422 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
423 " <foo>42</foo>\n"
424 " <baz>42</baz>\n"
425 "</hidden>\n");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200426
Radek Iša56ca9e42020-09-08 18:42:00 +0200427 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
428 assert_ptr_equal(model_1, NULL);
429
430 lyd_free_all(diff);
431 lyd_free_all(model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200432}
433
434static void
435test_empty_nested(void **state)
436{
Radek Iša56ca9e42020-09-08 18:42:00 +0200437 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200438 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
439
Radek Iša56ca9e42020-09-08 18:42:00 +0200440 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200441
Radek Iša56ca9e42020-09-08 18:42:00 +0200442 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200443
Radek Iša56ca9e42020-09-08 18:42:00 +0200444 struct lyd_node *diff = NULL;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200445
Radek Iša56ca9e42020-09-08 18:42:00 +0200446 assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, &diff), LY_SUCCESS);
447 assert_null(diff);
448
449 struct lyd_node *diff1;
450
451 CHECK_PARSE_LYD_DIFF(NULL, lyd_child(model_1), diff1);
452 CHECK_LYD_STRING(diff1,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100453 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
454 " <foo yang:operation=\"create\">42</foo>\n"
455 "</df>\n");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200456
Radek Iša56ca9e42020-09-08 18:42:00 +0200457 struct lyd_node *diff2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200458
Radek Iša56ca9e42020-09-08 18:42:00 +0200459 CHECK_PARSE_LYD_DIFF(lyd_child(model_1), NULL, diff2);
460 CHECK_LYD_STRING(diff2,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100461 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
462 " <foo yang:operation=\"delete\">42</foo>\n"
463 "</df>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200464
465 lyd_free_all(model_1);
466 lyd_free_all(diff1);
467 lyd_free_all(diff2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200468}
469
470static void
Michal Vasko17d0c5c2021-11-01 11:31:11 +0100471test_delete_merge(void **state)
472{
473 (void) state;
474 struct lyd_node *diff1, *diff2;
475 const char *xml1 =
476 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
477 " <list>\n"
478 " <name>a</name>\n"
479 " <list2 yang:operation=\"delete\">\n"
480 " <name2>a</name2>\n"
481 " </list2>\n"
482 " </list>\n"
483 "</df>\n";
484 const char *xml2 =
485 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
486 " <list yang:operation=\"delete\">\n"
487 " <name>a</name>\n"
488 " </list>\n"
489 "</df>\n";
490 const char *xml_merge =
491 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
492 " <list yang:operation=\"delete\">\n"
493 " <name>a</name>\n"
494 " <list2 yang:operation=\"delete\">\n"
495 " <name2>a</name2>\n"
496 " </list2>\n"
497 " </list>\n"
498 "</df>\n";
499
500 CHECK_PARSE_LYD(xml1, diff1);
501 CHECK_PARSE_LYD(xml2, diff2);
502
503 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);
504 CHECK_LYD_STRING(diff1, xml_merge);
505
506 lyd_free_all(diff1);
507 lyd_free_all(diff2);
508}
509
510static void
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200511test_leaf(void **state)
512{
Radek Iša56ca9e42020-09-08 18:42:00 +0200513 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200514 const char *xml1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100515 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
516 " <foo>42</foo>\n"
517 "</df>\n"
518 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
519 " <foo>42</foo>\n"
520 " <baz>42</baz>\n"
521 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200522 const char *xml2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100523 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
524 " <foo>41</foo>\n"
525 " <b1_1>42</b1_1>\n"
526 "</df>\n";
Michal Vaskoe6323f62020-07-09 15:49:02 +0200527 const char *xml3 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100528 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
529 " <foo>40</foo>\n"
530 "</df>\n"
531 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
532 " <foo>40</foo>\n"
533 "</hidden>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200534 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100535 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
536 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"42\">41</foo>\n"
537 " <b1_1 yang:operation=\"create\">42</b1_1>\n"
538 "</df>\n"
539 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
540 " <foo>42</foo>\n"
541 " <baz>42</baz>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200542 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200543
Radek Iša56ca9e42020-09-08 18:42:00 +0200544 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 +0100545 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"41\">40</foo>\n"
546 " <b1_1 yang:operation=\"delete\">42</b1_1>\n"
547 "</df>\n"
548 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
549 " <foo>40</foo>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200550 "</hidden>\n";
Michal Vaskoe6323f62020-07-09 15:49:02 +0200551
Radek Iša56ca9e42020-09-08 18:42:00 +0200552 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100553 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
554 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"42\">40</foo>\n"
555 "</df>\n"
556 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
557 " <foo yang:operation=\"replace\" yang:orig-value=\"42\" yang:orig-default=\"false\">40</foo>\n"
558 " <baz yang:operation=\"delete\">42</baz>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200559 "</hidden>\n";
560
561 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200562}
563
564static void
565test_list(void **state)
566{
Radek Iša56ca9e42020-09-08 18:42:00 +0200567 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100568 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
569 " <list>\n"
570 " <name>a</name>\n"
571 " <value>1</value>\n"
572 " </list>\n"
573 " <list>\n"
574 " <name>b</name>\n"
575 " <value>2</value>\n"
576 " </list>\n"
577 "</df>\n";
578 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
579 " <list>\n"
580 " <name>b</name>\n"
581 " <value>-2</value>\n"
582 " </list>\n"
583 " <list>\n"
584 " <name>c</name>\n"
585 " <value>3</value>\n"
586 " </list>\n"
587 "</df>\n";
588 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
589 " <list>\n"
590 " <name>b</name>\n"
591 " <value>-2</value>\n"
592 " </list>\n"
593 " <list>\n"
594 " <name>a</name>\n"
595 " <value>2</value>\n"
596 " </list>\n"
597 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200598
Radek Iša56ca9e42020-09-08 18:42:00 +0200599 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100600 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
601 " <list yang:operation=\"delete\">\n"
602 " <name>a</name>\n"
603 " <value>1</value>\n"
604 " </list>\n"
605 " <list yang:operation=\"none\">\n"
606 " <name>b</name>\n"
607 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\">-2</value>\n"
608 " </list>\n"
609 " <list yang:operation=\"create\">\n"
610 " <name>c</name>\n"
611 " <value>3</value>\n"
612 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200613 "</df>\n";
614 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100615 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
616 " <list yang:operation=\"delete\">\n"
617 " <name>c</name>\n"
618 " <value>3</value>\n"
619 " </list>\n"
620 " <list yang:operation=\"create\">\n"
621 " <name>a</name>\n"
622 " <value>2</value>\n"
623 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200624 "</df>\n";
625 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100626 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
627 " <list yang:operation=\"none\">\n"
628 " <name>a</name>\n"
629 " <value yang:operation=\"replace\" yang:orig-value=\"1\" yang:orig-default=\"false\">2</value>\n"
630 " </list>\n"
631 " <list yang:operation=\"none\">\n"
632 " <name>b</name>\n"
633 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\">-2</value>\n"
634 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200635 "</df>\n";
636
637 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200638}
639
640static void
641test_userord_llist(void **state)
642{
Radek Iša56ca9e42020-09-08 18:42:00 +0200643 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100644 const char *xml1 =
645 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
646 " <llist>1</llist>\n"
647 " <llist>2</llist>\n"
648 " <llist>3</llist>\n"
649 " <llist>4</llist>\n"
650 " <llist>5</llist>\n"
651 "</df>\n";
652 const char *xml2 =
653 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
654 " <llist>1</llist>\n"
655 " <llist>4</llist>\n"
656 " <llist>3</llist>\n"
657 " <llist>2</llist>\n"
658 " <llist>5</llist>\n"
659 "</df>\n";
660 const char *xml3 =
661 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
662 " <llist>5</llist>\n"
663 " <llist>4</llist>\n"
664 " <llist>3</llist>\n"
665 " <llist>2</llist>\n"
666 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200667
Radek Iša56ca9e42020-09-08 18:42:00 +0200668 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100669 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
670 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>\n"
671 " <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 +0200672 "</df>\n";
673 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100674 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
675 " <llist yang:operation=\"delete\" yang:orig-value=\"\">1</llist>\n"
676 " <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 +0200677 "</df>\n";
678 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100679 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
680 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>\n"
681 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\" yang:value=\"4\">3</llist>\n"
682 " <llist yang:orig-value=\"\" yang:operation=\"delete\">1</llist>\n"
683 " <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 +0200684 "</df>\n";
685
686 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200687}
688
689static void
690test_userord_llist2(void **state)
691{
Radek Iša56ca9e42020-09-08 18:42:00 +0200692 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100693 const char *xml1 =
694 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
695 " <llist>1</llist>\n"
696 " <list><name>a</name><value>1</value></list>\n"
697 " <llist>2</llist>\n"
698 " <llist>3</llist>\n"
699 " <llist>4</llist>\n"
700 "</df>\n";
701 const char *xml2 =
702 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
703 " <llist>1</llist>\n"
704 " <list><name>a</name><value>1</value></list>\n"
705 " <llist>2</llist>\n"
706 " <llist>4</llist>\n"
707 " <llist>3</llist>\n"
708 "</df>\n";
709 const char *xml3 =
710 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
711 " <llist>4</llist>\n"
712 " <llist>1</llist>\n"
713 " <list><name>a</name><value>1</value></list>\n"
714 " <llist>3</llist>\n"
715 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200716
Radek Iša56ca9e42020-09-08 18:42:00 +0200717 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100718 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
719 " <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 +0200720 "</df>\n";
721 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100722 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
723 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
724 " <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 +0200725 "</df>\n";
726 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100727 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
728 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\">4</llist>\n"
729 " <llist yang:orig-value=\"1\" yang:operation=\"delete\">2</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200730 "</df>\n";
731
732 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200733}
734
735static void
736test_userord_mix(void **state)
737{
Radek Iša56ca9e42020-09-08 18:42:00 +0200738 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100739 const char *xml1 =
740 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
741 " <llist>1</llist>\n"
742 " <llist>2</llist>\n"
743 " <llist>3</llist>\n"
744 "</df>\n";
745 const char *xml2 =
746 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
747 " <llist>3</llist>\n"
748 " <llist>1</llist>\n"
749 "</df>\n";
750 const char *xml3 =
751 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
752 " <llist>1</llist>\n"
753 " <llist>4</llist>\n"
754 " <llist>3</llist>\n"
755 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200756
Radek Iša56ca9e42020-09-08 18:42:00 +0200757 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100758 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
759 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
760 " <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 +0200761 "</df>\n";
762 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100763 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
764 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\">1</llist>\n"
765 " <llist yang:operation=\"create\" yang:value=\"1\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200766 "</df>\n";
767 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100768 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
769 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
770 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\" yang:value=\"\">3</llist>\n"
771 " <llist yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\" yang:operation=\"replace\">1</llist>\n"
772 " <llist yang:value=\"1\" yang:operation=\"create\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200773 "</df>\n";
774
775 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200776}
777
778static void
Michal Vaskoe78faec2021-04-08 17:24:43 +0200779test_userord_list(void **state)
780{
781 (void) state;
782 const char *xml1 =
783 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
784 " <ul>\n"
785 " <l1>a</l1>\n"
786 " <l2>1</l2>\n"
787 " </ul>\n"
788 " <ul>\n"
789 " <l1>b</l1>\n"
790 " <l2>2</l2>\n"
791 " </ul>\n"
792 " <ul>\n"
793 " <l1>c</l1>\n"
794 " <l2>3</l2>\n"
795 " </ul>\n"
796 "</df>\n";
797 const char *xml2 =
798 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
799 " <ul>\n"
800 " <l1>a</l1>\n"
801 " <l2>11</l2>\n"
802 " </ul>\n"
803 " <ul>\n"
804 " <l1>c</l1>\n"
805 " <l2>3</l2>\n"
806 " </ul>\n"
807 "</df>\n";
808 const char *xml3 =
809 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
810 " <ul>\n"
811 " <l1>c</l1>\n"
812 " <l2>33</l2>\n"
813 " </ul>\n"
814 " <ul>\n"
815 " <l1>b</l1>\n"
816 " <l2>2</l2>\n"
817 " </ul>\n"
818 "</df>\n";
819
820 const char *out_diff_1 =
821 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
822 " <ul>\n"
823 " <l1>a</l1>\n"
824 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\">11</l2>\n"
825 " </ul>\n"
826 " <ul yang:operation=\"delete\" yang:orig-key=\"[l1='a']\">\n"
827 " <l1>b</l1>\n"
828 " <l2>2</l2>\n"
829 " </ul>\n"
830 "</df>\n";
831 const char *out_diff_2 =
832 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
833 " <ul yang:operation=\"delete\" yang:orig-key=\"\">\n"
834 " <l1>a</l1>\n"
835 " <l2>11</l2>\n"
836 " </ul>\n"
837 " <ul yang:operation=\"none\">\n"
838 " <l1>c</l1>\n"
839 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\">33</l2>\n"
840 " </ul>\n"
841 " <ul yang:operation=\"create\" yang:key=\"[l1='c']\">\n"
842 " <l1>b</l1>\n"
843 " <l2>2</l2>\n"
844 " </ul>\n"
845 "</df>\n";
846 const char *out_merge =
847 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
848 " <ul yang:operation=\"delete\">\n"
849 " <l1>a</l1>\n"
850 " <l2 yang:operation=\"delete\">1</l2>\n"
851 " </ul>\n"
852 " <ul yang:orig-key=\"[l1='a']\" yang:operation=\"replace\" yang:key=\"[l1='c']\">\n"
853 " <l1>b</l1>\n"
854 " </ul>\n"
855 " <ul yang:operation=\"none\">\n"
856 " <l1>c</l1>\n"
857 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\">33</l2>\n"
858 " </ul>\n"
859 "</df>\n";
860
861 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
862}
863
864static void
865test_keyless_list(void **state)
866{
867 (void) state;
868 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
869 " <kl>\n"
870 " <l1>a</l1>\n"
871 " <l2>1</l2>\n"
872 " </kl>\n"
873 " <kl>\n"
874 " <l1>b</l1>\n"
875 " <l2>2</l2>\n"
876 " </kl>\n"
877 " <kl>\n"
878 " <l1>c</l1>\n"
879 " <l2>3</l2>\n"
880 " </kl>\n"
881 "</df>\n";
882 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
883 " <kl>\n"
884 " <l1>b</l1>\n"
885 " <l2>2</l2>\n"
886 " </kl>\n"
887 " <kl>\n"
888 " <l1>a</l1>\n"
889 " <l2>1</l2>\n"
890 " </kl>\n"
891 " <kl>\n"
892 " <l1>a</l1>\n"
893 " <l2>1</l2>\n"
894 " </kl>\n"
895 "</df>\n";
896 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
897 " <kl>\n"
898 " <l1>c</l1>\n"
899 " </kl>\n"
900 " <kl>\n"
901 " <l2>4</l2>\n"
902 " </kl>\n"
903 " <kl>\n"
904 " <l1>e</l1>\n"
905 " <l2>5</l2>\n"
906 " </kl>\n"
907 " <kl>\n"
908 " <l1>f</l1>\n"
909 " <l2>6</l2>\n"
910 " </kl>\n"
911 "</df>\n";
912
913 const char *out_diff_1 =
914 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
915 " <kl yang:operation=\"delete\" yang:orig-position=\"2\">\n"
916 " <l1>c</l1>\n"
917 " <l2>3</l2>\n"
918 " </kl>\n"
919 " <kl yang:operation=\"replace\" yang:position=\"\" yang:orig-position=\"1\">\n"
920 " <l1>b</l1>\n"
921 " <l2>2</l2>\n"
922 " </kl>\n"
923 " <kl yang:operation=\"create\" yang:position=\"2\">\n"
924 " <l1>a</l1>\n"
925 " <l2>1</l2>\n"
926 " </kl>\n"
927 "</df>\n";
928 const char *out_diff_2 =
929 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
930 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
931 " <l1>b</l1>\n"
932 " <l2>2</l2>\n"
933 " </kl>\n"
934 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
935 " <l1>a</l1>\n"
936 " <l2>1</l2>\n"
937 " </kl>\n"
938 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
939 " <l1>a</l1>\n"
940 " <l2>1</l2>\n"
941 " </kl>\n"
942 " <kl yang:operation=\"create\" yang:position=\"\">\n"
943 " <l1>c</l1>\n"
944 " </kl>\n"
945 " <kl yang:operation=\"create\" yang:position=\"1\">\n"
946 " <l2>4</l2>\n"
947 " </kl>\n"
948 " <kl yang:operation=\"create\" yang:position=\"2\">\n"
949 " <l1>e</l1>\n"
950 " <l2>5</l2>\n"
951 " </kl>\n"
952 " <kl yang:operation=\"create\" yang:position=\"3\">\n"
953 " <l1>f</l1>\n"
954 " <l2>6</l2>\n"
955 " </kl>\n"
956 "</df>\n";
957 const char *out_merge =
958 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
959 " <kl yang:operation=\"delete\" yang:orig-position=\"2\">\n"
960 " <l1>c</l1>\n"
961 " <l2>3</l2>\n"
962 " </kl>\n"
963 " <kl yang:orig-position=\"1\" yang:operation=\"delete\">\n"
964 " <l1>b</l1>\n"
965 " <l2>2</l2>\n"
966 " </kl>\n"
967 " <kl yang:orig-position=\"\" yang:operation=\"delete\">\n"
968 " <l1>a</l1>\n"
969 " <l2>1</l2>\n"
970 " </kl>\n"
971 " <kl yang:position=\"\" yang:operation=\"create\">\n"
972 " <l1>c</l1>\n"
973 " </kl>\n"
974 " <kl yang:position=\"1\" yang:operation=\"create\">\n"
975 " <l2>4</l2>\n"
976 " </kl>\n"
977 " <kl yang:position=\"2\" yang:operation=\"create\">\n"
978 " <l1>e</l1>\n"
979 " <l2>5</l2>\n"
980 " </kl>\n"
981 " <kl yang:position=\"3\" yang:operation=\"create\">\n"
982 " <l1>f</l1>\n"
983 " <l2>6</l2>\n"
984 " </kl>\n"
985 "</df>\n";
986
987 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
988}
989
990static void
991test_state_llist(void **state)
992{
993 (void) state;
994 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
995 " <kll>a</kll>\n"
996 " <kll>b</kll>\n"
997 " <kll>c</kll>\n"
998 "</df>\n";
999 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1000 " <kll>b</kll>\n"
1001 " <kll>c</kll>\n"
1002 " <kll>a</kll>\n"
1003 " <kll>a</kll>\n"
1004 " <kll>a</kll>\n"
1005 "</df>\n";
1006 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1007 " <kll>a</kll>\n"
1008 " <kll>d</kll>\n"
1009 " <kll>a</kll>\n"
1010 "</df>\n";
1011
1012 const char *out_diff_1 =
1013 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1014 " <kll yang:operation=\"replace\" yang:orig-default=\"false\" yang:position=\"\" yang:orig-position=\"1\">b</kll>\n"
1015 " <kll yang:operation=\"replace\" yang:orig-default=\"false\" yang:position=\"1\" yang:orig-position=\"2\">c</kll>\n"
1016 " <kll yang:operation=\"create\" yang:position=\"3\">a</kll>\n"
1017 " <kll yang:operation=\"create\" yang:position=\"4\">a</kll>\n"
1018 "</df>\n";
1019 const char *out_diff_2 =
1020 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1021 " <kll yang:operation=\"delete\" yang:orig-position=\"\">b</kll>\n"
1022 " <kll yang:operation=\"delete\" yang:orig-position=\"\">c</kll>\n"
1023 " <kll yang:operation=\"delete\" yang:orig-position=\"2\">a</kll>\n"
1024 " <kll yang:operation=\"create\" yang:position=\"1\">d</kll>\n"
1025 "</df>\n";
1026 const char *out_merge =
1027 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1028 " <kll yang:orig-default=\"false\" yang:orig-position=\"1\" yang:operation=\"delete\">b</kll>\n"
1029 " <kll yang:orig-default=\"false\" yang:orig-position=\"2\" yang:operation=\"delete\">c</kll>\n"
1030 " <kll yang:operation=\"create\" yang:position=\"4\">a</kll>\n"
1031 " <kll yang:position=\"1\" yang:operation=\"create\">d</kll>\n"
1032 "</df>\n";
1033
1034 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
1035}
1036
1037static void
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001038test_wd(void **state)
1039{
Radek Iša56ca9e42020-09-08 18:42:00 +02001040 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001041 const struct lys_module *mod;
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001042 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1043 " <foo>41</foo>\n"
1044 " <dllist>4</dllist>\n"
1045 "</df>\n";
1046 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
1047 " <foo>42</foo>\n"
1048 " <dllist>4</dllist>\n"
1049 " <dllist>1</dllist>\n"
1050 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001051
Radek Iša56ca9e42020-09-08 18:42:00 +02001052 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "defaults");
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001053 assert_non_null(mod);
1054
Radek Iša56ca9e42020-09-08 18:42:00 +02001055 struct lyd_node *model_1 = NULL;
1056
1057 assert_int_equal(lyd_validate_module(&model_1, mod, 0, NULL), LY_SUCCESS);
1058 assert_ptr_not_equal(model_1, NULL);
1059
1060 struct lyd_node *model_2;
1061 struct lyd_node *model_3;
1062
1063 CHECK_PARSE_LYD_PARAM(xml2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1064 CHECK_PARSE_LYD_PARAM(xml3, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_3);
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001065
Michal Vaskoe6323f62020-07-09 15:49:02 +02001066 /* diff1 */
Radek Iša56ca9e42020-09-08 18:42:00 +02001067 struct lyd_node *diff1 = NULL;
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001068
Radek Iša56ca9e42020-09-08 18:42:00 +02001069 assert_int_equal(lyd_diff_siblings(model_1, model_2, LYD_DIFF_DEFAULTS, &diff1), LY_SUCCESS);
1070 assert_non_null(diff1);
1071
1072 const char *diff1_out_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001073 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1074 " <foo yang:operation=\"replace\" yang:orig-default=\"true\" yang:orig-value=\"42\">41</foo>\n"
1075 " <dllist yang:operation=\"delete\">1</dllist>\n"
1076 " <dllist yang:operation=\"delete\">2</dllist>\n"
1077 " <dllist yang:operation=\"delete\">3</dllist>\n"
1078 " <dllist yang:operation=\"create\">4</dllist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001079 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001080
Radek Iša56ca9e42020-09-08 18:42:00 +02001081 CHECK_LYD_STRING_PARAM(diff1, diff1_out_1, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
1082 assert_int_equal(lyd_diff_apply_all(&model_1, diff1), LY_SUCCESS);
1083 CHECK_LYD(model_1, model_2);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001084
1085 /* diff2 */
Radek Iša56ca9e42020-09-08 18:42:00 +02001086 struct lyd_node *diff2;
Michal Vaskoe6323f62020-07-09 15:49:02 +02001087
Radek Iša56ca9e42020-09-08 18:42:00 +02001088 assert_int_equal(lyd_diff_siblings(model_2, model_3, LYD_DIFF_DEFAULTS, &diff2), LY_SUCCESS);
1089 assert_non_null(diff2);
1090 CHECK_LYD_STRING(diff2,
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001091 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1092 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"41\">42</foo>\n"
1093 " <dllist yang:operation=\"create\">1</dllist>\n"
1094 "</df>\n");
Michal Vaskoe6323f62020-07-09 15:49:02 +02001095
Radek Iša56ca9e42020-09-08 18:42:00 +02001096 assert_int_equal(lyd_diff_apply_all(&model_2, diff2), LY_SUCCESS);
1097 CHECK_LYD(model_2, model_3);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001098
1099 /* merge */
Radek Iša56ca9e42020-09-08 18:42:00 +02001100 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001101
Radek Iša56ca9e42020-09-08 18:42:00 +02001102 const char *diff1_out_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001103 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1104 " <foo yang:orig-default=\"true\" yang:operation=\"none\">42</foo>\n"
1105 " <dllist yang:operation=\"none\" yang:orig-default=\"true\">1</dllist>\n"
1106 " <dllist yang:operation=\"delete\">2</dllist>\n"
1107 " <dllist yang:operation=\"delete\">3</dllist>\n"
1108 " <dllist yang:operation=\"create\">4</dllist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001109 "</df>\n";
1110
1111 CHECK_LYD_STRING_PARAM(diff1, diff1_out_2, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
1112
1113 lyd_free_all(model_1);
1114 lyd_free_all(model_2);
1115 lyd_free_all(model_3);
1116 lyd_free_all(diff1);
1117 lyd_free_all(diff2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001118}
1119
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001120int
1121main(void)
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001122{
1123 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +02001124 UTEST(test_invalid, setup),
1125 UTEST(test_same, setup),
1126 UTEST(test_empty1, setup),
1127 UTEST(test_empty2, setup),
1128 UTEST(test_empty_nested, setup),
Michal Vasko17d0c5c2021-11-01 11:31:11 +01001129 UTEST(test_delete_merge, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001130 UTEST(test_leaf, setup),
1131 UTEST(test_list, setup),
1132 UTEST(test_userord_llist, setup),
1133 UTEST(test_userord_llist2, setup),
1134 UTEST(test_userord_mix, setup),
Michal Vaskoe78faec2021-04-08 17:24:43 +02001135 UTEST(test_userord_list, setup),
1136 UTEST(test_keyless_list, setup),
1137 UTEST(test_state_llist, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001138 UTEST(test_wd, setup),
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001139 };
1140
1141 return cmocka_run_group_tests(tests, NULL, NULL);
1142}