/** * @file test_diff.c * @author Radek Krejci * @author Michal Vasko * @brief tests for lyd_diff() * * Copyright (c) 2020 - 2023 CESNET, z.s.p.o. * * This source code is licensed under BSD 3-Clause License (the "License"). * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause */ #define _UTEST_MAIN_ #include "utests.h" #include "libyang.h" #define CHECK_PARSE_LYD(INPUT, OUTPUT) \ CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, OUTPUT) #define CHECK_LYD_STRING(INPUT, TEXT) \ CHECK_LYD_STRING_PARAM(INPUT, TEXT, LYD_XML, LYD_PRINT_WITHSIBLINGS) #define CHECK_PARSE_LYD_DIFF(INPUT_1, INPUT_2, OPTS, OUT_DIFF) \ assert_int_equal(LY_SUCCESS, lyd_diff_siblings(INPUT_1, INPUT_2, OPTS, &OUT_DIFF));\ assert_non_null(OUT_DIFF) #define TEST_DIFF_3(XML1, XML2, XML3, OPTS, DIFF1, DIFF2, MERGE) \ { \ struct lyd_node *data1;\ struct lyd_node *data2;\ struct lyd_node *data3;\ /*create*/\ CHECK_PARSE_LYD(XML1, data1);\ CHECK_PARSE_LYD(XML2, data2);\ CHECK_PARSE_LYD(XML3, data3);\ /* diff1 */ \ struct lyd_node *diff1;\ CHECK_PARSE_LYD_DIFF(data1, data2, OPTS, diff1); \ CHECK_LYD_STRING(diff1, DIFF1); \ assert_int_equal(lyd_diff_apply_all(&data1, diff1), LY_SUCCESS); \ CHECK_LYD(data1, data2); \ /* diff2 */ \ struct lyd_node *diff2;\ CHECK_PARSE_LYD_DIFF(data2, data3, OPTS, diff2); \ CHECK_LYD_STRING(diff2, DIFF2); \ assert_int_equal(lyd_diff_apply_all(&data2, diff2), LY_SUCCESS);\ CHECK_LYD(data2, data3);\ /* merge */ \ assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS);\ CHECK_LYD_STRING(diff1, MERGE); \ /* cleanup */ \ lyd_free_all(data1);\ lyd_free_all(data2);\ lyd_free_all(data3);\ lyd_free_all(diff1);\ lyd_free_all(diff2);\ } const char *schema = "module defaults {" "yang-version 1.1;" "namespace \"urn:libyang:tests:defaults\";" "prefix df;" "" "import ietf-yang-metadata {prefix md;}" "" "feature unhide;" "" "md:annotation my-meta {type string;}" "md:annotation my-meta2 {type string;}" "" "typedef defint32 {type int32; default \"42\";}" "" "leaf hiddenleaf {if-feature \"unhide\"; type int32; default \"42\";}" "container df {" " leaf foo {type defint32; }" " leaf hiddenleaf {if-feature \"unhide\"; type int32; default \"42\";}" " container bar { presence \"\";" " leaf hi {type int32; default \"42\";}" " leaf ho {type int32; mandatory true;}" " }" " leaf-list llist {type defint32; ordered-by user;}" " list ul {key \"l1\"; ordered-by user;" " leaf l1 {type string;}" " leaf l2 {type int32;}" " container cont {" " leaf l3 {type string;}" " }" " }" " leaf-list dllist {type uint8; default \"1\"; default \"2\"; default \"3\";}" " list list {key \"name\";" " leaf name {type string;}" " leaf value {type int32; default \"42\";}" " list list2 {key \"name2\";" " leaf name2 {type string;}" " leaf value2 {type int32;}" " }" " }" " choice select {default \"a\";" " case a {" " choice a {" " leaf a1 {type int32; default \"42\";}" " leaf a2 {type int32; default \"24\";}" " }" " }" " leaf b {type string;}" " container c {presence \"\";" " leaf x {type int32; default \"42\";}" " }" " }" " choice select2 {default \"s2b\";" " leaf s2a {type int32; default \"42\";}" " case s2b {" " choice s2b {default \"b1\";" " case b1 {" " leaf b1_1 {type int32; default \"42\";}" " leaf b1_2 {type string;}" " leaf b1_status {type int32; default \"42\"; config false;}" " }" " leaf b2 {type int32; default \"42\";}" " }" " }" " }" " list kl {config \"false\";" " leaf l1 {type string;}" " leaf l2 {type int32;}" " }" " leaf-list kll {config \"false\"; type string;}" "}" "container hidden {" " leaf foo {type int32; default \"42\";}" " leaf baz {type int32; default \"42\";}" " leaf papa {type int32; default \"42\"; config false;}" "}" "rpc rpc1 {" " input {" " leaf inleaf1 {type string;}" " leaf inleaf2 {type string; default \"def1\";}" " }" " output {" " leaf outleaf1 {type string; default \"def2\";}" " leaf outleaf2 {type string;}" " }" "}" "notification notif {" " leaf ntfleaf1 {type string; default \"def3\";}" " leaf ntfleaf2 {type string;}" "}" "}"; static int setup(void **state) { UTEST_SETUP; UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); return 0; } static void test_invalid(void **state) { (void) state; const char *xml = "42"; struct lyd_node *model_1; CHECK_PARSE_LYD(xml, model_1); struct lyd_node *diff = NULL; assert_int_equal(lyd_diff_siblings(model_1, lyd_child(model_1), 0, &diff), LY_EINVAL); CHECK_LOG_CTX("Invalid arguments - cannot create diff for unrelated data (lyd_diff()).", NULL, 0); assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, NULL), LY_EINVAL); lyd_free_all(model_1); lyd_free_all(diff); } static void test_same(void **state) { (void) state; const char *xml = "\n" " true\n" " permit\n" " deny\n" " permit\n" " true\n" "\n" " 4242\n" "\n" " 4242\n"; struct lyd_node *model_1; struct lyd_node *model_2; assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG)); assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-acm", "2018-02-14", NULL)); CHECK_PARSE_LYD(xml, model_1); CHECK_PARSE_LYD(xml, model_2); struct lyd_node *diff = NULL; assert_int_equal(lyd_diff_siblings(model_1, model_2, 0, &diff), LY_SUCCESS); assert_null(diff); assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS); CHECK_LYD(model_1, model_2); lyd_free_all(model_1); lyd_free_all(model_2); lyd_free_all(diff); } static void test_empty1(void **state) { (void) state; const char *xml_in = "\n" " 42\n" " 42\n" "\n" "\n" " 42\n" " 42\n" "\n"; struct lyd_node *model_1 = NULL; struct lyd_node *model_2; CHECK_PARSE_LYD(xml_in, model_2); struct lyd_node *diff; CHECK_PARSE_LYD_DIFF(model_1, model_2, 0, diff); CHECK_LYD_STRING(diff, "\n" " 42\n" " 42\n" "\n" "\n" " 42\n" " 42\n" "\n"); assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS); CHECK_LYD(model_1, model_2); lyd_free_all(model_1); lyd_free_all(model_2); lyd_free_all(diff); } static void test_empty2(void **state) { (void) state; const char *xml = "\n" " 42\n" " 42\n" "\n" " 42\n" " 42\n" "\n"; struct lyd_node *model_1; CHECK_PARSE_LYD(xml, model_1); struct lyd_node *diff; CHECK_PARSE_LYD_DIFF(model_1, NULL, 0, diff); CHECK_LYD_STRING(diff, "\n" " 42\n" " 42\n" "\n" "\n" " 42\n" " 42\n" "\n"); assert_int_equal(lyd_diff_apply_all(&model_1, diff), LY_SUCCESS); assert_ptr_equal(model_1, NULL); lyd_free_all(diff); lyd_free_all(model_1); } static void test_empty_nested(void **state) { (void) state; const char *xml = "42"; struct lyd_node *model_1; CHECK_PARSE_LYD(xml, model_1); struct lyd_node *diff = NULL; assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, &diff), LY_SUCCESS); assert_null(diff); struct lyd_node *diff1; CHECK_PARSE_LYD_DIFF(NULL, lyd_child(model_1), 0, diff1); CHECK_LYD_STRING(diff1, "\n" " 42\n" "\n"); struct lyd_node *diff2; CHECK_PARSE_LYD_DIFF(lyd_child(model_1), NULL, 0, diff2); CHECK_LYD_STRING(diff2, "\n" " 42\n" "\n"); lyd_free_all(model_1); lyd_free_all(diff1); lyd_free_all(diff2); } static void test_delete_merge(void **state) { (void) state; struct lyd_node *diff1, *diff2; const char *xml1 = "\n" " \n" " a\n" " \n" " a\n" " \n" " \n" "\n"; const char *xml2 = "\n" " \n" " a\n" " \n" "\n"; const char *xml_merge = "\n" " \n" " a\n" " \n" " a\n" " \n" " \n" "\n"; CHECK_PARSE_LYD(xml1, diff1); CHECK_PARSE_LYD(xml2, diff2); assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS); CHECK_LYD_STRING(diff1, xml_merge); lyd_free_all(diff1); lyd_free_all(diff2); } static void test_leaf(void **state) { (void) state; const char *xml1 = "\n" " 42\n" "\n" "\n" " 42\n" " 42\n" "\n"; const char *xml2 = "\n" " 41\n" " 42\n" "\n"; const char *xml3 = "\n" " 40\n" "\n" "\n" " 40\n" "\n"; const char *out_diff_1 = "\n" " 41\n" " 42\n" "\n" "\n" " 42\n" " 42\n" "\n"; const char *out_diff_2 = "\n" " 40\n" " 42\n" "\n" "\n" " 40\n" "\n"; const char *out_merge = "\n" " 40\n" "\n" "\n" " 40\n" " 42\n" "\n"; TEST_DIFF_3(xml1, xml2, xml3, 0, out_diff_1, out_diff_2, out_merge); } static void test_list(void **state) { (void) state; const char *xml1 = "\n" " \n" " a\n" " 1\n" " \n" " \n" " b\n" " 2\n" " \n" "\n"; const char *xml2 = "\n" " \n" " b\n" " -2\n" " \n" " \n" " c\n" " 3\n" " \n" "\n"; const char *xml3 = "\n" " \n" " b\n" " -2\n" " \n" " \n" " a\n" " 2\n" " \n" "\n"; const char *out_diff_1 = "\n" " \n" " a\n" " 1\n" " \n" " \n" " b\n" " -2\n" " \n" " \n" " c\n" " 3\n" " \n" "\n"; const char *out_diff_2 = "\n" " \n" " c\n" " 3\n" " \n" " \n" " a\n" " 2\n" " \n" "\n"; const char *out_merge = "\n" " \n" " a\n" " 2\n" " \n" " \n" " b\n" " -2\n" " \n" "\n"; TEST_DIFF_3(xml1, xml2, xml3, 0, out_diff_1, out_diff_2, out_merge); } static void test_nested_list(void **state) { struct lyd_node *data1, *data2, *diff; const char *xml1, *xml2; (void) state; xml1 = "" " " " n0" " 26" " " " n22" " 26" " " " " " n23" " 26" " " " " " " " n1" " 25" " " " n22" " 26" " " " " " " " n2" " 25" " " " n22" " 26" " " " " " " " n3" " 25" " " " n22" " 26" " " " " " " " n4" " 25" " " " n22" " 26" " " " " ""; xml2 = "" " " " n0" " 30" " " " n23" " 26" " " " " ""; CHECK_PARSE_LYD(xml1, data1); CHECK_PARSE_LYD(xml2, data2); CHECK_PARSE_LYD_DIFF(data1, data2, 0, diff); CHECK_LYD_STRING(diff, "\n" " \n" " n0\n" " 30\n" " \n" " n22\n" " 26\n" " \n" " \n" " \n" " n1\n" " 25\n" " \n" " n22\n" " 26\n" " \n" " \n" " \n" " n2\n" " 25\n" " \n" " n22\n" " 26\n" " \n" " \n" " \n" " n3\n" " 25\n" " \n" " n22\n" " 26\n" " \n" " \n" " \n" " n4\n" " 25\n" " \n" " n22\n" " 26\n" " \n" " \n" "\n"); lyd_free_all(data1); lyd_free_all(data2); lyd_free_all(diff); } static void test_userord_llist(void **state) { (void) state; const char *xml1 = "\n" " 1\n" " 2\n" " 3\n" " 4\n" " 5\n" "\n"; const char *xml2 = "\n" " 1\n" " 4\n" " 3\n" " 2\n" " 5\n" "\n"; const char *xml3 = "\n" " 5\n" " 4\n" " 3\n" " 2\n" "\n"; const char *out_diff_1 = "\n" " 4\n" " 3\n" "\n"; const char *out_diff_2 = "\n" " 1\n" " 5\n" "\n"; const char *out_merge = "\n" " 4\n" " 3\n" " 1\n" " 5\n" "\n"; TEST_DIFF_3(xml1, xml2, xml3, 0, out_diff_1, out_diff_2, out_merge); } static void test_userord_llist2(void **state) { (void) state; const char *xml1 = "\n" " 1\n" " a1\n" " 2\n" " 3\n" " 4\n" "\n"; const char *xml2 = "\n" " 1\n" " a1\n" " 2\n" " 4\n" " 3\n" "\n"; const char *xml3 = "\n" " 4\n" " 1\n" " a1\n" " 3\n" "\n"; const char *out_diff_1 = "\n" " 4\n" "\n"; const char *out_diff_2 = "\n" " 2\n" " 4\n" "\n"; const char *out_merge = "\n" " 4\n" " 2\n" "\n"; TEST_DIFF_3(xml1, xml2, xml3, 0, out_diff_1, out_diff_2, out_merge); } static void test_userord_mix(void **state) { (void) state; const char *xml1 = "\n" " 1\n" " 2\n" " 3\n" "\n"; const char *xml2 = "\n" " 3\n" " 1\n" "\n"; const char *xml3 = "\n" " 1\n" " 4\n" " 3\n" "\n"; const char *out_diff_1 = "\n" " 2\n" " 3\n" "\n"; const char *out_diff_2 = "\n" " 1\n" " 4\n" "\n"; const char *out_merge = "\n" " 2\n" " 3\n" " 1\n" " 4\n" "\n"; TEST_DIFF_3(xml1, xml2, xml3, 0, out_diff_1, out_diff_2, out_merge); } static void test_userord_list(void **state) { (void) state; const char *xml1 = "\n" "
    \n" " a\n" " 1\n" "
