[libsoup] test-utils: add cancellation support to soup_test_request_send



commit b980d54cb2b77b6b9c54168e9c7ff772734caaac
Author: Sergio Villar Senin <svillar igalia com>
Date:   Wed Jan 30 17:56:38 2013 +0100

    test-utils: add cancellation support to soup_test_request_send
    
    The function gets a new parametter used to enable request cancellation for
    both sync and async sessions. The cancellation could be performed by either
    using the GCancellable or by directly cancelling the SoupMessage.
    
    Also the GMainContext used to simulate sync operations with async ones will
    now try to execute all its pending events before quiting the main loop.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=692310

 tests/cache-test.c      |    2 +-
 tests/coding-test.c     |    2 +-
 tests/connection-test.c |    4 +-
 tests/misc-test.c       |   56 ++++++++++++++-------------------
 tests/proxy-test.c      |    2 +-
 tests/redirect-test.c   |    2 +-
 tests/sniffing-test.c   |    4 +-
 tests/test-utils.c      |   80 +++++++++++++++++++++++++++++++++++++++++++++--
 tests/test-utils.h      |   12 ++++++-
 tests/timeout-test.c    |    2 +-
 10 files changed, 120 insertions(+), 46 deletions(-)
---
diff --git a/tests/cache-test.c b/tests/cache-test.c
index ac19bfe..22ca6f8 100644
--- a/tests/cache-test.c
+++ b/tests/cache-test.c
@@ -146,7 +146,7 @@ do_request (SoupSession *session,
 	}
 	g_object_unref (msg);
 
