[libsoup] tests: split up some test programs into more tests



commit 8224b826bdadcf8676854723ff51604a5645aae2
Author: Dan Winship <danw gnome org>
Date:   Sun Mar 9 13:03:14 2014 -0400

    tests: split up some test programs into more tests

 tests/auth-test.c          |   83 +++++--
 tests/coding-test.c        |  569 +++++++++++++++++++++++--------------------
 tests/continue-test.c      |   68 +++++-
 tests/forms-test.c         |   96 +++++---
 tests/misc-test.c          |   20 ++-
 tests/ntlm-test.c          |  131 ++++++-----
 tests/server-auth-test.c   |  220 +++++++++--------
 tests/ssl-test.c           |  130 +++++------
 tests/xmlrpc-server-test.c |  136 ++++++-----
 tests/xmlrpc-test.c        |    2 +-
 10 files changed, 831 insertions(+), 624 deletions(-)
---
diff --git a/tests/auth-test.c b/tests/auth-test.c
index def5cfd..ccfed46 100644
--- a/tests/auth-test.c
+++ b/tests/auth-test.c
@@ -541,7 +541,7 @@ async_authenticate_assert_once_and_stop (SoupSession *session, SoupMessage *msg,
 }
 
 static void
-do_async_auth_test (void)
+do_async_auth_good_password_test (void)
 {
        SoupSession *session;
        SoupMessage *msg1, *msg2, *msg3, msg2_bak;
@@ -549,7 +549,6 @@ do_async_auth_test (void)
        char *uri;
        SoupAuth *auth = NULL;
        int remaining;
-       gboolean been_there;
 
        SOUP_TEST_SKIP_IF_NO_APACHE;
 
@@ -557,9 +556,8 @@ do_async_auth_test (void)
 
        loop = g_main_loop_new (NULL, TRUE);
        session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
-       remaining = 0;
-
        uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
+       remaining = 0;
 
        msg1 = soup_message_new ("GET", uri);
        g_object_set_data (G_OBJECT (msg1), "id", GINT_TO_POINTER (1));
@@ -621,27 +619,46 @@ do_async_auth_test (void)
        memcpy (msg2, &msg2_bak, sizeof (SoupMessage));
        g_object_unref (msg2);
 
+       g_free (uri);
+       g_main_loop_unref (loop);
+}
+
+static void
+do_async_auth_bad_password_test (void)
+{
+       SoupSession *session;
+       SoupMessage *msg;
+       guint auth_id;
+       char *uri;
+       SoupAuth *auth = NULL;
+       int remaining;
+       gboolean been_there;
+
        /* Test that giving the wrong password doesn't cause multiple
         * authenticate signals the second time.
         */
        debug_printf (1, "\nTesting async auth with wrong password (#522601):\n");
 
+       SOUP_TEST_SKIP_IF_NO_APACHE;
+
+       loop = g_main_loop_new (NULL, TRUE);
        session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
+       uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
        remaining = 0;
        auth = NULL;
 
-       msg1 = soup_message_new ("GET", uri);
-       g_object_set_data (G_OBJECT (msg1), "id", GINT_TO_POINTER (1));
+       msg = soup_message_new ("GET", uri);
+       g_object_set_data (G_OBJECT (msg), "id", GINT_TO_POINTER (1));
        auth_id = g_signal_connect (session, "authenticate",
                                    G_CALLBACK (async_authenticate), &auth);
-       g_object_ref (msg1);
+       g_object_ref (msg);
        remaining++;
-       soup_session_queue_message (session, msg1, async_finished, &remaining);
+       soup_session_queue_message (session, msg, async_finished, &remaining);
        g_main_loop_run (loop);
        g_signal_handler_disconnect (session, auth_id);
        soup_auth_authenticate (auth, "user1", "wrong");
        g_object_unref (auth);
-       soup_session_unpause_message (session, msg1);
+       soup_session_unpause_message (session, msg);
 
        been_there = FALSE;
        auth_id = g_signal_connect (session, "authenticate",
@@ -654,49 +671,67 @@ do_async_auth_test (void)
                          "authenticate not emitted");
 
        soup_test_session_abort_unref (session);
-       g_object_unref (msg1);
+       g_object_unref (msg);
+
+       g_free (uri);
+       g_main_loop_unref (loop);
+}
+
+static void
+do_async_auth_no_password_test (void)
+{
+       SoupSession *session;
+       SoupMessage *msg;
+       guint auth_id;
+       char *uri;
+       int remaining;
+       gboolean been_there;
 
        /* Test that giving no password doesn't cause multiple
         * authenticate signals the second time.
         */
        debug_printf (1, "\nTesting async auth with no password (#583462):\n");
 
+       SOUP_TEST_SKIP_IF_NO_APACHE;
+
+       loop = g_main_loop_new (NULL, TRUE);
        session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
+       uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
        remaining = 0;
 
        /* Send a message that doesn't actually authenticate
         */
-       msg1 = soup_message_new ("GET", uri);
-       g_object_set_data (G_OBJECT (msg1), "id", GINT_TO_POINTER (1));
+       msg = soup_message_new ("GET", uri);
+       g_object_set_data (G_OBJECT (msg), "id", GINT_TO_POINTER (1));
        auth_id = g_signal_connect (session, "authenticate",
                                    G_CALLBACK (async_authenticate), NULL);
-       g_object_ref (msg1);
+       g_object_ref (msg);
        remaining++;
-       soup_session_queue_message (session, msg1, async_finished, &remaining);
+       soup_session_queue_message (session, msg, async_finished, &remaining);
        g_main_loop_run (loop);
        g_signal_handler_disconnect (session, auth_id);
-       soup_session_unpause_message (session, msg1);
+       soup_session_unpause_message (session, msg);
        g_main_loop_run (loop);
-       g_object_unref(msg1);
+       g_object_unref(msg);
 
        /* Now send a second message */
-       msg1 = soup_message_new ("GET", uri);
-       g_object_set_data (G_OBJECT (msg1), "id", GINT_TO_POINTER (2));
-       g_object_ref (msg1);
+       msg = soup_message_new ("GET", uri);
+       g_object_set_data (G_OBJECT (msg), "id", GINT_TO_POINTER (2));
+       g_object_ref (msg);
        been_there = FALSE;
        auth_id = g_signal_connect (session, "authenticate",
                                    G_CALLBACK (async_authenticate_assert_once_and_stop),
                                    &been_there);
        remaining++;
-       soup_session_queue_message (session, msg1, async_finished, &remaining);
+       soup_session_queue_message (session, msg, async_finished, &remaining);
        g_main_loop_run (loop);
-       soup_session_unpause_message (session, msg1);
+       soup_session_unpause_message (session, msg);
 
        g_main_loop_run (loop);
        g_signal_handler_disconnect (session, auth_id);
 
        soup_test_session_abort_unref (session);
-       g_object_unref (msg1);
+       g_object_unref (msg);
 
        g_free (uri);
        g_main_loop_unref (loop);
@@ -1243,7 +1278,9 @@ main (int argc, char **argv)
        g_test_add_data_func ("/auth/relogin-tests", relogin_tests, do_batch_tests);
        g_test_add_func ("/auth/pipelined-auth", do_pipelined_auth_test);
        g_test_add_func ("/auth/digest-expiration", do_digest_expiration_test);
-       g_test_add_func ("/auth/async-auth", do_async_auth_test);
+       g_test_add_func ("/auth/async-auth/good-password", do_async_auth_good_password_test);
+       g_test_add_func ("/auth/async-auth/bad-password", do_async_auth_bad_password_test);
+       g_test_add_func ("/auth/async-auth/no-password", do_async_auth_no_password_test);
        g_test_add_func ("/auth/select-auth", do_select_auth_test);
        g_test_add_func ("/auth/auth-close", do_auth_close_test);
        g_test_add_func ("/auth/infinite-auth", do_infinite_auth_test);
diff --git a/tests/coding-test.c b/tests/coding-test.c
index d922a19..a044ad7 100644
--- a/tests/coding-test.c
+++ b/tests/coding-test.c
@@ -116,6 +116,20 @@ server_callback (SoupServer *server, SoupMessage *msg,
        soup_message_body_complete (msg->response_body);
 }
 
+typedef struct {
+       SoupSession *session;
+       SoupMessage *msg;
+       SoupRequest *req;
+       SoupBuffer *response;
+} CodingTestData;
+
+typedef enum {
+       CODING_TEST_DEFAULT     = 0,
+       CODING_TEST_NO_DECODER  = (1 << 0),
+       CODING_TEST_REQUEST_API = (1 << 1),
+       CODING_TEST_EMPTY       = (1 << 2)
+} CodingTestType;
+
 typedef enum {
        NO_CHECK,
        EXPECT_DECODED,
@@ -123,159 +137,195 @@ typedef enum {
 } MessageContentStatus;
 
 static void
-check_response (SoupMessage *msg,
+check_response (CodingTestData *data,
                const char *expected_encoding,
                const char *expected_content_type,
-               MessageContentStatus status)
+               MessageContentStatus status,
+               GByteArray *body)
 {
        const char *coding, *type;
 
-       soup_test_assert_message_status (msg, SOUP_STATUS_OK);
+       soup_test_assert_message_status (data->msg, SOUP_STATUS_OK);
 
-       coding = soup_message_headers_get_one (msg->response_headers, "Content-Encoding");
+       coding = soup_message_headers_get_one (data->msg->response_headers, "Content-Encoding");
        g_assert_cmpstr (coding, ==, expected_encoding);
 
        if (status != NO_CHECK) {
                if (status == EXPECT_DECODED)
-                       g_assert_true (soup_message_get_flags (msg) & SOUP_MESSAGE_CONTENT_DECODED);
+                       g_assert_true (soup_message_get_flags (data->msg) & SOUP_MESSAGE_CONTENT_DECODED);
                else
-                       g_assert_false (soup_message_get_flags (msg) & SOUP_MESSAGE_CONTENT_DECODED);
+                       g_assert_false (soup_message_get_flags (data->msg) & SOUP_MESSAGE_CONTENT_DECODED);
        }
 
-       type = soup_message_headers_get_one (msg->response_headers, "Content-Type");
+       type = soup_message_headers_get_one (data->msg->response_headers, "Content-Type");
        g_assert_cmpstr (type, ==, expected_content_type);
+
+       if (body) {
+               soup_assert_cmpmem (body->data,
+                                   body->len,
+                                   data->response->data,
+                                   data->response->length);
+       } else {
+               soup_assert_cmpmem (data->msg->response_body->data,
+                                   data->msg->response_body->length,
+                                   data->response->data,
+                                   data->response->length);
+       }
 }
 
 static void
-do_coding_test (void)
+setup_coding_test (CodingTestData *data, gconstpointer test_data)
 {
-       SoupSession *session;
-       SoupMessage *msg, *msgz, *msgj, *msge, *msgzl, *msgzlj, *msgzle, *msgzlr, *msgzlre;
+       CodingTestType test_type = GPOINTER_TO_INT (test_data);
+       SoupMessage *msg;
        SoupURI *uri;
 
-       debug_printf (1, "SoupMessage tests\n");
+       data->session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
+                                              SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
+                                              NULL);
 
-       session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
        uri = soup_uri_new_with_base (base_uri, "/mbox");
 
-       /* Plain text data, no claim */
+       if (test_type & CODING_TEST_EMPTY)
+               data->response = soup_buffer_new (SOUP_MEMORY_STATIC, "", 0);
+       else {
+               msg = soup_message_new_from_uri ("GET", uri);
+               soup_session_send_message (data->session, msg);
+
+               data->response = soup_message_body_flatten (msg->response_body);
+               g_object_unref (msg);
+       }
+
+       if (test_type & CODING_TEST_REQUEST_API) {
+               SoupRequestHTTP *reqh;
+
+               reqh = soup_session_request_http_uri (data->session, "GET", uri, NULL);
+               data->req = SOUP_REQUEST (reqh);
+               data->msg = soup_request_http_get_message (reqh);
+       } else
+               data->msg = soup_message_new_from_uri ("GET", uri);
+       soup_uri_free (uri);
+
+       if (! (test_type & CODING_TEST_NO_DECODER))
+               soup_session_add_feature_by_type (data->session, SOUP_TYPE_CONTENT_DECODER);
+}
+
+static void
+teardown_coding_test (CodingTestData *data, gconstpointer test_data)
+{
+       soup_buffer_free (data->response);
+
+       g_clear_object (&data->req);
+       g_object_unref (data->msg);
+
+       soup_test_session_abort_unref (data->session);
+}
+
+static void
+do_coding_test_plain (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, plain\n");
-       msg = soup_message_new_from_uri ("GET", uri);
-       soup_session_send_message (session, msg);
-       check_response (msg, NULL, "text/plain", EXPECT_NOT_DECODED);
 
-       /* Plain text data, claim gzip */
+       soup_session_send_message (data->session, data->msg);
+       check_response (data, NULL, "text/plain", EXPECT_NOT_DECODED, NULL);
+}
+
+static void
+do_coding_test_gzip (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: gzip\n");
-       soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_DECODER);
-       msgz = soup_message_new_from_uri ("GET", uri);
-       soup_session_send_message (session, msgz);
-       check_response (msgz, "gzip", "text/plain", EXPECT_DECODED);
-       soup_assert_cmpmem (msg->response_body->data,
-                           msg->response_body->length,
-                           msgz->response_body->data,
-                           msgz->response_body->length);
-
-       /* Plain text data, claim gzip w/ junk */
+
+       soup_session_send_message (data->session, data->msg);
+       check_response (data, "gzip", "text/plain", EXPECT_DECODED, NULL);
+}
+
+static void
+do_coding_test_gzip_with_junk (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: gzip, plus trailing junk\n");
-       msgj = soup_message_new_from_uri ("GET", uri);
-       soup_message_headers_append (msgj->request_headers,
+
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "trailing-junk");
-       soup_session_send_message (session, msgj);
-       check_response (msgj, "gzip", "text/plain", EXPECT_DECODED);
-       soup_assert_cmpmem (msg->response_body->data,
-                           msg->response_body->length,
-                           msgj->response_body->data,
-                           msgj->response_body->length);
-
-       /* Plain text data, claim gzip with server error */
+
+       soup_session_send_message (data->session, data->msg);
+       check_response (data, "gzip", "text/plain", EXPECT_DECODED, NULL);
+}
+
+static void
+do_coding_test_gzip_bad_server (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: gzip, with server error\n");
-       msge = soup_message_new_from_uri ("GET", uri);
-       soup_message_headers_append (msge->request_headers,
+
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "force-encode");
-       soup_session_send_message (session, msge);
-       check_response (msge, "gzip", "text/plain", EXPECT_NOT_DECODED);
+
+       soup_session_send_message (data->session, data->msg);
 
        /* Failed content-decoding should have left the body untouched
         * from what the server sent... which happens to be the
         * uncompressed data.
         */
-       soup_assert_cmpmem (msg->response_body->data,
-                           msg->response_body->length,
-                           msge->response_body->data,
-                           msge->response_body->length);
+       check_response (data, "gzip", "text/plain", EXPECT_NOT_DECODED, NULL);
+}
 
