void Subscribe::subtree_change_subscribe(const char *xpath, S_Callback callback, void *private_ctx, \ uint32_t priority, sr_subscr_options_t opts) { callback->private_ctx["subtree_change"] = private_ctx; cb_list.push_back(callback); int ret = sr_subtree_change_subscribe(_sess->_sess, xpath, subtree_change_cb, callback->get(), priority, opts, &_sub); if (SR_ERR_OK != ret) { throw_exception(ret); } }
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); }