blob: 22ae0b92d8092ca0b2701324bfe8be64161a2c6a [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 */
15
16#include <stdarg.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <setjmp.h>
20#include <cmocka.h>
21
22#include "libyang.h"
23#include "tests/config.h"
24
25struct state {
26 struct ly_ctx *ctx;
27 struct lyd_node *first;
28 struct lyd_node *second;
29 struct lyd_node *diff;
30 char *xml;
31 char *xml1;
32 char *xml2;
33};
34
35static int
36setup_f(void **state)
37{
38 struct state *st;
39 const char *schema =
40 "module defaults {"
41 "yang-version 1.1;"
42 "namespace \"urn:libyang:tests:defaults\";"
43 "prefix df;"
44
45 "feature unhide;"
46
47 "typedef defint32 {"
48 "type int32;"
49 "default \"42\";"
50 "}"
51
52 "leaf hiddenleaf {"
53 "if-feature \"unhide\";"
54 "type int32;"
55 "default \"42\";"
56 "}"
57
58 "container df {"
59 "leaf foo {"
60 "type defint32;"
61 "}"
62
63 "leaf hiddenleaf {"
64 "if-feature \"unhide\";"
65 "type int32;"
66 "default \"42\";"
67 "}"
68
69 "container bar {"
70 "presence \"\";"
71 "leaf hi {"
72 "type int32;"
73 "default \"42\";"
74 "}"
75
76 "leaf ho {"
77 "type int32;"
78 "mandatory true;"
79 "}"
80 "}"
81
82 "leaf-list llist {"
83 "type defint32;"
84 "ordered-by user;"
85 "}"
86
87 "leaf-list dllist {"
88 "type uint8;"
89 "default \"1\";"
90 "default \"2\";"
91 "default \"3\";"
92 "}"
93
94 "list list {"
95 "key \"name\";"
96 "leaf name {"
97 "type string;"
98 "}"
99
100 "leaf value {"
101 "type int32;"
102 "default \"42\";"
103 "}"
104 "}"
105
106 "choice select {"
107 "default \"a\";"
108 "case a {"
109 "choice a {"
110 "leaf a1 {"
111 "type int32;"
112 "default \"42\";"
113 "}"
114
115 "leaf a2 {"
116 "type int32;"
117 "default \"24\";"
118 "}"
119 "}"
120 "}"
121
122 "leaf b {"
123 "type string;"
124 "}"
125
126 "container c {"
127 "presence \"\";"
128 "leaf x {"
129 "type int32;"
130 "default \"42\";"
131 "}"
132 "}"
133 "}"
134
135 "choice select2 {"
136 "default \"s2b\";"
137 "leaf s2a {"
138 "type int32;"
139 "default \"42\";"
140 "}"
141
142 "case s2b {"
143 "choice s2b {"
144 "default \"b1\";"
145 "case b1 {"
146 "leaf b1_1 {"
147 "type int32;"
148 "default \"42\";"
149 "}"
150
151 "leaf b1_2 {"
152 "type string;"
153 "}"
154
155 "leaf b1_status {"
156 "type int32;"
157 "default \"42\";"
158 "config false;"
159 "}"
160 "}"
161
162 "leaf b2 {"
163 "type int32;"
164 "default \"42\";"
165 "}"
166 "}"
167 "}"
168 "}"
169 "}"
170
171 "container hidden {"
172 "leaf foo {"
173 "type int32;"
174 "default \"42\";"
175 "}"
176
177 "leaf baz {"
178 "type int32;"
179 "default \"42\";"
180 "}"
181
182 "leaf papa {"
183 "type int32;"
184 "default \"42\";"
185 "config false;"
186 "}"
187 "}"
188
189 "rpc rpc1 {"
190 "input {"
191 "leaf inleaf1 {"
192 "type string;"
193 "}"
194
195 "leaf inleaf2 {"
196 "type string;"
197 "default \"def1\";"
198 "}"
199 "}"
200
201 "output {"
202 "leaf outleaf1 {"
203 "type string;"
204 "default \"def2\";"
205 "}"
206
207 "leaf outleaf2 {"
208 "type string;"
209 "}"
210 "}"
211 "}"
212
213 "notification notif {"
214 "leaf ntfleaf1 {"
215 "type string;"
216 "default \"def3\";"
217 "}"
218
219 "leaf ntfleaf2 {"
220 "type string;"
221 "}"
222 "}"
223 "}";
224
225 (*state) = st = calloc(1, sizeof *st);
226 assert_non_null(st);
227 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &st->ctx));
228 assert_non_null(ly_ctx_load_module(st->ctx, "ietf-netconf-acm", "2018-02-14"));
229 assert_non_null(lys_parse_mem(st->ctx, schema, LYS_IN_YANG));
230
231 return 0;
232}
233
234static int
235teardown_f(void **state)
236{
237 struct state *st = (*state);
238
239 lyd_free_siblings(st->first);
240 lyd_free_siblings(st->second);
241 lyd_free_siblings(st->diff);
242 ly_ctx_destroy(st->ctx, NULL);
243 free(st->xml);
244 free(st->xml1);
245 free(st->xml2);
246 free(st);
247 (*state) = NULL;
248
249 return 0;
250}
251
252static void
253test_invalid(void **state)
254{
255 struct state *st = (*state);
256 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
257
Radek Krejci7931b192020-06-25 17:05:03 +0200258 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml, LYD_XML, LYD_PARSE_ONLY, 0, &st->first));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200259 assert_non_null(st->first);
260 st->second = NULL;
261
262 assert_int_equal(lyd_diff(st->first, lyd_node_children(st->first, 0), 0, &st->diff), LY_EINVAL);
263
264 assert_int_equal(lyd_diff(NULL, NULL, 0, NULL), LY_EINVAL);
265}
266
267static void
268test_same(void **state)
269{
270 struct state *st = (*state);
271 const char *xml = "<nacm xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-acm\">"
272 "<enable-nacm>true</enable-nacm>"
273 "<read-default>permit</read-default>"
274 "<write-default>deny</write-default>"
275 "<exec-default>permit</exec-default>"
276 "<enable-external-groups>true</enable-external-groups>"
277 "</nacm><df xmlns=\"urn:libyang:tests:defaults\">"
278 "<foo>42</foo><b1_1>42</b1_1>"
279 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">"
280 "<foo>42</foo><baz>42</baz></hidden>";
281
Radek Krejci7931b192020-06-25 17:05:03 +0200282 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml, LYD_XML, LYD_PARSE_ONLY, 0, &st->first));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200283 assert_non_null(st->first);
Radek Krejci7931b192020-06-25 17:05:03 +0200284 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml, LYD_XML, LYD_PARSE_ONLY, 0, &st->second));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200285 assert_non_null(st->second);
286
287 assert_int_equal(lyd_diff(st->first, st->second, 0, &st->diff), LY_SUCCESS);
288 assert_null(st->diff);
289
290 assert_int_equal(lyd_diff_apply(&st->first, st->diff), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200291 lyd_print_mem(&st->xml1, st->first, LYD_XML, LYD_PRINT_WITHSIBLINGS);
292 lyd_print_mem(&st->xml2, st->second, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200293 assert_string_equal(st->xml1, st->xml2);
294}
295
296static void
297test_empty1(void **state)
298{
299 struct state *st = (*state);
300 const char *xml =
301 "<df xmlns=\"urn:libyang:tests:defaults\">"
302 "<foo>42</foo><b1_1>42</b1_1>"
303 "</df>"
304 "<hidden xmlns=\"urn:libyang:tests:defaults\">"
305 "<foo>42</foo><baz>42</baz>"
306 "</hidden>";
307
308 st->first = NULL;
Radek Krejci7931b192020-06-25 17:05:03 +0200309 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml, LYD_XML, LYD_PARSE_ONLY, 0, &st->second));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200310 assert_non_null(st->second);
311
312 assert_int_equal(lyd_diff(st->first, st->second, 0, &st->diff), LY_SUCCESS);
313
314 assert_non_null(st->diff);
Radek Krejci7931b192020-06-25 17:05:03 +0200315 lyd_print_mem(&st->xml, st->diff, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200316 assert_string_equal(st->xml,
317 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">"
318 "<foo>42</foo><b1_1>42</b1_1>"
319 "</df>"
320 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"create\">"
321 "<foo>42</foo><baz>42</baz>"
322 "</hidden>"
323 );
324
325 assert_int_equal(lyd_diff_apply(&st->first, st->diff), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200326 lyd_print_mem(&st->xml1, st->first, LYD_XML, LYD_PRINT_WITHSIBLINGS);
327 lyd_print_mem(&st->xml2, st->second, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200328 assert_string_equal(st->xml1, st->xml2);
329}
330
331static void
332test_empty2(void **state)
333{
334 struct state *st = (*state);
335 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\">"
336 "<foo>42</foo><b1_1>42</b1_1>"
337 "</df><hidden xmlns=\"urn:libyang:tests:defaults\">"
338 "<foo>42</foo><baz>42</baz></hidden>";
339
Radek Krejci7931b192020-06-25 17:05:03 +0200340 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml, LYD_XML, LYD_PARSE_ONLY, 0, &st->first));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200341 assert_non_null(st->first);
342 st->second = NULL;
343
344 assert_int_equal(lyd_diff(st->first, st->second, 0, &st->diff), LY_SUCCESS);
345
346 assert_non_null(st->diff);
Radek Krejci7931b192020-06-25 17:05:03 +0200347 lyd_print_mem(&st->xml, st->diff, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200348 assert_string_equal(st->xml,
349 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">"
350 "<foo>42</foo><b1_1>42</b1_1>"
351 "</df>"
352 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">"
353 "<foo>42</foo><baz>42</baz>"
354 "</hidden>"
355 );
356
357 assert_int_equal(lyd_diff_apply(&st->first, st->diff), LY_SUCCESS);
358 assert_ptr_equal(st->first, st->second);
359}
360
361static void
362test_empty_nested(void **state)
363{
364 struct state *st = (*state);
365 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
366
Radek Krejci7931b192020-06-25 17:05:03 +0200367 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml, LYD_XML, LYD_PARSE_ONLY, 0, &st->first));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200368 assert_non_null(st->first);
369 st->second = NULL;
370
371 assert_int_equal(lyd_diff(NULL, NULL, 0, &st->diff), LY_SUCCESS);
372 assert_null(st->diff);
373
374 assert_int_equal(lyd_diff(NULL, lyd_node_children(st->first, 0), 0, &st->diff), LY_SUCCESS);
375
376 assert_non_null(st->diff);
Radek Krejci7931b192020-06-25 17:05:03 +0200377 lyd_print_mem(&st->xml, st->diff, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200378 assert_string_equal(st->xml,
379 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">"
380 "<foo yang:operation=\"create\">42</foo>"
381 "</df>"
382 );
383
384 free(st->xml);
385 lyd_free_siblings(st->diff);
386 assert_int_equal(lyd_diff(lyd_node_children(st->first, 0), NULL, 0, &st->diff), LY_SUCCESS);
387
388 assert_non_null(st->diff);
Radek Krejci7931b192020-06-25 17:05:03 +0200389 lyd_print_mem(&st->xml, st->diff, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200390 assert_string_equal(st->xml,
391 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">"
392 "<foo yang:operation=\"delete\">42</foo>"
393 "</df>"
394 );
395}
396
397static void
398test_leaf(void **state)
399{
400 struct state *st = (*state);
401 const char *xml1 =
402 "<df xmlns=\"urn:libyang:tests:defaults\">"
403 "<foo>42</foo>"
404 "</df>"
405 "<hidden xmlns=\"urn:libyang:tests:defaults\">"
406 "<foo>42</foo><baz>42</baz>"
407 "</hidden>";
408 const char *xml2 =
409 "<df xmlns=\"urn:libyang:tests:defaults\">"
410 "<foo>41</foo><b1_1>42</b1_1>"
411 "</df>";
412
Radek Krejci7931b192020-06-25 17:05:03 +0200413 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml1, LYD_XML, LYD_PARSE_ONLY, 0, &st->first));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200414 assert_non_null(st->first);
Radek Krejci7931b192020-06-25 17:05:03 +0200415 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml2, LYD_XML, LYD_PARSE_ONLY, 0, &st->second));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200416 assert_non_null(st->second);
417
418 assert_int_equal(lyd_diff(st->first, st->second, 0, &st->diff), LY_SUCCESS);
419
420 assert_non_null(st->diff);
Radek Krejci7931b192020-06-25 17:05:03 +0200421 lyd_print_mem(&st->xml, st->diff, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200422 assert_string_equal(st->xml,
423 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">"
424 "<foo yang:operation=\"replace\" yang:orig-value=\"42\">41</foo><b1_1 yang:operation=\"create\">42</b1_1>"
425 "</df>"
426 "<hidden xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"delete\">"
427 "<foo>42</foo><baz>42</baz>"
428 "</hidden>"
429 );
430
431 assert_int_equal(lyd_diff_apply(&st->first, st->diff), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200432 lyd_print_mem(&st->xml1, st->first, LYD_XML, LYD_PRINT_WITHSIBLINGS);
433 lyd_print_mem(&st->xml2, st->second, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200434 assert_string_equal(st->xml1, st->xml2);
435}
436
437static void
438test_list(void **state)
439{
440 struct state *st = (*state);
441 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">"
442 "<list><name>a</name><value>1</value></list>"
443 "<list><name>b</name><value>2</value></list>"
444 "</df>";
445 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">"
446 "<list><name>b</name><value>-2</value></list>"
447 "<list><name>c</name><value>3</value></list>"
448 "</df>";
449
Radek Krejci7931b192020-06-25 17:05:03 +0200450 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml1, LYD_XML, LYD_PARSE_ONLY, 0, &st->first));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200451 assert_non_null(st->first);
Radek Krejci7931b192020-06-25 17:05:03 +0200452 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml2, LYD_XML, LYD_PARSE_ONLY, 0, &st->second));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200453 assert_non_null(st->second);
454
455 assert_int_equal(lyd_diff(st->first, st->second, 0, &st->diff), LY_SUCCESS);
456
457 assert_non_null(st->diff);
Radek Krejci7931b192020-06-25 17:05:03 +0200458 lyd_print_mem(&st->xml, st->diff, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200459 assert_string_equal(st->xml,
460 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">"
461 "<list yang:operation=\"delete\"><name>a</name><value>1</value></list>"
462 "<list yang:operation=\"none\">"
463 "<name>b</name><value yang:operation=\"replace\" yang:orig-value=\"2\">-2</value>"
464 "</list>"
465 "<list yang:operation=\"create\"><name>c</name><value>3</value></list>"
466 "</df>"
467 );
468
469 assert_int_equal(lyd_diff_apply(&st->first, st->diff), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200470 lyd_print_mem(&st->xml1, st->first, LYD_XML, LYD_PRINT_WITHSIBLINGS);
471 lyd_print_mem(&st->xml2, st->second, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200472 assert_string_equal(st->xml1, st->xml2);
473}
474
475static void
476test_userord_llist(void **state)
477{
478 struct state *st = (*state);
479 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">"
480 "<llist>1</llist>"
481 "<llist>2</llist>"
482 "<llist>3</llist>"
483 "<llist>4</llist>"
484 "<llist>5</llist>"
485 "</df>";
486 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">"
487 "<llist>1</llist>"
488 "<llist>4</llist>"
489 "<llist>3</llist>"
490 "<llist>2</llist>"
491 "<llist>5</llist>"
492 "</df>";
493
Radek Krejci7931b192020-06-25 17:05:03 +0200494 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml1, LYD_XML, LYD_PARSE_ONLY, 0, &st->first));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200495 assert_non_null(st->first);
Radek Krejci7931b192020-06-25 17:05:03 +0200496 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml2, LYD_XML, LYD_PARSE_ONLY, 0, &st->second));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200497 assert_non_null(st->second);
498
499 assert_int_equal(lyd_diff(st->first, st->second, 0, &st->diff), LY_SUCCESS);
500
501 assert_non_null(st->diff);
Radek Krejci7931b192020-06-25 17:05:03 +0200502 lyd_print_mem(&st->xml, st->diff, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200503 assert_string_equal(st->xml,
504 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">"
505 "<llist yang:operation=\"replace\" yang:orig-value=\"3\" yang:value=\"1\">4</llist>"
506 "<llist yang:operation=\"replace\" yang:orig-value=\"2\" yang:value=\"4\">3</llist>"
507 "</df>"
508 );
509
510 assert_int_equal(lyd_diff_apply(&st->first, st->diff), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200511 lyd_print_mem(&st->xml1, st->first, LYD_XML, LYD_PRINT_WITHSIBLINGS);
512 lyd_print_mem(&st->xml2, st->second, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200513 assert_string_equal(st->xml1, st->xml2);
514}
515
516static void
517test_userord_llist2(void **state)
518{
519 struct state *st = (*state);
520 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">"
521 "<llist>1</llist>"
522 "<list><name>a</name><value>1</value></list>"
523 "<llist>2</llist>"
524 "<llist>3</llist>"
525 "<llist>4</llist>"
526 "</df>";
527 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">"
528 "<llist>1</llist>"
529 "<list><name>a</name><value>1</value></list>"
530 "<llist>2</llist>"
531 "<llist>4</llist>"
532 "<llist>3</llist>"
533 "</df>";
534
Radek Krejci7931b192020-06-25 17:05:03 +0200535 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml1, LYD_XML, LYD_PARSE_ONLY, 0, &st->first));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200536 assert_non_null(st->first);
Radek Krejci7931b192020-06-25 17:05:03 +0200537 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml2, LYD_XML, LYD_PARSE_ONLY, 0, &st->second));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200538 assert_non_null(st->second);
539
540 assert_int_equal(lyd_diff(st->first, st->second, 0, &st->diff), LY_SUCCESS);
541
542 assert_non_null(st->diff);
Radek Krejci7931b192020-06-25 17:05:03 +0200543 lyd_print_mem(&st->xml, st->diff, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200544 assert_string_equal(st->xml,
545 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">"
546 "<llist yang:operation=\"replace\" yang:orig-value=\"3\" yang:value=\"2\">4</llist>"
547 "</df>"
548 );
549
550 assert_int_equal(lyd_diff_apply(&st->first, st->diff), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200551 lyd_print_mem(&st->xml1, st->first, LYD_XML, LYD_PRINT_WITHSIBLINGS);
552 lyd_print_mem(&st->xml2, st->second, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200553 assert_string_equal(st->xml1, st->xml2);
554}
555
556static void
557test_userord_mix(void **state)
558{
559 struct state *st = (*state);
560 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">"
561 "<llist>1</llist>"
562 "<llist>2</llist>"
563 "<llist>3</llist>"
564 "</df>";
565 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">"
566 "<llist>3</llist>"
567 "<llist>1</llist>"
568 "</df>";
569
Radek Krejci7931b192020-06-25 17:05:03 +0200570 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml1, LYD_XML, LYD_PARSE_ONLY, 0, &st->first));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200571 assert_non_null(st->first);
Radek Krejci7931b192020-06-25 17:05:03 +0200572 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml2, LYD_XML, LYD_PARSE_ONLY, 0, &st->second));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200573 assert_non_null(st->second);
574
575 assert_int_equal(lyd_diff(st->first, st->second, 0, &st->diff), LY_SUCCESS);
576
577 assert_non_null(st->diff);
Radek Krejci7931b192020-06-25 17:05:03 +0200578 lyd_print_mem(&st->xml, st->diff, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200579 assert_string_equal(st->xml,
580 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">"
581 "<llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>"
582 "<llist yang:operation=\"replace\" yang:orig-value=\"1\" yang:value=\"\">3</llist>"
583 "</df>"
584 );
585
586 assert_int_equal(lyd_diff_apply(&st->first, st->diff), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200587 lyd_print_mem(&st->xml1, st->first, LYD_XML, LYD_PRINT_WITHSIBLINGS);
588 lyd_print_mem(&st->xml2, st->second, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200589 assert_string_equal(st->xml1, st->xml2);
590}
591
592static void
593test_userord_mix2(void **state)
594{
595 struct state *st = (*state);
596 const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">"
597 "<llist>1</llist>"
598 "<llist>2</llist>"
599 "<llist>3</llist>"
600 "</df>";
601 const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">"
602 "<llist>4</llist>"
603 "<llist>3</llist>"
604 "<llist>1</llist>"
605 "</df>";
606
Radek Krejci7931b192020-06-25 17:05:03 +0200607 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml1, LYD_XML, LYD_PARSE_ONLY, 0, &st->first));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200608 assert_non_null(st->first);
Radek Krejci7931b192020-06-25 17:05:03 +0200609 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml2, LYD_XML, LYD_PARSE_ONLY, 0, &st->second));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200610 assert_non_null(st->second);
611
612 assert_int_equal(lyd_diff(st->first, st->second, 0, &st->diff), LY_SUCCESS);
613
614 assert_non_null(st->diff);
Radek Krejci7931b192020-06-25 17:05:03 +0200615 lyd_print_mem(&st->xml, st->diff, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200616 assert_string_equal(st->xml,
617 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">"
618 "<llist yang:operation=\"delete\" yang:orig-value=\"1\">2</llist>"
619 "<llist yang:operation=\"create\" yang:value=\"\">4</llist>"
620 "<llist yang:operation=\"replace\" yang:orig-value=\"1\" yang:value=\"4\">3</llist>"
621 "</df>"
622 );
623
624 assert_int_equal(lyd_diff_apply(&st->first, st->diff), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200625 lyd_print_mem(&st->xml1, st->first, LYD_XML, LYD_PRINT_WITHSIBLINGS);
626 lyd_print_mem(&st->xml2, st->second, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200627 assert_string_equal(st->xml1, st->xml2);
628}
629
630static void
631test_wd(void **state)
632{
633 struct state *st = (*state);
634 const struct lys_module *mod;
635 const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\">"
636 "<foo>41</foo><dllist>4</dllist>"
637 "</df>";
638
639 mod = ly_ctx_get_module_implemented(st->ctx, "defaults");
640 assert_non_null(mod);
641
642 st->first = NULL;
Michal Vasko26e80012020-07-08 10:55:46 +0200643 assert_int_equal(lyd_validate_module(&st->first, mod, 0), LY_SUCCESS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200644 assert_ptr_not_equal(st->first, NULL);
Radek Krejci7931b192020-06-25 17:05:03 +0200645 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(st->ctx, xml, LYD_XML, 0, LYD_VALIDATE_PRESENT, &st->second));
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200646 assert_non_null(st->second);
647
648 assert_int_equal(lyd_diff(st->first, st->second, LYD_DIFF_WITHDEFAULTS, &st->diff), LY_SUCCESS);
649
650 assert_non_null(st->diff);
Radek Krejci7931b192020-06-25 17:05:03 +0200651 lyd_print_mem(&st->xml, st->diff, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200652 assert_string_equal(st->xml,
653 "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">"
654 "<foo yang:operation=\"replace\" yang:orig-default=\"true\" yang:orig-value=\"42\">41</foo>"
655 "<dllist yang:operation=\"delete\">1</dllist>"
656 "<dllist yang:operation=\"delete\">2</dllist>"
657 "<dllist yang:operation=\"delete\">3</dllist>"
658 "<dllist yang:operation=\"create\">4</dllist>"
659 "</df>"
660 );
661
662 assert_int_equal(lyd_diff_apply(&st->first, st->diff), LY_SUCCESS);
Radek Krejci7931b192020-06-25 17:05:03 +0200663 lyd_print_mem(&st->xml1, st->first, LYD_XML, LYD_PRINT_WITHSIBLINGS);
664 lyd_print_mem(&st->xml2, st->second, LYD_XML, LYD_PRINT_WITHSIBLINGS);
Michal Vaskoe893ddd2020-06-23 13:35:20 +0200665 /* TODO just an ordering problem
666 assert_string_equal(st->xml1, st->xml2);*/
667}
668
669int main(void)
670{
671 const struct CMUnitTest tests[] = {
672 cmocka_unit_test_setup_teardown(test_invalid, setup_f, teardown_f),
673 cmocka_unit_test_setup_teardown(test_same, setup_f, teardown_f),
674 cmocka_unit_test_setup_teardown(test_empty1, setup_f, teardown_f),
675 cmocka_unit_test_setup_teardown(test_empty2, setup_f, teardown_f),
676 cmocka_unit_test_setup_teardown(test_empty_nested, setup_f, teardown_f),
677 cmocka_unit_test_setup_teardown(test_leaf, setup_f, teardown_f),
678 cmocka_unit_test_setup_teardown(test_list, setup_f, teardown_f),
679 cmocka_unit_test_setup_teardown(test_userord_llist, setup_f, teardown_f),
680 cmocka_unit_test_setup_teardown(test_userord_llist2, setup_f, teardown_f),
681 cmocka_unit_test_setup_teardown(test_userord_mix, setup_f, teardown_f),
682 cmocka_unit_test_setup_teardown(test_userord_mix2, setup_f, teardown_f),
683 cmocka_unit_test_setup_teardown(test_wd, setup_f, teardown_f),
684 };
685
686 return cmocka_run_group_tests(tests, NULL, NULL);
687}