[libsoup] requester-test: add an early-cancellation test
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup] requester-test: add an early-cancellation test
- Date: Wed, 2 May 2012 14:34:57 +0000 (UTC)
commit 5022cfb7d332c4b85c8069f3d54a0e85506c0508
Author: Dan Winship <danw gnome org>
Date: Wed May 2 10:33:20 2012 -0400
requester-test: add an early-cancellation test
tests/requester-test.c | 188 ++++++++++++++++++++++++++++++++++++-----------
1 files changed, 144 insertions(+), 44 deletions(-)
---
diff --git a/tests/requester-test.c b/tests/requester-test.c
index 56c50f3..ae02451 100644
--- a/tests/requester-test.c
+++ b/tests/requester-test.c
@@ -97,6 +97,11 @@ server_callback (SoupServer *server, SoupMessage *msg,
soup_message_body_append_buffer (msg->response_body, response);
}
+typedef struct {
+ GString *body;
+ gboolean cancel;
+} RequestData;
+
static void
stream_closed (GObject *source, GAsyncResult *res, gpointer user_data)
{
@@ -116,7 +121,8 @@ static void
test_read_ready (GObject *source, GAsyncResult *res, gpointer user_data)
{
GInputStream *stream = G_INPUT_STREAM (source);
- GString *body = user_data;
+ RequestData *data = user_data;
+ GString *body = data->body;
GError *error = NULL;
gsize nread;
@@ -139,13 +145,13 @@ test_read_ready (GObject *source, GAsyncResult *res, gpointer user_data)
g_string_append_len (body, buf, nread);
g_input_stream_read_async (stream, buf, sizeof (buf),
G_PRIORITY_DEFAULT, NULL,
- test_read_ready, body);
+ test_read_ready, data);
}
static void
auth_test_sent (GObject *source, GAsyncResult *res, gpointer user_data)
{
- GString *body = user_data;
+ RequestData *data = user_data;
GInputStream *stream;
GError *error = NULL;
SoupMessage *msg;
@@ -178,35 +184,40 @@ auth_test_sent (GObject *source, GAsyncResult *res, gpointer user_data)
g_input_stream_read_async (stream, buf, sizeof (buf),
G_PRIORITY_DEFAULT, NULL,
- test_read_ready, body);
+ test_read_ready, data);
}
static void
test_sent (GObject *source, GAsyncResult *res, gpointer user_data)
{
- GString *body = user_data;
+ RequestData *data = user_data;
GInputStream *stream;
GError *error = NULL;
- SoupMessage *msg;
const char *content_type;
stream = soup_request_send_finish (SOUP_REQUEST (source), res, &error);
- if (!stream) {
- debug_printf (1, " send_async failed: %s\n", error->message);
- errors++;
- g_main_loop_quit (loop);
- return;
- }
-
- msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (source));
- if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
- debug_printf (1, " GET failed: %d %s\n", msg->status_code,
- msg->reason_phrase);
- errors++;
+ if (data->cancel) {
+ if (stream) {
+ debug_printf (1, " send_async succeeded??\n");
+ errors++;
+ g_input_stream_close (stream, NULL, NULL);
+ g_object_unref (stream);
+ } else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ debug_printf (1, " send_async failed with wrong error: %s\n", error->message);
+ errors++;
+ g_clear_error (&error);
+ }
g_main_loop_quit (loop);
return;
+ } else {
+ if (!stream) {
+ debug_printf (1, " send_async failed: %s\n", error->message);
+ errors++;
+ g_main_loop_quit (loop);
+ g_clear_error (&error);
+ return;
+ }
}
- g_object_unref (msg);
content_type = soup_request_get_content_type (SOUP_REQUEST (source));
if (g_strcmp0 (content_type, "text/plain") != 0) {
@@ -217,7 +228,13 @@ test_sent (GObject *source, GAsyncResult *res, gpointer user_data)
g_input_stream_read_async (stream, buf, sizeof (buf),
G_PRIORITY_DEFAULT, NULL,
- test_read_ready, body);
+ test_read_ready, data);
+}
+
+static void
+cancel_message (SoupMessage *msg, gpointer session)
+{
+ soup_session_cancel_message (session, msg, SOUP_STATUS_FORBIDDEN);
}
static void
@@ -230,26 +247,35 @@ request_started (SoupSession *session, SoupMessage *msg,
}
static void
-do_one_test (SoupSession *session, SoupURI *uri,
- GAsyncReadyCallback callback, SoupBuffer *expected_response,
- gboolean persistent)
+do_async_test (SoupSession *session, SoupURI *uri,
+ GAsyncReadyCallback callback, guint expected_status,
+ SoupBuffer *expected_response,
+ gboolean persistent, gboolean cancel)
{
SoupRequester *requester;
SoupRequest *request;
- GString *body;
guint started_id;
SoupSocket *socket = NULL;
+ SoupMessage *msg;
+ RequestData data;
requester = SOUP_REQUESTER (soup_session_get_feature (session, SOUP_TYPE_REQUESTER));
- body = g_string_new (NULL);
+ data.body = g_string_new (NULL);
+ data.cancel = cancel;
request = soup_requester_request_uri (requester, uri, NULL);
+ msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (request));
+
+ if (cancel) {
+ g_signal_connect (msg, "got-headers",
+ G_CALLBACK (cancel_message), session);
+ }
started_id = g_signal_connect (session, "request-started",
G_CALLBACK (request_started),
&socket);
- soup_request_send_async (request, NULL, callback, body);
+ soup_request_send_async (request, NULL, callback, &data);
g_object_unref (request);
loop = g_main_loop_new (soup_session_get_async_context (session), TRUE);
@@ -258,11 +284,27 @@ do_one_test (SoupSession *session, SoupURI *uri,
g_signal_handler_disconnect (session, started_id);
- if (body->len != expected_response->length) {
+ if (msg->status_code != expected_status) {
+ debug_printf (1, " GET failed: %d %s (expected %d)\n",
+ msg->status_code, msg->reason_phrase,
+ expected_status);
+ g_object_unref (msg);
+ errors++;
+ return;
+ }
+ g_object_unref (msg);
+
+ if (!expected_response) {
+ if (data.body->len) {
+ debug_printf (1, " body length mismatch: expected 0, got %d\n",
+ (int)data.body->len);
+ errors++;
+ }
+ } else if (data.body->len != expected_response->length) {
debug_printf (1, " body length mismatch: expected %d, got %d\n",
- (int)expected_response->length, (int)body->len);
+ (int)expected_response->length, (int)data.body->len);
errors++;
- } else if (memcmp (body->str, expected_response->data,
+ } else if (memcmp (data.body->str, expected_response->data,
expected_response->length) != 0) {
debug_printf (1, " body data mismatch\n");
errors++;
@@ -281,7 +323,7 @@ do_one_test (SoupSession *session, SoupURI *uri,
}
g_object_unref (socket);
- g_string_free (body, TRUE);
+ g_string_free (data.body, TRUE);
}
static void
@@ -297,25 +339,41 @@ do_test_for_thread_and_context (SoupSession *session, const char *base_uri)
debug_printf (1, " basic test\n");
uri = soup_uri_new (base_uri);
- do_one_test (session, uri, test_sent, response, TRUE);
+ do_async_test (session, uri, test_sent,
+ SOUP_STATUS_OK, response,
+ TRUE, FALSE);
soup_uri_free (uri);
debug_printf (1, " chunked test\n");
uri = soup_uri_new (base_uri);
soup_uri_set_path (uri, "/chunked");
- do_one_test (session, uri, test_sent, response, TRUE);
+ do_async_test (session, uri, test_sent,
+ SOUP_STATUS_OK, response,
+ TRUE, FALSE);
soup_uri_free (uri);
debug_printf (1, " auth test\n");
uri = soup_uri_new (base_uri);
soup_uri_set_path (uri, "/auth");
- do_one_test (session, uri, auth_test_sent, auth_response, TRUE);
+ do_async_test (session, uri, auth_test_sent,
+ SOUP_STATUS_UNAUTHORIZED, auth_response,
+ TRUE, FALSE);
soup_uri_free (uri);
debug_printf (1, " non-persistent test\n");
uri = soup_uri_new (base_uri);
soup_uri_set_path (uri, "/non-persistent");
- do_one_test (session, uri, test_sent, response, FALSE);
+ do_async_test (session, uri, test_sent,
+ SOUP_STATUS_OK, response,
+ FALSE, FALSE);
+ soup_uri_free (uri);
+
+ debug_printf (1, " cancellation test\n");
+ uri = soup_uri_new (base_uri);
+ soup_uri_set_path (uri, "/");
+ do_async_test (session, uri, test_sent,
+ SOUP_STATUS_FORBIDDEN, NULL,
+ FALSE, TRUE);
soup_uri_free (uri);
}
@@ -378,7 +436,7 @@ do_thread_test (const char *uri)
static void
do_sync_request (SoupSession *session, SoupRequest *request,
guint expected_status, SoupBuffer *expected_response,
- gboolean persistent)
+ gboolean persistent, gboolean cancel)
{
GInputStream *in;
SoupMessage *msg;
@@ -389,24 +447,45 @@ do_sync_request (SoupSession *session, SoupRequest *request,
guint started_id;
SoupSocket *socket = NULL;
+ msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (request));
+ if (cancel) {
+ g_signal_connect (msg, "got-headers",
+ G_CALLBACK (cancel_message), session);
+ }
+
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) {
+ if (cancel) {
+ if (in) {
+ debug_printf (1, " send succeeded??\n");
+ errors++;
+ g_input_stream_close (in, NULL, NULL);
+ g_object_unref (in);
+ } else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ debug_printf (1, " send failed with wrong error: %s\n", error->message);
+ errors++;
+ g_clear_error (&error);
+ }
+ g_object_unref (msg);
+ return;
+ } else if (!in) {
debug_printf (1, " soup_request_send failed: %s\n",
error->message);
+ g_object_unref (msg);
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,
+ debug_printf (1, " GET failed: %d %s\n", msg->status_code,
msg->reason_phrase);
+ g_object_unref (msg);
+ g_object_unref (in);
errors++;
return;
}
@@ -434,7 +513,13 @@ do_sync_request (SoupSession *session, SoupRequest *request,
}
g_object_unref (in);
- if (body->len != expected_response->length) {
+ if (!expected_response) {
+ if (body->len) {
+ debug_printf (1, " body length mismatch: expected 0, got %d\n",
+ (int)body->len);
+ errors++;
+ }
+ } else 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++;
@@ -478,26 +563,41 @@ do_sync_test (const char *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);
+ do_sync_request (session, request,
+ SOUP_STATUS_OK, response,
+ TRUE, FALSE);
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);
+ do_sync_request (session, request,
+ SOUP_STATUS_OK, response,
+ TRUE, FALSE);
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);
+ do_sync_request (session, request,
+ SOUP_STATUS_UNAUTHORIZED, auth_response,
+ TRUE, FALSE);
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);
+ do_sync_request (session, request,
+ SOUP_STATUS_OK, response,
+ FALSE, FALSE);
+ g_object_unref (request);
+
+ debug_printf (1, " cancel test\n");
+ soup_uri_set_path (uri, "/");
+ request = soup_requester_request_uri (requester, uri, NULL);
+ do_sync_request (session, request,
+ SOUP_STATUS_FORBIDDEN, NULL,
+ TRUE, TRUE);
g_object_unref (request);
soup_test_session_abort_unref (session);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]