\n" "
    \n" " b\n" " 2\n" "
\n" "
    \n" " c\n" " 3\n" "
\n" "
\n"; const char *xml2 = "\n" "
    \n" " a\n" " 11\n" "
\n" "
    \n" " c\n" " 3\n" "
\n" "
\n"; const char *xml3 = "\n" "
    \n" " c\n" " 33\n" "
\n" "
    \n" " b\n" " 2\n" "
\n" "
\n"; const char *out_diff_1 = "\n" "
    \n" " a\n" " 11\n" "
\n" "
    \n" " b\n" " 2\n" "
\n" "
\n"; const char *out_diff_2 = "\n" "
    \n" " a\n" " 11\n" "
\n" "
    \n" " c\n" " 33\n" "
\n" "
    \n" " b\n" " 2\n" "
\n" "
\n"; const char *out_merge = "\n" "
    \n" " a\n" " 1\n" "
\n" "
    \n" " c\n" " 33\n" "
\n" "
    \n" " b\n" "
\n" "
\n"; TEST_DIFF_3(xml1, xml2, xml3, 0, out_diff_1, out_diff_2, out_merge); } static void test_userord_list2(void **state) { (void) state; const char *xml1 = "\n" "
    \n" " d\n" " 4\n" "
\n" "
\n"; const char *xml2 = "\n" "
    \n" " c\n" " 3\n" "
