static void sr_print_val_test(void **state) { sr_val_t *value = NULL; /* empty tree */ sr_test_all_printers(value, NULL); assert_int_equal(SR_ERR_OK, sr_new_val(XPATH1, &value)); value->type = SR_UINT32_T; value->data.uint32_val = 123; sr_test_all_printers(value, XPATH1" = 123\n"); sr_free_val(value); assert_int_equal(SR_ERR_OK, sr_new_val(XPATH1, &value)); value->type = SR_BOOL_T; value->data.bool_val = true; sr_test_all_printers(value, XPATH1" = true\n"); sr_free_val(value); assert_int_equal(SR_ERR_OK, sr_new_val(XPATH3, &value)); value->type = SR_LIST_T; sr_test_all_printers(value, XPATH3" (list instance)\n"); sr_free_val(value); assert_int_equal(SR_ERR_OK, sr_new_val(XPATH4, &value)); value->type = SR_CONTAINER_T; sr_test_all_printers(value, XPATH4" (container)\n"); sr_free_val(value); assert_int_equal(SR_ERR_OK, sr_new_val(XPATH2, &value)); sr_val_set_str_data(value, SR_STRING_T, "192.168.1.1"); sr_test_all_printers(value, XPATH2" = 192.168.1.1\n"); sr_free_val(value); }
int np_server_cert_clb(const char *name, void *UNUSED(user_data), char **UNUSED(cert_path), char **cert_data, char **privkey_path, char **UNUSED(privkey_data), int *UNUSED(privkey_data_rsa)) { int ret; char *path, *key_begin, *key_end, quot; sr_val_t *sr_cert; ret = asprintf(&path, "/ietf-keystore:keystore/private-keys/private-key/certificate-chains/" "certificate-chain[name='%s']/certificate[1]", name); if (ret == -1) { EMEM; return 1; } if (np2srv.sr_sess.ds != SR_DS_RUNNING) { if (np2srv_sr_session_switch_ds(np2srv.sr_sess.srs, SR_DS_RUNNING, NULL)) { free(path); return 1; } np2srv.sr_sess.ds = SR_DS_RUNNING; } if (np2srv_sr_get_item(np2srv.sr_sess.srs, path, &sr_cert, NULL)) { free(path); return 1; } free(path); /* get the private key name */ key_begin = strstr(sr_cert->xpath, "private-key[name="); if (!key_begin) { EINT; sr_free_val(sr_cert); return 1; } key_begin += 17; quot = key_begin[0]; ++key_begin; key_end = strchr(key_begin, quot); if (!key_end) { EMEM; sr_free_val(sr_cert); return 1; } ret = asprintf(privkey_path, NP2SRV_KEYSTORED_DIR "/%.*s.pem", (int)(key_end - key_begin), key_begin); *cert_data = strdup(sr_cert->data.binary_val); sr_free_val(sr_cert); if ((ret == -1) || !*cert_data) { EMEM; return 1; } return 0; }
static void perf_get_item_test(void **state) { sr_conn_ctx_t *conn = *state; assert_non_null(conn); sr_session_ctx_t *session = NULL; sr_val_t *value = NULL; int rc = 0; /* start a session */ rc = sr_session_start(conn, SR_DS_STARTUP, SR_SESS_DEFAULT, &session); assert_int_equal(rc, SR_ERR_OK); /* perform a get-item request */ for (size_t i = 0; i<100000; i++){ /* existing leaf */ rc = sr_get_item(session, "/example-module:container/list[key1='key1'][key2='key2']/leaf", &value); assert_int_equal(rc, SR_ERR_OK); assert_non_null(value); assert_int_equal(SR_STRING_T, value->type); sr_free_val(value); } /* stop the session */ rc = sr_session_stop(session); assert_int_equal(rc, SR_ERR_OK); }
static void sr_val_set_xpath_test(void **state) { int rc = 0; sr_val_t *value = NULL, *values = NULL; char xpath[PATH_MAX] = { 0, }; rc = sr_new_val(NULL, &value); assert_int_equal(SR_ERR_OK, rc); assert_null(value->xpath); rc = sr_val_set_xpath(value, XPATH1); assert_int_equal(SR_ERR_OK, rc); assert_string_equal(XPATH1, value->xpath); rc = sr_val_set_xpath(value, XPATH2); assert_int_equal(SR_ERR_OK, rc); assert_string_equal(XPATH2, value->xpath); sr_free_val(value); rc = sr_new_values(10, &values); assert_int_equal(SR_ERR_OK, rc); for (int i = 0; i < 10; ++i) { assert_null(values[i].xpath); snprintf(xpath, PATH_MAX, XPATH_TEMPLATE1, i, i); rc = sr_val_set_xpath(values + i, xpath); assert_int_equal(SR_ERR_OK, rc); assert_string_equal(xpath, values[i].xpath); snprintf(xpath, PATH_MAX, XPATH_TEMPLATE2, i); rc = sr_val_set_xpath(values + i, xpath); assert_int_equal(SR_ERR_OK, rc); assert_string_equal(xpath, values[i].xpath); } sr_free_values(values, 10); }
static void sr_new_val_test(void **state) { int rc = 0; sr_val_t *value = NULL; rc = sr_new_val(NULL, &value); assert_int_equal(SR_ERR_OK, rc); #ifdef USE_SR_MEM_MGMT assert_non_null(value->_sr_mem); assert_int_equal(1, value->_sr_mem->obj_count); assert_true(0 < value->_sr_mem->used_total); #else assert_null(value->_sr_mem); #endif assert_null(value->xpath); assert_false(value->dflt); assert_int_equal(SR_UNKNOWN_T, value->type); assert_int_equal(0, value->data.uint64_val); sr_free_val(value); rc = sr_new_val(XPATH1, &value); assert_int_equal(SR_ERR_OK, rc); #ifdef USE_SR_MEM_MGMT assert_non_null(value->_sr_mem); assert_int_equal(1, value->_sr_mem->obj_count); assert_true(0 < value->_sr_mem->used_total); #else assert_null(value->_sr_mem); #endif assert_string_equal(XPATH1, value->xpath); assert_false(value->dflt); assert_int_equal(SR_UNKNOWN_T, value->type); assert_int_equal(0, value->data.uint64_val); sr_free_val(value); }
int main(int argc, char **argv) { int rc = SR_ERR_OK; sr_conn_ctx_t *conn = NULL; sr_session_ctx_t *sess = NULL; sr_val_t val = {0}; sr_log_stderr(SR_LL_DBG); rc = sr_connect("push kea config", SR_CONN_DEFAULT, &conn); CHECK_RC(rc, cleanup); rc = sr_session_start(conn, SR_DS_STARTUP, SR_SESS_DEFAULT, &sess); CHECK_RC(rc, cleanup); /* socket type */ val.xpath = "/ietf-kea-dhcpv6:server/serv-attributes/control-socket/socket-type"; val.type = SR_STRING_T; val.data.string_val = "unix"; rc = sr_set_item(sess, val.xpath, &val, SR_EDIT_DEFAULT); CHECK_RC(rc, cleanup); /* socket name */ val.xpath = "/ietf-kea-dhcpv6:server/serv-attributes/control-socket/socket-name"; val.type = SR_STRING_T; val.data.string_val = "/tmp/kea-dhcp6-ctrl.sock"; rc = sr_set_item(sess, val.xpath, &val, SR_EDIT_DEFAULT); CHECK_RC(rc, cleanup); rc = sr_commit(sess); /* retrieve field */ sr_val_t* val2 = 0; rc = sr_get_item(sess, val.xpath, &val2); printf("Retrieved: [%s]\n", val.data.string_val); sr_free_val(val2); CHECK_RC(rc, cleanup); cleanup: sr_session_stop(sess); sr_disconnect(conn); }
int main(int argc, char **argv) { sr_conn_ctx_t *conn = NULL; sr_session_ctx_t *sess = NULL; sr_val_t *value = NULL; sr_val_iter_t *iter = NULL; int rc = SR_ERR_OK; /* connect to sysrepo */ rc = sr_connect("app3", SR_CONN_DEFAULT, &conn); if (SR_ERR_OK != rc) { goto cleanup; } /* start session */ rc = sr_session_start(conn, SR_DS_STARTUP, SR_SESS_DEFAULT, &sess); if (SR_ERR_OK != rc) { goto cleanup; } /* get all list instances with their content (recursive) */ rc = sr_get_items_iter(sess, "/ietf-interfaces:interfaces/interface//*", &iter); if (SR_ERR_OK != rc) { goto cleanup; } while (SR_ERR_OK == sr_get_item_next(sess, iter, &value)){ print_value(value); sr_free_val(value); } sr_free_val_iter(iter); cleanup: if (NULL != sess) { sr_session_stop(sess); } if (NULL != conn) { sr_disconnect(conn); } return rc; }
static void sr_val_build_str_data_test(void **state) { int rc = 0; sr_val_t *value = NULL; rc = sr_new_val(NULL, &value); assert_int_equal(SR_ERR_OK, rc); assert_null(value->data.string_val); rc = sr_val_build_str_data(value, SR_UINT32_T, "string value n. %d", 1); assert_int_equal(SR_ERR_INVAL_ARG, rc); rc = sr_val_build_str_data(value, SR_STRING_T, "string value n. %d", 1); assert_int_equal(SR_ERR_OK, rc); assert_string_equal("string value n. 1", value->data.string_val); rc = sr_val_build_str_data(value, SR_BINARY_T, "binary value n. %d", 2); assert_int_equal(SR_ERR_OK, rc); assert_string_equal("binary value n. 2", value->data.binary_val); rc = sr_val_build_str_data(value, SR_ENUM_T, "enum value n. %d", 3); assert_int_equal(SR_ERR_OK, rc); assert_string_equal("enum value n. 3", value->data.enum_val); rc = sr_val_build_str_data(value, SR_BITS_T, "bits value n. %d", 4); assert_int_equal(SR_ERR_OK, rc); assert_string_equal("bits value n. 4", value->data.bits_val); rc = sr_val_build_str_data(value, SR_IDENTITYREF_T, "identityref value n. %d", 5); assert_int_equal(SR_ERR_OK, rc); assert_string_equal("identityref value n. 5", value->data.identityref_val); rc = sr_val_build_str_data(value, SR_INSTANCEID_T, "instance ID value n. %d", 6); assert_int_equal(SR_ERR_OK, rc); assert_string_equal("instance ID value n. 6", value->data.instanceid_val); sr_free_val(value); }
/** * @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 cl_children_subscription_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; int rc = SR_ERR_OK; /* start session */ rc = sr_session_start(conn, SR_DS_RUNNING, SR_SESS_DEFAULT, &session); assert_int_equal(rc, SR_ERR_OK); rc = sr_subtree_change_subscribe(session, "/example-module:container/list/leaf", subtree_example_change_cb, &changes, 0, SR_SUBSCR_DEFAULT, &subscription); assert_int_equal(rc, SR_ERR_OK); /* delete the parent of the subscribed node */ rc = sr_delete_item(session, "/example-module:*", SR_EDIT_DEFAULT); assert_int_equal(rc, SR_ERR_OK); 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); for (int i= 0; i < changes.cnt; i++) { assert_int_equal(changes.oper[i], SR_OP_DELETED); } assert_string_equal("/example-module:container", changes.old_values[0]->xpath); assert_string_equal("/example-module:container/list[key1='key1'][key2='key2']", changes.old_values[1]->xpath); assert_string_equal("/example-module:container/list[key1='key1'][key2='key2']/key1", changes.old_values[2]->xpath); assert_string_equal("/example-module:container/list[key1='key1'][key2='key2']/key2", changes.old_values[3]->xpath); 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); /* check that cb were called in correct order according to the priority */ sr_unsubscribe(session, subscription); sr_session_stop(session); } int main() { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(cl_get_changes_create_test, sysrepo_setup, sysrepo_teardown), cmocka_unit_test_setup_teardown(cl_get_changes_modified_test, sysrepo_setup, sysrepo_teardown), cmocka_unit_test_setup_teardown(cl_get_changes_deleted_test, sysrepo_setup, sysrepo_teardown), cmocka_unit_test_setup_teardown(cl_get_changes_moved_test, sysrepo_setup, sysrepo_teardown), cmocka_unit_test_setup_teardown(cl_notif_priority_test, sysrepo_setup, sysrepo_teardown), cmocka_unit_test_setup_teardown(cl_whole_module_changes, sysrepo_setup, sysrepo_teardown), cmocka_unit_test_setup_teardown(cl_invalid_xpath_test, sysrepo_setup, sysrepo_teardown), cmocka_unit_test_setup_teardown(cl_children_subscription_test, sysrepo_setup, sysrepo_teardown), }; return cmocka_run_group_tests(tests, NULL, NULL); }
static void cl_whole_module_changes(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; int rc = SR_ERR_OK; /* start session */ rc = sr_session_start(conn, SR_DS_RUNNING, SR_SESS_DEFAULT, &session); assert_int_equal(rc, SR_ERR_OK); rc = sr_module_change_subscribe(session, "test-module", cl_whole_module_cb, &changes, 0, SR_SUBSCR_DEFAULT, &subscription); assert_int_equal(rc, SR_ERR_OK); sr_val_t v = {0}; v.type = SR_UINT8_T; v.data.uint8_val = 19; rc = sr_set_item(session, "/test-module:main/ui8", &v, SR_EDIT_DEFAULT); assert_int_equal(rc, SR_ERR_OK); rc = sr_set_item(session, "/test-module:user[name='userA']", NULL, SR_EDIT_DEFAULT); assert_int_equal(rc, SR_ERR_OK); 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); for (int i= 0; i < changes.cnt; i++) { if (NULL != changes.new_values[i]) { puts(changes.new_values[i]->xpath); } } assert_int_equal(changes.cnt, 4); 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("/test-module:main/ui8", 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("/test-module:user[name='userA']", 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("/test-module:user[name='userA']/name", changes.new_values[2]->xpath); assert_int_equal(changes.oper[3], SR_OP_MOVED); assert_non_null(changes.new_values[3]); assert_null(changes.old_values[3]); assert_string_equal("/test-module:user[name='userA']", changes.new_values[3]->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); /* check that cb were called in correct order according to the priority */ sr_unsubscribe(session, subscription); sr_session_stop(session); } int cl_invalid_change_xpath_cb(sr_session_ctx_t *session, const char *module_name, sr_notif_event_t ev, void *private_ctx) { changes_t *ch = (changes_t *) private_ctx; sr_change_iter_t *it = NULL; int rc = SR_ERR_OK; pthread_mutex_lock(&ch->mutex); char change_path[50] = {0,}; snprintf(change_path, 50, "/---ERR%s:*", module_name); rc = sr_get_changes_iter(session, change_path, &it); assert_int_not_equal(SR_ERR_OK, rc); snprintf(change_path, 50, "/%s:abcdefgh", module_name); rc = sr_get_changes_iter(session, change_path, &it); assert_int_not_equal(SR_ERR_OK, rc); pthread_cond_signal(&ch->cv); pthread_mutex_unlock(&ch->mutex); return SR_ERR_OK; }
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; }
static void sr_dup_val_test(void **state) { int rc = 0; sr_val_t *value = NULL, *value_dup = NULL; /* create a new value using the API */ rc = sr_new_val(NULL, &value); rc = sr_val_set_str_data(value, SR_STRING_T, "string value"); assert_int_equal(SR_ERR_OK, rc); rc = sr_val_set_xpath(value, XPATH1); assert_int_equal(SR_ERR_OK, rc); /* duplicate */ rc = sr_dup_val(value, &value_dup); assert_int_equal(SR_ERR_OK, rc); assert_non_null(value_dup); #ifdef USE_SR_MEM_MGMT assert_non_null(value_dup->_sr_mem); assert_ptr_not_equal(value->_sr_mem, value_dup->_sr_mem); assert_int_equal(1, value_dup->_sr_mem->obj_count); assert_true(0 < value_dup->_sr_mem->used_total); #else assert_null(value_dup->_sr_mem); #endif assert_string_equal(XPATH1, value_dup->xpath); assert_false(value_dup->dflt); assert_int_equal(SR_STRING_T, value_dup->type); assert_string_equal("string value", value_dup->data.string_val); sr_free_val(value_dup); /* set dflt to true, change XPATH and duplicate */ value->dflt = true; rc = sr_val_set_xpath(value, XPATH2); assert_int_equal(SR_ERR_OK, rc); rc = sr_dup_val(value, &value_dup); assert_int_equal(SR_ERR_OK, rc); assert_non_null(value_dup); #ifdef USE_SR_MEM_MGMT assert_non_null(value_dup->_sr_mem); assert_ptr_not_equal(value->_sr_mem, value_dup->_sr_mem); assert_int_equal(1, value_dup->_sr_mem->obj_count); assert_true(0 < value_dup->_sr_mem->used_total); #else assert_null(value_dup->_sr_mem); #endif assert_string_equal(XPATH2, value_dup->xpath); assert_true(value_dup->dflt); assert_int_equal(SR_STRING_T, value_dup->type); assert_string_equal("string value", value_dup->data.string_val); sr_free_val(value_dup); /* change string and duplicate */ rc = sr_val_set_str_data(value, SR_STRING_T, "string value2"); assert_int_equal(SR_ERR_OK, rc); rc = sr_dup_val(value, &value_dup); assert_int_equal(SR_ERR_OK, rc); assert_non_null(value_dup); #ifdef USE_SR_MEM_MGMT assert_non_null(value_dup->_sr_mem); assert_ptr_not_equal(value->_sr_mem, value_dup->_sr_mem); assert_int_equal(1, value_dup->_sr_mem->obj_count); assert_true(0 < value_dup->_sr_mem->used_total); #else assert_null(value_dup->_sr_mem); #endif assert_string_equal(XPATH2, value_dup->xpath); assert_true(value_dup->dflt); assert_int_equal(SR_STRING_T, value_dup->type); assert_string_equal("string value2", value_dup->data.string_val); sr_free_val(value_dup); /* duplicate manually created value */ sr_free_val(value); value = calloc(1, sizeof *value); assert_non_null(value); value->xpath = strdup(XPATH1); assert_non_null(value->xpath); value->type = SR_STRING_T; value->data.string_val = strdup("string value"); assert_non_null(value->data.string_val); /* duplicate */ rc = sr_dup_val(value, &value_dup); assert_int_equal(SR_ERR_OK, rc); assert_non_null(value_dup); #ifdef USE_SR_MEM_MGMT assert_non_null(value_dup->_sr_mem); assert_int_equal(1, value_dup->_sr_mem->obj_count); assert_true(0 < value_dup->_sr_mem->used_total); #else assert_null(value_dup->_sr_mem); #endif assert_string_equal(XPATH1, value_dup->xpath); assert_false(value_dup->dflt); assert_int_equal(SR_STRING_T, value_dup->type); assert_string_equal("string value", value_dup->data.string_val); sr_free_val(value_dup); sr_free_val(value); }