summaryrefslogtreecommitdiff
path: root/tests/timeout-test.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/timeout-test.c')
-rw-r--r--tests/timeout-test.c300
1 files changed, 228 insertions, 72 deletions
diff --git a/tests/timeout-test.c b/tests/timeout-test.c
index 2bb91d8a..81fb4331 100644
--- a/tests/timeout-test.c
+++ b/tests/timeout-test.c
@@ -2,31 +2,14 @@
#include "test-utils.h"
+static gboolean slow_https;
+
static void
-do_message_to_session (SoupSession *session, const char *uri,
- const char *comment, guint expected_status)
+message_finished (SoupMessage *msg, gpointer user_data)
{
- SoupMessage *msg;
-
- debug_printf (1, " %s\n", comment);
- msg = soup_message_new ("GET", uri);
- soup_session_send_message (session, msg);
-
- if (msg->status_code != expected_status) {
- debug_printf (1, " FAILED: %d %s (expected %d %s)\n",
- msg->status_code, msg->reason_phrase,
- expected_status,
- soup_status_get_phrase (expected_status));
- errors++;
- }
+ gboolean *finished = user_data;
- if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code) &&
- !soup_message_is_keepalive (msg)) {
- debug_printf (1, " ERROR: message is not keepalive!");
- errors++;
- }
-
- g_object_unref (msg);
+ *finished = TRUE;
}
static void
@@ -39,10 +22,37 @@ request_started_cb (SoupSession *session, SoupMessage *msg,
}
static void
-do_tests_for_session (SoupSession *timeout_session,
- SoupSession *idle_session,
- SoupSession *plain_session,
- char *fast_uri, char *slow_uri)
+do_message_to_session (SoupSession *session, const char *uri,
+ const char *comment, guint expected_status)
+{
+ SoupMessage *msg;
+ gboolean finished = FALSE;
+
+ if (comment)
+ debug_printf (1, " msg %s\n", comment);
+ msg = soup_message_new ("GET", uri);
+
+ g_signal_connect (msg, "finished",
+ G_CALLBACK (message_finished), &finished);
+ soup_session_send_message (session, msg);
+
+ soup_test_assert_message_status (msg, expected_status);
+ if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
+ g_assert_true (soup_message_is_keepalive (msg));
+ g_assert_true (finished);
+
+ g_signal_handlers_disconnect_by_func (msg,
+ G_CALLBACK (message_finished),
+ &finished);
+ g_object_unref (msg);
+}
+
+static void
+do_msg_tests_for_session (SoupSession *timeout_session,
+ SoupSession *idle_session,
+ SoupSession *plain_session,
+ const char *fast_uri,
+ const char *slow_uri)
{
SoupSocket *ret, *idle_first, *idle_second;
SoupSocket *plain_first, *plain_second;
@@ -51,14 +61,14 @@ do_tests_for_session (SoupSession *timeout_session,
g_signal_connect (idle_session, "request-started",
G_CALLBACK (request_started_cb), &ret);
do_message_to_session (idle_session, fast_uri, "fast to idle", SOUP_STATUS_OK);
- idle_first = ret;
+ idle_first = g_object_ref (ret);
}
if (plain_session) {
g_signal_connect (plain_session, "request-started",
G_CALLBACK (request_started_cb), &ret);
do_message_to_session (plain_session, fast_uri, "fast to plain", SOUP_STATUS_OK);
- plain_first = ret;
+ plain_first = g_object_ref (ret);
}
do_message_to_session (timeout_session, fast_uri, "fast to timeout", SOUP_STATUS_OK);
@@ -71,10 +81,9 @@ do_tests_for_session (SoupSession *timeout_session,
(gpointer)request_started_cb,
&ret);
- if (idle_first == idle_second) {
- debug_printf (1, " ERROR: idle_session did not close first connection\n");
- errors++;
- }
+ soup_test_assert (idle_first != idle_second,
+ "idle_session did not close first connection");
+ g_object_unref (idle_first);
}
if (plain_session) {
@@ -84,46 +93,174 @@ do_tests_for_session (SoupSession *timeout_session,
(gpointer)request_started_cb,
&ret);
- if (plain_first != plain_second) {
- debug_printf (1, " ERROR: plain_session closed connection\n");
- errors++;
- }
+ soup_test_assert (plain_first == plain_second,
+ "plain_session closed connection");
+ g_object_unref (plain_first);
+ }
+}
+
+static void
+do_request_to_session (SoupSession *session, const char *uri,
+ const char *comment, gboolean expect_timeout)
+{
+ SoupRequest *req;
+ SoupMessage *msg;
+ GInputStream *stream;
+ GError *error = NULL;
+ gboolean finished = FALSE;
+
+ debug_printf (1, " req %s\n", comment);
+ req = soup_session_request (session, uri, NULL);
+ msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (req));
+
+ g_signal_connect (msg, "finished",
+ G_CALLBACK (message_finished), &finished);
+ stream = soup_test_request_send (req, NULL, 0, &error);
+
+ if (expect_timeout)
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
+ else
+ g_assert_no_error (error);
+ g_clear_error (&error);
+
+ if (stream) {
+ soup_test_request_read_all (req, stream, NULL, &error);
+ g_assert_no_error (error);
+ }
+
+ if (stream) {
+ soup_test_request_close_stream (req, stream, NULL, &error);
+ g_assert_no_error (error);
+ g_object_unref (stream);
}
+
+ if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
+ g_assert_true (soup_message_is_keepalive (msg));
+ g_assert_true (finished);
+
+ g_signal_handlers_disconnect_by_func (msg,
+ G_CALLBACK (message_finished),
+ &finished);
+ g_object_unref (msg);
+ g_object_unref (req);
}
static void
-do_timeout_tests (char *fast_uri, char *slow_uri)
+do_req_tests_for_session (SoupSession *timeout_session,
+ SoupSession *idle_session,
+ SoupSession *plain_session,
+ const char *fast_uri,
+ const char *slow_uri)
+{
+ SoupSocket *ret, *idle_first, *idle_second;
+ SoupSocket *plain_first, *plain_second;
+
+ if (idle_session) {
+ g_signal_connect (idle_session, "request-started",
+ G_CALLBACK (request_started_cb), &ret);
+ do_request_to_session (idle_session, fast_uri, "fast to idle", FALSE);
+ idle_first = g_object_ref (ret);
+ }
+
+ if (plain_session) {
+ g_signal_connect (plain_session, "request-started",
+ G_CALLBACK (request_started_cb), &ret);
+ do_request_to_session (plain_session, fast_uri, "fast to plain", FALSE);
+ plain_first = g_object_ref (ret);
+ }
+
+ do_request_to_session (timeout_session, fast_uri, "fast to timeout", FALSE);
+ do_request_to_session (timeout_session, slow_uri, "slow to timeout", TRUE);
+
+ if (idle_session) {
+ do_request_to_session (idle_session, fast_uri, "fast to idle", FALSE);
+ idle_second = ret;
+ g_signal_handlers_disconnect_by_func (idle_session,
+ (gpointer)request_started_cb,
+ &ret);
+
+ soup_test_assert (idle_first != idle_second,
+ "idle_session did not close first connection");
+ g_object_unref (idle_first);
+ }
+
+ if (plain_session) {
+ do_request_to_session (plain_session, fast_uri, "fast to plain", FALSE);
+ plain_second = ret;
+ g_signal_handlers_disconnect_by_func (plain_session,
+ (gpointer)request_started_cb,
+ &ret);
+
+ soup_test_assert (plain_first == plain_second,
+ "plain_session closed connection");
+ g_object_unref (plain_first);
+ }
+}
+
+static void
+do_async_timeout_tests (gconstpointer data)
{
SoupSession *timeout_session, *idle_session, *plain_session;
+ const char *fast_uri = data;
+ const char *slow_uri = g_build_path ("/", fast_uri, "slow", NULL);
+ gboolean extra_slow;
+
+ if (g_str_has_prefix (fast_uri, "https")) {
+ SOUP_TEST_SKIP_IF_NO_TLS;
+
+ extra_slow = slow_https;
+ } else
+ extra_slow = FALSE;
- debug_printf (1, " async\n");
timeout_session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
- SOUP_SESSION_TIMEOUT, 1,
- NULL);
+ SOUP_SESSION_TIMEOUT, extra_slow ? 3 : 1,
+ SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
+ NULL);
idle_session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
- SOUP_SESSION_IDLE_TIMEOUT, 1,
+ SOUP_SESSION_IDLE_TIMEOUT, extra_slow ? 2 : 1,
+ SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
NULL);
/* The "plain" session also has an idle timeout, but it's longer
* than the test takes, so for our purposes it should behave like
* it has no timeout.
*/
plain_session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
- SOUP_SESSION_IDLE_TIMEOUT, 2,
+ SOUP_SESSION_IDLE_TIMEOUT, 20,
+ SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
NULL);
- do_tests_for_session (timeout_session, idle_session, plain_session,
- fast_uri, slow_uri);
+
+ do_msg_tests_for_session (timeout_session, idle_session, plain_session,
+ fast_uri, slow_uri);
+ do_req_tests_for_session (timeout_session, idle_session, plain_session,
+ fast_uri, slow_uri);
soup_test_session_abort_unref (timeout_session);
soup_test_session_abort_unref (idle_session);
soup_test_session_abort_unref (plain_session);
+}
+
+static void
+do_sync_timeout_tests (gconstpointer data)
+{
+ SoupSession *timeout_session, *plain_session;
+ const char *fast_uri = data;
+ const char *slow_uri = g_build_path ("/", fast_uri, "slow", NULL);
+ gboolean extra_slow;
+
+ if (g_str_has_prefix (fast_uri, "https")) {
+ SOUP_TEST_SKIP_IF_NO_TLS;
+
+ extra_slow = slow_https;
+ } else
+ extra_slow = FALSE;
- debug_printf (1, " sync\n");
timeout_session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC,
- SOUP_SESSION_TIMEOUT, 1,
+ SOUP_SESSION_TIMEOUT, extra_slow ? 3 : 1,
NULL);
/* SOUP_SESSION_TIMEOUT doesn't work with sync sessions */
plain_session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC,
NULL);
- do_tests_for_session (timeout_session, NULL, plain_session, fast_uri, slow_uri);
+ do_msg_tests_for_session (timeout_session, NULL, plain_session, fast_uri, slow_uri);
+ do_req_tests_for_session (timeout_session, NULL, plain_session, fast_uri, slow_uri);
soup_test_session_abort_unref (timeout_session);
soup_test_session_abort_unref (plain_session);
}
@@ -154,44 +291,63 @@ server_handler (SoupServer *server,
soup_server_pause_message (server, msg);
g_object_set_data (G_OBJECT (msg), "server", server);
soup_add_timeout (soup_server_get_async_context (server),
- 1100, timeout_finish_message, msg);
+ 4000, timeout_finish_message, msg);
}
}
int
main (int argc, char **argv)
{
- SoupServer *server;
- char *fast_uri, *slow_uri;
+ SoupServer *server, *https_server = NULL;
+ char *uri, *https_uri = NULL;
+ int ret;
test_init (argc, argv, NULL);
- debug_printf (1, "http\n");
server = soup_test_server_new (TRUE);
soup_server_add_handler (server, NULL, server_handler, NULL, NULL);
- fast_uri = g_strdup_printf ("http://127.0.0.1:%u/",
- soup_server_get_port (server));
- slow_uri = g_strdup_printf ("http://127.0.0.1:%u/slow",
- soup_server_get_port (server));
- do_timeout_tests (fast_uri, slow_uri);
- g_free (fast_uri);
- g_free (slow_uri);
- soup_test_server_quit_unref (server);
+ uri = g_strdup_printf ("http://127.0.0.1:%u/",
+ soup_server_get_port (server));
if (tls_available) {
- debug_printf (1, "\nhttps\n");
- server = soup_test_server_new_ssl (TRUE);
- soup_server_add_handler (server, NULL, server_handler, NULL, NULL);
- fast_uri = g_strdup_printf ("https://127.0.0.1:%u/",
- soup_server_get_port (server));
- slow_uri = g_strdup_printf ("https://127.0.0.1:%u/slow",
- soup_server_get_port (server));
- do_timeout_tests (fast_uri, slow_uri);
- g_free (fast_uri);
- g_free (slow_uri);
- soup_test_server_quit_unref (server);
- }
+ SoupSession *test_session;
+ gint64 start, end;
+
+ https_server = soup_test_server_new_ssl (TRUE);
+ soup_server_add_handler (https_server, NULL, server_handler, NULL, NULL);
+ https_uri = g_strdup_printf ("https://127.0.0.1:%u/",
+ soup_server_get_port (https_server));
+
+ /* The 1-second timeouts are too fast for some machines... */
+ test_session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);
+ start = g_get_monotonic_time ();
+ do_message_to_session (test_session, uri, NULL, SOUP_STATUS_OK);
+ end = g_get_monotonic_time ();
+ soup_test_session_abort_unref (test_session);
+ debug_printf (2, " (https request took %0.3fs)\n", (end - start) / 1000000.0);
+ if (end - start > 750000) {
+ debug_printf (1, " (using extra-slow mode)\n\n");
+ slow_https = TRUE;
+ } else {
+ debug_printf (2, "\n");
+ slow_https = FALSE;
+ }
+ } else
+ https_uri = g_strdup ("https://fail.");
+
+ g_test_add_data_func ("/timeout/http/async", uri, do_async_timeout_tests);
+ g_test_add_data_func ("/timeout/http/sync", uri, do_sync_timeout_tests);
+ g_test_add_data_func ("/timeout/https/async", https_uri, do_async_timeout_tests);
+ g_test_add_data_func ("/timeout/https/sync", https_uri, do_sync_timeout_tests);
+
+ ret = g_test_run ();
+
+ g_free (uri);
+ g_free (https_uri);
+ soup_test_server_quit_unref (server);
+ if (https_server)
+ soup_test_server_quit_unref (https_server);
test_cleanup ();
- return errors != 0;
+ return ret;
}