/* PipeWire AGL Cluster IPC * * Copyright © 2021 Collabora Ltd. * @author Julian Bouzas * * SPDX-License-Identifier: MIT */ #include #include #include #include #define TEST_ADDRESS "icipc-client-server" static bool increment_request_handler (struct icipc_server *self, int client_fd, const char *name, const struct spa_pod *args, void *data) { int32_t val = 0; g_assert_true (spa_pod_is_int (args)); g_assert_true (spa_pod_get_int (args, &val) == 0); struct spa_pod_int res = SPA_POD_INIT_Int (val + 1); return icipc_server_reply_ok (self, client_fd, (struct spa_pod *)&res); } static bool error_request_handler (struct icipc_server *self, int client_fd, const char *name, const struct spa_pod *args, void *data) { return icipc_server_reply_error (self, client_fd, "error message"); } struct reply_data { int32_t incremented; const char *error; int n_replies; GMutex mutex; }; static void wait_for_reply (struct reply_data *data, int n_replies) { while (true) { g_mutex_lock (&data->mutex); if (data->n_replies == n_replies) { g_mutex_unlock (&data->mutex); break; } g_mutex_unlock (&data->mutex); } } static void reply_handler (struct icipc_sender *self, const uint8_t *buffer, size_t size, void *p) { struct reply_data *data = p; g_assert_nonnull (data); g_mutex_lock (&data->mutex); const struct spa_pod *pod = icipc_client_send_request_finish (self, buffer, size, &data->error); if (pod) { g_assert_true (spa_pod_is_int (pod)); g_assert_true (spa_pod_get_int (pod, &data->incremented) == 0); } data->n_replies++; g_mutex_unlock (&data->mutex); } static void test_icipc_server_client () { struct icipc_server *s = icipc_server_new (TEST_ADDRESS, true); g_assert_nonnull (s); struct icipc_client *c = icipc_client_new (TEST_ADDRESS, true); g_assert_nonnull (c); struct reply_data data; g_mutex_init (&data.mutex); /* add request handlers */ g_assert_true (icipc_server_set_request_handler (s, "INCREMENT", increment_request_handler, NULL)); g_assert_true (icipc_server_set_request_handler (s, "ERROR", error_request_handler, NULL)); /* send an INCREMENT request of 3, and make sure the returned value is 4 */ data.incremented = -1; data.error = NULL; data.n_replies = 0; struct spa_pod_int i = SPA_POD_INIT_Int (3); g_assert_true (icipc_client_send_request (c, "INCREMENT", (struct spa_pod *)&i, reply_handler, &data)); wait_for_reply (&data, 1); g_assert_null (data.error); g_assert_cmpint (data.incremented, ==, 4); /* send an ERROR request, and make sure the returned value is an error */ data.error = NULL; data.n_replies = 0; g_assert_true (icipc_client_send_request (c, "ERROR", NULL, reply_handler, &data)); wait_for_reply (&data, 1); g_assert_cmpstr (data.error, ==, "error message"); /* send an unhandled request, and make sure the server replies with an error */ data.error = NULL; data.n_replies = 0; g_assert_true (icipc_client_send_request (c, "UNHANDLED-REQUEST", NULL, reply_handler, &data)); wait_for_reply (&data, 1); g_assert_cmpstr (data.error, ==, "request handler not found"); /* clean up */ g_mutex_clear (&data.mutex); icipc_client_free (c); icipc_server_free (s); } gint main (gint argc, gchar *argv[]) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/icipc/icipc-server-client", test_icipc_server_client); return g_test_run (); }