[Spice-devel] [spice-server 6/8] test-listen: Add event loop helpers

Christophe Fergeau cfergeau at redhat.com
Tue Mar 6 13:53:20 UTC 2018


These factor a bit of common code, and more importantly, help with
freeing all event loop related data at the end of each test.
---
 server/tests/test-listen.c | 120 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 86 insertions(+), 34 deletions(-)

diff --git a/server/tests/test-listen.c b/server/tests/test-listen.c
index 562f07487..e88105eea 100644
--- a/server/tests/test-listen.c
+++ b/server/tests/test-listen.c
@@ -28,13 +28,62 @@
 #include <string.h>
 #include <gio/gio.h>
 
-static SpiceCoreInterface *core;
 
 static bool error_is_set(GError **error)
 {
     return ((error != NULL) && (*error != NULL));
 }
 
+
+typedef struct {
+    SpiceCoreInterface *core;
+    SpiceTimer *exit_mainloop_timer;
+    SpiceTimer *timeout_timer;
+} TestEventLoop;
+
+static void timeout_cb(SPICE_GNUC_UNUSED void *opaque)
+{
+    g_assert_not_reached();
+}
+
+static void exit_mainloop_cb(SPICE_GNUC_UNUSED void *opaque)
+{
+    basic_event_loop_quit();
+}
+
+static void test_event_loop_quit(TestEventLoop *event_loop)
+{
+    event_loop->core->timer_start(event_loop->exit_mainloop_timer, 0);
+}
+
+static void test_event_loop_init(TestEventLoop *event_loop)
+{
+    event_loop->core = basic_event_loop_init();
+    event_loop->timeout_timer = event_loop->core->timer_add(timeout_cb, NULL);
+    event_loop->exit_mainloop_timer = event_loop->core->timer_add(exit_mainloop_cb, NULL);
+}
+
+static void test_event_loop_destroy(TestEventLoop *event_loop)
+{
+    if (event_loop->timeout_timer != NULL) {
+        event_loop->core->timer_remove(event_loop->timeout_timer);
+        event_loop->timeout_timer = NULL;
+    }
+    if (event_loop->exit_mainloop_timer != NULL) {
+        event_loop->core->timer_remove(event_loop->exit_mainloop_timer);
+        event_loop->exit_mainloop_timer = NULL;
+    }
+    basic_event_loop_destroy();
+    event_loop->core = NULL;
+}
+
+static void test_event_loop_run(TestEventLoop *event_loop)
+{
+    event_loop->core->timer_start(event_loop->timeout_timer, 5000);
+    basic_event_loop_mainloop();
+}
+
+
 static GIOStream *fake_client_connect(GSocketConnectable *connectable, GError **error)
 {
     GSocketClient *client;
@@ -73,17 +122,19 @@ static void check_magic(GIOStream *io_stream, GError **error)
     g_assert_cmpint(memcmp(buffer, "REDQ", 4), ==, 0);
 }
 
-static void exit_mainloop_cb(SPICE_GNUC_UNUSED void *opaque)
+typedef struct
 {
-    basic_event_loop_quit();
-}
+    GSocketConnectable *connectable;
+    gpointer user_data;
+} ThreadData;
 
 static gpointer check_magic_thread(gpointer data)
 {
     GError *error = NULL;
-    GSocketConnectable *connectable = G_SOCKET_CONNECTABLE(data);
+    ThreadData *thread_data = data;
+    GSocketConnectable *connectable = G_SOCKET_CONNECTABLE(thread_data->connectable);
+    TestEventLoop *event_loop = thread_data->user_data;
     GIOStream *stream;
-    SpiceTimer *exit_mainloop_timer;
 
     stream = fake_client_connect(connectable, &error);
     g_assert_no_error(error);
@@ -92,8 +143,9 @@ static gpointer check_magic_thread(gpointer data)
 
     g_object_unref(stream);
     g_object_unref(connectable);
-    exit_mainloop_timer = core->timer_add(exit_mainloop_cb, NULL);
-    core->timer_start(exit_mainloop_timer, 0);
+    g_free(thread_data);
+
+    test_event_loop_quit(event_loop);
 
     return NULL;
 }
