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

Frediano Ziglio fziglio at redhat.com
Fri Mar 9 11:44:45 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();
> +}
> +
> +

single line

>  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;

looks like this is always a TestEventLoop pointer, I would change
to TestEventLoop *event_loop.

> +} 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)

Here too, is always a TestEventLoop pointer

>  {
> -    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)

Otherwise,
  Acked-by: Frediano Ziglio <fziglio at redhat.com>

Frediano


More information about the Spice-devel mailing list