-       /* Plain text data, claim deflate */
+static void
+do_coding_test_deflate (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: deflate\n");
-       msgzl = soup_message_new_from_uri ("GET", uri);
-       soup_message_headers_append (msgzl->request_headers,
+
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "prefer-deflate-zlib");
-       soup_session_send_message (session, msgzl);
-       check_response (msgzl, "deflate", "text/plain", EXPECT_DECODED);
-       soup_assert_cmpmem (msg->response_body->data,
-                           msg->response_body->length,
-                           msgzl->response_body->data,
-                           msgzl->response_body->length);
-
-       /* Plain text data, claim deflate w/ junk */
+       soup_session_send_message (data->session, data->msg);
+
+       check_response (data, "deflate", "text/plain", EXPECT_DECODED, NULL);
+}
+
+static void
+do_coding_test_deflate_with_junk (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: deflate, plus trailing junk\n");
-       msgzlj = soup_message_new_from_uri ("GET", uri);
-       soup_message_headers_append (msgzlj->request_headers,
+
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "prefer-deflate-zlib, trailing-junk");
-       soup_session_send_message (session, msgzlj);
-       check_response (msgzlj, "deflate", "text/plain", EXPECT_DECODED);
-       soup_assert_cmpmem (msg->response_body->data,
-                           msg->response_body->length,
-                           msgzlj->response_body->data,
-                           msgzlj->response_body->length);
-
-       /* Plain text data, claim deflate with server error */
+       soup_session_send_message (data->session, data->msg);
+
+       check_response (data, "deflate", "text/plain", EXPECT_DECODED, NULL);
+}
+
+static void
+do_coding_test_deflate_bad_server (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: deflate, with server error\n");
-       msgzle = soup_message_new_from_uri ("GET", uri);
-       soup_message_headers_append (msgzle->request_headers,
+
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "force-encode, prefer-deflate-zlib");
-       soup_session_send_message (session, msgzle);
-       check_response (msgzle, "deflate", "text/plain", EXPECT_NOT_DECODED);
-       soup_assert_cmpmem (msg->response_body->data,
-                           msg->response_body->length,
-                           msgzle->response_body->data,
-                           msgzle->response_body->length);
-
-       /* Plain text data, claim deflate (no zlib headers)*/
+       soup_session_send_message (data->session, data->msg);
+
+       check_response (data, "deflate", "text/plain", EXPECT_NOT_DECODED, NULL);
+}
+
+static void
+do_coding_test_deflate_raw (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: deflate (raw data)\n");
-       msgzlr = soup_message_new_from_uri ("GET", uri);
-       soup_message_headers_append (msgzlr->request_headers,
+
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "prefer-deflate-raw");
-       soup_session_send_message (session, msgzlr);
-       check_response (msgzlr, "deflate", "text/plain", EXPECT_DECODED);
-       soup_assert_cmpmem (msg->response_body->data,
-                           msg->response_body->length,
-                           msgzlr->response_body->data,
-                           msgzlr->response_body->length);
-
-       /* Plain text data, claim deflate with server error */
+       soup_session_send_message (data->session, data->msg);
+
+       check_response (data, "deflate", "text/plain", EXPECT_DECODED, NULL);
+}
+
+static void
+do_coding_test_deflate_raw_bad_server (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: deflate (raw data), with server error\n");
-       msgzlre = soup_message_new_from_uri ("GET", uri);
-       soup_message_headers_append (msgzlre->request_headers,
+
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "force-encode, prefer-deflate-raw");
-       soup_session_send_message (session, msgzlre);
-       check_response (msgzlre, "deflate", "text/plain", EXPECT_NOT_DECODED);
-       soup_assert_cmpmem (msg->response_body->data,
-                           msg->response_body->length,
-                           msgzlre->response_body->data,
-                           msgzlre->response_body->length);
-
-       g_object_unref (msg);
-       g_object_unref (msgzlre);
-       g_object_unref (msgzlr);
-       g_object_unref (msgzlj);
-       g_object_unref (msgzle);
-       g_object_unref (msgzl);
-       g_object_unref (msgz);
-       g_object_unref (msgj);
-       g_object_unref (msge);
-       soup_uri_free (uri);
+       soup_session_send_message (data->session, data->msg);
 
-       soup_test_session_abort_unref (session);
+       check_response (data, "deflate", "text/plain", EXPECT_NOT_DECODED, NULL);
 }
 
 static void
@@ -290,26 +340,25 @@ read_finished (GObject *stream, GAsyncResult *result, gpointer user_data)
        g_clear_error (&error);
 }
 
