static void test_mult_revisions(void **state) { struct ly_ctx *ctx = *state; const char *sch_yang = "module main_mod {" "namespace \"urn:cesnet:test:a\";" "prefix \"a\";" "include submod_r { revision-date \"2016-06-19\";}" "include submod1;}"; const char *sch_correct_yang = "module main_mod {" "namespace \"urn:cesnet:test:a\";" "prefix \"a\";" "include submod_r;" "include submod1;}"; const char *sch_yin = "<module name=\"main_mod\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">" "<namespace uri=\"urn:cesnet:test:a\"/><prefix value=\"a\"/>" "<include module=\"submod_r\"><revision-date date=\"2016-06-19\"/></include>" "<include module=\"submod1\"/></module>"; const char *sch_correct_yin = "<module name=\"main_mod\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">" "<namespace uri=\"urn:cesnet:test:a\"/><prefix value=\"a\"/>" "<include module=\"submod_r\"/>" "<include module=\"submod1\"/></module>"; ly_ctx_set_searchdir(ctx, SCHEMA_FOLDER_YIN); assert_ptr_equal(lys_parse_mem(ctx, sch_yin, LYS_IN_YIN), NULL); assert_ptr_not_equal(lys_parse_mem(ctx, sch_correct_yin, LYS_IN_YIN), NULL); ly_ctx_destroy(*state, NULL); *state = ctx = ly_ctx_new(SCHEMA_FOLDER_YANG); assert_ptr_equal(lys_parse_mem(ctx, sch_yang, LYS_IN_YANG), NULL); assert_ptr_not_equal(lys_parse_mem(ctx, sch_correct_yang, LYS_IN_YANG), NULL); }
static void test_lys_features_list(void **state) { (void) state; /* unused */ const struct lys_module *module; const char **result; uint8_t st = 1; uint8_t *states = &st; module = lys_parse_mem(ctx, lys_module_a, LYS_IN_YIN); if (!module) { fail(); } result = lys_features_list(module, &states); assert_string_equal("foo", *result); free(result); free(states); module = lys_parse_mem(ctx, lys_module_b, LYS_IN_YANG); if (!module) { fail(); } result = lys_features_list(module, &states); assert_string_equal("foo", *result); free(result); free(states); }
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_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); }
static void test_lys_features_disable(void **state) { (void) state; /* unused */ LYS_INFORMAT yang_format = LYS_IN_YIN; const struct lys_module *module; int rc; module = lys_parse_mem(ctx, lys_module_a, yang_format); if (!module) { fail(); } assert_string_equal("foo", module->features->name); assert_int_equal(0x0, module->features->flags); rc = lys_features_enable(module, "*"); if (rc) { fail(); } assert_int_equal(LYS_FENABLED, module->features->flags); rc = lys_features_disable(module, "*"); if (rc) { fail(); } assert_int_equal(0x0, module->features->flags); }
static void test_lys_is_disabled(void **state) { (void) state; /* unused */ LYS_INFORMAT yang_format = LYS_IN_YIN; const struct lys_module *module; const struct lys_node *node = NULL; int rc; module = lys_parse_mem(ctx, lys_module_a, yang_format); if (!module) { fail(); } node = lys_is_disabled(module->data->child, 2); if (!node) { fail(); } assert_string_equal("/a:top", node->name); rc = lys_features_enable(module, "bar"); if (rc) { fail(); } node = lys_is_disabled(module->data->child, 2); if (node) { fail(); } }
static void test_lys_set_private(void **state) { (void) state; /* unused */ LYS_INFORMAT yang_format = LYS_IN_YIN; const struct lys_node *node_parent; const struct lys_node *node_child; const struct lys_module *module; module = lys_parse_mem(ctx, lys_module_a, yang_format); if (!module) { fail(); } assert_string_equal("top", module->data->name); node_parent = module->data; node_child = module->data->child; assert_string_equal("bar-sub", node_child->name); node_parent = lys_parent(node_child); assert_string_equal("top", node_parent->name); }
static void test_lys_print_mem_jsons(void **state) { (void) state; /* unused */ const struct lys_module *module; LYS_INFORMAT yang_format = LYS_IN_YIN; const char *target = "grouping/gg"; char *result = NULL; int rc; module = lys_parse_mem(ctx, lys_module_a, yang_format); if (!module) { fail(); } rc = lys_print_mem(&result, module, LYS_OUT_JSON, NULL, 0, 0); if (rc) { fail(); } assert_string_equal(result_jsons, result); free(result); rc = lys_print_mem(&result, module, LYS_OUT_JSON, target, 0, 0); if (rc) { fail(); } assert_string_equal(result_jsons_grouping, result); free(result); }
static void test_lys_find_path(void **state) { (void) state; /* unused */ LYS_INFORMAT yang_format = LYS_IN_YIN; const struct lys_module *module; struct ly_set *set; module = lys_parse_mem(ctx, lys_module_a, yang_format); assert_ptr_not_equal(module, NULL); set = lys_find_path(module, NULL, "/x/*"); assert_ptr_not_equal(set, NULL); assert_int_equal(set->number, 5); ly_set_free(set); set = lys_find_path(module, NULL, "/x//*"); assert_ptr_not_equal(set, NULL); assert_int_equal(set->number, 6); ly_set_free(set); set = lys_find_path(module, NULL, "/x//."); assert_ptr_not_equal(set, NULL); assert_int_equal(set->number, 7); ly_set_free(set); }
static void test_lys_getnext(void **state) { (void) state; /* unused */ const struct lys_module *module; module = lys_parse_mem(ctx, lys_module_a, LYS_IN_YIN); if (!module) { fail(); } test_lys_getnext2(module); module = lys_parse_mem(ctx, lys_module_b, LYS_IN_YANG); if (!module) { fail(); } test_lys_getnext2(module); }
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); }
static void test_circle2(void **state) { struct ly_ctx *ctx = *state; const char *yang = "module features {\n" " namespace \"urn:features\";\n" " prefix f;\n" " feature a { if-feature \"a\"; }}"; assert_null(lys_parse_mem(ctx, yang, LYS_IN_YANG)); assert_int_equal(ly_vecode, LYVE_CIRC_FEATURES); }
static void test_circular_include(void **state) { struct ly_ctx *ctx = *state; const char *sch_yang = "module main-mod {" "namespace \"urn:cesnet:test:a\";" "prefix \"a\";" "include circ_inc1;}"; const char *sch_yin = "<module name=\"main-mod\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">" "<namespace uri=\"urn:cesnet:test:a\"/><prefix value=\"a\"/>" "<include module=\"circ_inc1\"/></module>"; ly_ctx_set_searchdir(ctx, SCHEMA_FOLDER_YIN); assert_ptr_equal(lys_parse_mem(ctx, sch_yin, LYS_IN_YIN), NULL); assert_int_equal(ly_vecode, LYVE_CIRC_INCLUDES); ly_ctx_set_searchdir(ctx, SCHEMA_FOLDER_YANG); assert_ptr_equal(lys_parse_mem(ctx, sch_yang, LYS_IN_YANG), NULL); assert_int_equal(ly_vecode, LYVE_CIRC_INCLUDES); }
static void test_lys_path(void **state) { (void) state; /* unused */ LYS_INFORMAT yang_format = LYS_IN_YIN; const struct lys_node *node; const struct lys_module *module; char *path; struct ly_set *set; const char *template; module = lys_parse_mem(ctx, lys_module_a, yang_format); assert_ptr_not_equal(module, NULL);
static void test_lys_print_fd_info(void **state) { (void) state; /* unused */ const struct lys_module *module; LYS_INFORMAT yang_format = LYS_IN_YIN; struct stat sb; char *target = "feature/foo"; char file_name[20]; char *result; int rc; int fd = -1; module = lys_parse_mem(ctx, lys_module_a, yang_format); if (!module) { goto error; } memset(file_name, 0, sizeof(file_name)); strncpy(file_name, TMP_TEMPLATE, sizeof(file_name)); fd = mkstemp(file_name); if (fd < 1) { goto error; } rc = lys_print_fd(fd, module, LYS_OUT_INFO, target, 0, 0); if (rc) { goto error; } if (fstat(fd, &sb) == -1 || !S_ISREG(sb.st_mode)) { goto error; } result = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); assert_string_equal(result_info, result); close(fd); unlink(file_name); return; error: if (fd > 0) { close(fd); unlink(file_name); } fail(); }
static void test_inval_expr5(void **state) { struct ly_ctx *ctx = *state; const char *yang = "module features {\n" " namespace \"urn:features\";\n" " prefix f;\n" " feature a;\n" " feature b;\n" " feature c { if-feature \"a and b\"; }}"; assert_null(lys_parse_mem(ctx, yang, LYS_IN_YANG)); assert_int_equal(ly_vecode, LYVE_INARG); }
static void test_lys_parse_mem(void **state) { (void) state; /* unused */ const struct lys_module *module; char *yang_folder = TESTS_DIR"/api/files"; LYS_INFORMAT yang_format = LYS_IN_YIN; module = NULL; ctx = NULL; ctx = ly_ctx_new(yang_folder, 0); module = lys_parse_mem(ctx, lys_module_a, yang_format); if (!module) { fail(); } assert_string_equal("a", module->name); module = NULL; module = lys_parse_mem(ctx, lys_module_a_with_typo, yang_format); if (module) { fail(); } module = NULL; module = lys_parse_mem(ctx, lys_module_b, LYS_IN_YANG); if (!module) { fail(); } assert_string_equal("b", module->name); module = NULL; ly_ctx_destroy(ctx, NULL); ctx = NULL; }
int generic_init(char *yang_file, char *yang_folder) { LYS_INFORMAT yang_format; char *schema = NULL; struct stat sb_schema; int fd = -1; if (!yang_file || !yang_folder) { goto error; } yang_format = LYS_IN_YIN; ctx = ly_ctx_new(yang_folder, 0); if (!ctx) { goto error; } fd = open(yang_file, O_RDONLY); if (fd == -1 || fstat(fd, &sb_schema) == -1 || !S_ISREG(sb_schema.st_mode)) { goto error; } schema = mmap(NULL, sb_schema.st_size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); if (!lys_parse_mem(ctx, schema, yang_format)) { goto error; } /* cleanup */ munmap(schema, sb_schema.st_size); return 0; error: if (schema) { munmap(schema, sb_schema.st_size); } if (fd != -1) { close(fd); } return -1; }
static void test_lys_parse_fd(void **state) { (void) state; /* unused */ const struct lys_module *module; char *yang_folder = TESTS_DIR"/api/files"; char *yin_file = TESTS_DIR"/api/files/a.yin"; char *yang_file = TESTS_DIR"/api/files/b.yang"; int fd = -1; ctx = ly_ctx_new(yang_folder, 0); fd = open(yin_file, O_RDONLY); if (fd == -1) { fail(); } module = lys_parse_fd(ctx, fd, LYS_IN_YIN); if (!module) { fail(); } close(fd); assert_string_equal("a", module->name); fd = open(yang_file, O_RDONLY); if (fd == -1) { fail(); } module = lys_parse_fd(ctx, fd, LYS_IN_YANG); if (!module) { fail(); } close(fd); assert_string_equal("b", module->name); module = lys_parse_mem(ctx, lys_module_a, LYS_IN_YIN); if (module) { fail(); } ly_ctx_destroy(ctx, NULL); ctx = NULL; }
static void test_lys_print_mem_yin(void **state) { (void) state; /* unused */ const struct lys_module *module; LYS_INFORMAT yang_format = LYS_IN_YIN; char *result = NULL; int rc; module = lys_parse_mem(ctx, lys_module_a, yang_format); if (!module) { fail(); } rc = lys_print_mem(&result, module, LYS_OUT_YIN, NULL, 0, 0); if (rc) { fail(); } assert_string_equal(result_yin, result); free(result); }
static void test_lys_parent(void **state) { (void) state; /* unused */ LYS_INFORMAT yang_format = LYS_IN_YIN; const struct lys_node *node; const struct lys_module *module; char *str = "node"; module = lys_parse_mem(ctx, lys_module_a, yang_format); if (!module) { fail(); } assert_string_equal("top", module->data->name); node = module->data; lys_set_private(node, str); assert_string_equal("node", node->priv); }
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."); }
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); }
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"); }
static void test_lys_print_file_yang(void **state) { (void) state; /* unused */ const struct lys_module *module; LYS_INFORMAT yang_format = LYS_IN_YIN; struct stat sb; char file_name[20]; char *result; FILE *f = NULL; int rc; int fd = -1; module = lys_parse_mem(ctx, lys_module_a, yang_format); if (!module) { goto error; } memset(file_name, 0, sizeof(file_name)); strncpy(file_name, TMP_TEMPLATE, sizeof(file_name)); fd = mkstemp(file_name); if (fd < 1) { goto error; } close(fd); f = (fopen(file_name,"r+")); if (f == NULL) { goto error; } rc = lys_print_file(f, module, LYS_OUT_YANG, NULL, 0, 0); if (rc) { goto error; } fclose(f); fd = open(file_name, O_RDONLY); if (fd == -1 || fstat(fd, &sb) == -1 || !S_ISREG(sb.st_mode)) { goto error; } result = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); assert_string_equal(result_yang, result); close(fd); unlink(file_name); return; error: if (f) fclose(f); if (fd > 0) { unlink(file_name); close(fd); } fail(); }
static void test_lys_print_file_jsons(void **state) { (void) state; /* unused */ const struct lys_module *module; LYS_INFORMAT yang_format = LYS_IN_YIN; struct stat sb; char *target = "grouping/gg"; char file_name1[20]; char file_name2[20]; char *result; FILE *f1 = NULL, *f2 = NULL; int rc; int fd1 = -1, fd2 = -1; module = lys_parse_mem(ctx, lys_module_a, yang_format); if (!module) { goto error; } memset(file_name1, 0, sizeof(file_name1)); memset(file_name2, 0, sizeof(file_name2)); strncpy(file_name1, TMP_TEMPLATE, sizeof(file_name1)); strncpy(file_name2, TMP_TEMPLATE, sizeof(file_name2)); fd1 = mkstemp(file_name1); fd2 = mkstemp(file_name2); if (fd1 < 1 || fd2 < 1) { goto error; } close(fd1); close(fd2); f1 = (fopen(file_name1,"r+")); f2 = (fopen(file_name2,"r+")); if (!f1 || !f2) { goto error; } /* module */ rc = lys_print_file(f1, module, LYS_OUT_JSON, NULL, 0, 0); if (rc) { goto error; } fclose(f1); f1 = NULL; fd1 = open(file_name1, O_RDONLY); if (fstat(fd1, &sb) == -1 || !S_ISREG(sb.st_mode)) { goto error; } result = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); assert_string_equal(result_jsons, result); /* grouping */ rc = lys_print_file(f2, module, LYS_OUT_JSON, target, 0, 0); if (rc) { goto error; } fclose(f2); f2 = NULL; fd2 = open(file_name2, O_RDONLY); if (fstat(fd2, &sb) == -1 || !S_ISREG(sb.st_mode)) { goto error; } result = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); assert_string_equal(result_jsons_grouping, result); close(fd1); close(fd2); unlink(file_name1); unlink(file_name2); return; error: if (f1) fclose(f1); if (fd1 > 0) { unlink(file_name1); close(fd1); } if (f2) fclose(f2); if (fd2 > 0) { unlink(file_name2); close(fd2); } fail(); }
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); }