@@ -101,9 +153,10 @@ static gpointer check_magic_thread(gpointer data)
 static gpointer check_no_connect_thread(gpointer data)
 {
     GError *error = NULL;
-    GSocketConnectable *connectable = G_SOCKET_CONNECTABLE(data);
+    ThreadData *thread_data = data;
+    GSocketConnectable *connectable = G_SOCKET_CONNECTABLE(thread_data->connectable);
+    TestEventLoop *event_loop = thread_data->user_data;
     GIOStream *stream;
-    SpiceTimer *exit_mainloop_timer;
 
     stream = fake_client_connect(connectable, &error);
     g_assert(error != NULL);
@@ -111,23 +164,26 @@ static gpointer check_no_connect_thread(gpointer data)
     g_clear_error(&error);
 
     g_object_unref(connectable);
-    exit_mainloop_timer = core->timer_add(exit_mainloop_cb, NULL);
-    core->timer_start(exit_mainloop_timer, 0);
+    g_free(thread_data);
+
+    test_event_loop_quit(event_loop);
 
     return NULL;
 }
 
-
-static GThread *fake_client_new(GThreadFunc thread_func, const char *hostname, int port)
+static GThread *fake_client_new(GThreadFunc thread_func,
+                                const char *hostname, int port,
+                                gpointer user_data)
 {
-    GSocketConnectable *connectable;
+    ThreadData *thread_data = g_new0(ThreadData, 1);
 
     g_assert_cmpuint(port, >, 0);
     g_assert_cmpuint(port, <, 65536);
-    connectable = g_network_address_new(hostname, port);
+    thread_data->connectable = g_network_address_new(hostname, port);
+    thread_data->user_data = user_data;
 
     /* check_magic_thread will assume ownership of 'connectable' */
-    return g_thread_new("fake-client-thread", thread_func, connectable);
+    return g_thread_new("fake-client-thread", thread_func, thread_data);
 }
 
 static void test_connect_plain(void)
@@ -135,44 +191,40 @@ static void test_connect_plain(void)
     GThread *thread;
     int result;
 
+    TestEventLoop event_loop = { 0, };
+
+    test_event_loop_init(&event_loop);
+
     /* server */
     SpiceServer *server = spice_server_new();
-    core = basic_event_loop_init();
     spice_server_set_name(server, "SPICE listen test");
     spice_server_set_noauth(server);
     spice_server_set_port(server, 5701);
-    result = spice_server_init(server, core);
+    result = spice_server_init(server, event_loop.core);
     g_assert_cmpint(result, ==, 0);
 
     /* fake client */
-    thread = fake_client_new(check_magic_thread, "localhost", 5701);
-
-    basic_event_loop_mainloop();
-
+    thread = fake_client_new(check_magic_thread, "localhost", 5701, &event_loop);
+    test_event_loop_run(&event_loop);
     g_assert_null(g_thread_join(thread));
 
-    g_thread_unref(thread);
-    basic_event_loop_destroy();
-    core = NULL;
+    test_event_loop_destroy(&event_loop);
     spice_server_destroy(server);
 }
 
 static void test_connect_ko(void)
 {
     GThread *thread;
+    TestEventLoop event_loop = { 0, };
 
-    core = basic_event_loop_init();
+    test_event_loop_init(&event_loop);
 
     /* fake client */
-    thread = fake_client_new(check_no_connect_thread, "localhost", 5701);
-
-    basic_event_loop_mainloop();
-
+    thread = fake_client_new(check_no_connect_thread, "localhost", 5701, &event_loop);
+    test_event_loop_run(&event_loop);
     g_assert_null(g_thread_join(thread));
 
-    g_thread_unref(thread);
-    basic_event_loop_destroy();
-    core = NULL;
+    test_event_loop_destroy(&event_loop);
 }
 
 int main(int argc, char **argv)
-- 
2.14.3



More information about the Spice-devel mailing list