[libsoup] tests: add some more SoupRequester-based tests



commit d587569cd53c0faf8821260d65e4bb38a3094a58
Author: Dan Winship <danw gnome org>
Date:   Wed Apr 11 23:17:13 2012 -0400

    tests: add some more SoupRequester-based tests
    
    Add SoupRequester-based tests to redirect-test and add
    SoupSessionSync-based tests to requester-test.

 tests/redirect-test.c  |  191 ++++++++++++++++++++++++++++++++++++++++++------
 tests/requester-test.c |  137 ++++++++++++++++++++++++++++++++++-
 2 files changed, 303 insertions(+), 25 deletions(-)
---
diff --git a/tests/redirect-test.c b/tests/redirect-test.c
index aa1fb54..cf294c4 100644
--- a/tests/redirect-test.c
+++ b/tests/redirect-test.c
@@ -10,7 +10,11 @@
 #include <string.h>
 
 #include <glib.h>
+
+#define LIBSOUP_USE_UNSTABLE_REQUEST_API
 #include <libsoup/soup.h>
+#include <libsoup/soup-requester.h>
+#include <libsoup/soup-request-http.h>
 
 #include "test-utils.h"
 
@@ -26,6 +30,7 @@ typedef struct {
 static struct {
 	TestRequest requests[3];
 	guint final_status;
+	guint request_api_final_status;
 } tests[] = {
 	/* A redirecty response to a GET or HEAD should cause a redirect */
 
@@ -110,7 +115,7 @@ static struct {
 
 	/* Test behavior with irrecoverably-bad Location header */
 	{ { { "GET", "/bad-no-host", 302 },
-	    { NULL } }, SOUP_STATUS_MALFORMED },
+	    { NULL } }, SOUP_STATUS_MALFORMED, 302 },
 
 	/* Test infinite redirection */
 	{ { { "GET", "/bad-recursive", 302, TRUE },
@@ -126,7 +131,7 @@ static const int n_tests = G_N_ELEMENTS (tests);
 static void
 got_headers (SoupMessage *msg, gpointer user_data)
 {
-	TestRequest **req = user_data;
+	TestRequest **treq = user_data;
 	const char *location;
 
 	debug_printf (2, "    -> %d %s\n", msg->status_code,
@@ -136,12 +141,12 @@ got_headers (SoupMessage *msg, gpointer user_data)
 	if (location)
 		debug_printf (2, "       Location: %s\n", location);
 
-	if (!(*req)->method)
+	if (!(*treq)->method)
 		return;
 
-	if (msg->status_code != (*req)->status_code) {
+	if (msg->status_code != (*treq)->status_code) {
 		debug_printf (1, "    - Expected %d !\n",
-			      (*req)->status_code);
+			      (*treq)->status_code);
 		errors++;
 	}
 }
@@ -149,36 +154,36 @@ got_headers (SoupMessage *msg, gpointer user_data)
 static void
 restarted (SoupMessage *msg, gpointer user_data)
 {
-	TestRequest **req = user_data;
+	TestRequest **treq = user_data;
 	SoupURI *uri = soup_message_get_uri (msg);
 
 	debug_printf (2, "    %s %s\n", msg->method, uri->path);
 
-	if ((*req)->method && !(*req)->repeat)
-		(*req)++;
+	if ((*treq)->method && !(*treq)->repeat)
+		(*treq)++;
 
-	if (!(*req)->method) {
+	if (!(*treq)->method) {
 		debug_printf (1, "    - Expected to be done!\n");
 		errors++;
 		return;
 	}
 
-	if (strcmp (msg->method, (*req)->method) != 0) {
-		debug_printf (1, "    - Expected %s !\n", (*req)->method);
+	if (strcmp (msg->method, (*treq)->method) != 0) {
+		debug_printf (1, "    - Expected %s !\n", (*treq)->method);
 		errors++;
 	}
-	if (strcmp (uri->path, (*req)->path) != 0) {
-		debug_printf (1, "    - Expected %s !\n", (*req)->path);
+	if (strcmp (uri->path, (*treq)->path) != 0) {
+		debug_printf (1, "    - Expected %s !\n", (*treq)->path);
 		errors++;
 	}
 }
 
 static void
-do_test (SoupSession *session, SoupURI *base_uri, int n)
+do_message_api_test (SoupSession *session, SoupURI *base_uri, int n)
 {
 	SoupURI *uri;
 	SoupMessage *msg;
-	TestRequest *req;
+	TestRequest *treq;
 
 	debug_printf (1, "%2d. %s %s\n", n + 1,
 		      tests[n].requests[0].method,
@@ -195,11 +200,11 @@ do_test (SoupSession *session, SoupURI *base_uri, int n)
 					  strlen ("post body"));
 	}
 
-	req = &tests[n].requests[0];
+	treq = &tests[n].requests[0];
 	g_signal_connect (msg, "got_headers",
-			  G_CALLBACK (got_headers), &req);
+			  G_CALLBACK (got_headers), &treq);
 	g_signal_connect (msg, "restarted",
-			  G_CALLBACK (restarted), &req);
+			  G_CALLBACK (restarted), &treq);
 
 	soup_session_send_message (session, msg);
 
@@ -214,21 +219,159 @@ do_test (SoupSession *session, SoupURI *base_uri, int n)
 }
 
 static void
+async_callback (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+	GAsyncResult **result_p = user_data;
+
+	*result_p = g_object_ref (result);
+}
+
+static void
+do_request_api_test (SoupSession *session, SoupURI *base_uri, int n)
+{
+	SoupRequester *requester = (SoupRequester *)soup_session_get_feature (session, SOUP_TYPE_REQUESTER);
+	SoupURI *uri;
+	SoupRequest *req;
+	SoupMessage *msg;
+	TestRequest *treq;
+	GInputStream *stream;
+	GAsyncResult *result;
+	GError *error = NULL;
+	guint final_status;
+
+	debug_printf (1, "%2d. %s %s\n", n + 1,
+		      tests[n].requests[0].method,
+		      tests[n].requests[0].path);
+
+	final_status = tests[n].request_api_final_status;
+	if (!final_status)
+		final_status = tests[n].final_status;
+
+	uri = soup_uri_new_with_base (base_uri, tests[n].requests[0].path);
+	req = soup_requester_request_uri (requester, uri, &error);
+	soup_uri_free (uri);
+	if (!req) {
+		debug_printf (1, "    could not create request: %s\n",
+			      error->message);
+		g_error_free (error);
+		errors++;
+		debug_printf (2, "\n");
+		return;
+	}
+
+	msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (req));
+	g_object_set (G_OBJECT (msg),
+		      SOUP_MESSAGE_METHOD, tests[n].requests[0].method,
+		      NULL);
+
+	if (msg->method == SOUP_METHOD_POST) {
+		soup_message_set_request (msg, "text/plain",
+					  SOUP_MEMORY_STATIC,
+					  "post body",
+					  strlen ("post body"));
+	}
+
+	treq = &tests[n].requests[0];
+	g_signal_connect (msg, "got_headers",
+			  G_CALLBACK (got_headers), &treq);
+	g_signal_connect (msg, "restarted",
+			  G_CALLBACK (restarted), &treq);
+
+	if (SOUP_IS_SESSION_SYNC (session)) {
+		stream = soup_request_send (req, NULL, &error);
+	} else {
+		result = NULL;
+		soup_request_send_async (req, NULL, async_callback, &result);
+		while (!result)
+			g_main_context_iteration (NULL, TRUE);
+		stream = soup_request_send_finish (req, result, &error);
+		g_object_unref (result);
+	}
+
+	if (SOUP_STATUS_IS_TRANSPORT_ERROR (final_status)) {
+		if (stream) {
+			debug_printf (1, "    expected failure (%s) but succeeded",
+				      soup_status_get_phrase (final_status));
+			errors++;
+			g_object_unref (stream);
+		}
+		if (error->domain != SOUP_HTTP_ERROR ||
+		    error->code != final_status) {
+			debug_printf (1, "    expected '%s' but got '%s'",
+				      soup_status_get_phrase (final_status),
+				      error->message);
+			errors++;
+		}
+
+		g_error_free (error);
+		g_object_unref (req);
+		debug_printf (2, "\n");
+		return;
+	} else if (!stream) {
+		debug_printf (1, "    could not send request: %s\n",
+			      error->message);
+		g_error_free (error);
+		g_object_unref (req);
+		errors++;
+		debug_printf (2, "\n");
+		return;
+	}
+
+	if (SOUP_IS_SESSION_SYNC (session)) {
+		g_input_stream_close (stream, NULL, &error);
+	} else {
+		result = NULL;
+		g_input_stream_close_async (stream, G_PRIORITY_DEFAULT,
+					    NULL, async_callback, &result);
+		while (!result)
+			g_main_context_iteration (NULL, TRUE);
+		g_input_stream_close_finish (stream, result, &error);
+		g_object_unref (result);
+	}
+	if (error) {
+		debug_printf (1, "    could not close stream: %s\n",
+			      error->message);
+		g_error_free (error);
+		errors++;
+	}
+
+	if (msg->status_code != final_status) {
+		debug_printf (1, "    - Expected final status of %d, got %d !\n",
+			      final_status, msg->status_code);
+		errors++;
+	}
+
+	g_object_unref (req);
+	debug_printf (2, "\n");
+}
+
+static void
 do_redirect_tests (SoupURI *base_uri)
 {
 	SoupSession *session;
 	int n;
 
-	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
-	debug_printf (1, "Async session\n");
+	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
+					 SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_REQUESTER,
+					 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
+					 NULL);
+	debug_printf (1, "Async session, SoupMessage\n");
+	for (n = 0; n < n_tests; n++)
+		do_message_api_test (session, base_uri, n);
+	debug_printf (1, "\nAsync session, SoupRequest\n");
 	for (n = 0; n < n_tests; n++)
-		do_test (session, base_uri, n);
+		do_request_api_test (session, base_uri, n);
 	soup_test_session_abort_unref (session);
 
-	session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
-	debug_printf (1, "\nSync session\n");
+	session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC,
+					 SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_REQUESTER,
+					 NULL);
+	debug_printf (1, "\nSync session, SoupMessage\n");
+	for (n = 0; n < n_tests; n++)
+		do_message_api_test (session, base_uri, n);
+	debug_printf (1, "\nSync session, SoupRequest\n");
 	for (n = 0; n < n_tests; n++)
-		do_test (session, base_uri, n);
+		do_request_api_test (session, base_uri, n);
 	soup_test_session_abort_unref (session);
 }
 
diff --git a/tests/requester-test.c b/tests/requester-test.c
index 0c71d0b..56c50f3 100644
--- a/tests/requester-test.c
+++ b/tests/requester-test.c
@@ -125,6 +125,7 @@ test_read_ready (GObject *source, GAsyncResult *res, gpointer user_data)
 		debug_printf (1, "    read_async failed: %s", error->message);
 		g_error_free (error);
 		errors++;
+		g_input_stream_close (stream, NULL, NULL);
 		g_object_unref (stream);
 		g_main_loop_quit (loop);
 		return;
@@ -325,7 +326,9 @@ do_simple_test (const char *uri)
 
 	debug_printf (1, "Simple streaming test\n");
 
-	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
+	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
+					 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
+					 NULL);
 	do_test_for_thread_and_context (session, uri);
 	soup_test_session_abort_unref (session);
 }
