static void test_df1(void **state) { struct state *st = (*state); struct lyd_node *node; const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\">" "<bar><ho>1</ho><hi>42</hi></bar>" "<foo>42</foo><b1_1>42</b1_1>" "</df><hidden xmlns=\"urn:libyang:tests:defaults\">" "<foo>42</foo><baz>42</baz></hidden>"; st->dt = lyd_new(NULL, st->mod, "df"); assert_ptr_not_equal(st->dt, NULL); /* presence container */ assert_ptr_not_equal((node = lyd_new(st->dt, NULL, "bar")), NULL); assert_int_not_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG), 0); assert_string_equal(ly_errmsg(), "Missing required element \"ho\" in \"bar\"."); /* manadatory node in bar */ assert_ptr_not_equal(lyd_new_leaf(node, NULL, "ho", "1"), NULL); assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG), 0); assert_int_equal(lyd_wd_add(NULL, &(st->dt), LYD_OPT_CONFIG | LYD_WD_ALL), 0); 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); }
static void test_df4(void **state) { struct state *st = (*state); const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">" "<b1_2>x</b1_2><foo>42</foo><b1_1>42</b1_1>" "</df><hidden xmlns=\"urn:libyang:tests:defaults\">" "<foo>42</foo><baz>42</baz></hidden>"; const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\" " "xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\">" "<b2>1</b2><foo ncwd:default=\"true\">42</foo>" "</df><hidden xmlns=\"urn:libyang:tests:defaults\" " "xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\">" "<foo ncwd:default=\"true\">42</foo><baz ncwd:default=\"true\">42</baz></hidden>"; const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\" " "xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\">" "<s2a>1</s2a><foo ncwd:default=\"true\">42</foo>" "</df><hidden xmlns=\"urn:libyang:tests:defaults\" " "xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\">" "<foo ncwd:default=\"true\">42</foo><baz ncwd:default=\"true\">42</baz></hidden>"; st->dt = lyd_new(NULL, st->mod, "df"); assert_ptr_not_equal(st->dt, NULL); /* select2 - s2a */ assert_ptr_not_equal(lyd_new_leaf(st->dt, NULL, "s2a", "1"), NULL); assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG), 0); assert_int_equal(lyd_wd_add(NULL, &(st->dt), LYD_OPT_CONFIG | LYD_WD_ALL_TAG), 0); 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, xml3); assert_int_equal(lyd_wd_cleanup(&(st->dt), 0), 0); free(st->xml); st->xml = NULL; /* select2 - s2b - b2 */ assert_ptr_not_equal(lyd_new_leaf(st->dt, NULL, "b2", "1"), NULL); assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG), 0); assert_int_equal(lyd_wd_add(NULL, &(st->dt), LYD_OPT_CONFIG | LYD_WD_ALL_TAG), 0); 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, xml2); assert_int_equal(lyd_wd_cleanup(&(st->dt), 0), 0); free(st->xml); st->xml = NULL; /* select2 - s2b - b1 */ assert_ptr_not_equal(lyd_new_leaf(st->dt, NULL, "b1_2", "x"), NULL); assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG), 0); assert_int_equal(lyd_wd_add(NULL, &(st->dt), LYD_OPT_CONFIG | LYD_WD_ALL), 0); 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, xml1); }
static void test_leafref_free(void **state) { struct state *st = (*state); int r; lyd_free(st->data->child->child->prev); r = lyd_validate(&(st->data), LYD_OPT_CONFIG, NULL); assert_int_not_equal(r, 0); lyd_new_leaf(st->data->child, NULL, "name", "jedna"); r = lyd_validate(&(st->data), LYD_OPT_CONFIG, NULL); assert_int_equal(r, 0); }
static void test_df2(void **state) { struct state *st = (*state); struct lyd_node *node; const char *xml = "<df xmlns=\"urn:libyang:tests:defaults\">" "<list><name>a</name><value>42</value></list>" "<list><name>b</name><value>1</value></list>" "<foo>42</foo><b1_1>42</b1_1>" "</df><hidden xmlns=\"urn:libyang:tests:defaults\">" "<foo>42</foo><baz>42</baz></hidden>"; st->dt = lyd_new(NULL, st->mod, "df"); assert_ptr_not_equal(st->dt, NULL); /* lists */ assert_ptr_not_equal(lyd_new_path(st->dt, NULL, "/defaults:df/defaults:list[name='a']", NULL, 0), NULL); assert_ptr_not_equal((node = lyd_new_path(st->dt, NULL, "/defaults:df/defaults:list[name='b']", NULL, 0)), NULL); assert_ptr_not_equal(lyd_new_leaf(node, NULL, "value", "1"), NULL); assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG), 0); assert_int_equal(lyd_wd_add(NULL, &(st->dt), LYD_OPT_CONFIG | LYD_WD_ALL), 0); 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); }
static void test_instid_unlink(void **state) { struct state *st = (*state); struct lyd_node *node; int r; node = st->data->child->prev; lyd_unlink(node); r = lyd_validate(st->data, 0); assert_int_not_equal(r, 0); lyd_insert(st->data, node); r = lyd_validate(st->data, 0); assert_int_equal(r, 0); }
static void test_empty_tag(void **state) { struct state *st = (*state); const char *xml = "<nacm xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-acm\" " "xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\">" "<enable-nacm ncwd:default=\"true\">true</enable-nacm>" "<read-default ncwd:default=\"true\">permit</read-default>" "<write-default ncwd:default=\"true\">deny</write-default>" "<exec-default ncwd:default=\"true\">permit</exec-default>" "<enable-external-groups ncwd:default=\"true\">true</enable-external-groups>" "</nacm><df xmlns=\"urn:libyang:tests:defaults\" " "xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\">" "<foo ncwd:default=\"true\">42</foo><b1_1 ncwd:default=\"true\">42</b1_1>" "</df><hidden xmlns=\"urn:libyang:tests:defaults\" " "xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\">" "<foo ncwd:default=\"true\">42</foo><baz ncwd:default=\"true\">42</baz></hidden>"; lyd_wd_add(st->ctx, &(st->dt), LYD_OPT_CONFIG | LYD_WD_ALL_TAG); assert_ptr_not_equal(st->dt, NULL); assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG | LYD_WD_ALL), 0); 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); }
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); }
static void test_leafref_unlink(void **state) { struct state *st = (*state); struct lyd_node *node; int r; node = st->data->child->child->next; lyd_unlink(node); r = lyd_validate(&(st->data), LYD_OPT_CONFIG, NULL); assert_int_not_equal(r, 0); lyd_insert(st->data->child, node); r = lyd_validate(&(st->data), LYD_OPT_CONFIG, NULL); assert_int_equal(r, 0); }
static void test_dependency_circular(void **state) { struct state *st = (struct state *)*state; struct lyd_node *node; /* schema */ st->mod = lys_parse_path(st->ctx, TESTS_DIR"/data/files/when-circdepend.yin", LYS_IN_YIN); assert_ptr_not_equal(st->mod, NULL); st->dt = lyd_new_path(NULL, st->ctx, "/when-circdepend:top/a", "val_a", 0, 0); assert_ptr_not_equal(st->dt, NULL); node = lyd_new_path(st->dt, st->ctx, "/when-circdepend:top/b", "val_b", 0, 0); assert_ptr_not_equal(node, NULL); node = lyd_new_path(st->dt, st->ctx, "/when-circdepend:top/d", "1", 0, 0); assert_ptr_not_equal(node, NULL); node = lyd_new_path(st->dt, st->ctx, "/when-circdepend:top/d", "2", 0, 0); assert_ptr_not_equal(node, NULL); node = lyd_new_path(st->dt, st->ctx, "/when-circdepend:top/e", "val_e", 0, 0); assert_ptr_not_equal(node, NULL); assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 1); assert_int_equal(ly_errno, LY_EVALID); assert_int_equal(ly_vecode, LYVE_INWHEN); }
void save_nacm_config(test_nacm_cfg_t *nacm_config) { /* validate & save */ assert_int_equal(0, lyd_validate(&nacm_config->root, LYD_OPT_STRICT | LYD_OPT_CONFIG, nacm_config->ly_ctx)); assert_int_equal(SR_ERR_OK, sr_save_data_tree_file(NACM_MODULE_DATA_FILE_NAME, nacm_config->root)); }
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); }
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); }
static void test_df3(void **state) { struct state *st = (*state); struct lyd_node *node; const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">" "<a1>1</a1>" "<foo>42</foo><b1_1>42</b1_1>" "</df><hidden xmlns=\"urn:libyang:tests:defaults\">" "<foo>42</foo><baz>42</baz></hidden>"; const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\" " "xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\">" "<c><x ncwd:default=\"true\">42</x></c>" "<foo ncwd:default=\"true\">42</foo><b1_1 ncwd:default=\"true\">42</b1_1>" "</df><hidden xmlns=\"urn:libyang:tests:defaults\" " "xmlns:ncwd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\">" "<foo ncwd:default=\"true\">42</foo><baz ncwd:default=\"true\">42</baz></hidden>"; st->dt = lyd_new(NULL, st->mod, "df"); assert_ptr_not_equal(st->dt, NULL); /* select - c */ assert_ptr_not_equal((node = lyd_new(st->dt, NULL, "c")), NULL); assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG), 0); assert_int_equal(lyd_wd_add(NULL, &(st->dt), LYD_OPT_CONFIG | LYD_WD_ALL_TAG), 0); 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, xml2); assert_int_equal(lyd_wd_cleanup(&(st->dt), 0), 0); free(st->xml); st->xml = NULL; /* select - a */ assert_ptr_not_equal(lyd_new_leaf(st->dt, NULL, "a1", "1"), NULL); assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG), 0); assert_int_equal(lyd_wd_add(NULL, &(st->dt), LYD_OPT_CONFIG | LYD_WD_ALL), 0); 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, xml1); }
int main(int argc, char *argv[]) { int fd, i; struct ly_ctx *ctx = NULL; char buf[30]; struct lyd_node *data = NULL, *next; const struct lys_module *mod; /* libyang context */ ctx = ly_ctx_new(NULL); if (!ctx) { fprintf(stderr, "Failed to create context.\n"); return 1; } /* schema */ if (!(mod = lys_parse_path(ctx, argv[1], LYS_IN_YIN))) { fprintf(stderr, "Failed to load data model.\n"); goto cleanup; } /* data */ data = NULL; fd = open("./addloop_result.xml", O_WRONLY | O_CREAT, 0666); data = NULL; for(i = 1; i <= 5000; i++) { next = lyd_new(NULL, mod, "ptest1"); // if (i == 2091) {sprintf(buf, "%d", 1);} else { sprintf(buf, "%d", i);//} lyd_new_leaf(next, mod, "index", buf); lyd_new_leaf(next, mod, "p1", buf); if (!data) { data = next; } else { lyd_insert_after(data->prev, next); } if (lyd_validate(&data, LYD_OPT_CONFIG, NULL)) { goto cleanup; } //lyd_print_fd(fd, data, LYD_XML); } lyd_print_fd(fd, data, LYD_XML, LYP_WITHSIBLINGS | LYP_FORMAT); close(fd); cleanup: lyd_free_withsiblings(data); ly_ctx_destroy(ctx, NULL); return 0; }
static void test_dummy(void **state) { struct state *st = (struct state *)*state; /* schema */ st->mod = lys_parse_path(st->ctx, TESTS_DIR"/data/files/when-dummy.yin", LYS_IN_YIN); assert_ptr_not_equal(st->mod, NULL); st->dt = lyd_new_path(NULL, st->ctx, "/when-dummy:c", "value", 0, 0); assert_ptr_not_equal(st->dt, NULL); assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 1); assert_int_equal(ly_errno, LY_EVALID); assert_int_equal(ly_vecode, LYVE_XPATH_DUMMY); }
static void test_unlink_choice(void **state) { struct state *st = (struct state *)*state; /* schema */ st->mod = lys_parse_path(st->ctx, TESTS_DIR"/data/files/when-unlink.yin", LYS_IN_YIN); assert_ptr_not_equal(st->mod, NULL); st->dt = lyd_new_path(NULL, st->ctx, "/when-unlink:top/cas2", NULL, 0, 0); assert_ptr_not_equal(st->dt, NULL); assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 0); lyd_print_mem(&(st->xml), st->dt, LYD_XML, LYP_WITHSIBLINGS); assert_string_equal(st->xml, "<top xmlns=\"urn:libyang:tests:when-unlink\"><cas2/></top>"); }
void createDataTreeExampleModule() { struct ly_ctx *ctx = NULL; struct lyd_node *root = NULL; ctx = ly_ctx_new(TEST_SCHEMA_SEARCH_DIR); assert_non_null(ctx); const struct lys_module *module = ly_ctx_load_module(ctx, "example-module", NULL); assert_non_null(module); #define XPATH "/example-module:container/list[key1='key1'][key2='key2']/leaf" root = lyd_new_path(NULL, ctx, XPATH, "Leaf value", 0); assert_int_equal(0, lyd_validate(&root, LYD_OPT_STRICT | LYD_OPT_CONFIG)); assert_int_equal(SR_ERR_OK, sr_save_data_tree_file(EXAMPLE_MODULE_DATA_FILE_NAME, root)); lyd_free_withsiblings(root); ly_ctx_destroy(ctx, NULL); }
static void test_feature(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><hiddenleaf xmlns=\"urn:libyang:tests:defaults\">42" "</hiddenleaf><df xmlns=\"urn:libyang:tests:defaults\">" "<foo>42</foo><hiddenleaf>42</hiddenleaf><b1_1>42</b1_1>" "</df><hidden xmlns=\"urn:libyang:tests:defaults\">" "<foo>42</foo><baz>42</baz></hidden>"; assert_int_equal(lys_features_enable(st->mod, "unhide"), 0); assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG | LYD_WD_ALL, 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); }
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"); }
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"); }
/** * @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, ¤t_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; }
/** * @brief Get complete libyang data tree of a specified module from sysrepo. */ static int srcfg_get_module_data(struct ly_ctx *ly_ctx, const char *module_name, struct lyd_node **data_tree) { int rc = SR_ERR_OK, ret = 0; sr_val_t *value = NULL; sr_val_iter_t *iter = NULL; struct lyd_node *node = NULL; const struct lys_node *schema = NULL; char query[PATH_MAX] = { 0, }; char *string_val = NULL; snprintf(query, PATH_MAX, "/%s:*//.", module_name); rc = sr_get_items_iter(srcfg_session, query, &iter); if (SR_ERR_OK != rc) { SR_LOG_ERR("Error by sr_get_items_iter: %s", sr_strerror(rc)); goto cleanup; } *data_tree = NULL; ly_errno = LY_SUCCESS; ly_diminish_errors = true; while (SR_ERR_OK == (rc = sr_get_item_next(srcfg_session, iter, &value))) { ly_diminish_errors = false; if (NULL == value) { goto next; } /* get node schema */ schema = ly_ctx_get_node2(ly_ctx, NULL, value->xpath, 0); if (!schema) { SR_LOG_ERR("Error by ly_ctx_get_node2: %s", ly_errmsg()); goto fail; } /* skip default values */ if (schema->nodetype == LYS_LEAF && value->dflt) { goto next; } /* skip non-presence containers */ if (value->type == SR_CONTAINER_T) { goto next; } /* convert value to string */ rc = sr_val_to_str(value, schema, &string_val); if (SR_ERR_OK != rc) { SR_LOG_ERR("Error by sr_val_to_str: %s", sr_strerror(rc)); goto fail; } /* add node to data tree */ ly_errno = LY_SUCCESS; node = lyd_new_path(*data_tree, ly_ctx, value->xpath, string_val, LYD_PATH_OPT_UPDATE); if (!node && LY_SUCCESS != ly_errno) { SR_LOG_ERR("Error by lyd_new_path: %s", ly_errmsg()); goto fail; } if (NULL == *data_tree) { *data_tree = node; } next: /* cleanup before next iteration */ if (NULL != string_val) { free(string_val); string_val = NULL; } if (NULL != value) { sr_free_val(value); value = NULL; } ly_diminish_errors = true; } ly_diminish_errors = false; if (SR_ERR_NOT_FOUND == rc) { rc = SR_ERR_OK; } if (SR_ERR_OK == rc) { if (NULL != *data_tree) { /* validate returned data, but most importantly resolve leafrefs */ ret = lyd_validate(data_tree, LYD_OPT_STRICT | LYD_OPT_CONFIG | LYD_WD_IMPL_TAG); CHECK_ZERO_LOG_GOTO(ret, rc, SR_ERR_INTERNAL, fail, "Received data tree from sysrepo is not valid: %s", ly_errmsg()); /* remove default nodes added by validation */ lyd_wd_cleanup(data_tree, 0); } goto cleanup; } fail: rc = SR_ERR_INTERNAL; if (NULL != *data_tree) { lyd_free_withsiblings(*data_tree); *data_tree = NULL; } cleanup: if (NULL != string_val) { free(string_val); } if (NULL != value) { sr_free_val(value); } if (NULL != iter) { sr_free_val_iter(iter); } return rc; }
static void test_multdfltvalues_yin(void **state) { struct ly_ctx *ctx = *state; struct lyd_node *root; const char *yin_cfg = "<module name=\"x\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">" " <namespace uri=\"urn:x\"/>" " <prefix value=\"x\"/>" " <yang-version value=\"1.1\"/>" " <container name=\"x\">" " <leaf-list name=\"ll\">" " <type name=\"string\"/>" " <default value=\"a\"/>" " <default value=\"a\"/>" " </leaf-list>" " </container>" "</module>"; const char *yin_status_10 = "<module name=\"x\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">" " <namespace uri=\"urn:x\"/>" " <prefix value=\"x\"/>" " <container name=\"x\">" " <leaf-list name=\"ll\">" " <config value=\"false\"/>" " <type name=\"string\"/>" " <default value=\"a\"/>" " <default value=\"a\"/>" " </leaf-list>" " </container>" "</module>"; const char *yin_status = "<module name=\"x\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">" " <namespace uri=\"urn:x\"/>" " <prefix value=\"x\"/>" " <yang-version value=\"1.1\"/>" " <container name=\"x\">" " <leaf-list name=\"ll\">" " <config value=\"false\"/>" " <type name=\"string\"/>" " <default value=\"a\"/>" " <default value=\"a\"/>" " </leaf-list>" " </container>" "</module>"; const char *xml = "<x xmlns=\"urn:x\"><ll>a</ll><ll>a</ll></x>"; char *printed; /* only config leaflists must be unique, so in case of default data * the same value can be specified as default multiple times */ assert_ptr_equal(lys_parse_mem(ctx, yin_cfg, LYS_IN_YIN), NULL); assert_ptr_equal(lys_parse_mem(ctx, yin_status_10, LYS_IN_YIN), NULL); assert_ptr_not_equal(lys_parse_mem(ctx, yin_status, LYS_IN_YIN), NULL); /* for validating complete data tree, we need data from ietf-yang-library */ root = ly_ctx_info(ctx); assert_int_equal(lyd_validate(&root, LYD_OPT_DATA, ctx), 0); assert_ptr_not_equal(root, NULL); /* ietf-yang-library */ assert_ptr_not_equal(root->next, NULL); /* added default nodes from module x */ lyd_print_mem(&printed, root->prev, LYD_XML, LYP_WD_ALL); /* print only the default nodes from module x */ assert_string_equal(printed, xml); free(printed); lyd_free_withsiblings(root); }
struct nc_server_reply * op_validate(struct lyd_node *rpc, struct nc_session *ncs) { struct np2_sessions *sessions; struct ly_set *nodeset; struct nc_server_error *e = NULL; int rc; struct lyd_node *config = NULL; struct lyd_node_anyxml *axml; const char *dsname; sr_datastore_t ds = SR_DS_CANDIDATE; /* get sysrepo connections for this session */ sessions = (struct np2_sessions *)nc_session_get_data(ncs); /* get know which datastore is being affected */ nodeset = lyd_get_node(rpc, "/ietf-netconf:validate/source/*"); dsname = nodeset->set.d[0]->schema->name; axml = (struct lyd_node_anyxml *)nodeset->set.d[0]; ly_set_free(nodeset); if (!strcmp(dsname, "running")) { ds = SR_DS_RUNNING; } else if (!strcmp(dsname, "startup")) { ds = SR_DS_STARTUP; } else if (!strcmp(dsname, "candidate")) { ds = SR_DS_CANDIDATE; } else if (!strcmp(dsname, "config")) { /* get data tree to validate */ config = lyd_parse_xml(rpc->schema->module->ctx, &axml->value.xml, LYD_OPT_CONFIG | LYD_OPT_DESTRUCT); if (ly_errno != LY_SUCCESS) { ly_set_free(nodeset); goto error; } rc = lyd_validate(&config, LYD_OPT_CONFIG, np2srv.ly_ctx); /* cleanup */ lyd_free_withsiblings(config); goto done; } /* TODO support URL */ if (ds != sessions->ds) { /* update sysrepo session */ sr_session_switch_ds(sessions->srs, ds); sessions->ds = ds; } if (ds != SR_DS_CANDIDATE) { /* refresh datastore content */ if (sr_session_refresh(sessions->srs) != SR_ERR_OK) { goto error; } } /* validate sysrepo's datastore */ rc = sr_validate(sessions->srs); if (rc != SR_ERR_OK) { goto error; } done: return nc_server_reply_ok(); error: /* handle error */ if (!e) { e = nc_err(NC_ERR_OP_FAILED, NC_ERR_TYPE_APP); nc_err_set_msg(e, np2log_lasterr(), "en"); } return nc_server_reply_err(e); }
void createDataTreeTestModule() { struct ly_ctx *ctx = NULL; struct lyd_node *node = NULL; struct lyd_node *n = NULL; struct lyd_node *r = NULL; ctx = ly_ctx_new(TEST_SCHEMA_SEARCH_DIR); assert_non_null(ctx); const struct lys_module *module = ly_ctx_load_module(ctx, "test-module", NULL); assert_non_null(module); r = lyd_new(NULL, module, "main"); assert_non_null(r); node = lyd_new_leaf(r, module, "enum", XP_TEST_MODULE_ENUM_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "raw", XP_TEST_MODULE_RAW_VALUE); assert_non_null(node); /*Strict = 1, Recursive = 1, Loggin = 0*/ node = lyd_new_leaf(r, module, "options", XP_TEST_MODULE_BITS_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "dec64", XP_TEST_MODULE_DEC64_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "i8", XP_TEST_MODULE_INT8_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "i16", XP_TEST_MODULE_INT16_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "i32", XP_TEST_MODULE_INT32_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "i64", XP_TEST_MODULE_INT64_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "ui8", XP_TEST_MODULE_UINT8_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "ui16", XP_TEST_MODULE_UINT16_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "ui32", XP_TEST_MODULE_UINT32_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "ui64", XP_TEST_MODULE_INT64_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "empty", XP_TEST_MODULE_EMPTY_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "boolean", XP_TEST_MODULE_BOOL_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "string", XP_TEST_MODULE_STRING_VALUE); assert_non_null(node); node = lyd_new_leaf(r, module, "id_ref", XP_TEST_MODULE_IDREF_VALUE); assert_non_null(node); /* leaf -list*/ n = lyd_new_leaf(r, module, "numbers", "1"); assert_non_null(n); n = lyd_new_leaf(r, module, "numbers", "2"); assert_non_null(n); n = lyd_new_leaf(r, module, "numbers", "42"); assert_non_null(n); /* list k1*/ node = lyd_new(NULL, module, "list"); assert_non_null(node); assert_int_equal(0,lyd_insert_after(r, node)); n = lyd_new_leaf(node, module, "key", "k1"); assert_non_null(n); n = lyd_new_leaf(node, module, "id_ref", "id_1"); assert_non_null(n); n = lyd_new_leaf(node, module, "union", "42"); assert_non_null(n); /* presence container*/ n = lyd_new(node, module, "wireless"); assert_non_null(n); /* list k2*/ node = lyd_new(NULL, module, "list"); assert_non_null(node); assert_int_equal(0, lyd_insert_after(r, node)); n = lyd_new_leaf(node, module, "key", "k2"); assert_non_null(n); n = lyd_new_leaf(node, module, "id_ref", "id_2"); assert_non_null(n); n = lyd_new_leaf(node, module, "union", "infinity"); assert_non_null(n); assert_int_equal(0, lyd_validate(&r, LYD_OPT_STRICT | LYD_OPT_CONFIG)); assert_int_equal(SR_ERR_OK, sr_save_data_tree_file(TEST_MODULE_DATA_FILE_NAME, r)); lyd_free_withsiblings(r); ly_ctx_destroy(ctx, NULL); }
API struct lyd_node * ly_ctx_info(struct ly_ctx *ctx) { int i; char id[8]; const struct lys_module *mod; struct lyd_node *root, *cont; mod = ly_ctx_get_module(ctx, "ietf-yang-library", NULL); if (!mod) { mod = lyp_search_file(ctx, NULL, "ietf-yang-library", NULL); } if (!mod || !mod->data || strcmp(mod->data->next->name, "modules")) { return NULL; } root = lyd_new(NULL, mod, "modules"); if (!root) { return NULL; } for (i = 0; i < ctx->models.used; ++i) { cont = lyd_new(root, NULL, "module"); if (!cont) { lyd_free(root); return NULL; } if (!lyd_new_leaf(cont, NULL, "name", ctx->models.list[i]->name)) { lyd_free(root); return NULL; } if (!lyd_new_leaf(cont, NULL, "revision", (ctx->models.list[i]->rev_size ? ctx->models.list[i]->rev[0].date : ""))) { lyd_free(root); return NULL; } if (ctx->models.list[i]->uri && !lyd_new_leaf(cont, NULL, "schema", ctx->models.list[i]->uri)) { lyd_free(root); return NULL; } if (!lyd_new_leaf(cont, NULL, "namespace", ctx->models.list[i]->ns)) { lyd_free(root); return NULL; } if (ylib_feature(cont, ctx->models.list[i])) { lyd_free(root); return NULL; } if (ylib_deviation(cont, ctx->models.list[i], ctx)) { lyd_free(root); return NULL; } if (ctx->models.list[i]->implemented && !lyd_new_leaf(cont, NULL, "conformance", "implement")) { lyd_free(root); return NULL; } if (!ctx->models.list[i]->implemented && !lyd_new_leaf(cont, NULL, "conformance", "import")) { lyd_free(root); return NULL; } if (ylib_submodules(cont, ctx->models.list[i])) { lyd_free(root); return NULL; } } sprintf(id, "%u", ctx->models.module_set_id); if (!lyd_new_leaf(root, mod, "module-set-id", id)) { lyd_free(root); return NULL; } if (lyd_validate(root, 0)) { lyd_free(root); return NULL; } return root; }
static void test_multdfltvalues_yang(void **state) { struct ly_ctx *ctx = *state; struct lyd_node *root; const char *yang_cfg = "module x {" " namespace urn:x;" " prefix x;" " yang-version 1.1;" " container x {" " leaf-list ll {" " type string;" " default a;" " default a;" " }" " }" "}"; const char *yang_status_10 = "module x {" " namespace urn:x;" " prefix x;" " container x {" " leaf-list ll {" " config false;" " type string;" " default a;" " default a;" " }" " }" "}"; const char *yang_status = "module x {" " namespace urn:x;" " prefix x;" " yang-version 1.1;" " container x {" " leaf-list ll {" " config false;" " type string;" " default a;" " default a;" " }" " }" "}"; const char *xml = "<x xmlns=\"urn:x\"><ll>a</ll><ll>a</ll></x>"; char *printed; /* only config leaflists must be unique, so in case of default data * the same value can be specified as default multiple times */ assert_ptr_equal(lys_parse_mem(ctx, yang_cfg, LYS_IN_YANG), NULL); assert_ptr_equal(lys_parse_mem(ctx, yang_status_10, LYS_IN_YANG), NULL); assert_ptr_not_equal(lys_parse_mem(ctx, yang_status, LYS_IN_YANG), NULL); /* for validating complete data tree, we need data from ietf-yang-library */ root = ly_ctx_info(ctx); assert_int_equal(lyd_validate(&root, LYD_OPT_DATA, ctx), 0); assert_ptr_not_equal(root, NULL); /* ietf-yang-library */ assert_ptr_not_equal(root->next, NULL); /* added default nodes from module x */ lyd_print_mem(&printed, root->prev, LYD_XML, LYP_WD_ALL); /* print only the default nodes from module x */ assert_string_equal(printed, xml); free(printed); lyd_free_withsiblings(root); }