diff options
Diffstat (limited to 'tests/session-test.c')
-rw-r--r-- | tests/session-test.c | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/tests/session-test.c b/tests/session-test.c new file mode 100644 index 00000000..15072058 --- /dev/null +++ b/tests/session-test.c @@ -0,0 +1,396 @@ +/* -*- 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 SoupMessagePriority expected_priorities[3]; + +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, + gboolean queue_is_async, + gboolean send_is_blocking, + gboolean cancel_is_immediate) +{ + SoupMessage *msg; + gboolean finished, local_timeout; + guint timeout_id; + char *timeout_uri; + + debug_printf (1, " queue_message\n"); + debug_printf (2, " requesting timeout\n"); + timeout_uri = g_strdup_printf ("%s/request-timeout", uri); + msg = soup_message_new ("GET", timeout_uri); + g_free (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) { + g_assert_false (server_processed_message); + debug_printf (2, " waiting for finished\n"); + while (!finished) + g_main_context_iteration (NULL, TRUE); + g_assert_true (server_processed_message); + } else { + g_assert_true (server_processed_message); + g_assert_false (finished); + debug_printf (2, " waiting for finished\n"); + 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); + + g_assert_true (server_processed_message); + + if (send_is_blocking) { + soup_test_assert (!local_timeout, + "send_message ran main loop"); + } else { + soup_test_assert (local_timeout, + "send_message didn't run main loop"); + } + + 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) + g_assert_true (finished); + else + g_assert_false (finished); + + if (!finished) { + debug_printf (2, " waiting for finished\n"); + while (!finished) + g_main_context_iteration (NULL, TRUE); + } + + soup_test_assert_message_status (msg, SOUP_STATUS_CANCELLED); + g_object_unref (msg); +} + +static void +do_plain_tests (gconstpointer uri) +{ + SoupSession *session; + + session = soup_test_session_new (SOUP_TYPE_SESSION, NULL); + do_test_for_session (session, uri, TRUE, TRUE, FALSE); + soup_test_session_abort_unref (session); +} + +static void +do_async_tests (gconstpointer uri) +{ + SoupSession *session; + + session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL); + do_test_for_session (session, uri, TRUE, FALSE, TRUE); + soup_test_session_abort_unref (session); +} + +static void +do_sync_tests (gconstpointer uri) +{ + SoupSession *session; + + session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL); + do_test_for_session (session, uri, FALSE, TRUE, FALSE); + soup_test_session_abort_unref (session); +} + +static void +priority_test_finished_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) +{ + guint *finished_count = user_data; + SoupMessagePriority priority = soup_message_get_priority (msg); + + debug_printf (1, " received message %d with priority %d\n", + *finished_count, priority); + + soup_test_assert (priority == expected_priorities[*finished_count], + "message %d should have priority %d (%d found)", + *finished_count, expected_priorities[*finished_count], priority); + + (*finished_count)++; +} + +static void +do_priority_tests (gconstpointer data) +{ + const char *uri = data; + SoupSession *session; + int i, finished_count = 0; + SoupMessagePriority priorities[] = + { SOUP_MESSAGE_PRIORITY_LOW, + SOUP_MESSAGE_PRIORITY_HIGH, + SOUP_MESSAGE_PRIORITY_NORMAL }; + + g_test_bug ("696277"); + + session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL); + g_object_set (session, "max-conns", 1, NULL); + + expected_priorities[0] = SOUP_MESSAGE_PRIORITY_HIGH; + expected_priorities[1] = SOUP_MESSAGE_PRIORITY_NORMAL; + expected_priorities[2] = SOUP_MESSAGE_PRIORITY_LOW; + + for (i = 0; i < 3; i++) { + char *msg_uri; + SoupMessage *msg; + + msg_uri = g_strdup_printf ("%s/%d", uri, i); + msg = soup_message_new ("GET", uri); + g_free (msg_uri); + + soup_message_set_priority (msg, priorities[i]); + soup_session_queue_message (session, msg, priority_test_finished_cb, &finished_count); + } + + debug_printf (2, " waiting for finished\n"); + while (finished_count != 3) + g_main_context_iteration (NULL, TRUE); + + soup_test_session_abort_unref (session); +} + +static void +test_session_properties (const char *name, + SoupSession *session, + GProxyResolver *expected_proxy_resolver, + GTlsDatabase *expected_tls_database) +{ + GProxyResolver *proxy_resolver = NULL; + GTlsDatabase *tlsdb = NULL; + + g_object_get (G_OBJECT (session), + SOUP_SESSION_PROXY_RESOLVER, &proxy_resolver, + SOUP_SESSION_TLS_DATABASE, &tlsdb, + NULL); + + soup_test_assert (proxy_resolver == expected_proxy_resolver, + "%s has %s proxy resolver", + name, proxy_resolver ? (expected_proxy_resolver ? "wrong" : "a") : "no"); + soup_test_assert (tlsdb == expected_tls_database, + "%s has %s TLS database", + name, tlsdb ? (expected_tls_database ? "wrong" : "a") : "no"); + + g_clear_object (&proxy_resolver); + g_clear_object (&tlsdb); +} + +static void +do_property_tests (void) +{ + SoupSession *session; + GProxyResolver *proxy_resolver, *default_proxy_resolver; + GTlsDatabase *tlsdb, *default_tlsdb; + SoupURI *uri; + + g_test_bug ("708696"); + + default_proxy_resolver = g_proxy_resolver_get_default (); + default_tlsdb = g_tls_backend_get_default_database (g_tls_backend_get_default ()); + + /* NOTE: We intentionally do not use soup_test_session_new() here */ + + session = g_object_new (SOUP_TYPE_SESSION, + NULL); + test_session_properties ("Base plain session", session, + default_proxy_resolver, default_tlsdb); + g_object_unref (session); + + session = g_object_new (SOUP_TYPE_SESSION, + SOUP_SESSION_PROXY_RESOLVER, NULL, + NULL); + test_session_properties ("Session with NULL :proxy-resolver", session, + NULL, default_tlsdb); + g_object_unref (session); + + proxy_resolver = g_simple_proxy_resolver_new (NULL, NULL); + session = g_object_new (SOUP_TYPE_SESSION, + SOUP_SESSION_PROXY_RESOLVER, proxy_resolver, + NULL); + test_session_properties ("Session with non-NULL :proxy-resolver", session, + proxy_resolver, default_tlsdb); + g_object_unref (proxy_resolver); + g_object_unref (session); + + session = g_object_new (SOUP_TYPE_SESSION, + SOUP_SESSION_PROXY_URI, NULL, + NULL); + test_session_properties ("Session with NULL :proxy-uri", session, + NULL, default_tlsdb); + g_object_unref (session); + + uri = soup_uri_new ("http://example.com/"); + session = g_object_new (SOUP_TYPE_SESSION, + SOUP_SESSION_PROXY_URI, uri, + NULL); + g_object_get (G_OBJECT (session), + SOUP_SESSION_PROXY_RESOLVER, &proxy_resolver, + NULL); + test_session_properties ("Session with non-NULL :proxy-uri", session, + proxy_resolver, default_tlsdb); + g_assert_cmpstr (G_OBJECT_TYPE_NAME (proxy_resolver), ==, "GSimpleProxyResolver"); + g_object_unref (proxy_resolver); + g_object_unref (session); + soup_uri_free (uri); + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + session = g_object_new (SOUP_TYPE_SESSION, + SOUP_SESSION_REMOVE_FEATURE_BY_TYPE, SOUP_TYPE_PROXY_URI_RESOLVER, + NULL); + test_session_properties ("Session with removed proxy resolver feature", session, + NULL, default_tlsdb); + g_object_unref (session); + G_GNUC_END_IGNORE_DEPRECATIONS; + + session = g_object_new (SOUP_TYPE_SESSION, + SOUP_SESSION_TLS_DATABASE, NULL, + NULL); + test_session_properties ("Session with NULL :tls-database", session, + default_proxy_resolver, NULL); + g_object_unref (session); + + /* g_tls_file_database_new() will fail with the dummy backend, + * so we can only do this test if we have a real TLS backend. + */ + if (tls_available) { + GError *error = NULL; + + tlsdb = g_tls_file_database_new (g_test_get_filename (G_TEST_DIST, + "test-cert.pem", + NULL), &error); + g_assert_no_error (error); + + session = g_object_new (SOUP_TYPE_SESSION, + SOUP_SESSION_TLS_DATABASE, tlsdb, + NULL); + test_session_properties ("Session with non-NULL :tls-database", session, + default_proxy_resolver, tlsdb); + g_object_unref (tlsdb); + g_object_unref (session); + } + + session = g_object_new (SOUP_TYPE_SESSION, + SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, FALSE, + NULL); + test_session_properties ("Session with :ssl-use-system-ca-file FALSE", session, + default_proxy_resolver, NULL); + g_object_unref (session); + + session = g_object_new (SOUP_TYPE_SESSION, + SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE, + NULL); + test_session_properties ("Session with :ssl-use-system-ca-file TRUE", session, + default_proxy_resolver, default_tlsdb); + g_object_unref (session); +} + +int +main (int argc, char **argv) +{ + SoupServer *server; + char *uri, *timeout_uri; + int ret; + + 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); + + g_test_add_data_func ("/session/SoupSession", uri, do_plain_tests); + g_test_add_data_func ("/session/SoupSessionAsync", uri, do_async_tests); + g_test_add_data_func ("/session/SoupSessionSync", uri, do_sync_tests); + g_test_add_data_func ("/session/priority", uri, do_priority_tests); + g_test_add_func ("/session/property", do_property_tests); + + ret = g_test_run (); + + g_free (uri); + g_free (timeout_uri); + soup_test_server_quit_unref (server); + + test_cleanup (); + return ret; +} |