@@ -341,6 +344,7 @@ do_test_with_context (const char *uri)
 
 	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
 					 SOUP_SESSION_ASYNC_CONTEXT, async_context,
+					 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
 					 NULL);
 
 	do_test_for_thread_and_context (session, uri);
@@ -371,6 +375,135 @@ do_thread_test (const char *uri)
 	g_thread_join (thread);
 }
 
+static void
+do_sync_request (SoupSession *session, SoupRequest *request,
+		 guint expected_status, SoupBuffer *expected_response,
+		 gboolean persistent)
+{
+	GInputStream *in;
+	SoupMessage *msg;
+	GError *error = NULL;
+	GString *body;
+	char buf[1024];
+	gssize nread;
+	guint started_id;
+	SoupSocket *socket = NULL;
+
+	started_id = g_signal_connect (session, "request-started",
+				       G_CALLBACK (request_started),
+				       &socket);
+
+	in = soup_request_send (request, NULL, &error);
+	g_signal_handler_disconnect (session, started_id);
+	if (!in) {
+		debug_printf (1, "    soup_request_send failed: %s\n",
+			      error->message);
+		g_clear_error (&error);
+		errors++;
+		return;
+	}
+
+	msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (request));
+	if (msg->status_code != expected_status) {
+		debug_printf (1, "    GET failed: %d %s", msg->status_code,
+			      msg->reason_phrase);
+		errors++;
+		return;
+	}
+	g_object_unref (msg);
+
+	body = g_string_new (NULL);
+	do {
+		nread = g_input_stream_read (in, buf, sizeof (buf),
+					     NULL, &error);
+		if (nread == -1) {
+			debug_printf (1, "    g_input_stream_read failed: %s\n",
+				      error->message);
+			g_clear_error (&error);
+			errors++;
+			break;
+		}
+		g_string_append_len (body, buf, nread);
+	} while (nread > 0);
+
+	if (!g_input_stream_close (in, NULL, &error)) {
+		debug_printf (1, "    g_input_stream_close failed: %s\n",
+			      error->message);
+		g_clear_error (&error);
+		errors++;
+	}
+	g_object_unref (in);
+
+	if (body->len != expected_response->length) {
+		debug_printf (1, "    body length mismatch: expected %d, got %d\n",
+			      (int)expected_response->length, (int)body->len);
+		errors++;
+	} else if (memcmp (body->str, expected_response->data, body->len) != 0) {
+		debug_printf (1, "    body data mismatch\n");
+		errors++;
+	}
+
+	if (persistent) {
+		if (!soup_socket_is_connected (socket)) {
+			debug_printf (1, "    socket not still connected!\n");
+			errors++;
+		}
+	} else {
+		if (soup_socket_is_connected (socket)) {
+			debug_printf (1, "    socket still connected!\n");
+			errors++;
+		}
+	}
+	g_object_unref (socket);
+
+	g_string_free (body, TRUE);
+}
+
+static void
+do_sync_test (const char *uri_string)
+{
+	SoupSession *session;
+	SoupRequester *requester;
+	SoupRequest *request;
+	SoupURI *uri;
+
+	debug_printf (1, "Sync streaming\n");
+
+	session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
+	requester = soup_requester_new ();
+	soup_session_add_feature (session, SOUP_SESSION_FEATURE (requester));
+	g_object_unref (requester);
+
+	uri = soup_uri_new (uri_string);
+
+	debug_printf (1, "  basic test\n");
+	request = soup_requester_request_uri (requester, uri, NULL);
+	do_sync_request (session, request, SOUP_STATUS_OK, response, TRUE);
+	g_object_unref (request);
+
+	debug_printf (1, "  chunked test\n");
+	soup_uri_set_path (uri, "/chunked");
+	request = soup_requester_request_uri (requester, uri, NULL);
+	do_sync_request (session, request, SOUP_STATUS_OK, response, TRUE);
+	g_object_unref (request);
+
+	debug_printf (1, "  auth test\n");
+	soup_uri_set_path (uri, "/auth");
+	request = soup_requester_request_uri (requester, uri, NULL);
+	do_sync_request (session, request, SOUP_STATUS_UNAUTHORIZED,
+			 auth_response, TRUE);
+	g_object_unref (request);
+
+	debug_printf (1, "  non-persistent test\n");
+	soup_uri_set_path (uri, "/non-persistent");
+	request = soup_requester_request_uri (requester, uri, NULL);
+	do_sync_request (session, request, SOUP_STATUS_OK, response, FALSE);
+	g_object_unref (request);
+
+	soup_test_session_abort_unref (session);
+	soup_uri_free (uri);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -387,9 +520,11 @@ main (int argc, char **argv)
 	do_simple_test (uri);
 	do_thread_test (uri);
 	do_context_test (uri);
+	do_sync_test (uri);
 
 	g_free (uri);
 	soup_buffer_free (response);
+	soup_buffer_free (auth_response);
 	soup_test_server_quit_unref (server);
 
 	test_cleanup ();



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