\n" "
    \n" " d\n" " 4\n" "
\n" "
\n"; const char *xml3 = "\n" "
    \n" " a\n" " 1\n" "
\n" "
    \n" " b\n" " 2\n" "
\n" "
    \n" " c\n" " 3\n" "
\n" "
    \n" " d\n" " 4\n" "
\n" "
\n"; const char *out_diff_1 = "\n" "
    \n" " c\n" " 3\n" "
\n" "
\n"; const char *out_diff_2 = "\n" "
    \n" " a\n" " 1\n" "
\n" "
    \n" " b\n" " 2\n" "
\n" "
\n"; const char *out_merge = "\n" "
    \n" " c\n" " 3\n" "
\n" "
    \n" " a\n" " 1\n" "
\n" "
    \n" " b\n" " 2\n" "
\n" "
\n"; TEST_DIFF_3(xml1, xml2, xml3, 0, out_diff_1, out_diff_2, out_merge); } static void test_userord_list3(void **state) { (void) state; const char *xml1 = "\n" "
    \n" " a\n" " 1\n" "
\n" "
    \n" " b\n" " 2\n" "
\n" "
    \n" " c\n" " \n" " val1\n" " \n" "
\n" "
    \n" " d\n" " 4\n" "
\n" "
\n"; const char *xml2 = "\n" "
    \n" " c\n" " 3\n" " \n" " val2\n" " \n" "
