void Session::session_switch_ds(sr_datastore_t ds) { int ret = sr_session_switch_ds(_sess, ds); if (ret != SR_ERR_OK) { throw_exception(ret); } }
static void cl_get_changes_create_test(void **state) { sr_conn_ctx_t *conn = *state; assert_non_null(conn); sr_session_ctx_t *session = NULL; sr_subscription_ctx_t *subscription = NULL; changes_t changes = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cv = PTHREAD_COND_INITIALIZER, 0}; struct timespec ts; sr_val_t *val = NULL; const char *xpath = NULL; int rc = SR_ERR_OK; xpath = "/example-module:container/list[key1='abc'][key2='def']"; /* start session */ rc = sr_session_start(conn, SR_DS_CANDIDATE, SR_SESS_DEFAULT, &session); assert_int_equal(rc, SR_ERR_OK); rc = sr_module_change_subscribe(session, "example-module", list_changes_cb, &changes, 0, SR_SUBSCR_DEFAULT, &subscription); assert_int_equal(rc, SR_ERR_OK); /* check the list presence in candidate */ rc = sr_get_item(session, xpath, &val); assert_int_equal(rc, SR_ERR_NOT_FOUND); /* create the list instance */ rc = sr_set_item(session, xpath, NULL, SR_EDIT_DEFAULT); assert_int_equal(rc, SR_ERR_OK); /* save changes to running */ pthread_mutex_lock(&changes.mutex); rc = sr_commit(session); assert_int_equal(rc, SR_ERR_OK); sr_clock_get_time(CLOCK_REALTIME, &ts); ts.tv_sec += COND_WAIT_SEC; pthread_cond_timedwait(&changes.cv, &changes.mutex, &ts); assert_int_equal(changes.cnt, 3); assert_int_equal(changes.oper[0], SR_OP_CREATED); assert_non_null(changes.new_values[0]); assert_null(changes.old_values[0]); assert_string_equal(xpath, changes.new_values[0]->xpath); assert_int_equal(changes.oper[1], SR_OP_CREATED); assert_non_null(changes.new_values[1]); assert_null(changes.old_values[1]); assert_string_equal("/example-module:container/list[key1='abc'][key2='def']/key1", changes.new_values[1]->xpath); assert_int_equal(changes.oper[2], SR_OP_CREATED); assert_non_null(changes.new_values[2]); assert_null(changes.old_values[2]); assert_string_equal("/example-module:container/list[key1='abc'][key2='def']/key2", changes.new_values[2]->xpath); for (size_t i = 0; i < changes.cnt; i++) { sr_free_val(changes.new_values[i]); sr_free_val(changes.old_values[i]); } pthread_mutex_unlock(&changes.mutex); rc = sr_unsubscribe(NULL, subscription); assert_int_equal(rc, SR_ERR_OK); rc = sr_session_stop(session); assert_int_equal(rc, SR_ERR_OK); } static void cl_get_changes_modified_test(void **state) { sr_conn_ctx_t *conn = *state; assert_non_null(conn); sr_session_ctx_t *session = NULL; sr_subscription_ctx_t *subscription = NULL; changes_t changes = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cv = PTHREAD_COND_INITIALIZER, 0}; struct timespec ts; sr_val_t *val = NULL; const char *xpath = NULL; int rc = SR_ERR_OK; xpath = "/example-module:container/list[key1='key1'][key2='key2']/leaf"; /* start session */ rc = sr_session_start(conn, SR_DS_CANDIDATE, SR_SESS_DEFAULT, &session); assert_int_equal(rc, SR_ERR_OK); rc = sr_module_change_subscribe(session, "example-module", list_changes_cb, &changes, 0, SR_SUBSCR_DEFAULT, &subscription); assert_int_equal(rc, SR_ERR_OK); /* check the list presence in candidate */ rc = sr_get_item(session, xpath, &val); assert_int_equal(rc, SR_ERR_OK); sr_val_t new_val = {0}; new_val.type = SR_STRING_T; new_val.data.string_val = "abcdef"; /* create the list instance */ rc = sr_set_item(session, xpath, &new_val, SR_EDIT_DEFAULT); assert_int_equal(rc, SR_ERR_OK); /* save changes to running */ pthread_mutex_lock(&changes.mutex); rc = sr_commit(session); assert_int_equal(rc, SR_ERR_OK); sr_clock_get_time(CLOCK_REALTIME, &ts); ts.tv_sec += COND_WAIT_SEC; pthread_cond_timedwait(&changes.cv, &changes.mutex, &ts); assert_int_equal(changes.cnt, 1); assert_int_equal(changes.oper[0], SR_OP_MODIFIED); assert_non_null(changes.new_values[0]); assert_non_null(changes.old_values[0]); assert_string_equal(val->data.string_val, changes.old_values[0]->data.string_val); assert_string_equal(new_val.data.string_val, changes.new_values[0]->data.string_val); for (size_t i = 0; i < changes.cnt; i++) { sr_free_val(changes.new_values[i]); sr_free_val(changes.old_values[i]); } sr_free_val(val); pthread_mutex_unlock(&changes.mutex); rc = sr_unsubscribe(NULL, subscription); assert_int_equal(rc, SR_ERR_OK); rc = sr_session_stop(session); assert_int_equal(rc, SR_ERR_OK); } static void cl_get_changes_deleted_test(void **state) { sr_conn_ctx_t *conn = *state; assert_non_null(conn); sr_session_ctx_t *session = NULL; sr_subscription_ctx_t *subscription = NULL; changes_t changes = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cv = PTHREAD_COND_INITIALIZER, 0}; struct timespec ts; sr_val_t *val = NULL; const char *xpath = NULL; int rc = SR_ERR_OK; xpath = "/example-module:container"; /* start session */ rc = sr_session_start(conn, SR_DS_CANDIDATE, SR_SESS_DEFAULT, &session); assert_int_equal(rc, SR_ERR_OK); rc = sr_module_change_subscribe(session, "example-module", list_changes_cb, &changes, 0, SR_SUBSCR_DEFAULT, &subscription); assert_int_equal(rc, SR_ERR_OK); /* check the list presence in candidate */ rc = sr_get_item(session, xpath, &val); assert_int_equal(rc, SR_ERR_OK); sr_free_val(val); /* delete container */ rc = sr_delete_item(session, xpath, SR_EDIT_DEFAULT); assert_int_equal(rc, SR_ERR_OK); /* save changes to running */ pthread_mutex_lock(&changes.mutex); rc = sr_commit(session); assert_int_equal(rc, SR_ERR_OK); sr_clock_get_time(CLOCK_REALTIME, &ts); ts.tv_sec += COND_WAIT_SEC; pthread_cond_timedwait(&changes.cv, &changes.mutex, &ts); assert_int_equal(changes.cnt, 5); assert_int_equal(changes.oper[0], SR_OP_DELETED); assert_null(changes.new_values[0]); assert_non_null(changes.old_values[0]); assert_string_equal(xpath, changes.old_values[0]->xpath); assert_int_equal(changes.oper[1], SR_OP_DELETED); assert_null(changes.new_values[1]); assert_non_null(changes.old_values[1]); assert_string_equal("/example-module:container/list[key1='key1'][key2='key2']", changes.old_values[1]->xpath); assert_int_equal(changes.oper[2], SR_OP_DELETED); assert_null(changes.new_values[2]); assert_non_null(changes.old_values[2]); assert_string_equal("/example-module:container/list[key1='key1'][key2='key2']/key1", changes.old_values[2]->xpath); assert_int_equal(changes.oper[3], SR_OP_DELETED); assert_null(changes.new_values[3]); assert_non_null(changes.old_values[3]); assert_string_equal("/example-module:container/list[key1='key1'][key2='key2']/key2", changes.old_values[3]->xpath); assert_int_equal(changes.oper[4], SR_OP_DELETED); assert_null(changes.new_values[4]); assert_non_null(changes.old_values[4]); assert_string_equal("/example-module:container/list[key1='key1'][key2='key2']/leaf", changes.old_values[4]->xpath); for (size_t i = 0; i < changes.cnt; i++) { sr_free_val(changes.new_values[i]); sr_free_val(changes.old_values[i]); } pthread_mutex_unlock(&changes.mutex); rc = sr_unsubscribe(NULL, subscription); assert_int_equal(rc, SR_ERR_OK); rc = sr_session_stop(session); assert_int_equal(rc, SR_ERR_OK); } static void cl_get_changes_moved_test(void **state) { sr_conn_ctx_t *conn = *state; assert_non_null(conn); sr_session_ctx_t *session = NULL; sr_subscription_ctx_t *subscription = NULL; changes_t changes = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cv = PTHREAD_COND_INITIALIZER, 0}; struct timespec ts; const char *xpath = NULL; int rc = SR_ERR_OK; xpath = "/test-module:ordered-numbers"; /* start session */ rc = sr_session_start(conn, SR_DS_STARTUP, SR_SESS_DEFAULT, &session); assert_int_equal(rc, SR_ERR_OK); sr_val_t v = {0}; v.type = SR_UINT8_T; v.data.uint8_val = 1; /* create user ordered leaf-list instance */ rc = sr_set_item(session, xpath, &v, SR_EDIT_STRICT); assert_int_equal(rc, SR_ERR_OK); v.data.uint8_val = 2; rc = sr_set_item(session, xpath, &v, SR_EDIT_STRICT); assert_int_equal(rc, SR_ERR_OK); v.data.uint8_val = 3; rc = sr_set_item(session, xpath, &v, SR_EDIT_STRICT); assert_int_equal(rc, SR_ERR_OK); /* save changes to running */ rc = sr_commit(session); assert_int_equal(rc, SR_ERR_OK); rc = sr_session_switch_ds(session, SR_DS_CANDIDATE); assert_int_equal(rc, SR_ERR_OK); rc = sr_module_change_subscribe(session, "test-module", list_changes_cb, &changes, 0, SR_SUBSCR_DEFAULT, &subscription); assert_int_equal(rc, SR_ERR_OK); /* move leaf-list */ rc = sr_move_item(session, "/test-module:ordered-numbers[.='3']", SR_MOVE_AFTER, "/test-module:ordered-numbers[.='1']"); assert_int_equal(rc, SR_ERR_OK); /* save changes to running */ pthread_mutex_lock(&changes.mutex); rc = sr_commit(session); assert_int_equal(rc, SR_ERR_OK); sr_clock_get_time(CLOCK_REALTIME, &ts); ts.tv_sec += COND_WAIT_SEC; pthread_cond_timedwait(&changes.cv, &changes.mutex, &ts); assert_int_equal(changes.cnt, 1); assert_int_equal(changes.oper[0], SR_OP_MOVED); assert_non_null(changes.new_values[0]); assert_non_null(changes.old_values[0]); assert_string_equal(xpath, changes.old_values[0]->xpath); assert_int_equal(changes.new_values[0]->data.uint8_val, 2); assert_int_equal(changes.old_values[0]->data.uint8_val, 3); for (size_t i = 0; i < changes.cnt; i++) { sr_free_val(changes.new_values[i]); sr_free_val(changes.old_values[i]); } pthread_mutex_unlock(&changes.mutex); rc = sr_unsubscribe(NULL, subscription); assert_int_equal(rc, SR_ERR_OK); rc = sr_session_stop(session); assert_int_equal(rc, SR_ERR_OK); } typedef struct priority_s { int count; int cb[3]; }priority_t; static int priority_zero_cb(sr_session_ctx_t *session, const char *module_name, sr_notif_event_t ev, void *private_ctx) { priority_t *pr = (priority_t *) private_ctx; pr->cb[pr->count] = 0; pr->count++; return SR_ERR_OK; }
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); }