-	stream = soup_test_request_send (SOUP_REQUEST (req), NULL, &error);
+	stream = soup_test_request_send (SOUP_REQUEST (req), NULL, 0, &error);
 	if (!stream) {
 		debug_printf (1, "    could not send request: %s\n",
 			      error->message);
diff --git a/tests/coding-test.c b/tests/coding-test.c
index 5d4f0e3..30417b4 100644
--- a/tests/coding-test.c
+++ b/tests/coding-test.c
@@ -337,7 +337,7 @@ do_single_coding_req_test (SoupRequestHTTP *reqh,
 
 	data = g_byte_array_new ();
 
-	stream = soup_test_request_send (SOUP_REQUEST (reqh), NULL, &error);
+	stream = soup_test_request_send (SOUP_REQUEST (reqh), NULL, 0, &error);
 	if (error) {
 		debug_printf (1, "    Error sending request: %s\n",
 			      error->message);
diff --git a/tests/connection-test.c b/tests/connection-test.c
index 6b57f24..b721136 100644
--- a/tests/connection-test.c
+++ b/tests/connection-test.c
@@ -316,7 +316,7 @@ do_timeout_req_test_for_session (SoupSession *session)
 	req = soup_session_request_uri (session, timeout_uri, NULL);
 	soup_uri_free (timeout_uri);
 
-	stream = soup_test_request_send (req, NULL, &error);
+	stream = soup_test_request_send (req, NULL, 0, &error);
 	if (!stream) {
 		debug_printf (1, "      Unexpected error on send: %s\n",
 			      error->message);
@@ -343,7 +343,7 @@ do_timeout_req_test_for_session (SoupSession *session)
 	debug_printf (1, "    Second request\n");
 	req = soup_session_request_uri (session, base_uri, NULL);
 
-	stream = soup_test_request_send (req, NULL, &error);
+	stream = soup_test_request_send (req, NULL, 0, &error);
 	if (!stream) {
 		debug_printf (1, "      Unexpected error on send: %s\n",
 			      error->message);
diff --git a/tests/misc-test.c b/tests/misc-test.c
index b243ce4..d434e9b 100644
--- a/tests/misc-test.c
+++ b/tests/misc-test.c
@@ -905,24 +905,9 @@ do_cancel_while_reading_test (void)
 	soup_test_session_abort_unref (session);
 }
 
-static gboolean
-cancel_request_timeout (gpointer cancellable)
-{
-	g_cancellable_cancel (cancellable);
-	return FALSE;
-}
-
-static gpointer
-cancel_request_thread (gpointer cancellable)
-{
-	g_usleep (100000); /* .1s */
-	g_cancellable_cancel (cancellable);
-	g_object_unref (cancellable);
-	return NULL;
-}
-
 static void
-do_cancel_while_reading_req_test_for_session (SoupSession *session)
+do_cancel_while_reading_req_test_for_session (SoupSession *session,
+					      guint flags)
 {
 	SoupRequest *req;
 	SoupURI *uri;
@@ -934,18 +919,7 @@ do_cancel_while_reading_req_test_for_session (SoupSession *session)
 	soup_uri_free (uri);
 
 	cancellable = g_cancellable_new ();
-
-	if (SOUP_IS_SESSION_ASYNC (soup_request_get_session (req))) {
-		g_timeout_add (100, cancel_request_timeout, cancellable);
-		soup_test_request_send (req, cancellable, &error);
-	} else {
-		GThread *thread;
-
-		thread = g_thread_new ("cancel_request_thread", cancel_request_thread, g_object_ref (cancellable));
-		soup_test_request_send (req, cancellable, &error);
-		g_thread_unref (thread);
-	}
-
+	soup_test_request_send (req, cancellable, flags, &error);
 	if (!error) {
 		debug_printf (1, "  Request succeeded?\n");
 		errors++;
@@ -964,20 +938,38 @@ static void
 do_cancel_while_reading_req_test (void)
 {
 	SoupSession *session;
+	guint flags;
+
+	debug_printf (1, "\nCancelling (immediately) message while reading response (request api)\n");
+	flags = SOUP_TEST_REQUEST_CANCEL_CANCELLABLE;
+
+	debug_printf (1, "  Async session\n");
+	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
+					 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
+					 NULL);
+	do_cancel_while_reading_req_test_for_session (session, flags);
+	soup_test_session_abort_unref (session);
+
+	debug_printf (1, "  Sync session\n");
+	session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC,
+					 NULL);
+	do_cancel_while_reading_req_test_for_session (session, flags);
+	soup_test_session_abort_unref (session);
 
-	debug_printf (1, "\nCancelling message while reading response (request api)\n");
+	debug_printf (1, "\nCancelling (after 100ms) message while reading response (request api)\n");
+	flags = SOUP_TEST_REQUEST_CANCEL_CANCELLABLE | SOUP_TEST_REQUEST_CANCEL_SOON;
 
 	debug_printf (1, "  Async session\n");
 	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
 					 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
 					 NULL);
-	do_cancel_while_reading_req_test_for_session (session);
+	do_cancel_while_reading_req_test_for_session (session, flags);
 	soup_test_session_abort_unref (session);
 
 	debug_printf (1, "  Sync session\n");
 	session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC,
 					 NULL);
-	do_cancel_while_reading_req_test_for_session (session);
+	do_cancel_while_reading_req_test_for_session (session, flags);
 	soup_test_session_abort_unref (session);
 }
 
diff --git a/tests/proxy-test.c b/tests/proxy-test.c
index 048acfa..1ac3855 100644
--- a/tests/proxy-test.c
+++ b/tests/proxy-test.c
@@ -164,7 +164,7 @@ test_url_new_api (const char *url, int proxy, guint expected,
 	request = soup_session_request (session, url, NULL);
 	msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (request));
 
-	stream = soup_test_request_send (request, NULL, &error);
+	stream = soup_test_request_send (request, NULL, 0, &error);
 	if (!stream) {
 		debug_printf (1, "  Unexpected error on Request: %s\n",
 			      error->message);
diff --git a/tests/redirect-test.c b/tests/redirect-test.c
index 3307ce6..9bc4621 100644
--- a/tests/redirect-test.c
+++ b/tests/redirect-test.c
@@ -252,7 +252,7 @@ do_request_api_test (SoupSession *session, SoupURI *base_uri, int n)
 	g_signal_connect (msg, "restarted",
 			  G_CALLBACK (restarted), &treq);
 
-	stream = soup_test_request_send (SOUP_REQUEST (reqh), NULL, &error);
+	stream = soup_test_request_send (SOUP_REQUEST (reqh), NULL, 0, &error);
 
 	if (SOUP_STATUS_IS_TRANSPORT_ERROR (final_status)) {
 		if (stream) {
diff --git a/tests/sniffing-test.c b/tests/sniffing-test.c
index f28ddaf..cbebaba 100644
--- a/tests/sniffing-test.c
+++ b/tests/sniffing-test.c
@@ -383,7 +383,7 @@ test_sniffing (const char *path, const char *expected_type)
 	g_object_unref (msg);
 
 	req = soup_session_request_uri (session, uri, NULL);
-	stream = soup_test_request_send (req, NULL, &error);
+	stream = soup_test_request_send (req, NULL, 0, &error);
 	if (stream) {
 		soup_test_request_close_stream (req, stream, NULL, &error);
 		g_object_unref (stream);
@@ -439,7 +439,7 @@ test_disabled (const char *path)
 	msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (req));
 	soup_message_disable_feature (msg, SOUP_TYPE_CONTENT_SNIFFER);
 	g_object_unref (msg);
-	stream = soup_test_request_send (req, NULL, &error);
+	stream = soup_test_request_send (req, NULL, 0, &error);
 	if (stream) {
 		soup_test_request_close_stream (req, stream, NULL, &error);
 		g_object_unref (stream);
diff --git a/tests/test-utils.c b/tests/test-utils.c
index fc5b18d..cc9aa8e 100644
--- a/tests/test-utils.c
+++ b/tests/test-utils.c
@@ -371,24 +371,98 @@ async_as_sync_callback (GObject      *object,
 			gpointer      user_data)
 {
 	AsyncAsSyncData *data = user_data;
+	GMainContext *context;
 
 	data->result = g_object_ref (result);
+	context = g_main_loop_get_context (data->loop);
+	while (g_main_context_pending (context))
+		g_main_context_iteration (context, FALSE);
 	g_main_loop_quit (data->loop);
 }
 
+typedef struct {
+	SoupRequest  *req;
+	GCancellable *cancellable;
+	SoupTestRequestFlags flags;
+} CancelData;
+
+static CancelData *
+create_cancel_data (SoupRequest          *req,
+		    GCancellable         *cancellable,
+		    SoupTestRequestFlags  flags)
+{
+	CancelData *cancel_data;
+
+	if (!flags)
+		return NULL;
+
+	cancel_data = g_slice_new0 (CancelData);
+	cancel_data->flags = flags;
+	if (flags & SOUP_TEST_REQUEST_CANCEL_MESSAGE && SOUP_IS_REQUEST_HTTP (req))
+		cancel_data->req = g_object_ref (req);
+	else if (flags & SOUP_TEST_REQUEST_CANCEL_CANCELLABLE)
+		cancel_data->cancellable = g_object_ref (cancellable);
+	return cancel_data;
+}
+
+static void inline
+cancel_message_or_cancellable (CancelData *cancel_data)
+{
+	if (cancel_data->flags & SOUP_TEST_REQUEST_CANCEL_MESSAGE) {
+		SoupRequest *req = cancel_data->req;
+		soup_session_cancel_message (soup_request_get_session (req),
+					     soup_request_http_get_message (SOUP_REQUEST_HTTP (req)),
+					     SOUP_STATUS_CANCELLED);
+		g_object_unref (req);
+	} else if (cancel_data->flags & SOUP_TEST_REQUEST_CANCEL_CANCELLABLE) {
+		g_cancellable_cancel (cancel_data->cancellable);
+		g_object_unref (cancel_data->cancellable);
+	}
+	g_slice_free (CancelData, cancel_data);
+}
+
+static gboolean
+cancel_request_timeout (gpointer data)
+{
+	cancel_message_or_cancellable ((CancelData *) data);
+	return FALSE;
+}
+
+static gpointer
+cancel_request_thread (gpointer data)
+{
+	g_usleep (100000); /* .1s */
+	cancel_message_or_cancellable ((CancelData *) data);
+	return NULL;
+}
+
 GInputStream *
 soup_test_request_send (SoupRequest   *req,
 			GCancellable  *cancellable,
+			guint          flags,
 			GError       **error)
 {
 	AsyncAsSyncData data;
 	GInputStream *stream;
+	CancelData *cancel_data = create_cancel_data (req, cancellable, flags);
 
-	if (SOUP_IS_SESSION_SYNC (soup_request_get_session (req)))
-		return soup_request_send (req, cancellable, error);
+	if (SOUP_IS_SESSION_SYNC (soup_request_get_session (req))) {
+		GThread *thread;
 
-	data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
+		if (cancel_data)
+			thread = g_thread_new ("cancel_request_thread", cancel_request_thread,
+					       cancel_data);
+		stream = soup_request_send (req, cancellable, error);
+		if (cancel_data)
+			g_thread_unref (thread);
+		return stream;
+	}
 
+	data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
+	if (cancel_data) {
+		guint interval = flags & SOUP_TEST_REQUEST_CANCEL_SOON ? 100 : 0;
+		g_timeout_add_full (G_PRIORITY_HIGH, interval, cancel_request_timeout, cancel_data, NULL);
+	}
 	soup_request_send_async (req, cancellable, async_as_sync_callback, &data);
 	g_main_loop_run (data.loop);
 
diff --git a/tests/test-utils.h b/tests/test-utils.h
index ca1003f..22a4a16 100644
--- a/tests/test-utils.h
+++ b/tests/test-utils.h
@@ -23,6 +23,13 @@ void apache_init    (void);
 void apache_cleanup (void);
 #endif
 
+typedef enum {
+  SOUP_TEST_REQUEST_NONE = 0,
+  SOUP_TEST_REQUEST_CANCEL_MESSAGE = (1 << 0),
+  SOUP_TEST_REQUEST_CANCEL_CANCELLABLE = (1 << 1),
+  SOUP_TEST_REQUEST_CANCEL_SOON = (1 << 2)
+} SoupTestRequestFlags;
+
 SoupSession *soup_test_session_new         (GType type, ...);
 void         soup_test_session_abort_unref (SoupSession *session);
 
@@ -30,8 +37,9 @@ SoupServer  *soup_test_server_new        (gboolean in_own_thread);
 SoupServer  *soup_test_server_new_ssl    (gboolean in_own_thread);
 void         soup_test_server_quit_unref (SoupServer *server);
 
-GInputStream *soup_test_request_send         (SoupRequest   *req,
-					      GCancellable  *cancellable,
+GInputStream *soup_test_request_send         (SoupRequest  *req,
+					      GCancellable *cancellable,
+					      guint         flags,
 					      GError       **error);
 gboolean      soup_test_request_close_stream (SoupRequest   *req,
 					      GInputStream  *stream,
diff --git a/tests/timeout-test.c b/tests/timeout-test.c
index e523f2d..27bcbff 100644
--- a/tests/timeout-test.c
+++ b/tests/timeout-test.c
@@ -127,7 +127,7 @@ do_request_to_session (SoupSession *session, const char *uri,
 
 	g_signal_connect (msg, "finished",
 			  G_CALLBACK (message_finished), &finished);
-	stream = soup_test_request_send (req, NULL, &error);
+	stream = soup_test_request_send (req, NULL, 0, &error);
 
 	if (expect_timeout && !error) {
 		debug_printf (1, "      FAILED: request did not time out\n");


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]