diff options
author | George Kiagiadakis <george.kiagiadakis@collabora.com> | 2021-07-07 19:40:51 +0300 |
---|---|---|
committer | George Kiagiadakis <george.kiagiadakis@collabora.com> | 2021-07-28 13:19:02 +0300 |
commit | 6804d3b2a2a93fa5113c962878867b373c0358f7 (patch) | |
tree | e22db2b4201f1664e5f85aa7a7e293a52890cea3 /tests | |
parent | 3b9acfa96683af1f1814db53cb81670bca68fc5f (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>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/client-server.c | 83 | ||||
-rw-r--r-- | tests/meson.build | 6 | ||||
-rw-r--r-- | tests/protocol.c | 45 | ||||
-rw-r--r-- | tests/sender-receiver.c | 218 | ||||
-rw-r--r-- | tests/test.h | 172 |
5 files changed, 352 insertions, 172 deletions
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) |