示例#1
0
static void
test_same(void **state)
{
    struct state *st = (*state);
    const char *xml = "<nacm xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-acm\">"
                        "<enable-nacm>true</enable-nacm>"
                        "<read-default>permit</read-default>"
                        "<write-default>deny</write-default>"
                        "<exec-default>permit</exec-default>"
                        "<enable-external-groups>true</enable-external-groups>"
                      "</nacm><df xmlns=\"urn:libyang:tests:defaults\">"
                        "<foo>42</foo><b1_1>42</b1_1>"
                      "</df><hidden xmlns=\"urn:libyang:tests:defaults\">"
                        "<foo>42</foo><baz>42</baz></hidden>";
    struct lyd_difflist *diff;

    assert_ptr_not_equal((st->first = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG)), NULL);
    assert_ptr_not_equal((st->second = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG)), NULL);

    assert_ptr_not_equal((diff = lyd_diff(st->first, st->second, 0)), NULL);
    assert_ptr_not_equal(diff->type, NULL);
    assert_int_equal(diff->type[0], LYD_DIFF_END);

    lyd_free_diff(diff);
}
示例#2
0
static void
test_move1(void **state)
{
    struct state *st = (*state);
    const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">"
                         "<llist>1</llist>"
                         "<llist>2</llist>"
                       "</df>";
    const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">"
                         "<llist>2</llist>"
                         "<llist>1</llist>"
                       "</df>";
    char *str;
    struct lyd_difflist *diff;

    assert_ptr_not_equal((st->first = lyd_parse_mem(st->ctx, xml1, LYD_XML, LYD_OPT_CONFIG)), NULL);
    assert_ptr_not_equal((st->second = lyd_parse_mem(st->ctx, xml2, LYD_XML, LYD_OPT_CONFIG)), NULL);

    assert_ptr_not_equal((diff = lyd_diff(st->first, st->second, 0)), NULL);
    assert_ptr_not_equal(diff->type, NULL);

    assert_int_equal(diff->type[0], LYD_DIFF_MOVEDAFTER1);
    assert_ptr_not_equal(diff->first[0], NULL);
    assert_string_equal((str = lyd_path(diff->first[0])), "/defaults:df/llist[.='1']");
    free(str);
    assert_ptr_not_equal(diff->second[0], NULL);
    assert_string_equal((str = lyd_path(diff->second[0])), "/defaults:df/llist[.='2']");
    free(str);

    assert_int_equal(diff->type[1], LYD_DIFF_END);

    lyd_free_diff(diff);
}
示例#3
0
static void
test_parse_print_oookeys_xml(void **state)
{
    struct state *st = (*state);
    const char *xmlin = "<cont1 xmlns=\"urn:all\">"
                          "<leaf3>-1</leaf3>"
                          "<list1><leaf18>aaa</leaf18></list1>"
                          "<list1><leaf19>123</leaf19><leaf18>bbb</leaf18></list1>"
                        "</cont1>";
    const char *xmlout = "<cont1 xmlns=\"urn:all\">"
                          "<leaf3>-1</leaf3>"
                          "<list1><leaf18>aaa</leaf18></list1>"
                          "<list1><leaf18>bbb</leaf18><leaf19>123</leaf19></list1>"
                        "</cont1>";
    st->dt = NULL;

    /* with strict parsing, it is error since the key is not encoded as the first child */
    st->dt = lyd_parse_mem(st->ctx, xmlin, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_STRICT);
    assert_ptr_equal(st->dt, NULL);
    assert_int_equal(ly_vecode, LYVE_INORDER);
    assert_string_equal(ly_errmsg(), "Invalid position of the key \"leaf18\" in a list \"list1\".");

    /* without strict, it produces only warning, but the data are correctly loaded */
    st->dt = lyd_parse_mem(st->ctx, xmlin, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_not_equal(st->dt, NULL);
    assert_int_equal(lyd_print_mem(&st->str1, st->dt, LYD_XML, 0), 0);
    assert_string_equal(st->str1, xmlout);
}
示例#4
0
static void
test_empty3(void **state)
{
    struct state *st = (*state);
    const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\"><foo>42</foo></df>";
    struct lyd_difflist *diff;

    assert_ptr_not_equal((st->first = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG)), NULL);

    assert_ptr_not_equal((diff = lyd_diff(NULL, NULL, 0)), NULL);
    assert_ptr_not_equal(diff->type, NULL);
    assert_int_equal(diff->type[0], LYD_DIFF_END);
    lyd_free_diff(diff);

    assert_ptr_equal((diff = lyd_diff(NULL, st->first->child, 0)), NULL);
    assert_int_equal(ly_errno, LY_EINVAL);

    assert_ptr_not_equal((diff = lyd_diff(st->first->child, NULL, 0)), NULL);
    assert_ptr_not_equal(diff->type, NULL);

    assert_int_equal(diff->type[0], LYD_DIFF_DELETED);
    assert_ptr_equal(diff->first[0], st->first->child);
    assert_ptr_equal(diff->second[0], NULL);

    assert_int_equal(diff->type[1], LYD_DIFF_END);
    lyd_free_diff(diff);
}
示例#5
0
static void
test_empty2(void **state)
{
    struct state *st = (*state);
    const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\">"
                        "<foo>42</foo><b1_1>42</b1_1>"
                      "</df><hidden xmlns=\"urn:libyang:tests:defaults\">"
                        "<foo>42</foo><baz>42</baz></hidden>";
    struct lyd_difflist *diff;

    assert_ptr_not_equal((st->first = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG)), NULL);

    assert_ptr_not_equal((diff = lyd_diff(st->first, NULL, 0)), NULL);
    assert_ptr_not_equal(diff->type, NULL);

    assert_int_equal(diff->type[0], LYD_DIFF_DELETED);
    assert_ptr_equal(diff->first[0], st->first);
    assert_ptr_equal(diff->second[0], NULL);

    assert_int_equal(diff->type[1], LYD_DIFF_DELETED);
    assert_ptr_equal(diff->first[1], st->first->next);
    assert_ptr_equal(diff->second[1], NULL);

    assert_int_equal(diff->type[2], LYD_DIFF_END);
    lyd_free_diff(diff);
}
示例#6
0
static void
test_status(void **state)
{
    struct state *st = (*state);
    const char *xml_min = "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
                          "<module-set-id>5</module-set-id>"
                          "</modules-state><nacm xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-acm\">"
                            "<denied-operations>0</denied-operations>"
                            "<denied-data-writes>0</denied-data-writes>"
                            "<denied-notifications>0</denied-notifications>"
                          "</nacm>";

    const char *xml = "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">"
                        "<module-set-id>5</module-set-id>"
                      "</modules-state><nacm xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-acm\">"
                        "<denied-operations>0</denied-operations>"
                        "<denied-data-writes>0</denied-data-writes>"
                        "<denied-notifications>0</denied-notifications>"
                      "</nacm><df xmlns=\"urn:libyang:tests:defaults\">"
                        "<b1_status>42</b1_status>"
                      "</df><hidden xmlns=\"urn:libyang:tests:defaults\">"
                        "<papa>42</papa></hidden>";

    assert_ptr_not_equal((st->dt = lyd_parse_mem(st->ctx, xml_min, LYD_XML, LYD_OPT_DATA | LYD_WD_EXPLICIT)), NULL);
    assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_DATA, st->ctx), 0);
    assert_ptr_not_equal(st->dt, NULL);

    assert_int_equal(lyd_print_mem(&(st->xml), st->dt, LYD_XML, LYP_WITHSIBLINGS), 0);
    assert_ptr_not_equal(st->xml, NULL);
    assert_string_equal(st->xml, xml);
}
示例#7
0
static void
test_diff2(void **state)
{
    struct state *st = (*state);
    const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">"
                         "<list><name>a</name><value>1</value></list>"
                         "<list><name>b</name><value>2</value></list>"
                       "</df>";
    const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">"
                         "<list><name>b</name><value>-2</value></list>"
                         "<list><name>c</name><value>3</value></list>"
                       "</df>";
    char *str;
    struct lyd_difflist *diff;

    assert_ptr_not_equal((st->first = lyd_parse_mem(st->ctx, xml1, LYD_XML, LYD_OPT_CONFIG)), NULL);
    assert_ptr_not_equal((st->second = lyd_parse_mem(st->ctx, xml2, LYD_XML, LYD_OPT_CONFIG)), NULL);

    assert_ptr_not_equal((diff = lyd_diff(st->first, st->second, 0)), NULL);
    assert_ptr_not_equal(diff->type, NULL);

    assert_int_equal(diff->type[0], LYD_DIFF_CHANGED);
    assert_ptr_not_equal(diff->first[0], NULL);
    assert_string_equal((str = lyd_path(diff->first[0])), "/defaults:df/list[name=\'b\']/value");
    free(str);
    assert_ptr_not_equal(diff->second[0], NULL);
    assert_string_equal((str = lyd_path(diff->second[0])), "/defaults:df/list[name=\'b\']/value");
    free(str);

    assert_int_equal(diff->type[1], LYD_DIFF_DELETED);
    assert_ptr_not_equal(diff->first[1], NULL);
    assert_string_equal((str = lyd_path(diff->first[1])), "/defaults:df/list[name=\'a\']");
    free(str);
    assert_ptr_equal(diff->second[1], NULL);

    assert_int_equal(diff->type[2], LYD_DIFF_CREATED);
    assert_ptr_not_equal(diff->first[2], NULL);
    assert_string_equal((str = lyd_path(diff->first[2])), "/defaults:df");
    free(str);
    assert_ptr_not_equal(diff->second[2], NULL);
    assert_string_equal((str = lyd_path(diff->second[2])), "/defaults:df/list[name=\'c\']");
    free(str);

    assert_int_equal(diff->type[3], LYD_DIFF_END);

    lyd_free_diff(diff);
}
示例#8
0
static int
setup_f(void **state)
{
    struct state *st;
    const char *augschema = "ietf-ip";
    const char *typeschema = "iana-if-type";
    const char *ietfdir = TESTS_DIR"/schema/yin/ietf/";
    const struct lys_module *mod;

    (*state) = st = calloc(1, sizeof *st);
    if (!st) {
        fprintf(stderr, "Memory allocation error.\n");
        return -1;
    }

    /* libyang context */
    st->ctx = ly_ctx_new(ietfdir);
    if (!st->ctx) {
        fprintf(stderr, "Failed to create context.\n");
        goto error;
    }

    /* schema */
    mod = ly_ctx_load_module(st->ctx, augschema, NULL);
    if (!mod) {
        fprintf(stderr, "Failed to load data module \"%s\".\n", augschema);
        goto error;
    }
    lys_features_enable(mod, "*");

    mod = ly_ctx_get_module(st->ctx, "ietf-interfaces", NULL);
    if (!mod) {
        fprintf(stderr, "Failed to get data module \"ietf-interfaces\".\n");
        goto error;
    }
    lys_features_enable(mod, "*");

    mod = ly_ctx_load_module(st->ctx, typeschema, NULL);
    if (!mod) {
        fprintf(stderr, "Failed to load data module \"%s\".\n", typeschema);
        goto error;
    }

    /* data */
    st->dt = lyd_parse_mem(st->ctx, data, LYD_XML, LYD_OPT_CONFIG);
    if (!st->dt) {
        fprintf(stderr, "Failed to build the data tree.\n");
        goto error;
    }

    return 0;

error:
    ly_ctx_destroy(st->ctx, NULL);
    free(st);
    (*state) = NULL;

    return -1;
}
示例#9
0
static void
test_diff1(void **state)
{
    struct state *st = (*state);
    const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">"
                        "<foo>42</foo>"
                      "</df><hidden xmlns=\"urn:libyang:tests:defaults\">"
                        "<foo>42</foo><baz>42</baz></hidden>";
    const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">"
                        "<foo>41</foo><b1_1>42</b1_1>"
                      "</df>";
    char *str;
    struct lyd_difflist *diff;

    assert_ptr_not_equal((st->first = lyd_parse_mem(st->ctx, xml1, LYD_XML, LYD_OPT_CONFIG)), NULL);
    assert_ptr_not_equal((st->second = lyd_parse_mem(st->ctx, xml2, LYD_XML, LYD_OPT_CONFIG)), NULL);

    assert_ptr_not_equal((diff = lyd_diff(st->first, st->second, 0)), NULL);
    assert_ptr_not_equal(diff->type, NULL);

    assert_int_equal(diff->type[0], LYD_DIFF_CHANGED);
    assert_ptr_not_equal(diff->first[0], NULL);
    assert_string_equal((str = lyd_path(diff->first[0])), "/defaults:df/foo");
    free(str);
    assert_ptr_not_equal(diff->second[0], NULL);
    assert_string_equal((str = lyd_path(diff->second[0])), "/defaults:df/foo");
    free(str);

    assert_int_equal(diff->type[1], LYD_DIFF_DELETED);
    assert_ptr_not_equal(diff->first[1], NULL);
    assert_string_equal((str = lyd_path(diff->first[1])), "/defaults:hidden");
    free(str);
    assert_ptr_equal(diff->second[1], NULL);

    assert_int_equal(diff->type[2], LYD_DIFF_CREATED);
    assert_ptr_not_equal(diff->first[2], NULL);
    assert_string_equal((str = lyd_path(diff->first[2])), "/defaults:df");
    free(str);
    assert_ptr_not_equal(diff->second[2], NULL);
    assert_string_equal((str = lyd_path(diff->second[2])), "/defaults:df/b1_1");
    free(str);

    assert_int_equal(diff->type[3], LYD_DIFF_END);

    lyd_free_diff(diff);
}
示例#10
0
static void
test_wd1(void **state)
{
    struct state *st = (*state);
    const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\">"
                        "<foo>41</foo><dllist>4</dllist>"
                      "</df>";
    char *str;
    struct lyd_difflist *diff;

    st->first = NULL;
    lyd_validate(&st->first, LYD_OPT_CONFIG, st->ctx);
    assert_ptr_not_equal(st->first, NULL);
    assert_ptr_not_equal((st->second = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG)), NULL);

    assert_ptr_not_equal((diff = lyd_diff(st->first, st->second, LYD_DIFFOPT_WITHDEFAULTS)), NULL);
    assert_ptr_not_equal(diff->type, NULL);

    assert_int_equal(diff->type[0], LYD_DIFF_CHANGED);
    assert_ptr_not_equal(diff->first[0], NULL);
    assert_string_equal((str = lyd_path(diff->first[0])), "/defaults:df/foo");
    assert_int_equal(((struct lyd_node_leaf_list*)diff->first[0])->value.int32, 42);
    free(str);
    assert_ptr_not_equal(diff->second[0], NULL);
    assert_string_equal((str = lyd_path(diff->second[0])), "/defaults:df/foo");
    assert_int_equal(((struct lyd_node_leaf_list*)diff->second[0])->value.int32, 41);
    free(str);

    assert_int_equal(diff->type[1], LYD_DIFF_DELETED);
    assert_ptr_not_equal(diff->first[1], NULL);
    assert_string_equal((str = lyd_path(diff->first[1])), "/defaults:df/dllist[.='1']");
    free(str);
    assert_ptr_equal(diff->second[1], NULL);

    assert_int_equal(diff->type[2], LYD_DIFF_DELETED);
    assert_ptr_not_equal(diff->first[2], NULL);
    assert_string_equal((str = lyd_path(diff->first[2])), "/defaults:df/dllist[.='2']");
    free(str);
    assert_ptr_equal(diff->second[2], NULL);

    assert_int_equal(diff->type[3], LYD_DIFF_DELETED);
    assert_ptr_not_equal(diff->first[3], NULL);
    assert_string_equal((str = lyd_path(diff->first[3])), "/defaults:df/dllist[.='3']");
    free(str);
    assert_ptr_equal(diff->second[3], NULL);

    assert_int_equal(diff->type[4], LYD_DIFF_CREATED);
    assert_ptr_not_equal(diff->first[4], NULL);
    assert_string_equal((str = lyd_path(diff->first[4])), "/defaults:df");
    free(str);
    assert_ptr_not_equal(diff->second[4], NULL);
    assert_string_equal((str = lyd_path(diff->second[4])), "/defaults:df/dllist[.='4']");
    free(str);

    assert_int_equal(diff->type[5], LYD_DIFF_END);

    lyd_free_diff(diff);
}
示例#11
0
static void
test_dup_to_ctx_leafrefs(void **state)
{
    struct state *st = (*state);
    const struct lys_module *mod;
    const char *sch = "module x {"
                    "  namespace urn:x;"
                    "  prefix x;"
                    "  container x {"
                    "    leaf a { type string; }"
                    "    leaf b { type leafref { path ../a; } } } }";
    const char *data = "<x xmlns=\"urn:x\"><b>hello</b><a>hello</a></x>";
    char *printed = NULL;

    mod = lys_parse_mem(st->ctx1, sch, LYS_IN_YANG);
    assert_ptr_not_equal(mod, NULL);
    mod = lys_parse_mem(st->ctx2, sch, LYS_IN_YANG);
    assert_ptr_not_equal(mod, NULL);

    st->dt1 = lyd_parse_mem(st->ctx1, data, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_not_equal(st->dt1, NULL);

    st->dt2 = lyd_dup_to_ctx(st->dt1, 1, st->ctx2);
    assert_ptr_not_equal(st->dt2, NULL);

    /* the result is not valid - the leafref is not resolved */
    assert_int_not_equal(((struct lyd_node_leaf_list *)st->dt2->child)->value_type, LY_TYPE_LEAFREF);
    assert_int_equal(lyd_validate(&st->dt2, LYD_OPT_CONFIG, st->ctx2), 0);
    assert_ptr_equal(((struct lyd_node_leaf_list *)st->dt2->child)->value_type, LY_TYPE_LEAFREF);

    /* the values are the same, but they are stored in different contexts */
    assert_string_equal(((struct lyd_node_leaf_list *)st->dt1->child)->value_str,
                        ((struct lyd_node_leaf_list *)st->dt2->child)->value_str);
    assert_ptr_not_equal(((struct lyd_node_leaf_list *)st->dt1->child)->value_str,
                         ((struct lyd_node_leaf_list *)st->dt2->child)->value_str);
    /* check the value data */
    assert_ptr_not_equal(((struct lyd_node_leaf_list *)st->dt1->child)->value.leafref,
                         ((struct lyd_node_leaf_list *)st->dt2->child)->value.leafref);
    /* and the schema nodes are the same, but comes from a different contexts */
    assert_int_equal(st->dt1->child->schema->nodetype, st->dt2->child->schema->nodetype);
    assert_string_equal(st->dt1->child->schema->name, st->dt2->child->schema->name);
    assert_string_equal(st->dt1->child->schema->module->name, st->dt2->child->schema->module->name);
    assert_ptr_equal(st->dt1->child->schema->module->ctx, st->ctx1);
    assert_ptr_equal(st->dt2->child->schema->module->ctx, st->ctx2);

    /* valgrind test - remove the first context and the access the duplicated data
     *                 supposed to be in the second context */
    lyd_free(st->dt1);
    ly_ctx_destroy(st->ctx1, NULL);
    st->dt1 = NULL;
    st->ctx1 = NULL;

    lyd_print_mem(&printed, st->dt2, LYD_XML, 0);
    assert_string_equal(printed, data);

    free(printed);
}
示例#12
0
static void
test_dup_to_ctx_bits(void **state)
{
    struct state *st = (*state);
    const struct lys_module *mod;
    const char *sch = "module x {"
                    "  namespace urn:x;"
                    "  prefix x;"
                    "  typedef mybits { type bits {"
                    "    bit disable;"
                    "    bit enable; } }"
                    "  leaf x { type mybits; }}";
    const char *data = "<x xmlns=\"urn:x\">enable</x>";
    char *printed = NULL;

    mod = lys_parse_mem(st->ctx1, sch, LYS_IN_YANG);
    assert_ptr_not_equal(mod, NULL);
    mod = lys_parse_mem(st->ctx2, sch, LYS_IN_YANG);
    assert_ptr_not_equal(mod, NULL);

    st->dt1 = lyd_parse_mem(st->ctx1, data, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_not_equal(st->dt1, NULL);

    st->dt2 = lyd_dup_to_ctx(st->dt1, 1, st->ctx2);
    assert_ptr_not_equal(st->dt2, NULL);
    /* the values are the same, but they are stored in different contexts */
    assert_string_equal(((struct lyd_node_leaf_list *)st->dt1)->value_str,
                        ((struct lyd_node_leaf_list *)st->dt2)->value_str);
    assert_ptr_not_equal(((struct lyd_node_leaf_list *)st->dt1)->value_str,
                         ((struct lyd_node_leaf_list *)st->dt2)->value_str);
    /* check the value data */
    assert_ptr_not_equal(((struct lyd_node_leaf_list *)st->dt1)->value.bit,
                         ((struct lyd_node_leaf_list *)st->dt2)->value.bit);
    assert_ptr_not_equal(((struct lyd_node_leaf_list *)st->dt1)->value.bit[1],
                         ((struct lyd_node_leaf_list *)st->dt2)->value.bit[1]);
    /* first bit is not set, so the value pointer is NULL in both cases */
    assert_ptr_equal(((struct lyd_node_leaf_list *)st->dt1)->value.bit[0], NULL);
    assert_ptr_equal(((struct lyd_node_leaf_list *)st->dt2)->value.bit[0], NULL);
    /* and the schema nodes are the same, but comes from a different contexts */
    assert_int_equal(st->dt1->schema->nodetype, st->dt2->schema->nodetype);
    assert_string_equal(st->dt1->schema->name, st->dt2->schema->name);
    assert_string_equal(st->dt1->schema->module->name, st->dt2->schema->module->name);
    assert_ptr_equal(st->dt1->schema->module->ctx, st->ctx1);
    assert_ptr_equal(st->dt2->schema->module->ctx, st->ctx2);

    /* valgrind test - remove the first context and the access the duplicated data
     *                 supposed to be in the second context */
    lyd_free(st->dt1);
    ly_ctx_destroy(st->ctx1, NULL);
    st->dt1 = NULL;
    st->ctx1 = NULL;

    lyd_print_mem(&printed, st->dt2, LYD_XML, 0);
    assert_string_equal(printed, data);

    free(printed);
}
示例#13
0
static void
test_parse_print_oookeys_json(void **state)
{
    struct state *st = (*state);
    const char *in = "{\"all:cont1\":{\"leaf3\":-1,\"list1\":[{\"leaf18\":\"a\"},{\"leaf19\":123,\"leaf18\":\"b\"}]}}";
    const char *out = "{\"all:cont1\":{\"leaf3\":-1,\"list1\":[{\"leaf18\":\"a\"},{\"leaf18\":\"b\",\"leaf19\":123}]}}";

    st->dt = NULL;

    /* in JSON, ordering does not matter, so it will succeed even with strict */
    st->dt = lyd_parse_mem(st->ctx, in, LYD_JSON, LYD_OPT_CONFIG | LYD_OPT_STRICT);
    assert_ptr_not_equal(st->dt, NULL);
    assert_int_equal(lyd_print_mem(&st->str1, st->dt, LYD_JSON, 0), 0);
    assert_string_equal(st->str1, out);
}
示例#14
0
static void
test_dup_to_ctx(void **state)
{
    struct state *st = (*state);
    const struct lys_module *mod;
    const char *sch = "module x {"
                    "  namespace urn:x;"
                    "  prefix x;"
                    "  leaf x { type string; }}";
    const char *data = "<x xmlns=\"urn:x\">hello</x>";

    /* case 1 - schema is only in the first context, duplicating data into the second context is supposed to
     *          fail because of missing schema */
    mod = lys_parse_mem(st->ctx1, sch, LYS_IN_YANG);
    assert_ptr_not_equal(mod, NULL);

    st->dt1 = lyd_parse_mem(st->ctx1, data, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_not_equal(st->dt1, NULL);

    st->dt2 = lyd_dup_to_ctx(st->dt1, 1, st->ctx2);
    assert_ptr_equal(st->dt2, NULL);
    assert_int_equal(ly_errno, LY_EINVAL);
    assert_string_equal(ly_errmsg(st->ctx2),
                        "Target context does not contain schema node for the data node being duplicated (x:x).");

    /* case 2 - with the schema present in both contexts, duplication should succeed */
    mod = lys_parse_mem(st->ctx2, sch, LYS_IN_YANG);
    assert_ptr_not_equal(mod, NULL);

    st->dt2 = lyd_dup_to_ctx(st->dt1, 1, st->ctx2);
    assert_ptr_not_equal(st->dt2, NULL);
    /* the values are the same, but they are stored in different contexts */
    assert_string_equal(((struct lyd_node_leaf_list *)st->dt1)->value_str,
                        ((struct lyd_node_leaf_list *)st->dt2)->value_str);
    assert_ptr_not_equal(((struct lyd_node_leaf_list *)st->dt1)->value_str,
                        ((struct lyd_node_leaf_list *)st->dt2)->value_str);
    /* and the schema nodes are the same, but comes from a different contexts */
    assert_int_equal(st->dt1->schema->nodetype, st->dt2->schema->nodetype);
    assert_string_equal(st->dt1->schema->name, st->dt2->schema->name);
    assert_string_equal(st->dt1->schema->module->name, st->dt2->schema->module->name);
    assert_ptr_equal(st->dt1->schema->module->ctx, st->ctx1);
    assert_ptr_equal(st->dt2->schema->module->ctx, st->ctx2);
}
示例#15
0
static void
test_mandatory(void **state)
{
    struct state *st = (*state);

    const char miss_leaf1[] = "<top xmlns=\"urn:libyang:tests:mandatory\"/>"
                              "<topleaf xmlns=\"urn:libyang:tests:mandatory\"/>";
    const char few_llist1[] = "<top xmlns=\"urn:libyang:tests:mandatory\"><leaf1>a</leaf1></top>";
    const char many_llist1[] = "<top xmlns=\"urn:libyang:tests:mandatory\">"
                                 "<leaf1>a</leaf1>"
                                 "<llist1>1</llist1><llist1>2</llist1><llist1>3</llist1>"
                                 "<llist1>4</llist1><llist1>5</llist1><llist1>6</llist1>"
                               "</top>";
    const char miss_leaf2[] = "<top xmlns=\"urn:libyang:tests:mandatory\">"
                                "<leaf1>a</leaf1><llist1>1</llist1><llist1>2</llist1>"
                              "</top>";
    const char miss_choice2[] = "<top xmlns=\"urn:libyang:tests:mandatory\">"
                                  "<leaf1>a</leaf1><llist1>1</llist1><llist1>2</llist1>"
                                  "<cont1><cont2><cont3><leaf2>5</leaf2></cont3></cont2></cont1>"
                                  "<leaf3>b</leaf3>"
                                "</top>";
    const char miss_leaf6[] = "<top xmlns=\"urn:libyang:tests:mandatory\">"
                                "<leaf1>a</leaf1><llist1>1</llist1><llist1>2</llist1>"
                                "<cont1><cont2><cont3><leaf2>5</leaf2></cont3></cont2></cont1>"
                              "</top>";
    const char miss_leaf7[] = "<top xmlns=\"urn:libyang:tests:mandatory\">"
                                "<leaf1>a</leaf1><llist1>1</llist1><llist1>2</llist1>"
                                "<cont1><cont2><cont3><leaf2>5</leaf2></cont3></cont2></cont1>"
                                "<leaf3>c</leaf3><leaf5>d</leaf5><leaf6/>"
                              "</top>";
    const char miss_topleaf[] = "<top xmlns=\"urn:libyang:tests:mandatory\">"
                           "<leaf1>a</leaf1><llist1>1</llist1><llist1>2</llist1>"
                           "<cont1><cont2><cont3><leaf2>5</leaf2></cont3></cont2></cont1>"
                           "<leaf3>c</leaf3><leaf5>d</leaf5><leaf6/><leaf7/>"
                         "</top>";
    const char valid[] = "<top xmlns=\"urn:libyang:tests:mandatory\">"
                           "<leaf1>a</leaf1><llist1>1</llist1><llist1>2</llist1>"
                           "<cont1><cont2><cont3><leaf2>5</leaf2></cont3></cont2></cont1>"
                           "<leaf3>c</leaf3><leaf5>d</leaf5><leaf6/><leaf7/>"
                         "</top><topleaf xmlns=\"urn:libyang:tests:mandatory\"/>";

    st->dt = lyd_parse_mem(st->ctx, miss_leaf1, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_equal(st->dt, NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_MISSELEM);
    assert_string_equal(ly_errpath(st->ctx), "/mandatory:top");

    st->dt = lyd_parse_mem(st->ctx, few_llist1, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_equal(st->dt, NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_NOMIN);
    assert_string_equal(ly_errpath(st->ctx), "/mandatory:top");

    st->dt = lyd_parse_mem(st->ctx, many_llist1, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_equal(st->dt, NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_NOMAX);
    assert_string_equal(ly_errpath(st->ctx), "/mandatory:top/llist1[.='6']");

    st->dt = lyd_parse_mem(st->ctx, miss_leaf2, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_equal(st->dt, NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_MISSELEM);
    assert_string_equal(ly_errpath(st->ctx), "/mandatory:top/cont1/cont2/cont3");

    st->dt = lyd_parse_mem(st->ctx, miss_choice2, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_equal(st->dt, NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_NOMANDCHOICE);
    assert_string_equal(ly_errpath(st->ctx), "/mandatory:top");

    st->dt = lyd_parse_mem(st->ctx, miss_leaf6, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_equal(st->dt, NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_MISSELEM);
    assert_string_equal(ly_errpath(st->ctx), "/mandatory:top");

    st->dt = lyd_parse_mem(st->ctx, miss_leaf7, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_equal(st->dt, NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_MISSELEM);
    assert_string_equal(ly_errpath(st->ctx), "/mandatory:top");

    st->dt = lyd_parse_mem(st->ctx, miss_topleaf, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_equal(st->dt, NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_MISSELEM);
    assert_string_equal(ly_errpath(st->ctx), "/");

    st->dt = lyd_parse_mem(st->ctx, valid, LYD_XML, LYD_OPT_CONFIG);
    assert_ptr_not_equal(st->dt, NULL);
    assert_int_equal(ly_errno, LY_SUCCESS);
}
示例#16
0
static void
test_status_yin(void **state)
{
    struct state *st = (*state);
    const char *yin = "<module name=\"status\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
        "<namespace uri=\"urn:status\"/>"
        "<prefix value=\"st\"/>"
        "<grouping name=\"g\">"
        "  <leaf name=\"gl1\">"
        "    <type name=\"string\"/>"
        "    <mandatory value=\"true\"/>"
        "  </leaf>"
        "  <leaf name=\"gl2\">"
        "    <type name=\"string\"/>"
        "    <status value=\"deprecated\"/>"
        "  </leaf>"
        "  <leaf name=\"gl3\">"
        "    <type name=\"string\"/>"
        "    <status value=\"obsolete\"/>"
        "  </leaf>"
        "</grouping>"
        "<container name=\"a\">"
        "  <status value=\"deprecated\"/>"
        "  <leaf name=\"l\">"
        "    <type name=\"string\"/>"
        "    <mandatory value=\"true\"/>"
        "  </leaf>"
        "  <uses name=\"g\"/>"
        "</container>"
        "<container name=\"b\">"
        "  <status value=\"deprecated\"/>"
        "  <leaf name=\"l\">"
        "    <status value=\"obsolete\"/>"
        "    <mandatory value=\"true\"/>"
        "    <type name=\"string\"/>"
        "  </leaf>"
        "</container>"
        "<container name=\"c\">"
        "  <status value=\"obsolete\"/>"
        "  <leaf name=\"l\">"
        "    <mandatory value=\"true\"/>"
        "    <type name=\"string\"/>"
        "  </leaf>"
        "  <uses name=\"g\"/>"
        "</container>"
        "</module>";
    const char *xml1 = "<a xmlns=\"urn:status\"><gl2>x</gl2><gl3>y</gl3></a>";
    const char *xml2 = "<c xmlns=\"urn:status\"><gl2>x</gl2><gl3>y</gl3></c>";

    const char *yin_fail1 = "<module name=\"status\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
        "<namespace uri=\"urn:status\"/>"
        "<prefix value=\"st\"/>"
        "<container name=\"c\">"
        "  <status value=\"deprecated\"/>"
        "  <leaf name=\"l\">"
        "    <status value=\"current\"/>"
        "    <type name=\"string\"/>"
        "  </leaf>"
        "</container>"
        "</module>";
    const char *yin_fail2 = "<module name=\"status\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
        "<namespace uri=\"urn:status\"/>"
        "<prefix value=\"st\"/>"
        "<container name=\"c\">"
        "  <status value=\"obsolete\"/>"
        "  <leaf name=\"l\">"
        "    <status value=\"current\"/>"
        "    <type name=\"string\"/>"
        "  </leaf>"
        "</container>"
        "</module>";
    const char *yin_fail3 = "<module name=\"status\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
        "<namespace uri=\"urn:status\"/>"
        "<prefix value=\"st\"/>"
        "<container name=\"c\">"
        "  <status value=\"obsolete\"/>"
        "  <leaf name=\"l\">"
        "    <status value=\"deprecated\"/>"
        "    <type name=\"string\"/>"
        "  </leaf>"
        "</container>"
        "</module>";

    /* deprecated nodes cannot be in obsolete data (obsolete is stronger) */
    assert_ptr_equal(NULL, lys_parse_mem(st->ctx, yin_fail3, LYS_IN_YIN));
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_INSTATUS);

    /* current nodes cannot be in obsolete data (obsolete is stronger) */
    assert_ptr_equal(NULL, lys_parse_mem(st->ctx, yin_fail2, LYS_IN_YIN));
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_INSTATUS);

    /* current nodes cannot be in deprecated data (deprecated is stronger) */
    assert_ptr_equal(NULL, lys_parse_mem(st->ctx, yin_fail1, LYS_IN_YIN));
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_INSTATUS);

    /* status is inherited so all the mandatory statements should be ignored and empty data tree is fine */
    assert_ptr_not_equal(NULL, lys_parse_mem(st->ctx, yin, LYS_IN_YIN));
    assert_int_equal(0, lyd_validate(&st->dt, LYD_OPT_CONFIG, st->ctx));

    /* xml1 - deprecated is applied to gl1, so it is not mandatory,
     *        gl2 is deprecated so it can appear in data,
     *        but gl3 is obsolete (not changed) so it cannot appear */
    assert_ptr_equal(NULL, lyd_parse_mem(st->ctx, xml1, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_OBSOLETE));
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_OBSDATA);
    assert_string_equal(ly_errpath(st->ctx), "/status:a/gl3");

    /* xml2 - obsolete is applied to gl1, so it is not mandatory,
     *        gl2 is obsolete so it cannot appear in data and here the error should raise,
     *        gl3 is obsolete (not changed) so it cannot appear */
    assert_ptr_equal(NULL, lyd_parse_mem(st->ctx, xml2, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_OBSOLETE));
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_OBSDATA);
    assert_string_equal(ly_errpath(st->ctx), "/status:c/gl2");
}
示例#17
0
static void
test_status_yang(void **state)
{
    struct state *st = (*state);
    const char *yang = "module status {"
        "  namespace urn:status;"
        "  prefix st;"
        "  grouping g {"
        "    leaf gl1 {"
        "      type string;"
        "      mandatory true;"
        "    }"
        "    leaf gl2 {"
        "      type string;"
        "      status deprecated;"
        "    }"
        "    leaf gl3 {"
        "      type string;"
        "      status obsolete;"
        "    }"
        "  }"
        "  container a {"
        "    status deprecated;"
        "    leaf l {"
        "      type string;"
        "      mandatory true;"
        "    }"
        "    uses g;"
        "  }"
        "  container b {"
        "    status deprecated;"
        "    leaf l {"
        "      status obsolete;"
        "      type string;"
        "      mandatory true;"
        "    }"
        "  }"
        "  container c {"
        "    status obsolete;"
        "    leaf l {"
        "      type string;"
        "      mandatory true;"
        "    }"
        "    uses g;"
        "  }"
        "}";
    const char *xml1 = "<a xmlns=\"urn:status\"><gl2>x</gl2><gl3>y</gl3></a>";
    const char *xml2 = "<c xmlns=\"urn:status\"><gl2>x</gl2><gl3>y</gl3></c>";
    const char *yang_fail1 = "module status {"
        "  namespace urn:status;"
        "  prefix st;"
        "  container c {"
        "    status deprecated;"
        "    leaf l {"
        "      status current;"
        "      type string;"
        "    }"
        "  }"
        "}";
    const char *yang_fail2 = "module status {"
        "  namespace urn:status;"
        "  prefix st;"
        "  container c {"
        "    status obsolete;"
        "    leaf l {"
        "      status current;"
        "      type string;"
        "    }"
        "  }"
        "}";
    const char *yang_fail3 = "module status {"
        "  namespace urn:status;"
        "  prefix st;"
        "  container c {"
        "    status obsolete;"
        "    leaf l {"
        "      status deprecated;"
        "      type string;"
        "    }"
        "  }"
        "}";

    /* deprecated nodes cannot be in obsolete data (obsolete is stronger) */
    assert_ptr_equal(NULL, lys_parse_mem(st->ctx, yang_fail3, LYS_IN_YANG));
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_INSTATUS);

    /* current nodes cannot be in obsolete data (obsolete is stronger) */
    assert_ptr_equal(NULL, lys_parse_mem(st->ctx, yang_fail2, LYS_IN_YANG));
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_INSTATUS);

    /* current nodes cannot be in deprecated data (deprecated is stronger) */
    assert_ptr_equal(NULL, lys_parse_mem(st->ctx, yang_fail1, LYS_IN_YANG));
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_INSTATUS);

    /* status is inherited so all the mandatory statements should be ignored and empty data tree is fine */
    assert_ptr_not_equal(NULL, lys_parse_mem(st->ctx, yang, LYS_IN_YANG));
    assert_int_equal(0, lyd_validate(&st->dt, LYD_OPT_CONFIG, st->ctx));

    /* xml1 - deprecated is applied to gl1, so it is not mandatory,
     *        gl2 is deprecated so it can appear in data,
     *        but gl3 is obsolete (not changed) so it cannot appear */
    assert_ptr_equal(NULL, lyd_parse_mem(st->ctx, xml1, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_OBSOLETE));
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_OBSDATA);
    assert_string_equal(ly_errpath(st->ctx), "/status:a/gl3");

    /* xml2 - obsolete is applied to gl1, so it is not mandatory,
     *        gl2 is obsolete so it cannot appear in data and here the error should raise,
     *        gl3 is obsolete (not changed) so it cannot appear */
    assert_ptr_equal(NULL, lyd_parse_mem(st->ctx, xml2, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_OBSOLETE));
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode(st->ctx), LYVE_OBSDATA);
    assert_string_equal(ly_errpath(st->ctx), "/status:c/gl2");
}
示例#18
0
/**
 * @brief Import content of the specified datastore for the given module from a file
 * referenced by the descriptor 'fd_in'
 */
static int
srcfg_import_datastore(struct ly_ctx *ly_ctx, int fd_in, const char *module_name, srcfg_datastore_t datastore,
                       LYD_FORMAT format, bool permanent)
{
    int rc = SR_ERR_INTERNAL;
    unsigned i = 0;
    struct lyd_node *new_data_tree = NULL;
    struct lyd_node *current_data_tree = NULL;
    struct lyd_difflist *diff = NULL;
    char *first_xpath = NULL, *second_xpath = NULL;
    char *input_data = NULL;
    int ret = 0;
    struct stat info;

    CHECK_NULL_ARG2(ly_ctx, module_name);

    /* parse input data */
    ret = fstat(fd_in, &info);
    CHECK_NOT_MINUS1_LOG_GOTO(ret, rc, SR_ERR_INTERNAL, cleanup,
                              "Unable to obtain input file info: %s.", sr_strerror_safe(errno));
    ly_errno = LY_SUCCESS;
    if (S_ISREG(info.st_mode)) {
        /* load (using mmap) and parse the input data in one step */
        new_data_tree = lyd_parse_fd(ly_ctx, fd_in, format, LYD_OPT_STRICT | LYD_OPT_CONFIG);
    } else { /* most likely STDIN */
        /* load input data into the memory first */
        ret = srcfg_read_file_content(fd_in, &input_data);
        CHECK_RC_MSG_GOTO(ret, cleanup, "Unable to read the input data.");
        /* parse the input data stored inside memory buffer */
        new_data_tree = lyd_parse_mem(ly_ctx, input_data, format, LYD_OPT_STRICT | LYD_OPT_CONFIG);
    }
    if (NULL == new_data_tree && LY_SUCCESS != ly_errno) {
        SR_LOG_ERR("Unable to parse the input data: %s", ly_errmsg());
        goto cleanup;
    }

    /* validate input data */
    if (NULL != new_data_tree) {
        ret = lyd_validate(&new_data_tree, LYD_OPT_STRICT | LYD_OPT_CONFIG | LYD_WD_IMPL_TAG);
        CHECK_ZERO_LOG_GOTO(ret, rc, SR_ERR_INTERNAL, cleanup, "Input data are not valid: %s", ly_errmsg());
    }

    /* remove default nodes */
    lyd_wd_cleanup(&new_data_tree, 0);

    /* get data tree of currently stored configuration */
    rc = srcfg_get_module_data(ly_ctx, module_name, &current_data_tree);
    if (SR_ERR_OK != rc) {
        goto cleanup;
    }

    /* get the list of changes made by the user */
    diff = lyd_diff(current_data_tree, new_data_tree, 0);
    if (NULL == diff) {
        SR_LOG_ERR("Unable to get the list of changes: %s", ly_errmsg());
        goto cleanup;
    }

    /* iterate over the list of differences and for each issue corresponding Sysrepo command(s) */
    while (diff->type && LYD_DIFF_END != diff->type[i]) {
        if (NULL != diff->first[i]) {
            first_xpath = lyd_path(diff->first[i]);
            if (NULL == first_xpath) {
                SR_LOG_ERR("Error returned from lyd_path: %s.", ly_errmsg());
                goto cleanup;
            }
        }
        if (NULL != diff->second[i]) {
            second_xpath = lyd_path(diff->second[i]);
            if (NULL == second_xpath) {
                free(first_xpath);
                first_xpath = NULL;
                SR_LOG_ERR("Error returned from lyd_path: %s.", ly_errmsg());
                goto cleanup;
            }
        }
        switch (diff->type[i]) {
            case LYD_DIFF_DELETED:
                SR_LOG_DBG("<LYD_DIFF_DELETED> node: %s", first_xpath);
                rc = srcfg_convert_lydiff_deleted(first_xpath);
                break;
            case LYD_DIFF_CHANGED:
                SR_LOG_DBG("<LYD_DIFF_CHANGED> orig: %s, new: %s", first_xpath, second_xpath);
                rc = srcfg_convert_lydiff_changed(first_xpath, diff->second[i]);
                break;
            case LYD_DIFF_MOVEDAFTER1:
                SR_LOG_DBG("<LYD_DIFF_MOVEDAFTER1> moved: %s, after: %s", first_xpath, second_xpath);
                rc = srcfg_convert_lydiff_movedafter(first_xpath, second_xpath);
                break;
            case LYD_DIFF_CREATED:
                SR_LOG_DBG("<LYD_DIFF_CREATED> parent: %s, new node: %s", first_xpath, second_xpath);
                rc = srcfg_convert_lydiff_created(diff->second[i]);
                break;
            case LYD_DIFF_MOVEDAFTER2:
                SR_LOG_DBG("<LYD_DIFF_MOVEDAFTER2> after: %s, this new node was inserted: %s", first_xpath, second_xpath);
                rc = srcfg_convert_lydiff_movedafter(second_xpath, first_xpath);
                break;
            default:
                assert(0 && "not reachable");
        }
        free(first_xpath);
        free(second_xpath);
        first_xpath = second_xpath = NULL;
        if (SR_ERR_OK != rc) {
            goto cleanup;
        }
        ++i;
    }
    if (0 == i) {
        SR_LOG_DBG_MSG("No changes were made.");
    } else {
        /* commit the changes */
        rc = sr_commit(srcfg_session);
        if (SR_ERR_OK != rc) {
            SR_LOG_ERR("Error returned from sr_commit: %s.", sr_strerror(rc));
            goto cleanup;
        }
        if (SRCFG_STORE_RUNNING == datastore && permanent) {
            /* copy running datastore data into the startup datastore */
            rc = sr_copy_config(srcfg_session, module_name, SR_DS_RUNNING, SR_DS_STARTUP);
            if (SR_ERR_OK != rc) {
                SR_LOG_ERR("Error returned from sr_copy_config: %s.", sr_strerror(rc));
                goto cleanup;
            }
        }
    }

    rc = SR_ERR_OK;

cleanup:
    if (NULL != diff) {
        lyd_free_diff(diff);
    }
    if (NULL != current_data_tree) {
        lyd_free_withsiblings(current_data_tree);
    }
    if (NULL != new_data_tree) {
        lyd_free_withsiblings(new_data_tree);
    }
    if (input_data) {
        free(input_data);
    }
    return rc;
}
示例#19
0
static void
test_parse_noncharacters_xml(void **state)
{
    struct state *st;
    const char* mod = "module x {namespace urn:x; prefix x; leaf x { type string;}}";
    const char* data = "<x xmlns=\"urn:x\">----------</x>";

    assert_ptr_not_equal(((*state) = st = calloc(1, sizeof *st)), NULL);
    assert_ptr_not_equal((st->ctx = ly_ctx_new(NULL)), NULL);

    /* test detection of invalid characters according to RFC 7950, sec 9.4 */
    assert_ptr_not_equal(lys_parse_mem(st->ctx, mod, LYS_IN_YANG), 0);
    assert_ptr_not_equal((st->str1 = strdup(data)), NULL);

    /* exclude surrogate blocks 0xD800-DFFF - trying 0xd800 */
    st->str1[17] = 0xed;
    st->str1[18] = 0xa0;
    st->str1[19] = 0x80;
    assert_ptr_equal(lyd_parse_mem(st->ctx, st->str1, LYD_XML, LYD_OPT_CONFIG), NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode, LYVE_XML_INCHAR);
    assert_string_equal(ly_errmsg(), "Invalid UTF-8 value 0x0000d800");

    /* exclude noncharacters %xFDD0-FDEF - trying 0xfdd0 */
    st->str1[17] = 0xef;
    st->str1[18] = 0xb7;
    st->str1[19] = 0x90;
    assert_ptr_equal(lyd_parse_mem(st->ctx, st->str1, LYD_XML, LYD_OPT_CONFIG), NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode, LYVE_XML_INCHAR);
    assert_string_equal(ly_errmsg(), "Invalid UTF-8 value 0x0000fdd0");

    /* exclude noncharacters %xFFFE-FFFF - trying 0xfffe */
    st->str1[17] = 0xef;
    st->str1[18] = 0xbf;
    st->str1[19] = 0xbe;
    assert_ptr_equal(lyd_parse_mem(st->ctx, st->str1, LYD_XML, LYD_OPT_CONFIG), NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode, LYVE_XML_INCHAR);
    assert_string_equal(ly_errmsg(), "Invalid UTF-8 value 0x0000fffe");

    /* exclude c0 control characters except tab, carriage return and line feed */
    st->str1[17] = 0x9; /* valid - horizontal tab */
    st->str1[18] = 0xa; /* valid - new line */
    st->str1[19] = 0xd; /* valid - carriage return */
    st->str1[20] = 0x6; /* invalid - ack */
    assert_ptr_equal(lyd_parse_mem(st->ctx, st->str1, LYD_XML, LYD_OPT_CONFIG), NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode, LYVE_XML_INCHAR);
    assert_string_equal(ly_errmsg(), "Invalid UTF-8 value 0x06");

    /* exclude noncharacters %x?FFFE-?FFFF - trying 0x10ffff */
    st->str1[17] = 0xf4;
    st->str1[18] = 0x8f;
    st->str1[19] = 0xbf;
    st->str1[20] = 0xbf;
    assert_ptr_equal(lyd_parse_mem(st->ctx, st->str1, LYD_XML, LYD_OPT_CONFIG), NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode, LYVE_XML_INCHAR);
    assert_string_equal(ly_errmsg(), "Invalid UTF-8 value 0x0010ffff");

    /* 0x6 */
    st->str1[17] = '&';
    st->str1[18] = '#';
    st->str1[19] = 'x';
    st->str1[20] = '6';
    st->str1[21] = ';';
    assert_ptr_equal(lyd_parse_mem(st->ctx, st->str1, LYD_XML, LYD_OPT_CONFIG), NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode, LYVE_XML_INVAL);
    assert_string_equal(ly_errmsg(), "Invalid character reference value.");

    /* 0xdfff */
    st->str1[17] = '&';
    st->str1[18] = '#';
    st->str1[19] = 'x';
    st->str1[20] = 'd';
    st->str1[21] = 'f';
    st->str1[22] = 'f';
    st->str1[23] = 'f';
    st->str1[24] = ';';
    assert_ptr_equal(lyd_parse_mem(st->ctx, st->str1, LYD_XML, LYD_OPT_CONFIG), NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode, LYVE_XML_INVAL);
    assert_string_equal(ly_errmsg(), "Invalid character reference value.");

    /* 0xfdef */
    st->str1[17] = '&';
    st->str1[18] = '#';
    st->str1[19] = 'x';
    st->str1[20] = 'f';
    st->str1[21] = 'd';
    st->str1[22] = 'e';
    st->str1[23] = 'f';
    st->str1[24] = ';';
    assert_ptr_equal(lyd_parse_mem(st->ctx, st->str1, LYD_XML, LYD_OPT_CONFIG), NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode, LYVE_XML_INVAL);
    assert_string_equal(ly_errmsg(), "Invalid character reference value.");

    /* 0xffff */
    st->str1[17] = '&';
    st->str1[18] = '#';
    st->str1[19] = 'x';
    st->str1[20] = 'f';
    st->str1[21] = 'f';
    st->str1[22] = 'f';
    st->str1[23] = 'f';
    st->str1[24] = ';';
    assert_ptr_equal(lyd_parse_mem(st->ctx, st->str1, LYD_XML, LYD_OPT_CONFIG), NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode, LYVE_XML_INVAL);
    assert_string_equal(ly_errmsg(), "Invalid character reference value.");

    /* the same using character reference */
    /* 0x10ffff */
    st->str1[17] = '&';
    st->str1[18] = '#';
    st->str1[19] = 'x';
    st->str1[20] = '1';
    st->str1[21] = '0';
    st->str1[22] = 'f';
    st->str1[23] = 'f';
    st->str1[24] = 'f';
    st->str1[25] = 'f';
    st->str1[26] = ';';
    assert_ptr_equal(lyd_parse_mem(st->ctx, st->str1, LYD_XML, LYD_OPT_CONFIG), NULL);
    assert_int_equal(ly_errno, LY_EVALID);
    assert_int_equal(ly_vecode, LYVE_XML_INVAL);
    assert_string_equal(ly_errmsg(), "Invalid character reference value.");

}