blob: da530697c8edc0503ebde3efd761602c0fb9df5b [file] [log] [blame]
Michal Vasko4490d312020-06-16 13:08:55 +02001/**
2 * @file test_merge.c
3 * @author Michal Vasko <mvasko@cesnet.cz>
4 * @brief tests for complex data merges.
5 *
6 * Copyright (c) 2020 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15#include <stdarg.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <setjmp.h>
20#include <cmocka.h>
21
22#include "libyang.h"
23
24struct state {
25 struct ly_ctx *ctx;
26 struct lyd_node *source;
27 struct lyd_node *target;
28 struct lyd_node *result;
29};
30
31static int
32setup_dflt(void **state)
33{
34 struct state *st;
35
36 (*state) = st = calloc(1, sizeof *st);
37 if (!st) {
38 fprintf(stderr, "Memory allocation error.\n");
39 return -1;
40 }
41
42 /* libyang context */
43 if (ly_ctx_new(NULL, 0, &st->ctx)) {
44 fprintf(stderr, "Failed to create context.\n");
45 goto error;
46 }
47
48 return 0;
49
50error:
51 ly_ctx_destroy(st->ctx, NULL);
52 free(st);
53 (*state) = NULL;
54
55 return -1;
56}
57
58static int
59teardown_dflt(void **state)
60{
61 struct state *st = (*state);
62
63 lyd_free_siblings(st->target);
64 lyd_free_siblings(st->source);
65 lyd_free_siblings(st->result);
66 ly_ctx_destroy(st->ctx, NULL);
67 free(st);
68 (*state) = NULL;
69
70 return 0;
71}
72
73static void
74test_batch(void **state)
75{
76 struct state *st = (*state);
77 LY_ERR ret;
78 uint32_t i;
79 char *str;
80
81 const char *start =
82 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
83 "<module>"
84 "<name>yang</name>"
85 "<revision>2016-02-11</revision>"
86 "<conformance-type>implement</conformance-type>"
87 "</module>"
88 "</modules-state>";
89 const char *data[] = {
90 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
91 "<module>"
92 "<name>ietf-yang-library</name>"
93 "<revision>2016-02-01</revision>"
94 "<conformance-type>implement</conformance-type>"
95 "</module>"
96 "</modules-state>"
97 ,
98 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
99 "<module>"
100 "<name>ietf-netconf-acm</name>"
101 "<revision>2012-02-22</revision>"
102 "<conformance-type>implement</conformance-type>"
103 "</module>"
104 "</modules-state>"
105 ,
106 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
107 "<module>"
108 "<name>ietf-netconf</name>"
109 "<revision>2011-06-01</revision>"
110 "<conformance-type>implement</conformance-type>"
111 "</module>"
112 "</modules-state>"
113 ,
114 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
115 "<module>"
116 "<name>ietf-netconf-monitoring</name>"
117 "<revision>2010-10-04</revision>"
118 "<conformance-type>implement</conformance-type>"
119 "</module>"
120 "</modules-state>"
121 ,
122 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
123 "<module>"
124 "<name>ietf-netconf-with-defaults</name>"
125 "<revision>2011-06-01</revision>"
126 "<conformance-type>implement</conformance-type>"
127 "</module>"
128 "</modules-state>"
129 ,
130 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
131 "<module>"
132 "<name>yang</name>"
133 "<revision>2016-02-11</revision>"
134 "<namespace>urn:ietf:params:xml:ns:yang:1</namespace>"
135 "<conformance-type>implement</conformance-type>"
136 "</module>"
137 "</modules-state>"
138 ,
139 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
140 "<module>"
141 "<name>ietf-yang-library</name>"
142 "<revision>2016-02-01</revision>"
143 "<namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>"
144 "<conformance-type>implement</conformance-type>"
145 "</module>"
146 "</modules-state>"
147 ,
148 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
149 "<module>"
150 "<name>ietf-netconf-acm</name>"
151 "<revision>2012-02-22</revision>"
152 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>"
153 "<conformance-type>implement</conformance-type>"
154 "</module>"
155 "</modules-state>"
156 ,
157 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
158 "<module>"
159 "<name>ietf-netconf</name>"
160 "<revision>2011-06-01</revision>"
161 "<namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>"
162 "<feature>writable-running</feature>"
163 "<feature>candidate</feature>"
164 "<feature>rollback-on-error</feature>"
165 "<feature>validate</feature>"
166 "<feature>startup</feature>"
167 "<feature>xpath</feature>"
168 "<conformance-type>implement</conformance-type>"
169 "</module>"
170 "</modules-state>"
171 ,
172 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
173 "<module>"
174 "<name>ietf-netconf-monitoring</name>"
175 "<revision>2010-10-04</revision>"
176 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</namespace>"
177 "<conformance-type>implement</conformance-type>"
178 "</module>"
179 "</modules-state>"
180 ,
181 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
182 "<module>"
183 "<name>ietf-netconf-with-defaults</name>"
184 "<revision>2011-06-01</revision>"
185 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults</namespace>"
186 "<conformance-type>implement</conformance-type>"
187 "</module>"
188 "</modules-state>"
189 };
190 const char *output_template =
191 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
192 "<module>"
193 "<name>yang</name>"
194 "<revision>2016-02-11</revision>"
195 "<conformance-type>implement</conformance-type>"
196 "<namespace>urn:ietf:params:xml:ns:yang:1</namespace>"
197 "</module>"
198 "<module>"
199 "<name>ietf-yang-library</name>"
200 "<revision>2016-02-01</revision>"
201 "<conformance-type>implement</conformance-type>"
202 "<namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>"
203 "</module>"
204 "<module>"
205 "<name>ietf-netconf-acm</name>"
206 "<revision>2012-02-22</revision>"
207 "<conformance-type>implement</conformance-type>"
208 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>"
209 "</module>"
210 "<module>"
211 "<name>ietf-netconf</name>"
212 "<revision>2011-06-01</revision>"
213 "<conformance-type>implement</conformance-type>"
214 "<namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>"
215 "<feature>writable-running</feature>"
216 "<feature>candidate</feature>"
217 "<feature>rollback-on-error</feature>"
218 "<feature>validate</feature>"
219 "<feature>startup</feature>"
220 "<feature>xpath</feature>"
221 "</module>"
222 "<module>"
223 "<name>ietf-netconf-monitoring</name>"
224 "<revision>2010-10-04</revision>"
225 "<conformance-type>implement</conformance-type>"
226 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</namespace>"
227 "</module>"
228 "<module>"
229 "<name>ietf-netconf-with-defaults</name>"
230 "<revision>2011-06-01</revision>"
231 "<conformance-type>implement</conformance-type>"
232 "<namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults</namespace>"
233 "</module>"
234 "</modules-state>";
235
236 st->target = lyd_parse_mem(st->ctx, start, LYD_XML, LYD_OPT_PARSE_ONLY);
237 assert_non_null(st->target);
238
239 for (i = 0; i < 11; ++i) {
240 st->source = lyd_parse_mem(st->ctx, data[i], LYD_XML, LYD_OPT_PARSE_ONLY);
241 assert_non_null(st->source);
242
243 ret = lyd_merge(&st->target, st->source, LYD_MERGE_DESTRUCT);
244 assert_int_equal(ret, LY_SUCCESS);
245 st->source = NULL;
246 }
247
248 lyd_print_mem(&str, st->target, LYD_XML, 0);
249 assert_string_equal(str, output_template);
250 free(str);
251}
252
253static void
254test_leaf(void **state)
255{
256 struct state *st = (*state);
257 const char *sch = "module x {"
258 " namespace urn:x;"
259 " prefix x;"
260 " container A {"
261 " leaf f1 {type string;}"
262 " container B {"
263 " leaf f2 {type string;}"
264 " }"
265 " }"
266 " }";
267 const char *trg = "<A xmlns=\"urn:x\"> <f1>block</f1> </A>";
268 const char *src = "<A xmlns=\"urn:x\"> <f1>aa</f1> <B> <f2>bb</f2> </B> </A>";
269 const char *result = "<A xmlns=\"urn:x\"><f1>aa</f1><B><f2>bb</f2></B></A>";
270 char *printed = NULL;
271
272 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
273
274 st->source = lyd_parse_mem(st->ctx, src, LYD_XML, LYD_VALOPT_DATA_ONLY);
275 assert_non_null(st->source);
276
277 st->target = lyd_parse_mem(st->ctx, trg, LYD_XML, LYD_VALOPT_DATA_ONLY);
278 assert_non_null(st->target);
279
280 /* merge them */
281 assert_int_equal(lyd_merge(&st->target, st->source, 0), LY_SUCCESS);
282 assert_int_equal(lyd_validate(&st->target, NULL, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
283
284 /* check the result */
285 lyd_print_mem(&printed, st->target, LYD_XML, LYDP_WITHSIBLINGS);
286 assert_string_equal(printed, result);
287 free(printed);
288}
289
290static void
291test_container(void **state)
292{
293 struct state *st = (*state);
294 const char *sch =
295 "module A {"
296 "namespace \"aa:A\";"
297 "prefix A;"
298 "container A {"
299 "leaf f1 {type string;}"
300 "container B {"
301 "leaf f2 {type string;}"
302 "}"
303 "container C {"
304 "leaf f3 {type string;}"
305 "}"
306 "}"
307 "}";
308
309 const char *trg = "<A xmlns=\"aa:A\"> <B> <f2>aaa</f2> </B> </A>";
310 const char *src = "<A xmlns=\"aa:A\"> <C> <f3>bbb</f3> </C> </A>";
311 const char *result = "<A xmlns=\"aa:A\"><B><f2>aaa</f2></B><C><f3>bbb</f3></C></A>";
312 char *printed = NULL;
313
314 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
315
316 st->source = lyd_parse_mem(st->ctx, src, LYD_XML, LYD_VALOPT_DATA_ONLY);
317 assert_non_null(st->source);
318
319 st->target = lyd_parse_mem(st->ctx, trg, LYD_XML, LYD_VALOPT_DATA_ONLY);
320 assert_non_null(st->target);
321
322 /* merge them */
323 assert_int_equal(lyd_merge(&st->target, st->source, 0), LY_SUCCESS);
324 assert_int_equal(lyd_validate(&st->target, NULL, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
325
326 /* check the result */
327 lyd_print_mem(&printed, st->target, LYD_XML, LYDP_WITHSIBLINGS);
328 assert_string_equal(printed, result);
329 free(printed);
330}
331
332static void
333test_list(void **state)
334{
335 struct state *st = (*state);
336 const char *sch =
337 "module merge {"
338 "namespace \"http://test/merge\";"
339 "prefix merge;"
340
341 "container inner1 {"
342 "list b-list1 {"
343 "key p1;"
344 "leaf p1 {"
345 "type uint8;"
346 "}"
347 "leaf p2 {"
348 "type string;"
349 "}"
350 "leaf p3 {"
351 "type boolean;"
352 "default false;"
353 "}"
354 "}"
355 "}"
356 "}";
357
358
359 const char *trg =
360 "<inner1 xmlns=\"http://test/merge\">"
361 "<b-list1>"
362 "<p1>1</p1>"
363 "<p2>a</p2>"
364 "<p3>true</p3>"
365 "</b-list1>"
366 "</inner1>";
367 const char *src =
368 "<inner1 xmlns=\"http://test/merge\">"
369 "<b-list1>"
370 "<p1>1</p1>"
371 "<p2>b</p2>"
372 "</b-list1>"
373 "</inner1>";
374 const char *result =
375 "<inner1 xmlns=\"http://test/merge\">"
376 "<b-list1>"
377 "<p1>1</p1>"
378 "<p2>b</p2>"
379 "<p3>true</p3>"
380 "</b-list1>"
381 "</inner1>";
382 char *printed = NULL;
383
384 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
385
386 st->source = lyd_parse_mem(st->ctx, src, LYD_XML, LYD_VALOPT_DATA_ONLY);
387 assert_non_null(st->source);
388
389 st->target = lyd_parse_mem(st->ctx, trg, LYD_XML, LYD_VALOPT_DATA_ONLY);
390 assert_non_null(st->target);
391
392 /* merge them */
393 assert_int_equal(lyd_merge(&st->target, st->source, LYD_MERGE_EXPLICIT), LY_SUCCESS);
394 assert_int_equal(lyd_validate(&st->target, NULL, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
395
396 /* check the result */
397 lyd_print_mem(&printed, st->target, LYD_XML, LYDP_WITHSIBLINGS);
398 assert_string_equal(printed, result);
399 free(printed);
400}
401
402static void
403test_list2(void **state)
404{
405 struct state *st = (*state);
406 const char *sch =
407 "module merge {"
408 "namespace \"http://test/merge\";"
409 "prefix merge;"
410
411 "container inner1 {"
412 "list b-list1 {"
413 "key p1;"
414 "leaf p1 {"
415 "type uint8;"
416 "}"
417 "leaf p2 {"
418 "type string;"
419 "}"
420 "container inner2 {"
421 "leaf p3 {"
422 "type boolean;"
423 "default false;"
424 "}"
425 "leaf p4 {"
426 "type string;"
427 "}"
428 "}"
429 "}"
430 "}"
431 "}";
432
433
434 const char *trg =
435 "<inner1 xmlns=\"http://test/merge\">"
436 "<b-list1>"
437 "<p1>1</p1>"
438 "<p2>a</p2>"
439 "<inner2>"
440 "<p4>val</p4>"
441 "</inner2>"
442 "</b-list1>"
443 "</inner1>";
444 const char *src =
445 "<inner1 xmlns=\"http://test/merge\">"
446 "<b-list1>"
447 "<p1>1</p1>"
448 "<p2>b</p2>"
449 "</b-list1>"
450 "</inner1>";
451 const char *result =
452 "<inner1 xmlns=\"http://test/merge\">"
453 "<b-list1>"
454 "<p1>1</p1>"
455 "<p2>b</p2>"
456 "<inner2>"
457 "<p4>val</p4>"
458 "</inner2>"
459 "</b-list1>"
460 "</inner1>";
461 char *printed = NULL;
462
463 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
464
465 st->source = lyd_parse_mem(st->ctx, src, LYD_XML, LYD_VALOPT_DATA_ONLY);
466 assert_non_null(st->source);
467
468 st->target = lyd_parse_mem(st->ctx, trg, LYD_XML, LYD_VALOPT_DATA_ONLY);
469 assert_non_null(st->target);
470
471 /* merge them */
472 assert_int_equal(lyd_merge(&st->target, st->source, LYD_MERGE_EXPLICIT), LY_SUCCESS);
473 assert_int_equal(lyd_validate(&st->target, NULL, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
474
475 /* check the result */
476 lyd_print_mem(&printed, st->target, LYD_XML, LYDP_WITHSIBLINGS);
477 assert_string_equal(printed, result);
478 free(printed);
479}
480
481static void
482test_case(void **state)
483{
484 struct state *st = (*state);
485 const char *sch =
486 "module merge {"
487 "namespace \"http://test/merge\";"
488 "prefix merge;"
489 "container cont {"
490 "choice ch {"
491 "container inner {"
492 "leaf p1 {"
493 "type string;"
494 "}"
495 "}"
496 "case c2 {"
497 "leaf p1 {"
498 "type string;"
499 "}"
500 "}"
501 "}"
502 "}"
503 "}";
504
505 const char *trg =
506 "<cont xmlns=\"http://test/merge\">"
507 "<inner>"
508 "<p1>1</p1>"
509 "</inner>"
510 "</cont>";
511 const char *src =
512 "<cont xmlns=\"http://test/merge\">"
513 "<p1>1</p1>"
514 "</cont>";
515 const char *result =
516 "<cont xmlns=\"http://test/merge\">"
517 "<p1>1</p1>"
518 "</cont>";
519 char *printed = NULL;
520
521 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
522
523 st->source = lyd_parse_mem(st->ctx, src, LYD_XML, LYD_VALOPT_DATA_ONLY);
524 assert_non_null(st->source);
525
526 st->target = lyd_parse_mem(st->ctx, trg, LYD_XML, LYD_VALOPT_DATA_ONLY);
527 assert_non_null(st->target);
528
529 /* merge them */
530 assert_int_equal(lyd_merge(&st->target, st->source, 0), LY_SUCCESS);
531 assert_int_equal(lyd_validate(&st->target, NULL, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
532
533 /* check the result */
534 lyd_print_mem(&printed, st->target, LYD_XML, LYDP_WITHSIBLINGS);
535 assert_string_equal(printed, result);
536 free(printed);
537}
538
539static void
540test_dflt(void **state)
541{
542 struct state *st = (*state);
543 struct lyd_node *tmp;
544 const char *sch =
545 "module merge-dflt {"
546 "namespace \"urn:merge-dflt\";"
547 "prefix md;"
548 "container top {"
549 "leaf a {"
550 "type string;"
551 "}"
552 "leaf b {"
553 "type string;"
554 "}"
555 "leaf c {"
556 "type string;"
557 "default \"c_dflt\";"
558 "}"
559 "}"
560 "}";
561
562 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
563
564 st->target = lyd_new_path(NULL, st->ctx, "/merge-dflt:top/c", "c_dflt", 0);
565 assert_non_null(st->target);
566 assert_int_equal(lyd_validate(&(st->target), NULL, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
567
568 st->source = lyd_new_path(NULL, st->ctx, "/merge-dflt:top/a", "a_val", 0);
569 assert_non_null(st->source);
570 tmp = lyd_new_path(st->source, st->ctx, "/merge-dflt:top/b", "b_val", 0);
571 assert_non_null(tmp);
572 assert_int_equal(lyd_validate(&(st->source), NULL, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
573
574 assert_int_equal(lyd_merge(&st->target, st->source, LYD_MERGE_DESTRUCT), LY_SUCCESS);
575 st->source = NULL;
576
577 /* c should be replaced and now be default */
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200578 assert_true(lyd_node_children(st->target, 0)->flags & LYD_DEFAULT);
Michal Vasko4490d312020-06-16 13:08:55 +0200579}
580
581static void
582test_dflt2(void **state)
583{
584 struct state *st = (*state);
585 struct lyd_node *tmp;
586 const char *sch =
587 "module merge-dflt {"
588 "namespace \"urn:merge-dflt\";"
589 "prefix md;"
590 "container top {"
591 "leaf a {"
592 "type string;"
593 "}"
594 "leaf b {"
595 "type string;"
596 "}"
597 "leaf c {"
598 "type string;"
599 "default \"c_dflt\";"
600 "}"
601 "}"
602 "}";
603
604 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
605
606 st->target = lyd_new_path(NULL, st->ctx, "/merge-dflt:top/c", "c_dflt", 0);
607 assert_non_null(st->target);
608 assert_int_equal(lyd_validate(&(st->target), NULL, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
609
610 st->source = lyd_new_path(NULL, st->ctx, "/merge-dflt:top/a", "a_val", 0);
611 assert_non_null(st->source);
612 tmp = lyd_new_path(st->source, st->ctx, "/merge-dflt:top/b", "b_val", 0);
613 assert_non_null(tmp);
614 assert_int_equal(lyd_validate(&(st->source), NULL, LYD_VALOPT_DATA_ONLY), LY_SUCCESS);
615
616 assert_int_equal(lyd_merge(&st->target, st->source, LYD_MERGE_EXPLICIT), LY_SUCCESS);
617
618 /* c should not be replaced, so c remains not default */
Michal Vasko5bfd4be2020-06-23 13:26:19 +0200619 assert_false(lyd_node_children(st->target, 0)->flags & LYD_DEFAULT);
Michal Vasko4490d312020-06-16 13:08:55 +0200620}
621
622static void
623test_leafrefs(void **state)
624{
625 struct state *st = (*state);
626 const char *sch = "module x {"
627 " namespace urn:x;"
628 " prefix x;"
629 " list l {"
630 " key n;"
631 " leaf n { type string; }"
632 " leaf t { type string; }"
633 " leaf r { type leafref { path '/l/n'; } }}}";
634 const char *trg = "<l xmlns=\"urn:x\"><n>a</n></l>"
635 "<l xmlns=\"urn:x\"><n>b</n><r>a</r></l>";
636 const char *src = "<l xmlns=\"urn:x\"><n>c</n><r>a</r></l>"
637 "<l xmlns=\"urn:x\"><n>a</n><t>*</t></l>";
638 const char *res = "<l xmlns=\"urn:x\"><n>a</n><t>*</t></l>"
639 "<l xmlns=\"urn:x\"><n>b</n><r>a</r></l>"
640 "<l xmlns=\"urn:x\"><n>c</n><r>a</r></l>";
641 char *prt = NULL;
642
643 assert_non_null(lys_parse_mem(st->ctx, sch, LYS_IN_YANG));
644
645 st->target = lyd_parse_mem(st->ctx, trg, LYD_XML, LYD_VALOPT_DATA_ONLY);
646 assert_non_null(st->target);
647
648 st->source = lyd_parse_mem(st->ctx, src, LYD_XML, LYD_VALOPT_DATA_ONLY);
649 assert_non_null(st->source);
650
651 assert_int_equal(lyd_merge(&st->target, st->source, LYD_MERGE_DESTRUCT), LY_SUCCESS);
652 st->source = NULL;
653
654 lyd_print_mem(&prt, st->target, LYD_XML, LYDP_WITHSIBLINGS);
655 assert_string_equal(prt, res);
656 free(prt);
657}
658
659int
660main(void)
661{
662 const struct CMUnitTest tests[] = {
663 cmocka_unit_test_setup_teardown(test_batch, setup_dflt, teardown_dflt),
664 cmocka_unit_test_setup_teardown(test_leaf, setup_dflt, teardown_dflt),
665 cmocka_unit_test_setup_teardown(test_container, setup_dflt, teardown_dflt),
666 cmocka_unit_test_setup_teardown(test_list, setup_dflt, teardown_dflt),
667 cmocka_unit_test_setup_teardown(test_list2, setup_dflt, teardown_dflt),
668 cmocka_unit_test_setup_teardown(test_case, setup_dflt, teardown_dflt),
669 cmocka_unit_test_setup_teardown(test_dflt, setup_dflt, teardown_dflt),
670 cmocka_unit_test_setup_teardown(test_dflt2, setup_dflt, teardown_dflt),
671 cmocka_unit_test_setup_teardown(test_leafrefs, setup_dflt, teardown_dflt),
672 };
673
674 return cmocka_run_group_tests(tests, NULL, NULL);
675}