\n" "
    \n" " a\n" " 1\n" "
\n" "
    \n" " d\n" " 44\n" "
\n" "
    \n" " b\n" " 2\n" "
\n" "
\n"; const char *xml3 = "\n" "
    \n" " a\n" "
\n" "
    \n" " c\n" " 3\n" " \n" " val2\n" " \n" "
\n" "
    \n" " d\n" " 44\n" "
\n" "
    \n" " b\n" " 2\n" "
\n" "
\n"; const char *out_diff_1 = "\n" "
    \n" " c\n" " 3\n" " \n" " val2\n" " \n" "
\n" "
    \n" " d\n" " 44\n" "
\n" "
\n"; const char *out_diff_2 = "\n" "
    \n" " a\n" " 1\n" "
\n" "
\n"; const char *out_merge = "\n" "
    \n" " c\n" " 3\n" " \n" " val2\n" " \n" "
\n" "
    \n" " d\n" " 44\n" "
\n" "
    \n" " a\n" " 1\n" "
\n" "
\n"; TEST_DIFF_3(xml1, xml2, xml3, 0, out_diff_1, out_diff_2, out_merge); } static void test_keyless_list(void **state) { (void) state; const char *xml1 = "\n" " \n" " a\n" " 1\n" " \n" " \n" " b\n" " 2\n" " \n" " \n" " c\n" " 3\n" " \n" "\n"; const char *xml2 = "\n" " \n" " b\n" " 2\n" " \n" " \n" " a\n" " 1\n" " \n" " \n" " a\n" " 1\n" " \n" "\n"; const char *xml3 = "\n" " \n" " c\n" " \n" " \n" " 4\n" " \n" " \n" " e\n" " 5\n" " \n" " \n" " f\n" " 6\n" " \n" "\n"; const char *out_diff_1 = "\n" " \n" " c\n" " 3\n" " \n" " \n" " b\n" " 2\n" " \n" " \n" " a\n" " 1\n" " \n" "\n"; const char *out_diff_2 = "\n" " \n" " b\n" " 2\n" " \n" " \n" " a\n" " 1\n" " \n" " \n" " a\n" " 1\n" " \n" " \n" " c\n" " \n" " \n" " 4\n" " \n" " \n" " e\n" " 5\n" " \n" " \n" " f\n" " 6\n" " \n" "\n"; const char *out_merge = "\n" " \n" " c\n" " 3\n" " \n" " \n" " b\n" " 2\n" " \n" " \n" " a\n" " 1\n" " \n" " \n" " c\n" " \n" " \n" " 4\n" " \n" " \n" " e\n" " 5\n" " \n" " \n" " f\n" " 6\n" " \n" "\n"; TEST_DIFF_3(xml1, xml2, xml3, 0, out_diff_1, out_diff_2, out_merge); } static void test_state_llist(void **state) { (void) state; const char *xml1 = "\n" " a\n" " b\n" " c\n" "\n"; const char *xml2 = "\n" " b\n" " c\n" " a\n" " a\n" " a\n" "\n"; const char *xml3 = "\n" " a\n" " d\n" " a\n" "\n"; const char *out_diff_1 = "\n" " b\n" " c\n" " a\n" " a\n" "\n"; const char *out_diff_2 = "\n" " b\n" " c\n" " a\n" " d\n" "\n"; const char *out_merge = "\n" " b\n" " c\n" " a\n" " d\n" "\n"; TEST_DIFF_3(xml1, xml2, xml3, 0, out_diff_1, out_diff_2, out_merge); } static void test_wd(void **state) { (void) state; const struct lys_module *mod; const char *xml2 = "\n" " 41\n" " 4\n" "\n"; const char *xml3 = "\n" " 42\n" " 4\n" " 1\n" "\n"; mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "defaults"); assert_non_null(mod); struct lyd_node *model_1 = NULL; assert_int_equal(lyd_validate_module(&model_1, mod, 0, NULL), LY_SUCCESS); assert_ptr_not_equal(model_1, NULL); struct lyd_node *model_2; struct lyd_node *model_3; CHECK_PARSE_LYD_PARAM(xml2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2); CHECK_PARSE_LYD_PARAM(xml3, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_3); /* diff1 */ struct lyd_node *diff1 = NULL; assert_int_equal(lyd_diff_siblings(model_1, model_2, LYD_DIFF_DEFAULTS, &diff1), LY_SUCCESS); assert_non_null(diff1); const char *diff1_out_1 = "\n" " 41\n" " 1\n" " 2\n" " 3\n" " 4\n" "\n"; CHECK_LYD_STRING_PARAM(diff1, diff1_out_1, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL); assert_int_equal(lyd_diff_apply_all(&model_1, diff1), LY_SUCCESS); CHECK_LYD(model_1, model_2); /* diff2 */ struct lyd_node *diff2; assert_int_equal(lyd_diff_siblings(model_2, model_3, LYD_DIFF_DEFAULTS, &diff2), LY_SUCCESS); assert_non_null(diff2); CHECK_LYD_STRING(diff2, "\n" " 42\n" " 1\n" "\n"); assert_int_equal(lyd_diff_apply_all(&model_2, diff2), LY_SUCCESS); CHECK_LYD(model_2, model_3); /* merge */ assert_int_equal(lyd_diff_merge_all(&diff1, diff2, 0), LY_SUCCESS); const char *diff1_out_2 = "\n" " 42\n" " 1\n" " 2\n" " 3\n" " 4\n" "\n"; CHECK_LYD_STRING_PARAM(diff1, diff1_out_2, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL); lyd_free_all(model_1); lyd_free_all(model_2); lyd_free_all(model_3); lyd_free_all(diff1); lyd_free_all(diff2); } static void test_metadata(void **state) { (void) state; const char *xml1 = "\n" " \n" " a\n" " 1\n" " \n" " \n" " b\n" " 2\n" " \n" "\n"; const char *xml2 = "\n" " \n" " b\n" " 2\n" " \n" " \n" " c\n" " 3\n" " \n" "\n"; const char *xml3 = "\n" " \n" " b\n" " 2\n" " \n" " \n" " c\n" " 3\n" " \n" "\n"; const char *out_diff_1 = "\n" " \n" " a\n" " 1\n" " \n" " \n" " b\n" " 2\n" " \n" " \n" " c\n" " 3\n" " \n" "\n"; const char *out_diff_2 = "\n" " \n" " b\n" " 2\n" " \n" " \n" " c\n" " 3\n" " \n" "\n"; const char *out_merge = "\n" " \n" " a\n" " 1\n" " \n" " \n" " b\n" " 2\n" " \n" " \n" " c\n" " 3\n" " \n" "\n"; TEST_DIFF_3(xml1, xml2, xml3, LYD_DIFF_META, out_diff_1, out_diff_2, out_merge); } int main(void) { const struct CMUnitTest tests[] = { UTEST(test_invalid, setup), UTEST(test_same, setup), UTEST(test_empty1, setup), UTEST(test_empty2, setup), UTEST(test_empty_nested, setup), UTEST(test_delete_merge, setup), UTEST(test_leaf, setup), UTEST(test_list, setup), UTEST(test_nested_list, setup), UTEST(test_userord_llist, setup), UTEST(test_userord_llist2, setup), UTEST(test_userord_mix, setup), UTEST(test_userord_list, setup), UTEST(test_userord_list2, setup), UTEST(test_userord_list3, setup), UTEST(test_keyless_list, setup), UTEST(test_state_llist, setup), UTEST(test_wd, setup), UTEST(test_metadata, setup), }; return cmocka_run_group_tests(tests, NULL, NULL); }