-static GByteArray *
-do_single_coding_req_test (SoupRequestHTTP *reqh,
+static void
+do_single_coding_req_test (CodingTestData *data,
                           const char *expected_encoding,
                           const char *expected_content_type,
                           MessageContentStatus status)
 {
        GInputStream *stream;
-       SoupMessage *msg;
-       GByteArray *data;
+       GByteArray *body;
        guchar buf[1024];
        gssize nread;
        GError *error = NULL;
 
-       data = g_byte_array_new ();
+       body = g_byte_array_new ();
 
-       stream = soup_test_request_send (SOUP_REQUEST (reqh), NULL, 0, &error);
+       stream = soup_test_request_send (data->req, NULL, 0, &error);
        if (!stream) {
                g_assert_no_error (error);
                g_error_free (error);
-               return data;
+               return;
        }
 
        do {
@@ -321,194 +370,125 @@ do_single_coding_req_test (SoupRequestHTTP *reqh,
                        g_main_context_iteration (NULL, TRUE);
 
                if (nread > 0)
-                       g_byte_array_append (data, buf, nread);
+                       g_byte_array_append (body, buf, nread);
        } while (nread > 0);
 
-       soup_test_request_close_stream (SOUP_REQUEST (reqh), stream, NULL, &error);
+       soup_test_request_close_stream (data->req, stream, NULL, &error);
        g_assert_no_error (error);
        g_clear_error (&error);
        g_object_unref (stream);
 
-       msg = soup_request_http_get_message (reqh);
-       check_response (msg, expected_encoding, expected_content_type, status);
-       g_object_unref (msg);
-
-       return data;
+       check_response (data, expected_encoding, expected_content_type, status, body);
+       g_byte_array_free (body, TRUE);
 }
 
 static void
-do_coding_req_test (void)
+do_coding_req_test_plain (CodingTestData *data, gconstpointer test_data)
 {
-       SoupSession *session;
-       SoupRequestHTTP *reqh;
-       SoupMessage *msg;
-       SoupURI *uri;
-       GByteArray *plain, *cmp;
-
-       debug_printf (1, "\nSoupRequest tests\n");
-
-       session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
-                                        SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
-                                        NULL);
-       uri = soup_uri_new_with_base (base_uri, "/mbox");
-
        /* Plain text data, no claim */
        debug_printf (1, "  GET /mbox, plain\n");
-       reqh = soup_session_request_http_uri (session, "GET", uri, NULL);
-       plain = do_single_coding_req_test (reqh, NULL, "text/plain", EXPECT_NOT_DECODED);
-       g_object_unref (reqh);
 
-       /* Plain text data, claim gzip */
+       do_single_coding_req_test (data, NULL, "text/plain", EXPECT_NOT_DECODED);
+}
+
+static void
+do_coding_req_test_gzip (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: gzip\n");
-       soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_DECODER);
-       reqh = soup_session_request_http_uri (session, "GET", uri, NULL);
-       cmp = do_single_coding_req_test (reqh, "gzip", "text/plain", EXPECT_DECODED);
-       soup_assert_cmpmem (plain->data, plain->len,
-                           cmp->data, cmp->len);
-       g_byte_array_free (cmp, TRUE);
-       g_object_unref (reqh);
-
-       /* Plain text data, claim gzip w/ junk */
+
+       do_single_coding_req_test (data, "gzip", "text/plain", EXPECT_DECODED);
+}
+
+static void
+do_coding_req_test_gzip_with_junk (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: gzip, plus trailing junk\n");
-       reqh = soup_session_request_http_uri (session, "GET", uri, NULL);
-       msg = soup_request_http_get_message (reqh);
-       soup_message_headers_append (msg->request_headers,
+
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "trailing-junk");
-       g_object_unref (msg);
-       cmp = do_single_coding_req_test (reqh, "gzip", "text/plain", EXPECT_DECODED);
-       soup_assert_cmpmem (plain->data, plain->len,
-                           cmp->data, cmp->len);
-       g_byte_array_free (cmp, TRUE);
-       g_object_unref (reqh);
-
-       /* Plain text data, claim gzip with server error */
+
+       do_single_coding_req_test (data, "gzip", "text/plain", EXPECT_DECODED);
+}
+
+static void
+do_coding_req_test_gzip_bad_server (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: gzip, with server error\n");
-       reqh = soup_session_request_http_uri (session, "GET", uri, NULL);
-       msg = soup_request_http_get_message (reqh);
-       soup_message_headers_append (msg->request_headers,
-                                    "X-Test-Options", "force-encode");
-       g_object_unref (msg);
-       cmp = do_single_coding_req_test (reqh, "gzip", "text/plain", EXPECT_NOT_DECODED);
 
-       /* Failed content-decoding should have left the body untouched
-        * from what the server sent... which happens to be the
-        * uncompressed data.
-        */
-       soup_assert_cmpmem (plain->data, plain->len,
-                           cmp->data, cmp->len);
-       g_byte_array_free (cmp, TRUE);
-       g_object_unref (reqh);
+       soup_message_headers_append (data->msg->request_headers,
+                                    "X-Test-Options", "force-encode");
+       do_single_coding_req_test (data, "gzip", "text/plain", EXPECT_NOT_DECODED);
+}
 
-       /* Plain text data, claim deflate */
+static void
+do_coding_req_test_deflate (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: deflate\n");
-       reqh = soup_session_request_http_uri (session, "GET", uri, NULL);
-       msg = soup_request_http_get_message (reqh);
-       soup_message_headers_append (msg->request_headers,
+
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "prefer-deflate-zlib");
-       g_object_unref (msg);
-       cmp = do_single_coding_req_test (reqh, "deflate", "text/plain", EXPECT_DECODED);
-       soup_assert_cmpmem (plain->data, plain->len,
-                           cmp->data, cmp->len);
-       g_byte_array_free (cmp, TRUE);
-       g_object_unref (reqh);
-
-       /* Plain text data, claim deflate w/ junk */
+       do_single_coding_req_test (data, "deflate", "text/plain", EXPECT_DECODED);
+}
+
+static void
+do_coding_req_test_deflate_with_junk (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: deflate, plus trailing junk\n");
-       reqh = soup_session_request_http_uri (session, "GET", uri, NULL);
-       msg = soup_request_http_get_message (reqh);
-       soup_message_headers_append (msg->request_headers,
+
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "prefer-deflate-zlib, trailing-junk");
-       g_object_unref (msg);
-       cmp = do_single_coding_req_test (reqh, "deflate", "text/plain", EXPECT_DECODED);
-       soup_assert_cmpmem (plain->data, plain->len,
-                           cmp->data, cmp->len);
-       g_byte_array_free (cmp, TRUE);
-       g_object_unref (reqh);
-
-       /* Plain text data, claim deflate with server error */
+       do_single_coding_req_test (data, "deflate", "text/plain", EXPECT_DECODED);
+}
+
+static void
+do_coding_req_test_deflate_bad_server (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: deflate, with server error\n");
-       reqh = soup_session_request_http_uri (session, "GET", uri, NULL);
-       msg = soup_request_http_get_message (reqh);
-       soup_message_headers_append (msg->request_headers,
+
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "force-encode, prefer-deflate-zlib");
-       g_object_unref (msg);
-       cmp = do_single_coding_req_test (reqh, "deflate", "text/plain", EXPECT_NOT_DECODED);
-       soup_assert_cmpmem (plain->data, plain->len,
-                           cmp->data, cmp->len);
-       g_byte_array_free (cmp, TRUE);
-       g_object_unref (reqh);
-
-       /* Plain text data, claim deflate (no zlib headers)*/
+       do_single_coding_req_test (data, "deflate", "text/plain", EXPECT_NOT_DECODED);
+}
+
+static void
+do_coding_req_test_deflate_raw (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: deflate (raw data)\n");
-       reqh = soup_session_request_http_uri (session, "GET", uri, NULL);
-       msg = soup_request_http_get_message (reqh);
-       soup_message_headers_append (msg->request_headers,
+
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "prefer-deflate-raw");
-       g_object_unref (msg);
-       cmp = do_single_coding_req_test (reqh, "deflate", "text/plain", EXPECT_DECODED);
-       soup_assert_cmpmem (plain->data, plain->len,
-                           cmp->data, cmp->len);
-       g_byte_array_free (cmp, TRUE);
-       g_object_unref (reqh);
-
-       /* Plain text data, claim deflate with server error */
+       do_single_coding_req_test (data, "deflate", "text/plain", EXPECT_DECODED);
+}
+
+static void
+do_coding_req_test_deflate_raw_bad_server (CodingTestData *data, gconstpointer test_data)
+{
        debug_printf (1, "  GET /mbox, Accept-Encoding: deflate (raw data), with server error\n");
-       reqh = soup_session_request_http_uri (session, "GET", uri, NULL);
-       msg = soup_request_http_get_message (reqh);
-       soup_message_headers_append (msg->request_headers,
-                                    "X-Test-Options", "force-encode, prefer-deflate-raw");
-       g_object_unref (msg);
-       cmp = do_single_coding_req_test (reqh, "deflate", "text/plain", EXPECT_NOT_DECODED);
-       soup_assert_cmpmem (plain->data, plain->len,
-                           cmp->data, cmp->len);
-       g_byte_array_free (cmp, TRUE);
-       g_object_unref (reqh);
-
-       g_byte_array_free (plain, TRUE);
-       soup_uri_free (uri);
 
-       soup_test_session_abort_unref (session);
+       soup_message_headers_append (data->msg->request_headers,
+                                    "X-Test-Options", "force-encode, prefer-deflate-raw");
+       do_single_coding_req_test (data, "deflate", "text/plain", EXPECT_NOT_DECODED);
 }
 
 static void
-do_coding_empty_test (void)
+do_coding_msg_empty_test (CodingTestData *data, gconstpointer test_data)
 {
-       SoupSession *session;
-       SoupMessage *msg;
-       SoupURI *uri;
-       SoupRequestHTTP *reqh;
-       GByteArray *body;
-
        debug_printf (1, "\nEmpty allegedly-encoded body test\n");
 
-       session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
-                                        SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_DECODER,
-                                        SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
-                                        NULL);
-       uri = soup_uri_new_with_base (base_uri, "/mbox");
-
-       debug_printf (1, "  SoupMessage\n");
-       msg = soup_message_new_from_uri ("GET", uri);
-       soup_message_headers_append (msg->request_headers,
-                                    "X-Test-Options", "empty");
-       soup_session_send_message (session, msg);
-       check_response (msg, "gzip", "text/plain", EXPECT_NOT_DECODED);
-       g_object_unref (msg);
-
-       debug_printf (1, "  SoupRequest\n");
-       reqh = soup_session_request_http_uri (session, "GET", uri, NULL);
-       msg = soup_request_http_get_message (reqh);
-       soup_message_headers_append (msg->request_headers,
+       soup_message_headers_append (data->msg->request_headers,
                                     "X-Test-Options", "empty");
-       g_object_unref (msg);
-       body = do_single_coding_req_test (reqh, "gzip", "text/plain", EXPECT_NOT_DECODED);
-       g_byte_array_free (body, TRUE);
-       g_object_unref (reqh);
+       soup_session_send_message (data->session, data->msg);
 
-       soup_uri_free (uri);
-       soup_test_session_abort_unref (session);
+       check_response (data, "gzip", "text/plain", EXPECT_NOT_DECODED, NULL);
 }
 
+static void
+do_coding_req_empty_test (CodingTestData *data, gconstpointer test_data)
+{
+       soup_message_headers_append (data->msg->request_headers,
+                                    "X-Test-Options", "empty");
+       do_single_coding_req_test (data, "gzip", "text/plain", EXPECT_NOT_DECODED);
+}
 
 int
 main (int argc, char **argv)
