blob: 7fee736118f1876739e06641cf9196786add3657 [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
63const char *schema =
64 "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"
140 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200141 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200142 " choice select {\n"
143 " default \"a\";\n"
144 " case a {\n"
145 " choice a {\n"
146 " leaf a1 {\n"
147 " type int32;\n"
148 " default \"42\";\n"
149 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200150 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200151 " leaf a2 {\n"
152 " type int32;\n"
153 " default \"24\";\n"
154 " }\n"
155 " }\n"
156 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200157 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200158 " leaf b {\n"
159 " type string;\n"
160 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200161 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200162 " container c {\n"
163 " presence \"\";\n"
164 " leaf x {\n"
165 " type int32;\n"
166 " default \"42\";\n"
167 " }\n"
168 " }\n"
169 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200170 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200171 " choice select2 {\n"
172 " default \"s2b\";\n"
173 " leaf s2a {\n"
174 " type int32;\n"
175 " default \"42\";\n"
176 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200177 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200178 " case s2b {\n"
179 " choice s2b {\n"
180 " default \"b1\";\n"
181 " case b1 {\n"
182 " leaf b1_1 {\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 " leaf b1_2 {\n"
188 " type string;\n"
189 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200190 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200191 " leaf b1_status {\n"
192 " type int32;\n"
193 " default \"42\";\n"
194 " config false;\n"
195 " }\n"
196 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200197 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200198 " leaf b2 {\n"
199 " type int32;\n"
200 " default \"42\";\n"
201 " }\n"
202 " }\n"
203 " }\n"
204 " }\n"
Michal Vaskoe78faec2021-04-08 17:24:43 +0200205 " list kl {\n"
206 " config \"false\";\n"
207 " leaf l1 {\n"
208 " type string;\n"
209 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200210 ""
Michal Vaskoe78faec2021-04-08 17:24:43 +0200211 " leaf l2 {\n"
212 " type int32;\n"
213 " }\n"
214 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200215 ""
Michal Vaskoe78faec2021-04-08 17:24:43 +0200216 " leaf-list kll {\n"
217 " config \"false\";\n"
218 " type string;\n"
219 " }\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200220 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200221 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200222 " container hidden {\n"
223 " leaf foo {\n"
224 " type int32;\n"
225 " default \"42\";\n"
226 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200227 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200228 " leaf baz {\n"
229 " type int32;\n"
230 " default \"42\";\n"
231 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200232 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200233 " leaf papa {\n"
234 " type int32;\n"
235 " default \"42\";\n"
236 " config false;\n"
237 " }\n"
238 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200239 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200240 " rpc rpc1 {\n"
241 " input {\n"
242 " leaf inleaf1 {\n"
243 " type string;\n"
244 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200245 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200246 " leaf inleaf2 {\n"
247 " type string;\n"
248 " default \"def1\";\n"
249 " }\n"
250 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200251 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200252 " output {\n"
253 " leaf outleaf1 {\n"
254 " type string;\n"
255 " default \"def2\";\n"
256 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200257 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200258 " leaf outleaf2 {\n"
259 " type string;\n"
260 " }\n"
261 " }\n"
262 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200263 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200264 " notification notif {\n"
265 " leaf ntfleaf1 {\n"
266 " type string;\n"
267 " default \"def3\";\n"
268 " }\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200269 ""
Radek Iša56ca9e42020-09-08 18:42:00 +0200270 " leaf ntfleaf2 {\n"
271 " type string;\n"
272 " }\n"
273 " }\n"
274 "}\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200275
276static int
Radek Iša56ca9e42020-09-08 18:42:00 +0200277setup(void **state)
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200278{
Radek Iša56ca9e42020-09-08 18:42:00 +0200279 UTEST_SETUP;
280 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200281
282 return 0;
283}
284
285static void
286test_invalid(void **state)
287{
Radek Iša56ca9e42020-09-08 18:42:00 +0200288 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200289 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
290
Radek Iša56ca9e42020-09-08 18:42:00 +0200291 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200292
Radek Iša56ca9e42020-09-08 18:42:00 +0200293 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200294
Radek Iša56ca9e42020-09-08 18:42:00 +0200295 struct lyd_node *diff = NULL;
296
297 assert_int_equal(lyd_diff_siblings(model_1, lyd_child(model_1), 0, &diff), LY_EINVAL);
Michal Vasko3a41dff2020-07-15 14:30:28 +0200298 assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, NULL), LY_EINVAL);
Radek Iša56ca9e42020-09-08 18:42:00 +0200299
300 lyd_free_all(model_1);
301 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200302}
303
304static void
305test_same(void **state)
306{
Radek Iša56ca9e42020-09-08 18:42:00 +0200307 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100308 const char *xml =
309 "<nacm xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-acm\">\n"
310 " <enable-nacm>true</enable-nacm>\n"
311 " <read-default>permit</read-default>\n"
312 " <write-default>deny</write-default>\n"
313 " <exec-default>permit</exec-default>\n"
314 " <enable-external-groups>true</enable-external-groups>\n"
315 "</nacm><df xmlns=\"urn:libyang:tests:defaults\">\n"
316 " <foo>42</foo><b1_1>42</b1_1>\n"
317 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">\n"
318 " <foo>42</foo><baz>42</baz></hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200319
Radek Iša56ca9e42020-09-08 18:42:00 +0200320 struct lyd_node *model_1;
321 struct lyd_node *model_2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200322
Radek Iša56ca9e42020-09-08 18:42:00 +0200323 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
324 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-acm", "2018-02-14", NULL));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200325
Radek Iša56ca9e42020-09-08 18:42:00 +0200326 CHECK_PARSE_LYD(xml, model_1);
327 CHECK_PARSE_LYD(xml, model_2);
328
329 struct lyd_node *diff = NULL;
330
331 assert_int_equal(lyd_diff_siblings(model_1, model_2, 0, &diff), LY_SUCCESS);
332 assert_null(diff);
333 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
334 CHECK_LYD(model_1, model_2);
335
336 lyd_free_all(model_1);
337 lyd_free_all(model_2);
338 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200339}
340
341static void
342test_empty1(void **state)
343{
Radek Iša56ca9e42020-09-08 18:42:00 +0200344 (void) state;
345 const char *xml_in =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100346 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
347 " <foo>42</foo>\n"
348 " <b1_1>42</b1_1>\n"
349 "</df>\n"
350 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
351 " <foo>42</foo>\n"
352 " <baz>42</baz>\n"
353 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200354
Radek Iša56ca9e42020-09-08 18:42:00 +0200355 struct lyd_node *model_1 = NULL;
356 struct lyd_node *model_2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200357
Radek Iša56ca9e42020-09-08 18:42:00 +0200358 CHECK_PARSE_LYD(xml_in, model_2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200359
Radek Iša56ca9e42020-09-08 18:42:00 +0200360 struct lyd_node *diff;
361
362 CHECK_PARSE_LYD_DIFF(model_1, model_2, diff);
363 CHECK_LYD_STRING(diff,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100364 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
365 " <foo>42</foo>\n"
366 " <b1_1>42</b1_1>\n"
367 "</df>\n"
368 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
369 " <foo>42</foo>\n"
370 " <baz>42</baz>\n"
371 "</hidden>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200372 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
373 CHECK_LYD(model_1, model_2);
374
375 lyd_free_all(model_1);
376 lyd_free_all(model_2);
377 lyd_free_all(diff);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200378}
379
380static void
381test_empty2(void **state)
382{
Radek Iša56ca9e42020-09-08 18:42:00 +0200383 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100384 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
385 " <foo>42</foo>\n"
386 " <b1_1>42</b1_1>\n"
387 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">\n"
388 " <foo>42</foo>\n"
389 " <baz>42</baz>\n"
390 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200391
Radek Iša56ca9e42020-09-08 18:42:00 +0200392 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200393
Radek Iša56ca9e42020-09-08 18:42:00 +0200394 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200395
Radek Iša56ca9e42020-09-08 18:42:00 +0200396 struct lyd_node *diff;
397
398 CHECK_PARSE_LYD_DIFF(model_1, NULL, diff);
399 CHECK_LYD_STRING(diff,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100400 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
401 " <foo>42</foo>\n"
402 " <b1_1>42</b1_1>\n"
403 "</df>\n"
404 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\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 assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS);
410 assert_ptr_equal(model_1, NULL);
411
412 lyd_free_all(diff);
413 lyd_free_all(model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200414}
415
416static void
417test_empty_nested(void **state)
418{
Radek Iša56ca9e42020-09-08 18:42:00 +0200419 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200420 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
421
Radek Iša56ca9e42020-09-08 18:42:00 +0200422 struct lyd_node *model_1;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200423
Radek Iša56ca9e42020-09-08 18:42:00 +0200424 CHECK_PARSE_LYD(xml, model_1);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200425
Radek Iša56ca9e42020-09-08 18:42:00 +0200426 struct lyd_node *diff = NULL;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200427
Radek Iša56ca9e42020-09-08 18:42:00 +0200428 assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, &diff), LY_SUCCESS);
429 assert_null(diff);
430
431 struct lyd_node *diff1;
432
433 CHECK_PARSE_LYD_DIFF(NULL, lyd_child(model_1), diff1);
434 CHECK_LYD_STRING(diff1,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100435 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
436 " <foo yang:operation=\"create\">42</foo>\n"
437 "</df>\n");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200438
Radek Iša56ca9e42020-09-08 18:42:00 +0200439 struct lyd_node *diff2;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200440
Radek Iša56ca9e42020-09-08 18:42:00 +0200441 CHECK_PARSE_LYD_DIFF(lyd_child(model_1), NULL, diff2);
442 CHECK_LYD_STRING(diff2,
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100443 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
444 " <foo yang:operation=\"delete\">42</foo>\n"
445 "</df>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200446
447 lyd_free_all(model_1);
448 lyd_free_all(diff1);
449 lyd_free_all(diff2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200450}
451
452static void
453test_leaf(void **state)
454{
Radek Iša56ca9e42020-09-08 18:42:00 +0200455 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200456 const char *xml1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100457 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
458 " <foo>42</foo>\n"
459 "</df>\n"
460 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
461 " <foo>42</foo>\n"
462 " <baz>42</baz>\n"
463 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200464 const char *xml2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100465 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
466 " <foo>41</foo>\n"
467 " <b1_1>42</b1_1>\n"
468 "</df>\n";
Michal Vaskoe6323f62020-07-09 15:49:02 +0200469 const char *xml3 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100470 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
471 " <foo>40</foo>\n"
472 "</df>\n"
473 "<hidden xmlns=\"urn:libyang:tests:defaults\">\n"
474 " <foo>40</foo>\n"
475 "</hidden>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200476 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100477 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
478 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"42\">41</foo>\n"
479 " <b1_1 yang:operation=\"create\">42</b1_1>\n"
480 "</df>\n"
481 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">\n"
482 " <foo>42</foo>\n"
483 " <baz>42</baz>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200484 "</hidden>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200485
Radek Iša56ca9e42020-09-08 18:42:00 +0200486 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 +0100487 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"41\">40</foo>\n"
488 " <b1_1 yang:operation=\"delete\">42</b1_1>\n"
489 "</df>\n"
490 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">\n"
491 " <foo>40</foo>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200492 "</hidden>\n";
Michal Vaskoe6323f62020-07-09 15:49:02 +0200493
Radek Iša56ca9e42020-09-08 18:42:00 +0200494 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100495 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
496 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"42\">40</foo>\n"
497 "</df>\n"
498 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
499 " <foo yang:operation=\"replace\" yang:orig-value=\"42\" yang:orig-default=\"false\">40</foo>\n"
500 " <baz yang:operation=\"delete\">42</baz>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200501 "</hidden>\n";
502
503 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200504}
505
506static void
507test_list(void **state)
508{
Radek Iša56ca9e42020-09-08 18:42:00 +0200509 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100510 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
511 " <list>\n"
512 " <name>a</name>\n"
513 " <value>1</value>\n"
514 " </list>\n"
515 " <list>\n"
516 " <name>b</name>\n"
517 " <value>2</value>\n"
518 " </list>\n"
519 "</df>\n";
520 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
521 " <list>\n"
522 " <name>b</name>\n"
523 " <value>-2</value>\n"
524 " </list>\n"
525 " <list>\n"
526 " <name>c</name>\n"
527 " <value>3</value>\n"
528 " </list>\n"
529 "</df>\n";
530 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
531 " <list>\n"
532 " <name>b</name>\n"
533 " <value>-2</value>\n"
534 " </list>\n"
535 " <list>\n"
536 " <name>a</name>\n"
537 " <value>2</value>\n"
538 " </list>\n"
539 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200540
Radek Iša56ca9e42020-09-08 18:42:00 +0200541 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100542 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
543 " <list yang:operation=\"delete\">\n"
544 " <name>a</name>\n"
545 " <value>1</value>\n"
546 " </list>\n"
547 " <list yang:operation=\"none\">\n"
548 " <name>b</name>\n"
549 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\">-2</value>\n"
550 " </list>\n"
551 " <list yang:operation=\"create\">\n"
552 " <name>c</name>\n"
553 " <value>3</value>\n"
554 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200555 "</df>\n";
556 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100557 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
558 " <list yang:operation=\"delete\">\n"
559 " <name>c</name>\n"
560 " <value>3</value>\n"
561 " </list>\n"
562 " <list yang:operation=\"create\">\n"
563 " <name>a</name>\n"
564 " <value>2</value>\n"
565 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200566 "</df>\n";
567 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100568 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
569 " <list yang:operation=\"none\">\n"
570 " <name>a</name>\n"
571 " <value yang:operation=\"replace\" yang:orig-value=\"1\" yang:orig-default=\"false\">2</value>\n"
572 " </list>\n"
573 " <list yang:operation=\"none\">\n"
574 " <name>b</name>\n"
575 " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\">-2</value>\n"
576 " </list>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200577 "</df>\n";
578
579 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200580}
581
582static void
583test_userord_llist(void **state)
584{
Radek Iša56ca9e42020-09-08 18:42:00 +0200585 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100586 const char *xml1 =
587 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
588 " <llist>1</llist>\n"
589 " <llist>2</llist>\n"
590 " <llist>3</llist>\n"
591 " <llist>4</llist>\n"
592 " <llist>5</llist>\n"
593 "</df>\n";
594 const char *xml2 =
595 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
596 " <llist>1</llist>\n"
597 " <llist>4</llist>\n"
598 " <llist>3</llist>\n"
599 " <llist>2</llist>\n"
600 " <llist>5</llist>\n"
601 "</df>\n";
602 const char *xml3 =
603 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
604 " <llist>5</llist>\n"
605 " <llist>4</llist>\n"
606 " <llist>3</llist>\n"
607 " <llist>2</llist>\n"
608 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200609
Radek Iša56ca9e42020-09-08 18:42:00 +0200610 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100611 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
612 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>\n"
613 " <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 +0200614 "</df>\n";
615 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100616 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
617 " <llist yang:operation=\"delete\" yang:orig-value=\"\">1</llist>\n"
618 " <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 +0200619 "</df>\n";
620 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100621 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
622 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>\n"
623 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"2\" yang:value=\"4\">3</llist>\n"
624 " <llist yang:orig-value=\"\" yang:operation=\"delete\">1</llist>\n"
625 " <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 +0200626 "</df>\n";
627
628 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200629}
630
631static void
632test_userord_llist2(void **state)
633{
Radek Iša56ca9e42020-09-08 18:42:00 +0200634 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100635 const char *xml1 =
636 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
637 " <llist>1</llist>\n"
638 " <list><name>a</name><value>1</value></list>\n"
639 " <llist>2</llist>\n"
640 " <llist>3</llist>\n"
641 " <llist>4</llist>\n"
642 "</df>\n";
643 const char *xml2 =
644 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
645 " <llist>1</llist>\n"
646 " <list><name>a</name><value>1</value></list>\n"
647 " <llist>2</llist>\n"
648 " <llist>4</llist>\n"
649 " <llist>3</llist>\n"
650 "</df>\n";
651 const char *xml3 =
652 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
653 " <llist>4</llist>\n"
654 " <llist>1</llist>\n"
655 " <list><name>a</name><value>1</value></list>\n"
656 " <llist>3</llist>\n"
657 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200658
Radek Iša56ca9e42020-09-08 18:42:00 +0200659 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100660 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
661 " <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 +0200662 "</df>\n";
663 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100664 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
665 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
666 " <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 +0200667 "</df>\n";
668 const char *out_merge =
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=\"\">4</llist>\n"
671 " <llist yang:orig-value=\"1\" yang:operation=\"delete\">2</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200672 "</df>\n";
673
674 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200675}
676
677static void
678test_userord_mix(void **state)
679{
Radek Iša56ca9e42020-09-08 18:42:00 +0200680 (void) state;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100681 const char *xml1 =
682 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
683 " <llist>1</llist>\n"
684 " <llist>2</llist>\n"
685 " <llist>3</llist>\n"
686 "</df>\n";
687 const char *xml2 =
688 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
689 " <llist>3</llist>\n"
690 " <llist>1</llist>\n"
691 "</df>\n";
692 const char *xml3 =
693 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
694 " <llist>1</llist>\n"
695 " <llist>4</llist>\n"
696 " <llist>3</llist>\n"
697 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200698
Radek Iša56ca9e42020-09-08 18:42:00 +0200699 const char *out_diff_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100700 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
701 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
702 " <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 +0200703 "</df>\n";
704 const char *out_diff_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100705 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
706 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\">1</llist>\n"
707 " <llist yang:operation=\"create\" yang:value=\"1\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200708 "</df>\n";
709 const char *out_merge =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100710 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
711 " <llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>\n"
712 " <llist yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\" yang:value=\"\">3</llist>\n"
713 " <llist yang:orig-default=\"false\" yang:orig-value=\"3\" yang:value=\"\" yang:operation=\"replace\">1</llist>\n"
714 " <llist yang:value=\"1\" yang:operation=\"create\">4</llist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200715 "</df>\n";
716
717 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200718}
719
720static void
Michal Vaskoe78faec2021-04-08 17:24:43 +0200721test_userord_list(void **state)
722{
723 (void) state;
724 const char *xml1 =
725 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
726 " <ul>\n"
727 " <l1>a</l1>\n"
728 " <l2>1</l2>\n"
729 " </ul>\n"
730 " <ul>\n"
731 " <l1>b</l1>\n"
732 " <l2>2</l2>\n"
733 " </ul>\n"
734 " <ul>\n"
735 " <l1>c</l1>\n"
736 " <l2>3</l2>\n"
737 " </ul>\n"
738 "</df>\n";
739 const char *xml2 =
740 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
741 " <ul>\n"
742 " <l1>a</l1>\n"
743 " <l2>11</l2>\n"
744 " </ul>\n"
745 " <ul>\n"
746 " <l1>c</l1>\n"
747 " <l2>3</l2>\n"
748 " </ul>\n"
749 "</df>\n";
750 const char *xml3 =
751 "<df xmlns=\"urn:libyang:tests:defaults\">\n"
752 " <ul>\n"
753 " <l1>c</l1>\n"
754 " <l2>33</l2>\n"
755 " </ul>\n"
756 " <ul>\n"
757 " <l1>b</l1>\n"
758 " <l2>2</l2>\n"
759 " </ul>\n"
760 "</df>\n";
761
762 const char *out_diff_1 =
763 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
764 " <ul>\n"
765 " <l1>a</l1>\n"
766 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\">11</l2>\n"
767 " </ul>\n"
768 " <ul yang:operation=\"delete\" yang:orig-key=\"[l1='a']\">\n"
769 " <l1>b</l1>\n"
770 " <l2>2</l2>\n"
771 " </ul>\n"
772 "</df>\n";
773 const char *out_diff_2 =
774 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
775 " <ul yang:operation=\"delete\" yang:orig-key=\"\">\n"
776 " <l1>a</l1>\n"
777 " <l2>11</l2>\n"
778 " </ul>\n"
779 " <ul yang:operation=\"none\">\n"
780 " <l1>c</l1>\n"
781 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\">33</l2>\n"
782 " </ul>\n"
783 " <ul yang:operation=\"create\" yang:key=\"[l1='c']\">\n"
784 " <l1>b</l1>\n"
785 " <l2>2</l2>\n"
786 " </ul>\n"
787 "</df>\n";
788 const char *out_merge =
789 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
790 " <ul yang:operation=\"delete\">\n"
791 " <l1>a</l1>\n"
792 " <l2 yang:operation=\"delete\">1</l2>\n"
793 " </ul>\n"
794 " <ul yang:orig-key=\"[l1='a']\" yang:operation=\"replace\" yang:key=\"[l1='c']\">\n"
795 " <l1>b</l1>\n"
796 " </ul>\n"
797 " <ul yang:operation=\"none\">\n"
798 " <l1>c</l1>\n"
799 " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\">33</l2>\n"
800 " </ul>\n"
801 "</df>\n";
802
803 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
804}
805
806static void
807test_keyless_list(void **state)
808{
809 (void) state;
810 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
811 " <kl>\n"
812 " <l1>a</l1>\n"
813 " <l2>1</l2>\n"
814 " </kl>\n"
815 " <kl>\n"
816 " <l1>b</l1>\n"
817 " <l2>2</l2>\n"
818 " </kl>\n"
819 " <kl>\n"
820 " <l1>c</l1>\n"
821 " <l2>3</l2>\n"
822 " </kl>\n"
823 "</df>\n";
824 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
825 " <kl>\n"
826 " <l1>b</l1>\n"
827 " <l2>2</l2>\n"
828 " </kl>\n"
829 " <kl>\n"
830 " <l1>a</l1>\n"
831 " <l2>1</l2>\n"
832 " </kl>\n"
833 " <kl>\n"
834 " <l1>a</l1>\n"
835 " <l2>1</l2>\n"
836 " </kl>\n"
837 "</df>\n";
838 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
839 " <kl>\n"
840 " <l1>c</l1>\n"
841 " </kl>\n"
842 " <kl>\n"
843 " <l2>4</l2>\n"
844 " </kl>\n"
845 " <kl>\n"
846 " <l1>e</l1>\n"
847 " <l2>5</l2>\n"
848 " </kl>\n"
849 " <kl>\n"
850 " <l1>f</l1>\n"
851 " <l2>6</l2>\n"
852 " </kl>\n"
853 "</df>\n";
854
855 const char *out_diff_1 =
856 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
857 " <kl yang:operation=\"delete\" yang:orig-position=\"2\">\n"
858 " <l1>c</l1>\n"
859 " <l2>3</l2>\n"
860 " </kl>\n"
861 " <kl yang:operation=\"replace\" yang:position=\"\" yang:orig-position=\"1\">\n"
862 " <l1>b</l1>\n"
863 " <l2>2</l2>\n"
864 " </kl>\n"
865 " <kl yang:operation=\"create\" yang:position=\"2\">\n"
866 " <l1>a</l1>\n"
867 " <l2>1</l2>\n"
868 " </kl>\n"
869 "</df>\n";
870 const char *out_diff_2 =
871 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
872 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
873 " <l1>b</l1>\n"
874 " <l2>2</l2>\n"
875 " </kl>\n"
876 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
877 " <l1>a</l1>\n"
878 " <l2>1</l2>\n"
879 " </kl>\n"
880 " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
881 " <l1>a</l1>\n"
882 " <l2>1</l2>\n"
883 " </kl>\n"
884 " <kl yang:operation=\"create\" yang:position=\"\">\n"
885 " <l1>c</l1>\n"
886 " </kl>\n"
887 " <kl yang:operation=\"create\" yang:position=\"1\">\n"
888 " <l2>4</l2>\n"
889 " </kl>\n"
890 " <kl yang:operation=\"create\" yang:position=\"2\">\n"
891 " <l1>e</l1>\n"
892 " <l2>5</l2>\n"
893 " </kl>\n"
894 " <kl yang:operation=\"create\" yang:position=\"3\">\n"
895 " <l1>f</l1>\n"
896 " <l2>6</l2>\n"
897 " </kl>\n"
898 "</df>\n";
899 const char *out_merge =
900 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
901 " <kl yang:operation=\"delete\" yang:orig-position=\"2\">\n"
902 " <l1>c</l1>\n"
903 " <l2>3</l2>\n"
904 " </kl>\n"
905 " <kl yang:orig-position=\"1\" yang:operation=\"delete\">\n"
906 " <l1>b</l1>\n"
907 " <l2>2</l2>\n"
908 " </kl>\n"
909 " <kl yang:orig-position=\"\" yang:operation=\"delete\">\n"
910 " <l1>a</l1>\n"
911 " <l2>1</l2>\n"
912 " </kl>\n"
913 " <kl yang:position=\"\" yang:operation=\"create\">\n"
914 " <l1>c</l1>\n"
915 " </kl>\n"
916 " <kl yang:position=\"1\" yang:operation=\"create\">\n"
917 " <l2>4</l2>\n"
918 " </kl>\n"
919 " <kl yang:position=\"2\" yang:operation=\"create\">\n"
920 " <l1>e</l1>\n"
921 " <l2>5</l2>\n"
922 " </kl>\n"
923 " <kl yang:position=\"3\" yang:operation=\"create\">\n"
924 " <l1>f</l1>\n"
925 " <l2>6</l2>\n"
926 " </kl>\n"
927 "</df>\n";
928
929 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
930}
931
932static void
933test_state_llist(void **state)
934{
935 (void) state;
936 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
937 " <kll>a</kll>\n"
938 " <kll>b</kll>\n"
939 " <kll>c</kll>\n"
940 "</df>\n";
941 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
942 " <kll>b</kll>\n"
943 " <kll>c</kll>\n"
944 " <kll>a</kll>\n"
945 " <kll>a</kll>\n"
946 " <kll>a</kll>\n"
947 "</df>\n";
948 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
949 " <kll>a</kll>\n"
950 " <kll>d</kll>\n"
951 " <kll>a</kll>\n"
952 "</df>\n";
953
954 const char *out_diff_1 =
955 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
956 " <kll yang:operation=\"replace\" yang:orig-default=\"false\" yang:position=\"\" yang:orig-position=\"1\">b</kll>\n"
957 " <kll yang:operation=\"replace\" yang:orig-default=\"false\" yang:position=\"1\" yang:orig-position=\"2\">c</kll>\n"
958 " <kll yang:operation=\"create\" yang:position=\"3\">a</kll>\n"
959 " <kll yang:operation=\"create\" yang:position=\"4\">a</kll>\n"
960 "</df>\n";
961 const char *out_diff_2 =
962 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
963 " <kll yang:operation=\"delete\" yang:orig-position=\"\">b</kll>\n"
964 " <kll yang:operation=\"delete\" yang:orig-position=\"\">c</kll>\n"
965 " <kll yang:operation=\"delete\" yang:orig-position=\"2\">a</kll>\n"
966 " <kll yang:operation=\"create\" yang:position=\"1\">d</kll>\n"
967 "</df>\n";
968 const char *out_merge =
969 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
970 " <kll yang:orig-default=\"false\" yang:orig-position=\"1\" yang:operation=\"delete\">b</kll>\n"
971 " <kll yang:orig-default=\"false\" yang:orig-position=\"2\" yang:operation=\"delete\">c</kll>\n"
972 " <kll yang:operation=\"create\" yang:position=\"4\">a</kll>\n"
973 " <kll yang:position=\"1\" yang:operation=\"create\">d</kll>\n"
974 "</df>\n";
975
976 TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
977}
978
979static void
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200980test_wd(void **state)
981{
Radek Iša56ca9e42020-09-08 18:42:00 +0200982 (void) state;
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200983 const struct lys_module *mod;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100984 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
985 " <foo>41</foo>\n"
986 " <dllist>4</dllist>\n"
987 "</df>\n";
988 const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
989 " <foo>42</foo>\n"
990 " <dllist>4</dllist>\n"
991 " <dllist>1</dllist>\n"
992 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200993
Radek Iša56ca9e42020-09-08 18:42:00 +0200994 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "defaults");
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200995 assert_non_null(mod);
996
Radek Iša56ca9e42020-09-08 18:42:00 +0200997 struct lyd_node *model_1 = NULL;
998
999 assert_int_equal(lyd_validate_module(&model_1, mod, 0, NULL), LY_SUCCESS);
1000 assert_ptr_not_equal(model_1, NULL);
1001
1002 struct lyd_node *model_2;
1003 struct lyd_node *model_3;
1004
1005 CHECK_PARSE_LYD_PARAM(xml2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2);
1006 CHECK_PARSE_LYD_PARAM(xml3, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_3);
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001007
Michal Vaskoe6323f62020-07-09 15:49:02 +02001008 /* diff1 */
Radek Iša56ca9e42020-09-08 18:42:00 +02001009 struct lyd_node *diff1 = NULL;
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001010
Radek Iša56ca9e42020-09-08 18:42:00 +02001011 assert_int_equal(lyd_diff_siblings(model_1, model_2, LYD_DIFF_DEFAULTS, &diff1), LY_SUCCESS);
1012 assert_non_null(diff1);
1013
1014 const char *diff1_out_1 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001015 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1016 " <foo yang:operation=\"replace\" yang:orig-default=\"true\" yang:orig-value=\"42\">41</foo>\n"
1017 " <dllist yang:operation=\"delete\">1</dllist>\n"
1018 " <dllist yang:operation=\"delete\">2</dllist>\n"
1019 " <dllist yang:operation=\"delete\">3</dllist>\n"
1020 " <dllist yang:operation=\"create\">4</dllist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001021 "</df>\n";
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001022
Radek Iša56ca9e42020-09-08 18:42:00 +02001023 CHECK_LYD_STRING_PARAM(diff1, diff1_out_1, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
1024 assert_int_equal(lyd_diff_apply_all(&model_1, diff1), LY_SUCCESS);
1025 CHECK_LYD(model_1, model_2);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001026
1027 /* diff2 */
Radek Iša56ca9e42020-09-08 18:42:00 +02001028 struct lyd_node *diff2;
Michal Vaskoe6323f62020-07-09 15:49:02 +02001029
Radek Iša56ca9e42020-09-08 18:42:00 +02001030 assert_int_equal(lyd_diff_siblings(model_2, model_3, LYD_DIFF_DEFAULTS, &diff2), LY_SUCCESS);
1031 assert_non_null(diff2);
1032 CHECK_LYD_STRING(diff2,
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001033 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1034 " <foo yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"41\">42</foo>\n"
1035 " <dllist yang:operation=\"create\">1</dllist>\n"
1036 "</df>\n");
Michal Vaskoe6323f62020-07-09 15:49:02 +02001037
Radek Iša56ca9e42020-09-08 18:42:00 +02001038 assert_int_equal(lyd_diff_apply_all(&model_2, diff2), LY_SUCCESS);
1039 CHECK_LYD(model_2, model_3);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001040
1041 /* merge */
Radek Iša56ca9e42020-09-08 18:42:00 +02001042 assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);
Michal Vaskoe6323f62020-07-09 15:49:02 +02001043
Radek Iša56ca9e42020-09-08 18:42:00 +02001044 const char *diff1_out_2 =
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001045 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
1046 " <foo yang:orig-default=\"true\" yang:operation=\"none\">42</foo>\n"
1047 " <dllist yang:operation=\"none\" yang:orig-default=\"true\">1</dllist>\n"
1048 " <dllist yang:operation=\"delete\">2</dllist>\n"
1049 " <dllist yang:operation=\"delete\">3</dllist>\n"
1050 " <dllist yang:operation=\"create\">4</dllist>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +02001051 "</df>\n";
1052
1053 CHECK_LYD_STRING_PARAM(diff1, diff1_out_2, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
1054
1055 lyd_free_all(model_1);
1056 lyd_free_all(model_2);
1057 lyd_free_all(model_3);
1058 lyd_free_all(diff1);
1059 lyd_free_all(diff2);
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001060}
1061
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001062int
1063main(void)
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001064{
1065 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +02001066 UTEST(test_invalid, setup),
1067 UTEST(test_same, setup),
1068 UTEST(test_empty1, setup),
1069 UTEST(test_empty2, setup),
1070 UTEST(test_empty_nested, setup),
1071 UTEST(test_leaf, setup),
1072 UTEST(test_list, setup),
1073 UTEST(test_userord_llist, setup),
1074 UTEST(test_userord_llist2, setup),
1075 UTEST(test_userord_mix, setup),
Michal Vaskoe78faec2021-04-08 17:24:43 +02001076 UTEST(test_userord_list, setup),
1077 UTEST(test_keyless_list, setup),
1078 UTEST(test_state_llist, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001079 UTEST(test_wd, setup),
Michal Vaskoe893ddd2020-06-23 13:35:20 +02001080 };
1081
1082 return cmocka_run_group_tests(tests, NULL, NULL);
1083}