aboutsummaryrefslogtreecommitdiffstats
path: root/tests/client-server.c
diff options
context:
space:
mode:
authorJulian Bouzas <julian.bouzas@collabora.com>2021-04-20 04:08:58 -0400
committerGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2021-07-28 13:19:02 +0300
commitf25bb13718f334bc0c96d29ea9f3a57c0a6f3a34 (patch)
treeeaa30eafe2df92e3d5d75571d022c3a775246bff /tests/client-server.c
parent7bf96bda703dd157385cbb175ec90bd6f38af404 (diff)
lib: add wpipc library
Simple library that uses sockets for inter-process communication. It provides an API to create server and client objects. Users can add custom handlers in the server, and clients can send requests for those custom handlers. Signed-off-by: George Kiagiadakis <george.kiagiadakis@collabora.com>
Diffstat (limited to 'tests/client-server.c')
-rw-r--r--tests/client-server.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/tests/client-server.c b/tests/client-server.c
new file mode 100644
index 0000000..ca6d1c3
--- /dev/null
+++ b/tests/client-server.c
@@ -0,0 +1,124 @@
+/* PipeWire AGL Cluster IPC
+ *
+ * Copyright © 2021 Collabora Ltd.
+ * @author Julian Bouzas <julian.bouzas@collabora.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <glib.h>
+#include <spa/pod/builder.h>
+#include <spa/pod/parser.h>
+#include <icipc/icipc.h>
+
+#define TEST_ADDRESS "/tmp/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 ();
+}