@@ -522,9 +502,68 @@ main (int argc, char **argv)
        base_uri = soup_uri_new ("http://127.0.0.1/";);
        soup_uri_set_port (base_uri, soup_server_get_port (server));
 
-       g_test_add_func ("/coding/message", do_coding_test);
-       g_test_add_func ("/coding/request", do_coding_req_test);
-       g_test_add_func ("/coding/empty", do_coding_empty_test);
+       g_test_add ("/coding/message/plain", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_NO_DECODER),
+                   setup_coding_test, do_coding_test_plain, teardown_coding_test);
+       g_test_add ("/coding/message/gzip", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_DEFAULT),
+                   setup_coding_test, do_coding_test_gzip, teardown_coding_test);
+       g_test_add ("/coding/message/gzip/with-junk", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_DEFAULT),
+                   setup_coding_test, do_coding_test_gzip_with_junk, teardown_coding_test);
+       g_test_add ("/coding/message/gzip/bad-server", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_DEFAULT),
+                   setup_coding_test, do_coding_test_gzip_bad_server, teardown_coding_test);
+       g_test_add ("/coding/message/deflate", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_DEFAULT),
+                   setup_coding_test, do_coding_test_deflate, teardown_coding_test);
+       g_test_add ("/coding/message/deflate/with-junk", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_DEFAULT),
+                   setup_coding_test, do_coding_test_deflate_with_junk, teardown_coding_test);
+       g_test_add ("/coding/message/deflate/bad-server", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_DEFAULT),
+                   setup_coding_test, do_coding_test_deflate_bad_server, teardown_coding_test);
+       g_test_add ("/coding/message/deflate-raw", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_DEFAULT),
+                   setup_coding_test, do_coding_test_deflate_raw, teardown_coding_test);
+       g_test_add ("/coding/message/deflate-raw/bad-server", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_DEFAULT),
+                   setup_coding_test, do_coding_test_deflate_raw_bad_server, teardown_coding_test);
+
+       g_test_add ("/coding/request/plain", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_NO_DECODER | CODING_TEST_REQUEST_API),
+                   setup_coding_test, do_coding_req_test_plain, teardown_coding_test);
+       g_test_add ("/coding/request/gzip", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_REQUEST_API),
+                   setup_coding_test, do_coding_req_test_gzip, teardown_coding_test);
+       g_test_add ("/coding/request/gzip/with-junk", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_REQUEST_API),
+                   setup_coding_test, do_coding_req_test_gzip_with_junk, teardown_coding_test);
+       g_test_add ("/coding/request/gzip/bad-server", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_REQUEST_API),
+                   setup_coding_test, do_coding_req_test_gzip_bad_server, teardown_coding_test);
+       g_test_add ("/coding/request/deflate", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_REQUEST_API),
+                   setup_coding_test, do_coding_req_test_deflate, teardown_coding_test);
+       g_test_add ("/coding/request/deflate/with-junk", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_REQUEST_API),
+                   setup_coding_test, do_coding_req_test_deflate_with_junk, teardown_coding_test);
+       g_test_add ("/coding/request/deflate/bad-server", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_REQUEST_API),
+                   setup_coding_test, do_coding_req_test_deflate_bad_server, teardown_coding_test);
+       g_test_add ("/coding/request/deflate-raw", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_REQUEST_API),
+                   setup_coding_test, do_coding_req_test_deflate_raw, teardown_coding_test);
+       g_test_add ("/coding/request/deflate-raw/bad-server", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_REQUEST_API),
+                   setup_coding_test, do_coding_req_test_deflate_raw_bad_server, teardown_coding_test);
+
+       g_test_add ("/coding/message/empty", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_EMPTY),
+                   setup_coding_test, do_coding_msg_empty_test, teardown_coding_test);
+       g_test_add ("/coding/request/empty", CodingTestData,
+                   GINT_TO_POINTER (CODING_TEST_REQUEST_API | CODING_TEST_EMPTY),
+                   setup_coding_test, do_coding_req_empty_test, teardown_coding_test);
 
        ret = g_test_run ();
 
diff --git a/tests/continue-test.c b/tests/continue-test.c
index 42138ce..1736a32 100644
--- a/tests/continue-test.c
+++ b/tests/continue-test.c
@@ -153,7 +153,7 @@ do_message (const char *path, gboolean long_body,
 }
 
 static void
-run_tests (void)
+do_test_unauth_short_noexpect_nopass (void)
 {
        do_message ("unauth", FALSE, FALSE, FALSE,
                    "client-wrote_headers",
@@ -167,6 +167,11 @@ run_tests (void)
                    "client-got_body",
                    "client-finished",
                    NULL);
+}
+
+static void
+do_test_unauth_long_noexpect_nopass (void)
+{
        do_message ("unauth", TRUE, FALSE, FALSE,
                    "client-wrote_headers",
                    "client-wrote_body",
@@ -179,6 +184,11 @@ run_tests (void)
                    "client-got_body",
                    "client-finished",
                    NULL);
+}
+
+static void
+do_test_unauth_short_expect_nopass (void)
+{
        do_message ("unauth", FALSE, TRUE, FALSE,
                    "client-wrote_headers",
                    "server-got_headers",
@@ -193,6 +203,11 @@ run_tests (void)
                    "client-got_body",
                    "client-finished",
                    NULL);
+}
+
+static void
+do_test_unauth_long_expect_nopass (void)
+{
        do_message ("unauth", TRUE, TRUE, FALSE,
                    "client-wrote_headers",
                    "server-got_headers",
@@ -203,7 +218,11 @@ run_tests (void)
                    "client-got_body",
                    "client-finished",
                    NULL);
+}
 
+static void
+do_test_auth_short_noexpect_nopass (void)
+{
        do_message ("auth", FALSE, FALSE, FALSE,
                    "client-wrote_headers",
                    "client-wrote_body",
@@ -216,6 +235,11 @@ run_tests (void)
                    "client-got_body",
                    "client-finished",
                    NULL);
+}
+
+static void
+do_test_auth_long_noexpect_nopass (void)
+{
        do_message ("auth", TRUE, FALSE, FALSE,
                    "client-wrote_headers",
                    "client-wrote_body",
@@ -228,6 +252,11 @@ run_tests (void)
                    "client-got_body",
                    "client-finished",
                    NULL);
+}
+
+static void
+do_test_auth_short_expect_nopass (void)
+{
        do_message ("auth", FALSE, TRUE, FALSE,
                    "client-wrote_headers",
                    "server-got_headers",
@@ -238,6 +267,11 @@ run_tests (void)
                    "client-got_body",
                    "client-finished",
                    NULL);
+}
+
+static void
+do_test_auth_long_expect_nopass (void)
+{
        do_message ("auth", TRUE, TRUE, FALSE,
                    "client-wrote_headers",
                    "server-got_headers",
@@ -248,7 +282,11 @@ run_tests (void)
                    "client-got_body",
                    "client-finished",
                    NULL);
+}
 
+static void
+do_test_auth_short_noexpect_pass (void)
+{
        do_message ("auth", FALSE, FALSE, TRUE,
                    "client-wrote_headers",
                    "client-wrote_body",
@@ -270,6 +308,11 @@ run_tests (void)
                    "client-got_body",
                    "client-finished",
                    NULL);
+}
+
+static void
+do_test_auth_long_noexpect_pass (void)
+{
        do_message ("auth", TRUE, FALSE, TRUE,
                    "client-wrote_headers",
                    "client-wrote_body",
@@ -291,6 +334,11 @@ run_tests (void)
                    "client-got_body",
                    "client-finished",
                    NULL);
+}
+
+static void
+do_test_auth_short_expect_pass (void)
+{
        do_message ("auth", FALSE, TRUE, TRUE,
                    "client-wrote_headers",
                    "server-got_headers",
@@ -312,6 +360,11 @@ run_tests (void)
                    "client-got_body",
                    "client-finished",
                    NULL);
+}
+
+static void
+do_test_auth_long_expect_pass (void)
+{
        do_message ("auth", TRUE, TRUE, TRUE,
                    "client-wrote_headers",
                    "server-got_headers",
@@ -437,7 +490,18 @@ main (int argc, char **argv)
        server = setup_server ();
        port = soup_server_get_port (server);
 
-       g_test_add_func ("/continue", run_tests);
+       g_test_add_func ("/continue/unauth_short_noexpect_nopass", do_test_unauth_short_noexpect_nopass);
+       g_test_add_func ("/continue/unauth_long_noexpect_nopass", do_test_unauth_long_noexpect_nopass);
+       g_test_add_func ("/continue/unauth_short_expect_nopass", do_test_unauth_short_expect_nopass);
+       g_test_add_func ("/continue/unauth_long_expect_nopass", do_test_unauth_long_expect_nopass);
+       g_test_add_func ("/continue/auth_short_noexpect_nopass", do_test_auth_short_noexpect_nopass);
+       g_test_add_func ("/continue/auth_long_noexpect_nopass", do_test_auth_long_noexpect_nopass);
+       g_test_add_func ("/continue/auth_short_expect_nopass", do_test_auth_short_expect_nopass);
+       g_test_add_func ("/continue/auth_long_expect_nopass", do_test_auth_long_expect_nopass);
+       g_test_add_func ("/continue/auth_short_noexpect_pass", do_test_auth_short_noexpect_pass);
+       g_test_add_func ("/continue/auth_long_noexpect_pass", do_test_auth_long_noexpect_pass);
+       g_test_add_func ("/continue/auth_short_expect_pass", do_test_auth_short_expect_pass);
+       g_test_add_func ("/continue/auth_long_expect_pass", do_test_auth_long_expect_pass);
 
        ret = g_test_run ();
 
diff --git a/tests/forms-test.c b/tests/forms-test.c
index 6e6334f..a3401db 100644
--- a/tests/forms-test.c
+++ b/tests/forms-test.c
@@ -96,20 +96,61 @@ do_hello_tests (gconstpointer uri)
 #endif
 
        debug_printf (1, "Hello tests (GET, application/x-www-form-urlencoded)\n");
+
        for (n = 0; n < G_N_ELEMENTS (tests); n++) {
                do_hello_test (n, FALSE, uri);
                do_hello_test (n, TRUE, uri);
        }
 }
 
+#define MD5_TEST_FILE (g_test_get_filename (G_TEST_DIST, "index.txt", NULL))
+#define MD5_TEST_FILE_BASENAME "index.txt"
+#define MD5_TEST_FILE_MIME_TYPE "text/plain"
+
+static char *
+get_md5_data (char **contents, gsize *length)
+{
+       char *my_contents, *md5;
+       gsize my_length;
+       GError *error = NULL;
+
+       if (!g_file_get_contents (MD5_TEST_FILE, &my_contents, &my_length, &error)) {
+               g_assert_no_error (error);
+               g_error_free (error);
+               return NULL;
+       }
+
+       md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, my_contents, my_length);
+
+       if (contents)
+               *contents = my_contents;
+       else
+               g_free (my_contents);
+       if (length)
+               *length = my_length;
+
+       return md5;
+}
+
 static void
