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; }
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_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 int setup_f(void **state) { struct state *st; const char *schema = TESTS_DIR"/data/files/all.yin"; const char *schemadev = TESTS_DIR"/data/files/all-dev.yin"; (*state) = st = calloc(1, sizeof *st); if (!st) { fprintf(stderr, "Memory allocation error"); return -1; } /* libyang context */ st->ctx = ly_ctx_new(TESTS_DIR"/data/files"); if (!st->ctx) { fprintf(stderr, "Failed to create context.\n"); goto error; } /* schema */ st->mod = lys_parse_path(st->ctx, schema, LYS_IN_YIN); if (!st->mod) { fprintf(stderr, "Failed to load data model \"%s\".\n", schema); goto error; } lys_features_enable(st->mod, "feat2"); lys_features_enable(st->mod, "*"); st->mod = lys_parse_path(st->ctx, schemadev, LYS_IN_YIN); if (!st->mod) { fprintf(stderr, "Failed to load data model \"%s\".\n", schemadev); goto error; } return 0; error: ly_ctx_destroy(st->ctx, NULL); free(st); (*state) = NULL; return -1; }
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_fullset(void **state) { struct ly_ctx *ctx = *state; const struct lys_module *mod; char *buf = NULL; const char *tree_alldisabled = "module: features\n" " +--rw lst* [id] {not a}?\n" " | +--rw id string\n" " +--rw (ch)? {not (a and b)}?\n" " | +--:(ch3)\n" " | +--rw ch3? string\n" " +--rw axml? anyxml {not (a or b)}?\n"; const char *tree_a = "module: features\n" " +--rw grp? string\n" " +--rw cont! {a}?\n" " +--rw ll* string {a or b}?\n" " +--rw (ch)? {not (a and b)}?\n" " +--:(ch1) {a}?\n" " | +--rw ch1? string\n" " +--:(ch3)\n" " +--rw ch3? string\n"; const char *tree_ab = "module: features\n" " +--rw grp? string\n" " +--rw cont! {a}?\n" " +--rw lf? string {a and b}?\n" " +--rw ll* string {a or b}?\n"; const char *tree_abaa = "module: features\n" " +--rw grp? string\n" " +--rw cont! {a}?\n" " | +--rw aug? string\n" " +--rw lf? string {a and b}?\n" " +--rw ll* string {a or b}?\n" "rpcs:\n" " +---x rpc1 {aa}?\n" "notifications:\n" " +---n notif1 {aa}?\n"; const char *tree_b = "module: features\n" " +--rw ll* string {a or b}?\n" " +--rw lst* [id] {not a}?\n" " | +--rw id string\n" " +--rw (ch)? {not (a and b)}?\n" " +--:(ch2) {b}?\n" " | +--rw ch2? string\n" " +--:(ch3)\n" " +--rw ch3? string\n"; mod = ly_ctx_load_module(ctx, "features", NULL); assert_non_null(mod); lys_print_mem(&buf, mod, LYS_OUT_TREE, NULL); assert_non_null(buf); assert_string_equal(buf, tree_alldisabled); free(buf); buf = NULL; lys_features_enable(mod, "a"); lys_print_mem(&buf, mod, LYS_OUT_TREE, NULL); assert_non_null(buf); assert_string_equal(buf, tree_a); free(buf); buf = NULL; lys_features_enable(mod, "b"); lys_print_mem(&buf, mod, LYS_OUT_TREE, NULL); assert_non_null(buf); assert_string_equal(buf, tree_ab); free(buf); buf = NULL; lys_features_enable(mod, "aa"); lys_print_mem(&buf, mod, LYS_OUT_TREE, NULL); assert_non_null(buf); assert_string_equal(buf, tree_abaa); free(buf); buf = NULL; lys_features_disable(mod, "a"); /* aa is also disabled by disabling a */ lys_print_mem(&buf, mod, LYS_OUT_TREE, NULL); assert_non_null(buf); assert_string_equal(buf, tree_b); free(buf); buf = NULL; }
/** * @brief Initializes libyang ctx with all schemas installed for specified module in sysrepo. */ static int srcfg_ly_init(struct ly_ctx **ly_ctx, const char *module_name) { DIR *dp = NULL; struct dirent *ep = NULL; char *delim = NULL; char schema_filename[PATH_MAX] = { 0, }; const struct lys_module *module = NULL; CHECK_NULL_ARG2(ly_ctx, module_name); *ly_ctx = ly_ctx_new(srcfg_schema_search_dir); if (NULL == *ly_ctx) { SR_LOG_ERR("Unable to initialize libyang context: %s", ly_errmsg()); return SR_ERR_INTERNAL; } ly_set_log_clb(srcfg_ly_log_cb, 1); /* iterate over all files in the directory with schemas */ dp = opendir(srcfg_schema_search_dir); if (NULL == dp) { SR_LOG_ERR("Failed to open the schema directory: %s.", sr_strerror_safe(errno)); return SR_ERR_INTERNAL; } while (NULL != (ep = readdir(dp))) { /* test file extension */ LYS_INFORMAT fmt = LYS_IN_UNKNOWN; if (sr_str_ends_with(ep->d_name, SR_SCHEMA_YIN_FILE_EXT)) { fmt = LYS_IN_YIN; } else if (sr_str_ends_with(ep->d_name, SR_SCHEMA_YANG_FILE_EXT)) { fmt = LYS_IN_YANG; } if (fmt != LYS_IN_UNKNOWN) { /* strip extension and revision */ strcpy(schema_filename, ep->d_name); delim = strrchr(schema_filename, '.'); assert(delim); *delim = '\0'; delim = strrchr(schema_filename, '@'); if (delim) { *delim = '\0'; } /* TODO install all revisions and dependencies of the specified module, but not more */ #if 0 /* XXX install all schemas until we can resolve all dependencies */ if (strcmp(schema_filename, module_name) == 0) { #endif /* construct full file path */ snprintf(schema_filename, PATH_MAX, "%s%s", srcfg_schema_search_dir, ep->d_name); /* load the schema into the context */ SR_LOG_DBG("Loading module schema: '%s'.", schema_filename); module = lys_parse_path(*ly_ctx, schema_filename, fmt); if (NULL == module) { continue; } for (uint8_t i = 0; i < module->features_size; i++) { lys_features_enable(module, module->features[i].name); } #if 0 } #endif } } closedir(dp); return SR_ERR_OK; }
static void TEST_NOTIFICATION(void **state) { struct state *st = (*state); const int schemas_fail[] = {TEST_SCHEMA_LOAD_FAIL}; const int data_files_fail[] = {TEST_DATA_FILE_LOAD_FAIL}; char buf[1024]; LYS_INFORMAT schema_format = LYS_IN_YANG; const struct lys_module *mod; int i, j, ret; for (i = 0; i < 2; ++i) { for (j = 0; j < TEST_SCHEMA_COUNT; ++j) { sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/mod%d.%s", j + 1, (schema_format == LYS_IN_YANG ? "yang" : "yin")); mod = lys_parse_path(st->ctx, buf, schema_format); if (schemas_fail[j]) { assert_ptr_equal(mod, NULL); } else { assert_ptr_not_equal(mod, NULL); lys_features_enable(mod, "*"); } } for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) { sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1); st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_NOTIF, NULL); if (data_files_fail[j]) { assert_ptr_equal(st->node, NULL); } else { assert_ptr_not_equal(st->node, NULL); } lyd_free_withsiblings(st->node); st->node = NULL; } if (schema_format == LYS_IN_YANG) { /* convert the modules */ for (j = 0; j < TEST_SCHEMA_COUNT; ++j) { sprintf(buf, BUILD_DIR "/yang2yin " TESTS_DIR "/conformance/" TEST_DIR "/mod%d.yang " TESTS_DIR "/conformance/" TEST_DIR "/mod%d.yin", j + 1, j + 1); ret = system(buf); if (ret == -1) { fprintf(stderr, "system() failed (%s).\n", strerror(errno)); fail(); } else if (WEXITSTATUS(ret) != 0) { fprintf(stderr, "Executing command \"%s\" finished with %d.\n", buf, WEXITSTATUS(ret)); fail(); } } schema_format = LYS_IN_YIN; ly_ctx_destroy(st->ctx, NULL); st->ctx = ly_ctx_new(TESTS_DIR "/conformance/" TEST_DIR); if (!st->ctx) { fprintf(stderr, "Failed to create context.\n"); fail(); } } else { /* remove the modules */ for (j = 0; j < TEST_SCHEMA_COUNT; ++j) { sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/mod%d.yin", j + 1); if (unlink(buf)) { fprintf(stderr, "unlink() on \"%s\" failed (%s).\n", buf, strerror(errno)); } } } } }