aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2021-07-07 19:40:51 +0300
committerGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2021-07-28 13:19:02 +0300
commit6804d3b2a2a93fa5113c962878867b373c0358f7 (patch)
treee22db2b4201f1664e5f85aa7a7e293a52890cea3
parent3b9acfa96683af1f1814db53cb81670bca68fc5f (diff)
tests: port away from glib
Use a heavily stripped-down copy of pipewire's test framework instead Signed-off-by: George Kiagiadakis <george.kiagiadakis@collabora.com>
-rw-r--r--meson.build1
-rw-r--r--tests/client-server.c83
-rw-r--r--tests/meson.build6
-rw-r--r--tests/protocol.c45
-rw-r--r--tests/sender-receiver.c218
-rw-r--r--tests/test.h172
6 files changed, 352 insertions, 173 deletions
diff --git a/meson.build b/meson.build
index c342c42..3aac10f 100644
--- a/meson.build
+++ b/meson.build
@@ -10,7 +10,6 @@ project('icipc', ['c'],
threads_dep = dependency('threads', required: true)
spa_dep = dependency('libspa-0.2', version: '>= 0.2', required: true)
-glib_dep = dependency('glib-2.0', required: true)
pkgconfig = import('pkgconfig')
cc = meson.get_compiler('c')
diff --git a/tests/client-server.c b/tests/client-server.c
index 7d1cfc6..97f2f6d 100644
--- a/tests/client-server.c
+++ b/tests/client-server.c
@@ -6,19 +6,29 @@
* SPDX-License-Identifier: MIT
*/
-#include <glib.h>
+#define _GNU_SOURCE
+#include "test.h"
#include <spa/pod/builder.h>
#include <spa/pod/parser.h>
#include <icipc.h>
#include <unistd.h>
+#include <pthread.h>
+
+static inline char *new_address()
+{
+ char *address = NULL;
+ (void) asprintf(&address, "icipc-test-%d-%d", getpid(), rand());
+ test_ptr_notnull(address);
+ return address;
+}
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);
+ test_bool_true (spa_pod_is_int (args));
+ test_bool_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);
}
@@ -34,92 +44,89 @@ struct reply_data {
int32_t incremented;
const char *error;
int n_replies;
- GMutex mutex;
- GCond cond;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
};
static void
wait_for_reply (struct reply_data *data, int n_replies)
{
- g_mutex_lock (&data->mutex);
+ pthread_mutex_lock (&data->mutex);
while (data->n_replies < n_replies)
- g_cond_wait (&data->cond, &data->mutex);
- g_mutex_unlock (&data->mutex);
+ pthread_cond_wait (&data->cond, &data->mutex);
+ pthread_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);
+ test_ptr_notnull(data);
- g_mutex_lock (&data->mutex);
+ pthread_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);
+ test_bool_true (spa_pod_is_int (pod));
+ test_bool_true (spa_pod_get_int (pod, &data->incremented) == 0);
}
data->n_replies++;
- g_cond_signal (&data->cond);
+ pthread_cond_signal (&data->cond);
- g_mutex_unlock (&data->mutex);
+ pthread_mutex_unlock (&data->mutex);
}
static void
test_icipc_server_client ()
{
- g_autofree gchar *address = g_strdup_printf ("%s/icipc-test-%d-%d",
- g_get_tmp_dir(), getpid(), g_random_int ());
+ char *address = new_address();
struct icipc_server *s = icipc_server_new (address, true);
- g_assert_nonnull (s);
+ test_ptr_notnull(s);
struct icipc_client *c = icipc_client_new (address, true);
- g_assert_nonnull (c);
+ test_ptr_notnull(c);
struct reply_data data;
- g_mutex_init (&data.mutex);
- g_cond_init (&data.cond);
+ pthread_mutex_init (&data.mutex, NULL);
+ pthread_cond_init (&data.cond, NULL);
/* 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));
+ test_bool_true (icipc_server_set_request_handler (s, "INCREMENT", increment_request_handler, NULL));
+ test_bool_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));
+ test_bool_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);
+ test_ptr_null(data.error);
+ test_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));
+ test_bool_true (icipc_client_send_request (c, "ERROR", NULL, reply_handler, &data));
wait_for_reply (&data, 1);
- g_assert_cmpstr (data.error, ==, "error message");
+ test_str_eq(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));
+ test_bool_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");
+ test_str_eq(data.error, "request handler not found");
/* clean up */
- g_cond_clear (&data.cond);
- g_mutex_clear (&data.mutex);
+ pthread_cond_destroy (&data.cond);
+ pthread_mutex_destroy (&data.mutex);
icipc_client_free (c);
icipc_server_free (s);
+ free(address);
}
-gint
-main (gint argc, gchar *argv[])
+int
+main (int argc, char *argv[])
{
- g_test_init (&argc, &argv, NULL);
-
- g_test_add_func ("/icipc/icipc-server-client", test_icipc_server_client);
-
- return g_test_run ();
+ test_icipc_server_client();
+ return TEST_PASS;
}
diff --git a/tests/meson.build b/tests/meson.build
index c8a8249..a5ee7bb 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -1,7 +1,7 @@
-common_deps = [icipc_dep, glib_dep]
+common_deps = [icipc_dep, threads_dep]
common_env = environment({
- 'G_TEST_SRCDIR': meson.current_source_dir(),
- 'G_TEST_BUILDDIR': meson.current_build_dir(),
+ 'XDG_RUNTIME_DIR': '/tmp',
+ 'ICIPC_DEBUG': '3',
})
test(
diff --git a/tests/protocol.c b/tests/protocol.c
index 66f645e..334c511 100644
--- a/tests/protocol.c
+++ b/tests/protocol.c
@@ -6,7 +6,7 @@
* SPDX-License-Identifier: MIT
*/
-#include <glib.h>
+#include "test.h"
#include <spa/pod/builder.h>
#include <spa/pod/parser.h>
#include <icipc.h>
@@ -21,9 +21,9 @@ test_icipc_protocol ()
icipc_protocol_build_request (b, sizeof(b), "name", NULL);
const char *name = NULL;
const struct spa_pod *value = NULL;
- g_assert_true (icipc_protocol_parse_request (b, sizeof(b), &name, &value));
- g_assert_cmpstr (name, ==, "name");
- g_assert_true (spa_pod_is_none (value));
+ test_bool_true (icipc_protocol_parse_request (b, sizeof(b), &name, &value));
+ test_str_eq (name, "name");
+ test_bool_true (spa_pod_is_none (value));
}
/* request */
@@ -32,47 +32,44 @@ test_icipc_protocol ()
icipc_protocol_build_request (b, sizeof(b), "name", (struct spa_pod *)&i);
const char *name = NULL;
const struct spa_pod_int *value = NULL;
- g_assert_true (icipc_protocol_parse_request (b, sizeof(b), &name, (const struct spa_pod **)&value));
- g_assert_cmpstr (name, ==, "name");
- g_assert_cmpint (value->value, ==, 8);
+ test_bool_true (icipc_protocol_parse_request (b, sizeof(b), &name, (const struct spa_pod **)&value));
+ test_str_eq (name, "name");
+ test_cmpint (value->value, ==, 8);
}
/* reply error */
{
icipc_protocol_build_reply_error (b, sizeof(b), "error message");
- g_assert_true (icipc_protocol_is_reply_error (b, sizeof(b)));
+ test_bool_true (icipc_protocol_is_reply_error (b, sizeof(b)));
const char *msg = NULL;
- g_assert_true (icipc_protocol_parse_reply_error (b, sizeof(b), &msg));
- g_assert_cmpstr (msg, ==, "error message");
+ test_bool_true (icipc_protocol_parse_reply_error (b, sizeof(b), &msg));
+ test_str_eq (msg, "error message");
}
/* reply ok null value */
{
icipc_protocol_build_reply_ok (b, sizeof(b), NULL);
- g_assert_true (icipc_protocol_is_reply_ok (b, sizeof(b)));
+ test_bool_true (icipc_protocol_is_reply_ok (b, sizeof(b)));
const struct spa_pod *value = NULL;
- g_assert_true (icipc_protocol_parse_reply_ok (b, sizeof(b), &value));
- g_assert_nonnull (value);
- g_assert_true (spa_pod_is_none (value));
+ test_bool_true (icipc_protocol_parse_reply_ok (b, sizeof(b), &value));
+ test_ptr_notnull (value);
+ test_bool_true (spa_pod_is_none (value));
}
/* reply ok */
{
struct spa_pod_int i = SPA_POD_INIT_Int (3);
icipc_protocol_build_reply_ok (b, sizeof(b), (struct spa_pod *)&i);
- g_assert_true (icipc_protocol_is_reply_ok (b, sizeof(b)));
+ test_bool_true (icipc_protocol_is_reply_ok (b, sizeof(b)));
const struct spa_pod_int *value = NULL;
- g_assert_true (icipc_protocol_parse_reply_ok (b, sizeof(b), (const struct spa_pod **)&value));
- g_assert_cmpint (value->value, ==, 3);
+ test_bool_true (icipc_protocol_parse_reply_ok (b, sizeof(b), (const struct spa_pod **)&value));
+ test_cmpint (value->value, ==, 3);
}
}
-gint
-main (gint argc, gchar *argv[])
+int
+main (int argc, char *argv[])
{
- g_test_init (&argc, &argv, NULL);
-
- g_test_add_func ("/icipc/icipc-protocol", test_icipc_protocol);
-
- return g_test_run ();
+ test_icipc_protocol();
+ return TEST_PASS;
}
diff --git a/tests/sender-receiver.c b/tests/sender-receiver.c
index 75a10be..19a989d 100644
--- a/tests/sender-receiver.c
+++ b/tests/sender-receiver.c
@@ -6,26 +6,36 @@
* SPDX-License-Identifier: MIT
*/
-#include <glib.h>
+#define _GNU_SOURCE
+#include "test.h"
#include <icipc.h>
#include <unistd.h>
+#include <pthread.h>
struct event_data {
const uint8_t * expected_data;
size_t expected_size;
int connections;
int n_events;
- GMutex mutex;
- GCond cond;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
};
+static inline char *new_address()
+{
+ char *address = NULL;
+ (void) asprintf(&address, "icipc-test-%d-%d", getpid(), rand());
+ test_ptr_notnull(address);
+ return address;
+}
+
static void
wait_for_event (struct event_data *data, int n_events)
{
- g_mutex_lock (&data->mutex);
+ pthread_mutex_lock (&data->mutex);
while (data->n_events < n_events)
- g_cond_wait (&data->cond, &data->mutex);
- g_mutex_unlock (&data->mutex);
+ pthread_cond_wait (&data->cond, &data->mutex);
+ pthread_mutex_unlock (&data->mutex);
}
static void
@@ -33,9 +43,9 @@ sender_state_callback (struct icipc_receiver *self, int sender_fd,
enum icipc_receiver_sender_state sender_state, void *p)
{
struct event_data *data = p;
- g_assert_nonnull (data);
+ test_ptr_notnull (data);
- g_mutex_lock (&data->mutex);
+ pthread_mutex_lock (&data->mutex);
switch (sender_state) {
case ICIPC_RECEIVER_SENDER_STATE_CONNECTED:
data->connections++;
@@ -44,57 +54,58 @@ sender_state_callback (struct icipc_receiver *self, int sender_fd,
data->connections--;
break;
default:
- g_assert_not_reached ();
+ test_fail_if_reached ();
break;
}
data->n_events++;
- g_cond_signal (&data->cond);
- g_mutex_unlock (&data->mutex);
+ pthread_cond_signal (&data->cond);
+ pthread_mutex_unlock (&data->mutex);
}
static void
reply_callback (struct icipc_sender *self, const uint8_t *buffer, size_t size, void *p)
{
struct event_data *data = p;
- g_assert_nonnull (data);
- g_assert_nonnull (buffer);
+ test_ptr_notnull (data);
+ test_ptr_notnull (buffer);
- g_mutex_lock (&data->mutex);
- g_assert_cmpmem (buffer, size, data->expected_data, data->expected_size);
+ pthread_mutex_lock (&data->mutex);
+ test_cmpint(size, ==, data->expected_size);
+ test_cmpint(memcmp(buffer, data->expected_data, size), ==, 0);
data->n_events++;
- g_cond_signal (&data->cond);
- g_mutex_unlock (&data->mutex);
+ pthread_cond_signal (&data->cond);
+ pthread_mutex_unlock (&data->mutex);
}
static void
test_icipc_receiver_basic ()
{
- g_autofree gchar *address = g_strdup_printf ("%s/icipc-test-%d-%d",
- g_get_tmp_dir(), getpid(), g_random_int ());
+ char *address = new_address();
struct icipc_receiver *r = icipc_receiver_new (address, 16, NULL, NULL, 0);
- g_assert_nonnull (r);
+ test_ptr_notnull (r);
/* start and stop */
- g_assert_false (icipc_receiver_is_running (r));
- g_assert_true (icipc_receiver_start (r));
- g_assert_true (icipc_receiver_is_running (r));
+ test_bool_false (icipc_receiver_is_running (r));
+ test_bool_true (icipc_receiver_start (r));
+ test_bool_true (icipc_receiver_is_running (r));
icipc_receiver_stop (r);
- g_assert_false (icipc_receiver_is_running (r));
+ test_bool_false (icipc_receiver_is_running (r));
/* clean up */
icipc_receiver_free (r);
+ free(address);
}
static void
test_icipc_sender_basic ()
{
- g_autofree gchar *address = g_strdup_printf ("%s/icipc-test-%d-%d",
- g_get_tmp_dir(), getpid(), g_random_int ());
+ char *address = new_address();
struct icipc_sender *s = icipc_sender_new (address, 16, NULL, NULL, 0);
- g_assert_nonnull (s);
+ test_ptr_notnull (s);
/* clean up */
icipc_sender_free (s);
+ free(address);
}
static void
@@ -104,73 +115,71 @@ test_icipc_sender_connect ()
.sender_state = sender_state_callback,
.handle_message = NULL,
};
- struct event_data data;
- g_mutex_init (&data.mutex);
- g_cond_init (&data.cond);
- data.n_events = 0;
- data.connections = 0;
+ struct event_data data = {0};
- g_autofree gchar *address = g_strdup_printf ("%s/icipc-test-%d-%d",
- g_get_tmp_dir(), getpid(), g_random_int ());
+ pthread_mutex_init (&data.mutex, NULL);
+ pthread_cond_init (&data.cond, NULL);
+
+ char *address = new_address();
struct icipc_receiver *r = icipc_receiver_new (address, 16, &events, &data, 0);
- g_assert_nonnull (r);
+ test_ptr_notnull (r);
struct icipc_sender *s = icipc_sender_new (address, 16, NULL, NULL, 0);
- g_assert_nonnull (s);
+ test_ptr_notnull (s);
/* start receiver */
- g_assert_true (icipc_receiver_start (r));
+ test_bool_true (icipc_receiver_start (r));
/* connect sender */
- g_assert_true (icipc_sender_connect (s));
- g_assert_true (icipc_sender_is_connected (s));
+ test_bool_true (icipc_sender_connect (s));
+ test_bool_true (icipc_sender_is_connected (s));
wait_for_event (&data, 1);
- g_assert_cmpint (data.connections, ==, 1);
+ test_cmpint (data.connections, ==, 1);
/* disconnect sender */
icipc_sender_disconnect (s);
- g_assert_false (icipc_sender_is_connected (s));
+ test_bool_false (icipc_sender_is_connected (s));
wait_for_event (&data, 2);
- g_assert_cmpint (data.connections, ==, 0);
+ test_cmpint (data.connections, ==, 0);
/* stop receiver */
icipc_receiver_stop (r);
/* clean up */
- g_cond_clear (&data.cond);
- g_mutex_clear (&data.mutex);
+ pthread_cond_destroy (&data.cond);
+ pthread_mutex_destroy (&data.mutex);
icipc_sender_free (s);
icipc_receiver_free (r);
+ free(address);
}
static void
lost_connection_handler (struct icipc_sender *self, int receiver_fd, void *p)
{
struct event_data *data = p;
- g_assert_nonnull (data);
+ test_ptr_notnull (data);
- g_mutex_lock (&data->mutex);
+ pthread_mutex_lock (&data->mutex);
data->n_events++;
- g_cond_signal (&data->cond);
- g_mutex_unlock (&data->mutex);
+ pthread_cond_signal (&data->cond);
+ pthread_mutex_unlock (&data->mutex);
}
static void
test_icipc_sender_lost_connection ()
{
- struct event_data data;
- g_mutex_init (&data.mutex);
- g_cond_init (&data.cond);
+ struct event_data data = {0};
+ pthread_mutex_init (&data.mutex, NULL);
+ pthread_cond_init (&data.cond, NULL);
- g_autofree gchar *address = g_strdup_printf ("%s/icipc-test-%d-%d",
- g_get_tmp_dir(), getpid(), g_random_int ());
+ char *address = new_address();
struct icipc_receiver *r = icipc_receiver_new (address, 16, NULL, NULL, 0);
- g_assert_nonnull (r);
+ test_ptr_notnull (r);
struct icipc_sender *s = icipc_sender_new (address, 16, lost_connection_handler, &data, 0);
- g_assert_nonnull (s);
+ test_ptr_notnull (s);
/* connect sender */
- g_assert_true (icipc_sender_connect (s));
- g_assert_true (icipc_sender_is_connected (s));
+ test_bool_true (icipc_sender_connect (s));
+ test_bool_true (icipc_sender_is_connected (s));
/* destroy receiver and make sure the lost connection handler is triggered */
data.n_events = 0;
@@ -178,108 +187,107 @@ test_icipc_sender_lost_connection ()
wait_for_event (&data, 1);
/* make sure the connection was lost */
- g_assert_false (icipc_sender_is_connected (s));
+ test_bool_false (icipc_sender_is_connected (s));
/* create a new receiver */
struct icipc_receiver *r2 = icipc_receiver_new (address, 16, NULL, NULL, 0);
- g_assert_nonnull (r2);
+ test_ptr_notnull (r2);
/* re-connect sender with new receiver */
- g_assert_true (icipc_sender_connect (s));
- g_assert_true (icipc_sender_is_connected (s));
+ test_bool_true (icipc_sender_connect (s));
+ test_bool_true (icipc_sender_is_connected (s));
/* clean up */
- g_cond_clear (&data.cond);
- g_mutex_clear (&data.mutex);
+ pthread_cond_destroy (&data.cond);
+ pthread_mutex_destroy (&data.mutex);
icipc_sender_free (s);
icipc_receiver_free (r2);
+ free(address);
}
static void
test_icipc_sender_send ()
{
- g_autofree gchar *address = g_strdup_printf ("%s/icipc-test-%d-%d",
- g_get_tmp_dir(), getpid(), g_random_int ());
+ char *address = new_address();
struct icipc_receiver *r = icipc_receiver_new (address, 2, NULL, NULL, 0);
- g_assert_nonnull (r);
+ test_ptr_notnull (r);
struct icipc_sender *s = icipc_sender_new (address, 2, NULL, NULL, 0);
- g_assert_nonnull (s);
- struct event_data data;
- g_mutex_init (&data.mutex);
- g_cond_init (&data.cond);
- data.n_events = 0;
+ test_ptr_notnull (s);
+ struct event_data data = {0};
+ pthread_mutex_init (&data.mutex, NULL);
+ pthread_cond_init (&data.cond, NULL);
/* start receiver */
- g_assert_true (icipc_receiver_start (r));
+ test_bool_true (icipc_receiver_start (r));
/* connect */
- g_assert_true (icipc_sender_connect (s));
- g_assert_true (icipc_sender_is_connected (s));
+ test_bool_true (icipc_sender_connect (s));
+ test_bool_true (icipc_sender_is_connected (s));
/* send 1 byte message (should not realloc) */
data.n_events = 0;
data.expected_data = (const uint8_t *)"h";
data.expected_size = 1;
- g_assert_true (icipc_sender_send (s, (const uint8_t *)"h", 1, reply_callback, &data));
+ test_bool_true (icipc_sender_send (s, (const uint8_t *)"h", 1, reply_callback, &data));
wait_for_event (&data, 1);
/* send 2 bytes message (should realloc once to 4) */
data.n_events = 0;
data.expected_data = (const uint8_t *)"hi";
data.expected_size = 2;
- g_assert_true (icipc_sender_send (s, (const uint8_t *)"hi", 2, reply_callback, &data));
+ test_bool_true (icipc_sender_send (s, (const uint8_t *)"hi", 2, reply_callback, &data));
wait_for_event (&data, 1);
/* send 3 bytes message (should not realloc) */
data.n_events = 0;
data.expected_data = (const uint8_t *)"hii";
data.expected_size = 3;
- g_assert_true (icipc_sender_send (s, (const uint8_t *)"hii", 3, reply_callback, &data));
+ test_bool_true (icipc_sender_send (s, (const uint8_t *)"hii", 3, reply_callback, &data));
wait_for_event (&data, 1);
/* send 28 bytes message (should realloc 3 times: first to 8, then to 16 and finally to 32) */
data.n_events = 0;
data.expected_data = (const uint8_t *)"bigger than 16 bytes message";
data.expected_size = 28;
- g_assert_true (icipc_sender_send (s, (const uint8_t *)"bigger than 16 bytes message", 28, reply_callback, &data));
+ test_bool_true (icipc_sender_send (s, (const uint8_t *)"bigger than 16 bytes message", 28, reply_callback, &data));
wait_for_event (&data, 1);
/* don't allow empty messages */
data.n_events = 0;
- g_assert_false (icipc_sender_send (s, (const uint8_t *)"", 0, NULL, NULL));
+ test_bool_false (icipc_sender_send (s, (const uint8_t *)"", 0, NULL, NULL));
/* stop receiver */
icipc_receiver_stop (r);
/* clean up */
- g_cond_clear (&data.cond);
- g_mutex_clear (&data.mutex);
+ pthread_cond_destroy (&data.cond);
+ pthread_mutex_destroy (&data.mutex);
icipc_sender_free (s);
icipc_receiver_free (r);
+ free(address);
}
static void
test_icipc_multiple_senders_send ()
{
- g_autofree gchar *address = g_strdup_printf ("%s/icipc-test-%d-%d",
- g_get_tmp_dir(), getpid(), g_random_int ());
+ char *address = new_address();
struct icipc_receiver *r = icipc_receiver_new (address, 16, NULL, NULL, 0);
- g_assert_nonnull (r);
+ test_ptr_notnull (r);
struct icipc_sender *senders[50];
struct event_data data;
- g_mutex_init (&data.mutex);
- g_cond_init (&data.cond);
+ pthread_mutex_init (&data.mutex, NULL);
+ pthread_cond_init (&data.cond, NULL);
data.n_events = 0;
/* start receiver */
- g_assert_true (icipc_receiver_start (r));
+ test_bool_true (icipc_receiver_start (r));
/* create and connect 50 senders */
for (int i = 0; i < 50; i++) {
senders[i] = icipc_sender_new (address, 16, NULL, NULL, 0);
- g_assert_nonnull (senders[i]);
- g_assert_true (icipc_sender_connect (senders[i]));
- g_assert_true (icipc_sender_is_connected (senders[i]));
+ test_ptr_notnull (senders[i]);
+ test_bool_true (icipc_sender_connect (senders[i]));
+ test_bool_true (icipc_sender_is_connected (senders[i]));
}
/* send 50 messages (1 per sender) */
@@ -287,33 +295,29 @@ test_icipc_multiple_senders_send ()
data.expected_data = (const uint8_t *)"hello";
data.expected_size = 5;
for (int i = 0; i < 50; i++)
- g_assert_true (icipc_sender_send (senders[i], (const uint8_t *)"hello", 5, reply_callback, &data));
+ test_bool_true (icipc_sender_send (senders[i], (const uint8_t *)"hello", 5, reply_callback, &data));
wait_for_event (&data, 50);
/* stop receiver */
icipc_receiver_stop (r);
/* clean up */
- g_cond_clear (&data.cond);
- g_mutex_clear (&data.mutex);
+ pthread_cond_destroy (&data.cond);
+ pthread_mutex_destroy (&data.mutex);
for (int i = 0; i < 50; i++)
icipc_sender_free (senders[i]);
icipc_receiver_free (r);
+ free(address);
}
-gint
-main (gint argc, gchar *argv[])
+int
+main (int argc, char *argv[])
{
- g_test_init (&argc, &argv, NULL);
-
- g_test_add_func ("/icipc/receiver-basic", test_icipc_receiver_basic);
- g_test_add_func ("/icipc/sender-basic", test_icipc_sender_basic);
- g_test_add_func ("/icipc/sender-connect", test_icipc_sender_connect);
- g_test_add_func ("/icipc/sender-lost-connection",
- test_icipc_sender_lost_connection);
- g_test_add_func ("/icipc/sender-send", test_icipc_sender_send);
- g_test_add_func ("/icipc/multiple-senders-send",
- test_icipc_multiple_senders_send);
-
- return g_test_run ();
+ test_icipc_receiver_basic();
+ test_icipc_sender_basic();
+ test_icipc_sender_connect();
+ test_icipc_sender_lost_connection();
+ test_icipc_sender_send();
+ test_icipc_multiple_senders_send();
+ return TEST_PASS;
}
diff --git a/tests/test.h b/tests/test.h
new file mode 100644
index 0000000..ca349b0
--- /dev/null
+++ b/tests/test.h
@@ -0,0 +1,172 @@
+/* PipeWire
+ *
+ * Copyright © 2021 Red Hat, Inc.
+ * Copyright © 2021 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <math.h>
+
+#ifdef __GNUC__
+#define TEST_NORETURN __attribute__ ((noreturn))
+#define TEST_LIKELY(x) (__builtin_expect(!!(x),1))
+#else
+#define TEST_NORETURN
+#define TEST_LIKELY(x) (x)
+#endif
+
+enum {
+ TEST_PASS = EXIT_SUCCESS,
+ TEST_FAIL = EXIT_FAILURE,
+ TEST_SKIP = 77,
+};
+
+#define test_log(...) fprintf(stderr, __VA_ARGS__)
+#define test_vlog(format_, args_) vfprintf(stderr, format_, args_)
+
+static inline bool _test_streq(const char *s1, const char *s2) {
+ return TEST_LIKELY(s1 && s2) ? strcmp(s1, s2) == 0 : s1 == s2;
+}
+
+TEST_NORETURN
+static inline void _test_fail(
+ const char *file, int line, const char *func,
+ const char *message) {
+ test_log("FAILED: %s\n", message);
+ test_log("in %s() (%s:%d)\n", func, file, line);
+ exit(TEST_FAIL);
+}
+
+TEST_NORETURN
+static inline void _test_fail_comparison_bool(
+ const char *file, int line, const char *func,
+ const char *operator, bool a, bool b,
+ const char *astr, const char *bstr) {
+ test_log("FAILED COMPARISON: %s %s %s\n", astr, operator, bstr);
+ test_log("Resolved to: %s %s %s\n", a ? "true" : "false", operator,
+ b ? "true" : "false");
+ test_log("in %s() (%s:%d)\n", func, file, line);
+ exit(TEST_FAIL);
+}
+
+TEST_NORETURN
+static inline void _test_fail_comparison_int(
+ const char *file, int line, const char *func,
+ const char *operator, int a, int b,
+ const char *astr, const char *bstr) {
+ test_log("FAILED COMPARISON: %s %s %s\n", astr, operator, bstr);
+ test_log("Resolved to: %d %s %d\n", a, operator, b);
+ test_log("in %s() (%s:%d)\n", func, file, line);
+ exit(TEST_FAIL);
+}
+
+TEST_NORETURN
+static inline void _test_fail_comparison_double(
+ const char *file, int line, const char *func,
+ const char *operator, double a, double b,
+ const char *astr, const char *bstr) {
+ test_log("FAILED COMPARISON: %s %s %s\n", astr, operator, bstr);
+ test_log("Resolved to: %.3f %s %.3f\n", a, operator, b);
+ test_log("in %s() (%s:%d)\n", func, file, line);
+ exit(TEST_FAIL);
+}
+
+TEST_NORETURN
+static inline void _test_fail_comparison_ptr(
+ const char *file, int line, const char *func,
+ const char *comparison) {
+ test_log("FAILED COMPARISON: %s\n", comparison);
+ test_log("in %s() (%s:%d)\n", func, file, line);
+ exit(TEST_FAIL);
+}
+
+TEST_NORETURN
+static inline void _test_fail_comparison_str(
+ const char *file, int line, const char *func,
+ const char *comparison, const char *a, const char *b) {
+ test_log("FAILED COMPARISON: %s, expanded (\"%s\" vs \"%s\")\n",
+ comparison, a, b);
+ test_log("in %s() (%s:%d)\n", func, file, line);
+ exit(TEST_FAIL);
+}
+
+#define test_fail_if_reached() \
+ _test_fail(__FILE__, __LINE__, __func__, \
+ "This line is supposed to be unreachable")
+
+#define test_cmpbool(a_, op_, b_) \
+ do { \
+ bool _a = !!(a_); \
+ bool _b = !!(b_); \
+ if (!(_a op_ _b)) \
+ _test_fail_comparison_bool(__FILE__, __LINE__, __func__,\
+ #op_, _a, _b, #a_, #b_); \
+ } while(0)
+
+#define test_bool_true(cond_) \
+ test_cmpbool(cond_, ==, true)
+
+#define test_bool_false(cond_) \
+ test_cmpbool(cond_, ==, false)
+
+#define test_cmpint(a_, op_, b_) \
+ do { \
+ __typeof__(a_) _a = a_; \
+ __typeof__(b_) _b = b_; \
+ if (trunc(_a) != _a || trunc(_b) != _b) \
+ _test_fail(__FILE__, __LINE__, __func__, \
+ "test_int_* used for non-integer value"); \
+ if (!((_a) op_ (_b))) \
+ _test_fail_comparison_int(__FILE__, __LINE__, __func__,\
+ #op_, _a, _b, #a_, #b_); \
+ } while(0)
+
+#define test_cmpptr(a_, op_, b_) \
+ do { \
+ __typeof__(a_) _a = a_; \
+ __typeof__(b_) _b = b_; \
+ if (!((_a) op_ (_b))) \
+ _test_fail_comparison_ptr(__FILE__, __LINE__, __func__,\
+ #a_ " " #op_ " " #b_); \
+ } while(0)
+
+#define test_ptr_null(a_) \
+ test_cmpptr(a_, ==, NULL)
+
+#define test_ptr_notnull(a_) \
+ test_cmpptr(a_, !=, NULL)
+
+#define test_cmpdouble(a_, op_, b_) \
+ do { \
+ const double EPSILON = 1.0/256; \
+ __typeof__(a_) _a = a_; \
+ __typeof__(b_) _b = b_; \
+ if (!((_a) op_ (_b)) && fabs((_a) - (_b)) > EPSILON) \
+ _test_fail_comparison_double(__FILE__, __LINE__, __func__,\
+ #op_, _a, _b, #a_, #b_); \
+ } while(0)
+
+#define test_str_eq(a_, b_) \
+ do { \
+ const char *_a = a_; \
+ const char *_b = b_; \
+ if (!_test_streq(_a, _b)) \
+ _test_fail_comparison_str(__FILE__, __LINE__, __func__, \
+ #a_ " equals " #b_, _a, _b); \
+ } while(0)
+
+#define test_str_ne(a_, b_) \
+ do { \
+ const char *_a = a_; \
+ const char *_b = b_; \
+ if (_test_streq(_a, _b)) \
+ _test_fail_comparison_str(__FILE__, __LINE__, __func__, \
+ #a_ " not equal to " #b_, _a, _b); \
+ } while(0)