-do_md5_test_curl (const char *uri, const char *file, const char *md5)
+do_md5_test_curl (gconstpointer data)
 {
+       const char *uri = data;
+       char *md5;
        GPtrArray *args;
        char *file_arg, *str_stdout;
        GError *error = NULL;
 
-       debug_printf (1, "  via curl: ");
+#ifndef HAVE_CURL
+       g_test_skip ("/usr/bin/curl is not available");
+       return;
+#endif
+
+       debug_printf (1, "\nMD5 test via curl (POST, multipart/form-data)\n");
+
+       md5 = get_md5_data (NULL, NULL);
+       if (!md5)
+               return;
 
        args = g_ptr_array_new ();
        g_ptr_array_add (args, "curl");
@@ -117,7 +158,7 @@ do_md5_test_curl (const char *uri, const char *file, const char *md5)
        g_ptr_array_add (args, "*");
        g_ptr_array_add (args, "-L");
        g_ptr_array_add (args, "-F");
-       file_arg = g_strdup_printf ("file= %s", file);
+       file_arg = g_strdup_printf ("file= %s", MD5_TEST_FILE);
        g_ptr_array_add (args, file_arg);
        g_ptr_array_add (args, "-F");
        g_ptr_array_add (args, "fmt=txt");
@@ -136,22 +177,26 @@ do_md5_test_curl (const char *uri, const char *file, const char *md5)
        }
        g_ptr_array_free (args, TRUE);
        g_free (file_arg);
-}
 
-#define MD5_TEST_FILE (g_test_get_filename (G_TEST_DIST, "index.txt", NULL))
-#define MD5_TEST_FILE_BASENAME "index.txt"
-#define MD5_TEST_FILE_MIME_TYPE "text/plain"
+       g_free (md5);
+}
 
 static void
-do_md5_test_libsoup (const char *uri, const char *contents,
-                    gsize length, const char *md5)
+do_md5_test_libsoup (gconstpointer data)
 {
+       const char *uri = data;
+       char *contents, *md5;
+       gsize length;
        SoupMultipart *multipart;
        SoupBuffer *buffer;
        SoupMessage *msg;
        SoupSession *session;
 
-       debug_printf (1, "  via libsoup: ");
+       debug_printf (1, "\nMD5 test via libsoup (POST, multipart/form-data)\n");
+
+       md5 = get_md5_data (&contents, &length);
+       if (!md5)
+               return;
 
        multipart = soup_multipart_new (SOUP_FORM_MIME_TYPE_MULTIPART);
        buffer = soup_buffer_new (SOUP_MEMORY_COPY, contents, length);
@@ -173,38 +218,11 @@ do_md5_test_libsoup (const char *uri, const char *contents,
 
        g_object_unref (msg);
        soup_test_session_abort_unref (session);
-}
-
-static void
-do_md5_tests (gconstpointer uri)
-{
-       char *contents, *md5;
-       gsize length;
-       GError *error = NULL;
-
-#ifndef HAVE_CURL
-       g_test_skip ("/usr/bin/curl is not available");
-       return;
-#endif
-
-       debug_printf (1, "\nMD5 tests (POST, multipart/form-data)\n");
-
-       if (!g_file_get_contents (MD5_TEST_FILE, &contents, &length, &error)) {
-               g_assert_no_error (error);
-               g_error_free (error);
-               return;
-       }
-
-       md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, contents, length);
-
-       do_md5_test_curl (uri, MD5_TEST_FILE, md5);
-       do_md5_test_libsoup (uri, contents, length, md5);
 
        g_free (contents);
        g_free (md5);
 }
 
-
 static void
 do_form_decode_test (void)
 {
@@ -428,7 +446,9 @@ main (int argc, char **argv)
                g_test_add_data_func_full ("/forms/hello", uri_str, do_hello_tests, g_free);
 
                uri_str = g_strdup_printf ("http://127.0.0.1:%u/md5";, port);
-               g_test_add_data_func_full ("/forms/md5", uri_str, do_md5_tests, g_free);
+               g_test_add_data_func_full ("/forms/md5/curl", g_strdup (uri_str), do_md5_test_curl, g_free);
+               g_test_add_data_func_full ("/forms/md5/libsoup", g_strdup (uri_str), do_md5_test_libsoup, 
g_free);
+               g_free (uri_str);
 
                g_test_add_func ("/forms/decode", do_form_decode_test);
 
diff --git a/tests/misc-test.c b/tests/misc-test.c
index 46c9cb1..7ee1981 100644
--- a/tests/misc-test.c
+++ b/tests/misc-test.c
@@ -741,7 +741,7 @@ do_cancel_while_reading_req_test_for_session (SoupSession *session,
 }
 
 static void
-do_cancel_while_reading_req_test (void)
+do_cancel_while_reading_immediate_req_test (void)
 {
        SoupSession *session;
        guint flags;
@@ -761,6 +761,13 @@ do_cancel_while_reading_req_test (void)
                                         NULL);
        do_cancel_while_reading_req_test_for_session (session, flags);
        soup_test_session_abort_unref (session);
+}
+
+static void
+do_cancel_while_reading_delayed_req_test (void)
+{
+       SoupSession *session;
+       guint flags;
 
        debug_printf (1, "\nCancelling (after 100ms) message while reading response (request api)\n");
        flags = SOUP_TEST_REQUEST_CANCEL_CANCELLABLE | SOUP_TEST_REQUEST_CANCEL_SOON;
@@ -777,6 +784,13 @@ do_cancel_while_reading_req_test (void)
                                         NULL);
        do_cancel_while_reading_req_test_for_session (session, flags);
        soup_test_session_abort_unref (session);
