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 int teardown_ctx(void **state) { ly_ctx_destroy(*state, NULL); return 0; }
static int setup_f(void **state) { struct state *st; const char *schemafile = TESTS_DIR"/data/files/defaults.yin"; (*state) = st = calloc(1, sizeof *st); if (!st) { fprintf(stderr, "Memory allocation error"); return -1; } /* libyang context */ st->ctx = ly_ctx_new(NULL, 0); if (!st->ctx) { fprintf(stderr, "Failed to create context.\n"); goto error; } /* schemas */ st->mod = lys_parse_path(st->ctx, schemafile, LYS_IN_YIN); if (!st->mod) { fprintf(stderr, "Failed to load data model \"%s\".\n", schemafile); goto error; } return 0; error: ly_ctx_destroy(st->ctx, NULL); free(st); (*state) = NULL; return -1; }
API struct ly_ctx * ly_ctx_new(const char *search_dir) { struct ly_ctx *ctx; char *cwd; ctx = calloc(1, sizeof *ctx); if (!ctx) { LOGMEM; return NULL; } /* dictionary */ lydict_init(&ctx->dict); /* models list */ ctx->models.list = calloc(16, sizeof *ctx->models.list); ctx->models.used = 0; ctx->models.size = 16; if (search_dir) { cwd = get_current_dir_name(); if (chdir(search_dir)) { LOGERR(LY_ESYS, "Unable to use search directory \"%s\" (%s)", search_dir, strerror(errno)); free(cwd); ly_ctx_destroy(ctx); return NULL; } ctx->models.search_path = get_current_dir_name(); chdir(cwd); free(cwd); } return ctx; }
static int setup_ctx(void **state) { struct state *st; (*state) = st = calloc(1, sizeof *st); if (!st) { fprintf(stderr, "Memory allocation error"); return -1; } /* libyang context */ st->ctx = ly_ctx_new(NULL, 0); if (!st->ctx) { fprintf(stderr, "Failed to create context.\n"); goto error; } return 0; error: ly_ctx_destroy(st->ctx, NULL); free(st); (*state) = NULL; return -1; }
int cmd_clear(const char *UNUSED(arg)) { ly_ctx_destroy(ctx); ctx = ly_ctx_new(search_path); return 0; }
static int teardown_f(void **state) { struct state *st = (*state); lyd_free(st->dt1); lyd_free(st->dt2); lyd_free(st->dt3); ly_ctx_destroy(st->ctx1, NULL); ly_ctx_destroy(st->ctx2, NULL); free(st); (*state) = NULL; return 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; }
static int teardown_ctx(void **state) { ly_ctx_destroy((struct ly_ctx *)(*state), NULL); (*state) = NULL; return 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); }
void delete_nacm_config(test_nacm_cfg_t *nacm_config) { if (NULL != nacm_config) { lyd_free_withsiblings(nacm_config->root); ly_ctx_destroy(nacm_config->ly_ctx, NULL); free(nacm_config); } }
static int teardown_f(void **state) { (void) state; /* unused */ if (ctx) ly_ctx_destroy(ctx, NULL); return 0; }
static int teardown_f(void **state) { (void) state; /* unused */ lyd_free(root); ly_ctx_destroy(ctx); return 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); }
static void test_ctx_new_destroy(void **state) { (void) state; /* unused */ ctx = ly_ctx_new(NULL); if (!ctx) { fail(); } ly_ctx_destroy(ctx); }
static int teardown_f(void **state) { struct state *st = (*state); lyd_free_withsiblings(st->node); ly_ctx_destroy(st->ctx, NULL); free(st); (*state) = NULL; return 0; }
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; }
/** * @brief Performs the --import operation. */ static int srcfg_import_operation(const char *module_name, srcfg_datastore_t datastore, const char *filepath, LYD_FORMAT format, bool permanent) { int rc = SR_ERR_INTERNAL, ret = 0; struct ly_ctx *ly_ctx = NULL; int fd_in = STDIN_FILENO; CHECK_NULL_ARG(module_name); /* init libyang context */ ret = srcfg_ly_init(&ly_ctx, module_name); CHECK_RC_MSG_GOTO(ret, fail, "Failed to initialize libyang context."); if (filepath) { /* try to open the input file */ fd_in = open(filepath, O_RDONLY); CHECK_NOT_MINUS1_LOG_GOTO(fd_in, rc, SR_ERR_INTERNAL, fail, "Unable to open the input file '%s': %s.", filepath, sr_strerror_safe(errno)); } else { /* read configuration from stdin */ printf("Please enter the new configuration:\n"); } /* import datastore data */ ret = srcfg_import_datastore(ly_ctx, fd_in, module_name, datastore, format, permanent); if (SR_ERR_OK != ret) { goto fail; } rc = SR_ERR_OK; printf("The new configuration was successfully applied.\n"); goto cleanup; fail: printf("Errors were encountered during importing. Cancelling the operation.\n"); cleanup: if (STDIN_FILENO != fd_in && -1 != fd_in) { close(fd_in); } if (ly_ctx) { ly_ctx_destroy(ly_ctx, NULL); } return rc; }
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 int teardown_f(void **state) { struct state *st = (*state); lyd_free_withsiblings(st->dt); lyd_free_withsiblings(st->rpc_act); ly_ctx_destroy(st->ctx, NULL); if (st->fd > 0) { close(st->fd); } free(st->str1); free(st->str2); free(st); (*state) = NULL; return 0; }
/** * @brief Performs the --export operation. */ static int srcfg_export_operation(const char *module_name, const char *filepath, LYD_FORMAT format) { int rc = SR_ERR_INTERNAL, ret = 0; struct ly_ctx *ly_ctx = NULL; int fd_out = STDOUT_FILENO; CHECK_NULL_ARG(module_name); /* init libyang context */ ret = srcfg_ly_init(&ly_ctx, module_name); CHECK_RC_MSG_GOTO(ret, fail, "Failed to initialize libyang context."); /* try to open/create the output file if needed */ if (filepath) { fd_out = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0666); CHECK_NOT_MINUS1_LOG_GOTO(fd_out, rc, SR_ERR_INTERNAL, fail, "Unable to open the output file '%s': %s.", filepath, sr_strerror_safe(errno)); } /* export diatastore data */ ret = srcfg_export_datastore(ly_ctx, fd_out, module_name, format); if (SR_ERR_OK != ret) { goto fail; } rc = SR_ERR_OK; if (filepath) { /* do not clutter the output sent to stdout */ printf("The configuration was successfully exported.\n"); } goto cleanup; fail: printf("Errors were encountered during exporting. Cancelling the operation.\n"); cleanup: if (STDOUT_FILENO != fd_out && -1 != fd_out) { close(fd_out); } if (ly_ctx) { ly_ctx_destroy(ly_ctx, NULL); } return rc; }
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 int teardown_sessions(void **state) { (void)state; nc_server_destroy(); ly_ctx_destroy(server_session->ctx, NULL); close(server_session->ti.fd.in); pthread_mutex_destroy(server_session->ti_lock); free(server_session->ti_lock); free(server_session); close(client_session->ti.fd.in); pthread_mutex_destroy(client_session->ti_lock); free(client_session->ti_lock); free(client_session); return 0; }
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_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; }
API struct ly_ctx * ly_ctx_new(const char *search_dir) { struct ly_ctx *ctx; char *cwd; ctx = calloc(1, sizeof *ctx); if (!ctx) { LOGMEM; return NULL; } /* dictionary */ lydict_init(&ctx->dict); /* models list */ ctx->models.list = calloc(16, sizeof *ctx->models.list); if (!ctx->models.list) { LOGMEM; free(ctx); return NULL; } ctx->models.used = 0; ctx->models.size = 16; if (search_dir) { cwd = get_current_dir_name(); if (chdir(search_dir)) { LOGERR(LY_ESYS, "Unable to use search directory \"%s\" (%s)", search_dir, strerror(errno)); free(cwd); ly_ctx_destroy(ctx); return NULL; } ctx->models.search_path = get_current_dir_name(); chdir(cwd); free(cwd); } ctx->models.module_set_id = 1; /* load ietf-inet-types */ ctx->models.list[0] = (struct lys_module *)lys_parse_data(ctx, (char *)ietf_inet_types_2013_07_15_yin, LYS_IN_YIN); if (!ctx->models.list[0]) { ly_ctx_destroy(ctx); return NULL; } /* load ietf-yang-types */ ctx->models.list[1] = (struct lys_module *)lys_parse_data(ctx, (char *)ietf_yang_types_2013_07_15_yin, LYS_IN_YIN); if (!ctx->models.list[1]) { ly_ctx_destroy(ctx); return NULL; } /* load ietf-yang-library */ ctx->models.list[2] = (struct lys_module *)lys_parse_data(ctx, (char *)ietf_yang_library_2015_07_03_yin, LYS_IN_YIN); if (!ctx->models.list[2]) { ly_ctx_destroy(ctx); return NULL; } return ctx; }
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)); } } } } }
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); }
/** * @brief Performs the program's main operation: lets user to edit specified module and datastore * using the preferred editor. New configuration is validated before it is saved. */ static int srcfg_edit_operation(const char *module_name, srcfg_datastore_t datastore, LYD_FORMAT format, const char *editor, bool keep, bool permanent) { int rc = SR_ERR_INTERNAL, ret = 0; struct ly_ctx *ly_ctx = NULL; char tmpfile_path[PATH_MAX] = { 0, }, cmd[2*PATH_MAX+4] = { 0, }; char *dest = NULL; int fd_tmp = -1; bool locked = false; pid_t child_pid = -1; int child_status = 0, first_attempt = 1; CHECK_NULL_ARG2(module_name, editor); /* init libyang context */ ret = srcfg_ly_init(&ly_ctx, module_name); CHECK_RC_MSG_GOTO(ret, fail, "Failed to initialize libyang context."); /* lock module for the time of editing if requested */ if (keep) { rc = sr_lock_module(srcfg_session, module_name); if (SR_ERR_OK != rc) { srcfg_report_error(rc); goto fail; } locked = true; } /* export: */ /* create temporary file for datastore editing */ mode_t orig_umask = umask(S_IRWXO|S_IRWXG); snprintf(tmpfile_path, PATH_MAX, "/tmp/srcfg.%s%s.XXXXXX", module_name, datastore == SRCFG_STORE_RUNNING ? SR_RUNNING_FILE_EXT : SR_STARTUP_FILE_EXT); fd_tmp = mkstemp(tmpfile_path); umask(orig_umask); CHECK_NOT_MINUS1_MSG_GOTO(fd_tmp, rc, SR_ERR_INTERNAL, fail, "Failed to create temporary file for datastore editing."); /* export datastore content into a temporary file */ ret = srcfg_export_datastore(ly_ctx, fd_tmp, module_name, format); if (SR_ERR_OK != ret) { goto fail; } close(fd_tmp); fd_tmp = -1; edit: if (!first_attempt) { if (!srcfg_prompt("Unable to apply the changes. " "Would you like to continue editing the configuration?", "y", "n")) { goto save; } } first_attempt = 0; /* Open the temporary file inside the preferred text editor */ child_pid = fork(); if (0 <= child_pid) { /* fork succeeded */ if (0 == child_pid) { /* child process */ /* Open text editor */ return execlp(editor, editor, tmpfile_path, (char *)NULL); } else { /* parent process */ /* wait for the child to exit */ ret = waitpid(child_pid, &child_status, 0); if (child_pid != ret) { SR_LOG_ERR_MSG("Unable to wait for the editor to exit."); goto save; } /* Check return status from the child */ if (!WIFEXITED(child_status) || 0 != WEXITSTATUS(child_status)) { SR_LOG_ERR_MSG("Text editor didn't start/terminate properly."); goto save; } } } else /* fork failed */ { SR_LOG_ERR_MSG("Failed to fork a new process for the text editor."); goto fail; } /* import: */ /* re-open temporary file */ fd_tmp = open(tmpfile_path, O_RDONLY); CHECK_NOT_MINUS1_MSG_GOTO(fd_tmp, rc, SR_ERR_INTERNAL, save, "Unable to re-open the configuration after it was edited using the text editor."); /* import temporary file content into the datastore */ ret = srcfg_import_datastore(ly_ctx, fd_tmp, module_name, datastore, format, permanent); close(fd_tmp); fd_tmp = -1; if (SR_ERR_OK != ret) { goto edit; } /* operation succeeded */ rc = SR_ERR_OK; printf("The new configuration was successfully applied.\n"); goto cleanup; save: /* save to a (ordinary) file if requested */ if (srcfg_prompt("Failed to commit the new configuration. " "Would you like to save your changes to a file?", "y", "n")) { /* copy whatever is in the temporary file right now */ snprintf(cmd, PATH_MAX + 4, "cp %s ", tmpfile_path); dest = cmd + strlen(cmd); do { printf("Enter a file path: "); ret = scanf("%" PATH_MAX_STR "s", dest); if (EOF == ret) { SR_LOG_ERR_MSG("Scanf failed: end of the input stream."); goto discard; } sr_str_trim(dest); ret = system(cmd); if (0 != ret) { printf("Unable to save the configuration to '%s'. ", dest); if (!srcfg_prompt("Retry?", "y", "n")) { goto discard; } } } while (0 != ret); printf("Your changes have been saved to '%s'. " "You may try to apply them again using the import operation.\n", dest); goto cleanup; } discard: printf("Your changes were discarded.\n"); goto cleanup; fail: printf("Errors were encountered during editing. Cancelling the operation.\n"); cleanup: if (-1 != fd_tmp) { close(fd_tmp); } if ('\0' != tmpfile_path[0]) { unlink(tmpfile_path); } if (locked) { rc = sr_unlock_module(srcfg_session, module_name); if (SR_ERR_OK != rc) { srcfg_report_error(rc); } } if (ly_ctx) { ly_ctx_destroy(ly_ctx, NULL); } return rc; }