From 6aa0c81d5785f0553418030edf2758c3ef5f0b09 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Fri, 14 Dec 2012 15:50:59 -0500 Subject: [PATCH] tests: add session-test Add a test that each of the 3 SoupSession types (plain, async, sync) behaves as expected with soup_session_queue_message(), soup_session_send_message(), and soup_session_cancel_message(). --- tests/Makefile.am | 3 + tests/session-test.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 237 insertions(+) create mode 100644 tests/session-test.c diff --git a/tests/Makefile.am b/tests/Makefile.am index cd132bd..fdd2c3d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -29,6 +29,7 @@ noinst_PROGRAMS = \ redirect-test \ requester-test \ resource-test \ + session-test \ simple-httpd \ simple-proxy \ sniffing-test \ @@ -72,6 +73,7 @@ redirect_test_SOURCES = redirect-test.c $(TEST_SRCS) requester_test_SOURCES = requester-test.c $(TEST_SRCS) resource_test_SOURCES = resource-test.c $(TEST_SRCS) server_auth_test_SOURCES = server-auth-test.c $(TEST_SRCS) +session_test_SOURCES = session-test.c $(TEST_SRCS) simple_httpd_SOURCES = simple-httpd.c simple_proxy_SOURCES = simple-proxy.c sniffing_test_SOURCES = sniffing-test.c $(TEST_SRCS) @@ -132,6 +134,7 @@ TESTS = \ redirect-test \ requester-test \ resource-test \ + session-test \ sniffing-test \ socket-test \ ssl-test \ diff --git a/tests/session-test.c b/tests/session-test.c new file mode 100644 index 0000000..3207797 --- /dev/null +++ b/tests/session-test.c @@ -0,0 +1,234 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +#include "test-utils.h" + +static gboolean server_processed_message; +static gboolean timeout; +static GMainLoop *loop; + +static gboolean +timeout_cb (gpointer user_data) +{ + gboolean *timeout = user_data; + + *timeout = TRUE; + return FALSE; +} + +static void +server_handler (SoupServer *server, + SoupMessage *msg, + const char *path, + GHashTable *query, + SoupClientContext *client, + gpointer user_data) +{ + if (!strcmp (path, "/request-timeout")) { + GMainContext *context = soup_server_get_async_context (server); + GSource *timer; + + timer = g_timeout_source_new (100); + g_source_set_callback (timer, timeout_cb, &timeout, NULL); + g_source_attach (timer, context); + g_source_unref (timer); + } else + server_processed_message = TRUE; + + soup_message_set_status (msg, SOUP_STATUS_OK); + soup_message_set_response (msg, "text/plain", + SOUP_MEMORY_STATIC, + "ok\r\n", 4); +} + +static void +finished_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) +{ + gboolean *finished = user_data; + + *finished = TRUE; +} + +static void +cancel_message_cb (SoupMessage *msg, gpointer session) +{ + soup_session_cancel_message (session, msg, SOUP_STATUS_CANCELLED); + g_main_loop_quit (loop); +} + +static void +do_test_for_session (SoupSession *session, + const char *uri, const char *timeout_uri, + gboolean queue_is_async, + gboolean send_is_blocking, + gboolean cancel_is_immediate) +{ + SoupMessage *msg; + gboolean finished, local_timeout; + guint timeout_id; + + debug_printf (1, " queue_message\n"); + debug_printf (2, " requesting timeout\n"); + msg = soup_message_new ("GET", timeout_uri); + soup_session_send_message (session, msg); + g_object_unref (msg); + + msg = soup_message_new ("GET", uri); + server_processed_message = timeout = finished = FALSE; + soup_session_queue_message (session, msg, finished_cb, &finished); + while (!timeout) + g_usleep (100); + debug_printf (2, " got timeout\n"); + + if (queue_is_async) { + if (server_processed_message) { + debug_printf (1, " message processed without running main loop!\n"); + errors++; + } + debug_printf (2, " waiting for finished\n"); + while (!finished) + g_main_context_iteration (NULL, TRUE); + if (!server_processed_message) { + debug_printf (1, " message finished without server seeing it???\n"); + errors++; + } + } else { + if (!server_processed_message) { + debug_printf (1, " server failed to immediately receive message!\n"); + errors++; + } + debug_printf (2, " waiting for finished\n"); + if (finished) { + debug_printf (1, " message finished without main loop running???\n"); + errors++; + } + while (!finished) + g_main_context_iteration (NULL, TRUE); + } + + debug_printf (1, " send_message\n"); + msg = soup_message_new ("GET", uri); + server_processed_message = local_timeout = FALSE; + timeout_id = g_idle_add_full (G_PRIORITY_HIGH, timeout_cb, &local_timeout, NULL); + soup_session_send_message (session, msg); + + if (!server_processed_message) { + debug_printf (1, " message finished without server seeing it???\n"); + errors++; + } + + if (send_is_blocking) { + if (local_timeout) { + debug_printf (1, " send_message ran main loop!\n"); + errors++; + } + } else { + if (!local_timeout) { + debug_printf (1, " send_message didn't run main loop!\n"); + errors++; + } + } + + if (!local_timeout) + g_source_remove (timeout_id); + + if (!queue_is_async) + return; + + debug_printf (1, " cancel_message\n"); + msg = soup_message_new ("GET", uri); + g_object_ref (msg); + finished = FALSE; + soup_session_queue_message (session, msg, finished_cb, &finished); + g_signal_connect (msg, "wrote-headers", + G_CALLBACK (cancel_message_cb), session); + + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + if (cancel_is_immediate) { + if (!finished) { + debug_printf (1, " cancel did not finish message!\n"); + errors++; + debug_printf (2, " waiting for finished\n"); + while (!finished) + g_main_context_iteration (NULL, TRUE); + } + } else { + if (finished) { + debug_printf (1, " cancel finished message!\n"); + errors++; + } else { + while (!finished) + g_main_context_iteration (NULL, TRUE); + } + } + + if (msg->status_code != SOUP_STATUS_CANCELLED) { + debug_printf (1, " message finished with status %d %s!\n", + msg->status_code, msg->reason_phrase); + errors++; + } + g_object_unref (msg); +} + +static void +do_plain_tests (char *uri, char *timeout_uri) +{ + SoupSession *session; + + debug_printf (1, "SoupSession\n"); + + session = soup_test_session_new (SOUP_TYPE_SESSION, NULL); + do_test_for_session (session, uri, timeout_uri, TRUE, TRUE, FALSE); + soup_test_session_abort_unref (session); +} + +static void +do_async_tests (char *uri, char *timeout_uri) +{ + SoupSession *session; + + debug_printf (1, "\nSoupSessionAsync\n"); + + session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL); + do_test_for_session (session, uri, timeout_uri, TRUE, FALSE, TRUE); + soup_test_session_abort_unref (session); +} + +static void +do_sync_tests (char *uri, char *timeout_uri) +{ + SoupSession *session; + + debug_printf (1, "\nSoupSessionSync\n"); + + session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL); + do_test_for_session (session, uri, timeout_uri, FALSE, TRUE, FALSE); + soup_test_session_abort_unref (session); +} + +int +main (int argc, char **argv) +{ + SoupServer *server; + char *uri, *timeout_uri; + + test_init (argc, argv, NULL); + + server = soup_test_server_new (TRUE); + soup_server_add_handler (server, NULL, server_handler, NULL, NULL); + uri = g_strdup_printf ("http://127.0.0.1:%u", + soup_server_get_port (server)); + timeout_uri = g_strdup_printf ("%s/request-timeout", uri); + + do_plain_tests (uri, timeout_uri); + do_async_tests (uri, timeout_uri); + do_sync_tests (uri, timeout_uri); + + g_free (uri); + g_free (timeout_uri); + soup_test_server_quit_unref (server); + + test_cleanup (); + return errors != 0; +} -- 2.7.4