+}
+
+static void
+do_cancel_while_reading_preemptive_req_test (void)
+{
+       SoupSession *session;
+       guint flags;
 
        debug_printf (1, "\nCancelling (preemptively) message while reading response (request api)\n");
        flags = SOUP_TEST_REQUEST_CANCEL_CANCELLABLE | SOUP_TEST_REQUEST_CANCEL_PREEMPTIVE;
@@ -939,7 +953,9 @@ main (int argc, char **argv)
        g_test_add_func ("/misc/early-abort/req", do_early_abort_req_test);
        g_test_add_func ("/misc/accept-language", do_accept_language_test);
        g_test_add_func ("/misc/cancel-while-reading/msg", do_cancel_while_reading_test);
-       g_test_add_func ("/misc/cancel-while-reading/req", do_cancel_while_reading_req_test);
+       g_test_add_func ("/misc/cancel-while-reading/req/immediate", 
do_cancel_while_reading_immediate_req_test);
+       g_test_add_func ("/misc/cancel-while-reading/req/delayed", do_cancel_while_reading_delayed_req_test);
+       g_test_add_func ("/misc/cancel-while-reading/req/preemptive", 
do_cancel_while_reading_preemptive_req_test);
        g_test_add_func ("/misc/aliases", do_aliases_test);
        g_test_add_func ("/misc/idle-on-dispose", do_idle_on_dispose_test);
        g_test_add_func ("/misc/pause-abort", do_pause_abort_test);
diff --git a/tests/ntlm-test.c b/tests/ntlm-test.c
index e05213a..7aa532e 100644
--- a/tests/ntlm-test.c
+++ b/tests/ntlm-test.c
@@ -11,6 +11,8 @@
 
 #include "test-utils.h"
 
+static SoupURI *uri;
+
 typedef enum {
        NTLM_UNAUTHENTICATED,
        NTLM_RECEIVED_REQUEST,
@@ -430,71 +432,84 @@ do_ntlm_round (SoupURI *base_uri, gboolean use_ntlm,
        soup_test_session_abort_unref (session);
 }
 
-static void
-do_ntlm_tests (SoupURI *base_uri, gboolean use_builtin_ntlm)
-{
-       debug_printf (1, "Round 1: Non-NTLM Connection, no auth\n");
-       do_ntlm_round (base_uri, FALSE, NULL, use_builtin_ntlm);
-       debug_printf (1, "Round 2: NTLM Connection, user=alice\n");
-       do_ntlm_round (base_uri, TRUE, "alice", use_builtin_ntlm);
-       debug_printf (1, "Round 3: NTLM Connection, user=bob\n");
-       do_ntlm_round (base_uri, TRUE, "bob", use_builtin_ntlm);
-       debug_printf (1, "Round 4: Non-NTLM Connection, user=alice\n");
-       do_ntlm_round (base_uri, FALSE, "alice", use_builtin_ntlm);
-}
-
-static void
-do_builtin_ntlm_test (gconstpointer data)
-{
-       SoupURI *uri = (SoupURI *)data;
+typedef enum {
+       BUILTIN,
+       WINBIND,
+       FALLBACK
+} NtlmType;
 
-       /* Built-in NTLM auth support. (We set SOUP_NTLM_AUTH_DEBUG to
-        * an empty string to ensure that the built-in support is
-        * being used, even if /usr/bin/ntlm_auth is available.)
-        */
-       g_setenv ("SOUP_NTLM_AUTH_DEBUG", "", TRUE);
-       do_ntlm_tests (uri, TRUE);
-}
+typedef struct {
+       const char *name, *user;
+       gboolean conn_uses_ntlm;
+       NtlmType ntlm_type;
+} NtlmTest;
+
+static const NtlmTest ntlm_tests[] = {
+       { "/ntlm/builtin/none",   NULL,    FALSE, BUILTIN },
+       { "/ntlm/builtin/alice",  "alice", TRUE,  BUILTIN },
+       { "/ntlm/builtin/bob",    "bob",   TRUE,  BUILTIN },
+       { "/ntlm/builtin/basic",  "alice", FALSE, BUILTIN },
+
+       { "/ntlm/winbind/none",   NULL,    FALSE, WINBIND },
+       { "/ntlm/winbind/alice",  "alice", TRUE,  WINBIND },
+       { "/ntlm/winbind/bob",    "bob",   TRUE,  WINBIND },
+       { "/ntlm/winbind/basic",  "alice", FALSE, WINBIND },
+
+       { "/ntlm/fallback/none",  NULL,    FALSE, FALLBACK },
+       { "/ntlm/fallback/alice", "alice", TRUE,  FALLBACK },
+       { "/ntlm/fallback/bob",   "bob",   TRUE,  FALLBACK },
+       { "/ntlm/fallback/basic", "alice", FALSE, FALLBACK }
+};
 
 static void
-do_winbind_ntlm_test (gconstpointer data)
+do_ntlm_test (gconstpointer data)
 {
-       SoupURI *uri = (SoupURI *)data;
+       const NtlmTest *test = data;
+       gboolean use_builtin_ntlm = TRUE;
+
+       switch (test->ntlm_type) {
+       case BUILTIN:
+               /* Built-in NTLM auth support. (We set SOUP_NTLM_AUTH_DEBUG to
+                * an empty string to ensure that the built-in support is
+                * being used, even if /usr/bin/ntlm_auth is available.)
+                */
+               g_setenv ("SOUP_NTLM_AUTH_DEBUG", "", TRUE);
+               break;
 
+       case WINBIND:
 #ifndef USE_NTLM_AUTH
-       g_test_skip ("/usr/bin/ntlm_auth is not available");
-       return;
+               g_test_skip ("/usr/bin/ntlm_auth is not available");
+               return;
 #endif
 
-       /* Samba winbind /usr/bin/ntlm_auth helper support (via a
-        * helper program that emulates its interface).
-        */
-       g_setenv ("SOUP_NTLM_AUTH_DEBUG",
-                 g_test_get_filename (G_TEST_BUILT, "ntlm-test-helper", NULL),
-                 TRUE);
-       g_unsetenv ("SOUP_NTLM_AUTH_DEBUG_NOCREDS");
-       do_ntlm_tests (uri, FALSE);
-}
-
-static void
-do_fallback_ntlm_test (gconstpointer data)
-{
-       SoupURI *uri = (SoupURI *)data;
-
+               /* Samba winbind /usr/bin/ntlm_auth helper support (via a
+                * helper program that emulates its interface).
+                */
+               g_setenv ("SOUP_NTLM_AUTH_DEBUG",
+                         g_test_get_filename (G_TEST_BUILT, "ntlm-test-helper", NULL),
+                         TRUE);
+               g_unsetenv ("SOUP_NTLM_AUTH_DEBUG_NOCREDS");
+               use_builtin_ntlm = FALSE;
+               break;
+
+       case FALLBACK:
 #ifndef USE_NTLM_AUTH
-       g_test_skip ("/usr/bin/ntlm_auth is not available");
-       return;
+               g_test_skip ("/usr/bin/ntlm_auth is not available");
+               return;
 #endif
 
-       /* Support for when ntlm_auth is installed, but the user has
-        * no cached credentials (and thus we have to fall back to
-        * libsoup's built-in NTLM support).
-        */
-       g_setenv ("SOUP_NTLM_AUTH_DEBUG",
-                 g_test_get_filename (G_TEST_BUILT, "ntlm-test-helper", NULL),
-                 TRUE);
-       g_setenv ("SOUP_NTLM_AUTH_DEBUG_NOCREDS", "1", TRUE);
-       do_ntlm_tests (uri, TRUE);
+               /* Support for when ntlm_auth is installed, but the user has
+                * no cached credentials (and thus we have to fall back to
+                * libsoup's built-in NTLM support).
+                */
+               g_setenv ("SOUP_NTLM_AUTH_DEBUG",
+                         g_test_get_filename (G_TEST_BUILT, "ntlm-test-helper", NULL),
+                         TRUE);
+               g_setenv ("SOUP_NTLM_AUTH_DEBUG_NOCREDS", "1", TRUE);
+               break;
+       }
+
+       do_ntlm_round (uri, test->conn_uses_ntlm, test->user, use_builtin_ntlm);
 }
 
 static void
@@ -576,8 +591,7 @@ main (int argc, char **argv)
 {
        SoupServer *server;
        GHashTable *connections;
-       SoupURI *uri;
-       int ret;
+       int i, ret;
 
        test_init (argc, argv, NULL);
 
@@ -589,9 +603,8 @@ main (int argc, char **argv)
        uri = soup_uri_new ("http://127.0.0.1/";);
        soup_uri_set_port (uri, soup_server_get_port (server));
 
-       g_test_add_data_func ("/ntlm/builtin", uri, do_builtin_ntlm_test);
-       g_test_add_data_func ("/ntlm/winbind", uri, do_winbind_ntlm_test);
-       g_test_add_data_func ("/ntlm/fallback", uri, do_fallback_ntlm_test);
+       for (i = 0; i < G_N_ELEMENTS (ntlm_tests); i++)
+               g_test_add_data_func (ntlm_tests[i].name, &ntlm_tests[i], do_ntlm_test);
        g_test_add_data_func ("/ntlm/retry", uri, do_retrying_test);
 
        ret = g_test_run ();
diff --git a/tests/server-auth-test.c b/tests/server-auth-test.c
index b5580c8..f386f52 100644
--- a/tests/server-auth-test.c
+++ b/tests/server-auth-test.c
@@ -5,6 +5,8 @@
 
 #include "test-utils.h"
 
+static SoupURI *base_uri;
+
 static struct {
        gboolean client_sent_basic, client_sent_digest;
        gboolean server_requested_basic, server_requested_digest;
@@ -21,7 +23,7 @@ curl_exited (GPid pid, int status, gpointer data)
 }
 
 static void
-do_test (int n, SoupURI *base_uri, const char *path,
+do_test (SoupURI *base_uri, const char *path,
         gboolean good_user, gboolean good_password,
         gboolean offer_basic, gboolean offer_digest,
         gboolean client_sends_basic, gboolean client_sends_digest,
@@ -34,12 +36,6 @@ do_test (int n, SoupURI *base_uri, const char *path,
        GPid pid;
        gboolean done;
 
-       debug_printf (1, "%2d. %s, %soffer Basic, %soffer Digest, %s user, %s password\n",
-                     n, path, offer_basic ? "" : "don't ",
-                     offer_digest ? "" : "don't ",
-                     good_user ? "good" : "bad",
-                     good_password ? "good" : "bad");
-
        uri = soup_uri_new_with_base (base_uri, path);
        uri_str = soup_uri_to_string (uri, FALSE);
        soup_uri_free (uri);
@@ -96,104 +92,95 @@ do_test (int n, SoupURI *base_uri, const char *path,
        g_assert_cmpint (success, ==, test_data.succeeded);
 }
 
+#define TEST_USES_BASIC(t)    (((t) & 1) == 1)
+#define TEST_USES_DIGEST(t)   (((t) & 2) == 2)
+#define TEST_GOOD_USER(t)     (((t) & 4) == 4)
+#define TEST_GOOD_PASSWORD(t) (((t) & 8) == 8)
+
+#define TEST_GOOD_AUTH(t)        (TEST_GOOD_USER (t) && TEST_GOOD_PASSWORD (t))
+#define TEST_PREEMPTIVE_BASIC(t) (TEST_USES_BASIC (t) && !TEST_USES_DIGEST (t))
+
 static void
-do_auth_tests (gconstpointer data)
+do_server_auth_test (gconstpointer data)
 {
-       SoupURI *base_uri = (SoupURI *)data;
-       int i, n = 1;
-       gboolean use_basic, use_digest, good_user, good_password;
-       gboolean preemptive_basic, good_auth;
+       int i = GPOINTER_TO_INT (data);
 
 #ifndef HAVE_CURL
        g_test_skip ("/usr/bin/curl is not available");
        return;
 #endif
 
-       for (i = 0; i < 16; i++) {
-               use_basic     = (i & 1) == 1;
-               use_digest    = (i & 2) == 2;
-               good_user     = (i & 4) == 4;
-               good_password = (i & 8) == 8;
-
-               good_auth = good_user && good_password;
-
-               /* Curl will preemptively send Basic if it's told to
-                * use Basic but not Digest.
-                */
-               preemptive_basic = use_basic && !use_digest;
-
-               /* 1. No auth required. The server will ignore the
-                * Authorization headers completely, and the request
-                * will always succeed.
-                */
-               do_test (n++, base_uri, "/foo",
-                        good_user, good_password,
-                        /* request */
-                        use_basic, use_digest,
-                        /* expected from client */
-                        preemptive_basic, FALSE,
-                        /* expected from server */
-                        FALSE, FALSE,
-                        /* success? */
-                        TRUE);
-
-               /* 2. Basic auth required. The server will send
-                * "WWW-Authenticate: Basic" if the client fails to
-                * send an Authorization: Basic on the first request,
-                * or if it sends a bad password.
-                */
-               do_test (n++, base_uri, "/Basic/foo",
-                        good_user, good_password,
-                        /* request */
-                        use_basic, use_digest,
-                        /* expected from client */
-                        use_basic, FALSE,
-                        /* expected from server */
-                        !preemptive_basic || !good_auth, FALSE,
-                        /* success? */
-                        use_basic && good_auth);
-
-               /* 3. Digest auth required. Simpler than the basic
-                * case because the client can't send Digest auth
-                * premptively.
-                */
-               do_test (n++, base_uri, "/Digest/foo",
-                        good_user, good_password,
-                        /* request */
-                        use_basic, use_digest,
-                        /* expected from client */
-                        preemptive_basic, use_digest,
-                        /* expected from server */
-                        FALSE, TRUE,
-                        /* success? */
-                        use_digest && good_auth);
-
-               /* 4. Any auth required. */
-               do_test (n++, base_uri, "/Any/foo",
-                        good_user, good_password,
-                        /* request */
-                        use_basic, use_digest,
-                        /* expected from client */
-                        preemptive_basic, use_digest,
-                        /* expected from server */
-                        !preemptive_basic || !good_auth, !preemptive_basic || !good_auth,
-                        /* success? */
-                        (use_basic || use_digest) && good_auth);
-
-               /* 5. No auth required again. (Makes sure that
-                * SOUP_AUTH_DOMAIN_REMOVE_PATH works.)
-                */
-               do_test (n++, base_uri, "/Any/Not/foo",
-                        good_user, good_password,
-                        /* request */
-                        use_basic, use_digest,
-                        /* expected from client */
-                        preemptive_basic, FALSE,
-                        /* expected from server */
-                        FALSE, FALSE,
-                        /* success? */
-                        TRUE);
-       }
+       /* 1. No auth required. The server will ignore the
+        * Authorization headers completely, and the request
+        * will always succeed.
+        */
+       do_test (base_uri, "/foo",
+                TEST_GOOD_USER (i), TEST_GOOD_PASSWORD (i),
+                /* request */
+                TEST_USES_BASIC (i), TEST_USES_DIGEST (i),
+                /* expected from client */
+                TEST_PREEMPTIVE_BASIC (i), FALSE,
+                /* expected from server */
+                FALSE, FALSE,
+                /* success? */
+                TRUE);
+
+       /* 2. Basic auth required. The server will send
+        * "WWW-Authenticate: Basic" if the client fails to
+        * send an Authorization: Basic on the first request,
+        * or if it sends a bad password.
+        */
+       do_test (base_uri, "/Basic/foo",
+                TEST_GOOD_USER (i), TEST_GOOD_PASSWORD (i),
+                /* request */
+                TEST_USES_BASIC (i), TEST_USES_DIGEST (i),
+                /* expected from client */
+                TEST_USES_BASIC (i), FALSE,
+                /* expected from server */
+                !TEST_PREEMPTIVE_BASIC (i) || !TEST_GOOD_AUTH (i), FALSE,
+                /* success? */
+                TEST_USES_BASIC (i) && TEST_GOOD_AUTH (i));
+
+       /* 3. Digest auth required. Simpler than the basic
+        * case because the client can't send Digest auth
+        * premptively.
+        */
+       do_test (base_uri, "/Digest/foo",
+                TEST_GOOD_USER (i), TEST_GOOD_PASSWORD (i),
+                /* request */
+                TEST_USES_BASIC (i), TEST_USES_DIGEST (i),
+                /* expected from client */
+                TEST_PREEMPTIVE_BASIC (i), TEST_USES_DIGEST (i),
+                /* expected from server */
+                FALSE, TRUE,
+                /* success? */
+                TEST_USES_DIGEST (i) && TEST_GOOD_AUTH (i));
+
+       /* 4. Any auth required. */
+       do_test (base_uri, "/Any/foo",
+                TEST_GOOD_USER (i), TEST_GOOD_PASSWORD (i),
+                /* request */
+                TEST_USES_BASIC (i), TEST_USES_DIGEST (i),
+                /* expected from client */
+                TEST_PREEMPTIVE_BASIC (i), TEST_USES_DIGEST (i),
+                /* expected from server */
+                !TEST_PREEMPTIVE_BASIC (i) || !TEST_GOOD_AUTH (i), !TEST_PREEMPTIVE_BASIC (i) || 
!TEST_GOOD_AUTH (i),
+                /* success? */
+                (TEST_USES_BASIC (i) || TEST_USES_DIGEST (i)) && TEST_GOOD_AUTH (i));
+
+       /* 5. No auth required again. (Makes sure that
+        * SOUP_AUTH_DOMAIN_REMOVE_PATH works.)
+        */
+       do_test (base_uri, "/Any/Not/foo",
+                TEST_GOOD_USER (i), TEST_GOOD_PASSWORD (i),
+                /* request */
+                TEST_USES_BASIC (i), TEST_USES_DIGEST (i),
+                /* expected from client */
+                TEST_PREEMPTIVE_BASIC (i), FALSE,
+                /* expected from server */
+                FALSE, FALSE,
+                /* success? */
+                TRUE);
 }
 
 static gboolean
@@ -290,7 +277,6 @@ main (int argc, char **argv)
 {
        GMainLoop *loop;
        SoupServer *server;
-       SoupURI *uri;
        SoupAuthDomain *auth_domain;
        int ret;
 
@@ -325,15 +311,41 @@ main (int argc, char **argv)
        loop = g_main_loop_new (NULL, TRUE);
 
        if (run_tests) {
-               uri = soup_uri_new ("http://127.0.0.1";);
-               soup_uri_set_port (uri, soup_server_get_port (server));
-
-               /* FIXME: split this up! */
-               g_test_add_data_func ("/server-auth", uri, do_auth_tests);
+               int i;
+
+               base_uri = soup_uri_new ("http://127.0.0.1";);
+               soup_uri_set_port (base_uri, soup_server_get_port (server));
+
+               for (i = 0; i < 16; i++) {
+                       char *path;
+                       const char *authtypes;
+
+                       if (!TEST_GOOD_USER (i) && !TEST_GOOD_PASSWORD (i))
+                               continue;
+                       if (TEST_USES_BASIC (i)) {
+                               if (TEST_USES_DIGEST (i))
+                                       authtypes = "basic+digest";
+                               else
+                                       authtypes = "basic";
+                       } else {
+                               if (TEST_USES_DIGEST (i))
+                                       authtypes = "digest";
+                               else
+                                       authtypes = "none";
+                       }
+
+                       path = g_strdup_printf ("/server-auth/%s/%s-user%c%s-password",
+                                               authtypes,
+                                               TEST_GOOD_USER (i) ? "good" : "bad",
+                                               TEST_GOOD_USER (i) ? '/' : '\0',
+                                               TEST_GOOD_PASSWORD (i) ? "good" : "bad");
+                       g_test_add_data_func (path, GINT_TO_POINTER (i), do_server_auth_test);
+                       g_free (path);
+               }
 
                ret = g_test_run ();
 
-               soup_uri_free (uri);
+               soup_uri_free (base_uri);
        } else {
                g_print ("Listening on port %d\n", soup_server_get_port (server));
                g_main_loop_run (loop);
diff --git a/tests/ssl-test.c b/tests/ssl-test.c
index 3eb61af..65e8a55 100644
--- a/tests/ssl-test.c
+++ b/tests/ssl-test.c
@@ -2,6 +2,8 @@
 
 #include "test-utils.h"
 
+static char *uri;
+
 static void
 do_properties_test_for_session (SoupSession *session, const char *uri)
 {
@@ -24,7 +26,7 @@ do_properties_test_for_session (SoupSession *session, const char *uri)
 }
 
 static void
-do_async_properties_tests (gconstpointer uri)
+do_async_properties_tests (void)
 {
        SoupSession *session;
 
@@ -40,7 +42,7 @@ do_async_properties_tests (gconstpointer uri)
 }
 
 static void
-do_sync_properties_tests (gconstpointer uri)
+do_sync_properties_tests (void)
 {
        SoupSession *session;
 
@@ -55,80 +57,70 @@ do_sync_properties_tests (gconstpointer uri)
        soup_test_session_abort_unref (session);
 }
 
+typedef struct {
+       const char *name;
+       gboolean sync;
+       gboolean strict;
+       gboolean with_ca_list;
+       guint expected_status;
+} StrictnessTest;
+
+static const StrictnessTest strictness_tests[] = {
+       { "/ssl/strictness/async/strict/with-ca",
+         FALSE, TRUE, TRUE, SOUP_STATUS_OK },
+       { "/ssl/strictness/async/strict/without-ca",
+         FALSE, TRUE, FALSE, SOUP_STATUS_SSL_FAILED },
+       { "/ssl/strictness/async/non-strict/with-ca",
+         FALSE, FALSE, TRUE, SOUP_STATUS_OK },
+       { "/ssl/strictness/async/non-strict/without-ca",
+         FALSE, FALSE, FALSE, SOUP_STATUS_OK },
+       { "/ssl/strictness/sync/strict/with-ca",
+         TRUE, TRUE, TRUE, SOUP_STATUS_OK },
+       { "/ssl/strictness/sync/strict/without-ca",
+         TRUE, TRUE, FALSE, SOUP_STATUS_SSL_FAILED },
+       { "/ssl/strictness/sync/non-strict/with-ca",
+         TRUE, FALSE, TRUE, SOUP_STATUS_OK },
+       { "/ssl/strictness/sync/non-strict/without-ca",
+         TRUE, FALSE, FALSE, SOUP_STATUS_OK },
+};
+
 static void
-do_one_strict_test (SoupSession *session, const char *uri,
-                   gboolean strict, gboolean with_ca_list,
-                   guint expected_status)
+do_strictness_test (gconstpointer data)
 {
+       const StrictnessTest *test = data;
+       SoupSession *session;
        SoupMessage *msg;
+       GTlsCertificateFlags flags = 0;
 
-       /* Note that soup_test_session_new() sets
-        * SOUP_SESSION_SSL_CA_FILE by default, and turns off
-        * SOUP_SESSION_SSL_STRICT.
-        */
+       SOUP_TEST_SKIP_IF_NO_TLS;
 
-       g_object_set (G_OBJECT (session),
-                     SOUP_SESSION_SSL_STRICT, strict,
-                     SOUP_SESSION_SSL_CA_FILE,
-                     (with_ca_list ?
-                      g_test_get_filename (G_TEST_DIST, "/test-cert.pem", NULL) :
-                      "/dev/null"),
-                     NULL);
-       /* Close existing connections with old params */
-       soup_session_abort (session);
+       session = soup_test_session_new (test->sync ? SOUP_TYPE_SESSION_SYNC : SOUP_TYPE_SESSION_ASYNC,
+                                        NULL);
+       if (!test->strict) {
+               g_object_set (G_OBJECT (session),
+                             SOUP_SESSION_SSL_STRICT, FALSE,
+                             NULL);
+       }
+       if (!test->with_ca_list) {
+               g_object_set (G_OBJECT (session),
+                             SOUP_SESSION_SSL_CA_FILE, "/dev/null",
+                             NULL);
+       }
 
        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));
-               if (msg->status_code == SOUP_STATUS_SSL_FAILED) {
-                       GTlsCertificateFlags flags = 0;
-
-                       soup_message_get_https_status (msg, NULL, &flags);
-                       debug_printf (1, "              tls error flags: 0x%x\n", flags);
-               }
-       } else if (with_ca_list && SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
+       soup_test_assert_message_status (msg, test->expected_status);
+       g_assert_true (soup_message_get_https_status (msg, NULL, &flags));
+       if (test->with_ca_list && SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
                g_assert_true (soup_message_get_flags (msg) & SOUP_MESSAGE_CERTIFICATE_TRUSTED);
        else
                g_assert_false (soup_message_get_flags (msg) & SOUP_MESSAGE_CERTIFICATE_TRUSTED);
 
-       g_assert_true (soup_message_get_https_status (msg, NULL, NULL));
+       if (msg->status_code == SOUP_STATUS_SSL_FAILED &&
+           test->expected_status != SOUP_STATUS_SSL_FAILED)
+               debug_printf (1, "              tls error flags: 0x%x\n", flags);
 
        g_object_unref (msg);
-}
-
-static void
-do_strict_tests (gconstpointer uri)
-{
-       SoupSession *session;
-
-       SOUP_TEST_SKIP_IF_NO_TLS;
-
-       debug_printf (1, "\nstrict/nonstrict\n");
-
-       session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
-       debug_printf (1, "  async with CA list\n");
-       do_one_strict_test (session, uri, TRUE, TRUE, SOUP_STATUS_OK);
-       debug_printf (1, "  async without CA list\n");
-       do_one_strict_test (session, uri, TRUE, FALSE, SOUP_STATUS_SSL_FAILED);
-       debug_printf (1, "  async non-strict with CA list\n");
-       do_one_strict_test (session, uri, FALSE, TRUE, SOUP_STATUS_OK);
-       debug_printf (1, "  async non-strict without CA list\n");
-       do_one_strict_test (session, uri, FALSE, FALSE, SOUP_STATUS_OK);
-       soup_test_session_abort_unref (session);
-
-       session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
-       debug_printf (1, "  sync with CA list\n");
-       do_one_strict_test (session, uri, TRUE, TRUE, SOUP_STATUS_OK);
-       debug_printf (1, "  sync without CA list\n");
-       do_one_strict_test (session, uri, TRUE, FALSE, SOUP_STATUS_SSL_FAILED);
-       debug_printf (1, "  sync non-strict with CA list\n");
-       do_one_strict_test (session, uri, FALSE, TRUE, SOUP_STATUS_OK);
-       debug_printf (1, "  sync non-strict without CA list\n");
-       do_one_strict_test (session, uri, FALSE, FALSE, SOUP_STATUS_OK);
        soup_test_session_abort_unref (session);
 }
 
@@ -254,8 +246,7 @@ int
 main (int argc, char **argv)
 {
        SoupServer *server;
-       char *uri;
-       int ret;
+       int i, ret;
 
        test_init (argc, argv, NULL);
 
@@ -267,11 +258,14 @@ main (int argc, char **argv)
        }
 
        g_test_add_func ("/ssl/session-properties", do_session_property_tests);
-       g_test_add_data_func ("/ssl/message-properties/async", uri, do_async_properties_tests);
-       g_test_add_data_func ("/ssl/message-properties/sync", uri, do_sync_properties_tests);
+       g_test_add_func ("/ssl/message-properties/async", do_async_properties_tests);
+       g_test_add_func ("/ssl/message-properties/sync", do_sync_properties_tests);
 
-       /* FIXME: split this up */
-       g_test_add_data_func ("/ssl/strict", uri, do_strict_tests);
+       for (i = 0; i < G_N_ELEMENTS (strictness_tests); i++) {
+               g_test_add_data_func (strictness_tests[i].name,
+                                     &strictness_tests[i],
+                                     do_strictness_test);
+       }
 
        ret = g_test_run ();
 
diff --git a/tests/xmlrpc-server-test.c b/tests/xmlrpc-server-test.c
index 1a046c7..bfeb200 100644
--- a/tests/xmlrpc-server-test.c
+++ b/tests/xmlrpc-server-test.c
@@ -5,12 +5,12 @@
 
 #include "test-utils.h"
 
+static char *uri;
+
 #ifdef G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 #endif
 
-GMainLoop *loop;
-
 static void
 type_error (SoupMessage *msg, GType expected, GValueArray *params, int bad_value)
 {
@@ -237,76 +237,64 @@ server_callback (SoupServer *server, SoupMessage *msg,
        g_value_array_free (params);
 }
 
-static void
-xmlrpc_test_exited (GPid pid, int status, gpointer data)
-{
-       g_assert_true (WIFEXITED (status) && WEXITSTATUS (status) == 0);
-       g_main_loop_quit (loop);
-}
-
 static gboolean
-xmlrpc_test_print (GIOChannel *io, GIOCondition cond, gpointer data)
+run_xmlrpc_test (char **argv,
+                char **stdout_out,
+                char **stderr_out,
+                GError **error)
 {
-       char *line;
-       gsize len;
-       GIOStatus status;
+       gboolean ok;
+       int status;
 
-       if (!(cond & G_IO_IN))
-               return FALSE;
+       argv[0] = g_test_build_filename (G_TEST_BUILT, "xmlrpc-test", NULL);
+       ok = g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL,
+                          stdout_out, stderr_out, &status,
+                          error);
+       g_free (argv[0]);
 
-       status = g_io_channel_read_line (io, &line, &len, NULL, NULL);
-       if (status == G_IO_STATUS_NORMAL) {
-               /* Don't print the exit status, just the debug stuff */
-               if (strncmp (line, "xmlrpc-test:", strlen ("xmlrpc-test:")) != 0)
-                       g_print ("%s", line);
-               g_free (line);
-               return TRUE;
-       } else if (status == G_IO_STATUS_AGAIN)
-               return TRUE;
-       else
+       if (!ok)
                return FALSE;
+
+       return g_spawn_check_exit_status (status, error);
 }
 
 static void
-do_xmlrpc_tests (gconstpointer data)
+do_one_xmlrpc_test (gconstpointer data)
 {
-       SoupURI *uri = (SoupURI *)data;
-       char *argv[10];
-       int arg, out;
-       gboolean ok;
-       GPid pid;
+       const char *path = data;
+       char *argv[12];
+       char *stdout_out, *stderr_out;
        GError *error = NULL;
-       GIOChannel *child_out;
+       int arg;
 
-       argv[0] = (char *) g_test_get_filename (G_TEST_BUILT, "xmlrpc-test", NULL);
+       argv[0] = NULL;
        argv[1] = "-S";
        argv[2] = "-U";
-       argv[3] = soup_uri_to_string (uri, FALSE);
+       argv[3] = uri;
        argv[4] = "-q";
+       argv[5] = "-p";
+       argv[6] = (char *) path;
 
        for (arg = 0; arg < debug_level && arg < 3; arg++)
-               argv[arg + 5] = "-d";
-       argv[arg + 5] = NULL;
+               argv[arg + 7] = "-d";
+       argv[arg + 7] = NULL;
 
-       ok = g_spawn_async_with_pipes (NULL, argv, NULL,
-                                      G_SPAWN_DO_NOT_REAP_CHILD,
-                                      NULL, NULL, &pid,
-                                      NULL, &out, NULL,
-                                      &error);
-       g_free (argv[3]);
-
-       g_assert_no_error (error);
-       if (!ok)
-               return;
-
-       g_child_watch_add (pid, xmlrpc_test_exited, NULL);
-       child_out = g_io_channel_unix_new (out);
-       g_io_add_watch (child_out, G_IO_IN | G_IO_ERR | G_IO_HUP,
-                       xmlrpc_test_print, NULL);
-       g_io_channel_unref (child_out);
+       run_xmlrpc_test (argv, &stdout_out, &stderr_out, &error);
+       if (stdout_out) {
+               g_print ("%s", stdout_out);
+               g_free (stdout_out);
+       }
+       if (stderr_out) {
+               g_printerr ("%s", stderr_out);
+               g_free (stderr_out);
+       }
 
-       g_main_loop_run (loop);
-       g_main_loop_unref (loop);
+       if (   g_error_matches (error, G_SPAWN_EXIT_ERROR, 1)
+           || g_error_matches (error, G_SPAWN_EXIT_ERROR, 77))
+               g_test_fail ();
+       else
+               g_assert_no_error (error);
+       g_clear_error (&error);
 }
 
 gboolean run_tests = TRUE;
@@ -322,29 +310,52 @@ int
 main (int argc, char **argv)
 {
        SoupServer *server;
-       SoupURI *uri;
        int ret;
 
        test_init (argc, argv, no_test_entry);
 
-       server = soup_test_server_new (FALSE);
+       server = soup_test_server_new (run_tests);
        soup_server_add_handler (server, "/xmlrpc-server.php",
                                 server_callback, NULL, NULL);
-
-       loop = g_main_loop_new (NULL, TRUE);
+       uri = g_strdup_printf ("http://127.0.0.1:%u/xmlrpc-server.php";,
+                              soup_server_get_port (server));
 
        if (run_tests) {
-               uri = soup_uri_new ("http://127.0.0.1/xmlrpc-server.php";);
-               soup_uri_set_port (uri, soup_server_get_port (server));
+               char *out, **tests, *path;
+               char *list_argv[4];
+               GError *error = NULL;
+               int i;
+
+               list_argv[0] = NULL;
+               list_argv[1] = "-S";
+               list_argv[2] = "-l";
+               list_argv[3] = NULL;
+
+               if (!run_xmlrpc_test (list_argv, &out, NULL, &error)) {
+                       g_printerr ("'xmlrpc-test -l' failed: %s\n", error->message);
+                       g_error_free (error);
+                       return 1;
+               }
 
-               g_test_add_data_func ("/xmlrpc/server", uri, do_xmlrpc_tests);
+               tests = g_strsplit (out, "\n", -1);
+               g_free (out);
+
+               for (i = 0; tests[i] && *tests[i]; i++) {
+                       g_assert_true (g_str_has_prefix (tests[i], "/xmlrpc/"));
+                       path = g_strdup_printf ("/xmlrpc-server/%s", tests[i] + strlen ("/xmlrpc/"));
+                       g_test_add_data_func (path, tests[i], do_one_xmlrpc_test);
+                       g_free (path);
+               }
 
                ret = g_test_run ();
 
-               soup_uri_free (uri);
+               g_strfreev (tests);
        } else {
+               GMainLoop *loop;
+
                g_print ("Listening on port %d\n", soup_server_get_port (server));
 
+               loop = g_main_loop_new (NULL, TRUE);
                g_main_loop_run (loop);
                g_main_loop_unref (loop);
 
@@ -352,6 +363,7 @@ main (int argc, char **argv)
        }
 
        soup_test_server_quit_unref (server);
+       g_free (uri);
        if (run_tests)
                test_cleanup ();
        return ret;
diff --git a/tests/xmlrpc-test.c b/tests/xmlrpc-test.c
index 15623a6..73518c8 100644
--- a/tests/xmlrpc-test.c
+++ b/tests/xmlrpc-test.c
@@ -504,7 +504,7 @@ main (int argc, char **argv)
 
        test_init (argc, argv, xmlrpc_entries);
 
-       if (!uri) {
+       if (!uri && !server_test) {
                apache_init ();
                uri = default_uri;
        }


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