[serf] r1860 committed - Add two new test cases, for large request bodies. Fix the test framewo...

1 view
Skip to first unread message

se...@googlecode.com

unread,
May 20, 2013, 7:13:48 AM5/20/13
to serf...@googlegroups.com
Revision: 1860
Author: lieven....@gmail.com
Date: Mon May 20 04:13:29 2013
Log: Add two new test cases, for large request bodies. Fix the test
framework to
correctly handle these with both the http and https test servers.

* test/server/test_server.c
(replay): Keep looping until all available data is read from the socket.

* test/server/test_server.h
(struct serv_ctx_t): Add variable bio_read_status.

* test/server/test_sslserver.c
(bio_apr_socket_read): Store the status returned from the stream bucket
in the context.
(init_ssl_context): Init bio_read_status.
(ssl_socket_read): Handle errors. Pass bio_read_status back to the caller
for
the actual status of the socket.

* test/test_context.c
(struct handler_baton_t): Add request variable.
(setup_request): Use the request member of handler_baton_t as the raw
request message.
(setup_handler): Initialize request variable.
(create_large_request_message): New helper function.
(test_serf_connection_large_request,
test_serf_ssl_large_request): New tests.
(test_context): Run the new tests.

http://code.google.com/p/serf/source/detail?r=1860

Modified:
/trunk/test/server/test_server.c
/trunk/test/server/test_server.h
/trunk/test/server/test_sslserver.c
/trunk/test/test_context.c

=======================================
--- /trunk/test/server/test_server.c Sun May 5 12:24:31 2013
+++ /trunk/test/server/test_server.c Mon May 20 04:13:29 2013
@@ -134,39 +134,46 @@
message = &servctx->message_list[servctx->cur_message];
msg_len = strlen(message->text);

- len = msg_len - servctx->message_buf_pos;
- if (len > sizeof(buf))
- len = sizeof(buf);
+ do
+ {
+ len = msg_len - servctx->message_buf_pos;
+ if (len > sizeof(buf))
+ len = sizeof(buf);
+
+ status = servctx->read(servctx, buf, &len);
+ if (SERF_BUCKET_READ_ERROR(status))
+ return status;

- status = servctx->read(servctx, buf, &len);
- if (status != APR_SUCCESS)
- return status;
+ if (servctx->options & TEST_SERVER_DUMP)
+ fwrite(buf, len, 1, stdout);

- if (servctx->options & TEST_SERVER_DUMP)
- fwrite(buf, len, 1, stdout);
+ if (strncmp(buf,
+ message->text + servctx->message_buf_pos,
+ len) != 0) {
+ /* ## TODO: Better diagnostics. */
+ printf("Expected: (\n");
+ fwrite(message->text + servctx->message_buf_pos, len,
1,
+ stdout);
+ printf(")\n");
+ printf("Actual: (\n");
+ fwrite(buf, len, 1, stdout);
+ printf(")\n");

- if (strncmp(buf, message->text + servctx->message_buf_pos,
len) != 0) {
- /* ## TODO: Better diagnostics. */
- printf("Expected: (\n");
- fwrite(message->text + servctx->message_buf_pos, len, 1,
stdout);
- printf(")\n");
- printf("Actual: (\n");
- fwrite(buf, len, 1, stdout);
- printf(")\n");
-
- return SERF_ERROR_ISSUE_IN_TESTSUITE;
- }
+ return SERF_ERROR_ISSUE_IN_TESTSUITE;
+ }

- servctx->message_buf_pos += len;
+ servctx->message_buf_pos += len;

- if (servctx->message_buf_pos >= msg_len) {
- next_message(servctx);
- servctx->message_buf_pos -= msg_len;
- if (action->kind == SERVER_RESPOND)
- servctx->outstanding_responses++;
- if (action->kind == SERVER_RECV)
- next_action(servctx);
- }
+ if (servctx->message_buf_pos >= msg_len) {
+ next_message(servctx);
+ servctx->message_buf_pos -= msg_len;
+ if (action->kind == SERVER_RESPOND)
+ servctx->outstanding_responses++;
+ if (action->kind == SERVER_RECV)
+ next_action(servctx);
+ break;
+ }
+ } while (!status);
}
}
if (rtnevents & APR_POLLOUT) {
=======================================
--- /trunk/test/server/test_server.h Thu May 2 15:11:59 2013
+++ /trunk/test/server/test_server.h Mon May 20 04:13:29 2013
@@ -94,6 +94,7 @@
handshake_func_t handshake;
void *ssl_ctx;
const char *client_cn;
+ apr_status_t bio_read_status;
};

void test_setup_server(serv_ctx_t **servctx_p,
=======================================
--- /trunk/test/server/test_sslserver.c Sun May 5 12:55:07 2013
+++ /trunk/test/server/test_sslserver.c Mon May 20 04:13:29 2013
@@ -91,11 +91,14 @@
BIO_clear_retry_flags(bio);

status = apr_socket_recv(serv_ctx->client_sock, in, &len);
+ serv_ctx->bio_read_status = status;
+
if (status == APR_EAGAIN) {
+ serf__log(TEST_VERBOSE, __FILE__, "Read %d bytes from socket with "
+ "status %d.\n", len, status);
BIO_set_retry_read(bio);
if (len == 0)
return -1;
-
}

if (SERF_BUCKET_READ_ERROR(status))
@@ -156,6 +159,7 @@
ssl_context_t *ssl_ctx = apr_pcalloc(serv_ctx->pool, sizeof(*ssl_ctx));
serv_ctx->ssl_ctx = ssl_ctx;
serv_ctx->client_cn = client_cn;
+ serv_ctx->bio_read_status = APR_SUCCESS;

/* Init OpenSSL globally */
if (!init_done)
@@ -312,8 +316,26 @@
if (result > 0) {
*len = result;
return APR_SUCCESS;
+ } else {
+ int ssl_err;
+
+ ssl_err = SSL_get_error(ssl_ctx, result);
+ switch (ssl_err) {
+ case SSL_ERROR_SYSCALL:
+ /* error in bio_bucket_read, probably APR_EAGAIN or
APR_EOF */
+ *len = 0;
+ return serv_ctx->bio_read_status;
+ case SSL_ERROR_WANT_READ:
+ *len = 0;
+ return APR_EAGAIN;
+ case SSL_ERROR_SSL:
+ default:
+ *len = 0;
+ return SERF_ERROR_ISSUE_IN_TESTSUITE;
+ }
}

+ /* not reachable */
return SERF_ERROR_ISSUE_IN_TESTSUITE;
}

=======================================
--- /trunk/test/test_context.c Fri May 17 13:20:35 2013
+++ /trunk/test/test_context.c Mon May 20 04:13:29 2013
@@ -38,6 +38,8 @@

const char *method;
const char *path;
+ /* Use this for a raw request message */
+ const char *request;
int done;

test_baton_t *tb;
@@ -136,15 +138,26 @@
handler_baton_t *ctx = setup_baton;
serf_bucket_t *body_bkt;

- /* create a simple body text */
- const char *str = apr_psprintf(pool, "%d", ctx->req_id);
- body_bkt = serf_bucket_simple_create(str, strlen(str), NULL, NULL,
- serf_request_get_alloc(request));
- *req_bkt =
- serf_request_bucket_request_create(request,
- ctx->method, ctx->path,
- body_bkt,
-
serf_request_get_alloc(request));
+ if (ctx->request)
+ {
+ /* Create a raw request bucket. */
+ *req_bkt = serf_bucket_simple_create(ctx->request,
strlen(ctx->request),
+ NULL, NULL,
+
serf_request_get_alloc(request));
+ }
+ else
+ {
+ /* create a simple body text */
+ const char *str = apr_psprintf(pool, "%d", ctx->req_id);
+
+ body_bkt = serf_bucket_simple_create(str, strlen(str), NULL, NULL,
+
serf_request_get_alloc(request));
+ *req_bkt =
+ serf_request_bucket_request_create(request,
+ ctx->method, ctx->path,
+ body_bkt,
+
serf_request_get_alloc(request));
+ }

APR_ARRAY_PUSH(ctx->sent_requests, int) = ctx->req_id;

@@ -211,6 +224,7 @@
handler_ctx->sent_requests = tb->sent_requests;
handler_ctx->handled_requests = tb->handled_requests;
handler_ctx->tb = tb;
+ handler_ctx->request = NULL;
}

static void create_new_prio_request(test_baton_t *tb,
@@ -1109,6 +1123,75 @@
test_helper_run_requests_expect_ok(tc, tb, num_requests, handler_ctx,
test_pool);
}
+
+static const char *create_large_request_message(apr_pool_t *pool)
+{
+ const char *request = "GET / HTTP/1.1" CRLF
+ "Host: localhost:12345" CRLF
+ "Transfer-Encoding: chunked" CRLF
+ CRLF;
+ struct iovec vecs[500];
+ const int num_vecs = 5;
+ int i, j;
+ apr_size_t len;
+
+ vecs[0].iov_base = (char *)request;
+ vecs[0].iov_len = strlen(request);
+
+ for (i = 1; i < num_vecs; i++)
+ {
+ int chunk_len = 10 * i * 3;
+
+ /* end with empty chunk */
+ if (i == num_vecs - 1)
+ chunk_len = 0;
+
+ char *chunk, *buf = apr_pcalloc(pool, chunk_len + 1);
+ for (j = 0; j < chunk_len; j += 10)
+ memcpy(buf + j, "0123456789", 10);
+
+ chunk = apr_pstrcat(pool,
+ apr_psprintf(pool, "%x", chunk_len),
+ CRLF, buf, CRLF, NULL);
+ vecs[i].iov_base = chunk;
+ vecs[i].iov_len = strlen(chunk);
+ }
+
+ return apr_pstrcatv(pool, vecs, num_vecs, &len);
+}
+
+/* Validate sending a large chunked response. */
+static void test_serf_connection_large_request(CuTest *tc)
+{
+ test_baton_t *tb;
+ handler_baton_t handler_ctx[1];
+ const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
+ test_server_message_t message_list[1];
+ test_server_action_t action_list[] = {
+ {SERVER_RESPOND, CHUNKED_EMPTY_RESPONSE},
+ };
+ const char *request;
+ apr_status_t status;
+
+ apr_pool_t *test_pool = tc->testBaton;
+
+ /* Set up a test context with a server */
+ status = test_server_setup(&tb,
+ message_list, num_requests,
+ action_list, num_requests, 0, NULL,
+ test_pool);
+ CuAssertIntEquals(tc, APR_SUCCESS, status);
+
+ /* create large chunked request message */
+ request = create_large_request_message(test_pool);
+ message_list[0].text = request;
+
+ create_new_request(tb, &handler_ctx[0], "GET", "/", 1);
+ handler_ctx[0].request = request;
+
+ test_helper_run_requests_expect_ok(tc, tb, num_requests, handler_ctx,
+ test_pool);
+}


/*****************************************************************************
* SSL handshake tests
@@ -1684,6 +1767,45 @@
test_helper_run_requests_expect_ok(tc, tb, num_requests,
handler_ctx, test_pool);
}
+
+/* Similar to test_serf_connection_large_request, validate sending a large
+ chunked request over SSL. */
+static void test_serf_ssl_large_request(CuTest *tc)
+{
+ test_baton_t *tb;
+ handler_baton_t handler_ctx[1];
+ const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
+ test_server_message_t message_list[1];
+ test_server_action_t action_list[] = {
+ {SERVER_RESPOND, CHUNKED_EMPTY_RESPONSE},
+ };
+ const char *request;
+ apr_status_t status;
+
+ /* Set up a test context with a server */
+ apr_pool_t *test_pool = tc->testBaton;
+
+ status = test_https_server_setup(&tb,
+ message_list, num_requests,
+ action_list, num_requests, 0,
+ https_set_root_ca_conn_setup,
+ "test/server/serfserverkey.pem",
+ server_certs,
+ NULL, /* no client cert */
+ NULL, /* No server cert callback */
+ test_pool);
+ CuAssertIntEquals(tc, APR_SUCCESS, status);
+
+ /* create large chunked request message */
+ request = create_large_request_message(test_pool);
+ message_list[0].text = request;
+
+ create_new_request(tb, &handler_ctx[0], "GET", "/", 1);
+ handler_ctx[0].request = request;
+
+ test_helper_run_requests_expect_ok(tc, tb, num_requests,
+ handler_ctx, test_pool);
+}

apr_status_t client_cert_cb(void *data,
const char **cert_path)
@@ -1888,6 +2010,7 @@
SUITE_ADD_TEST(suite, test_serf_progress_callback);
SUITE_ADD_TEST(suite, test_serf_request_timeout);
SUITE_ADD_TEST(suite, test_serf_connection_large_response);
+ SUITE_ADD_TEST(suite, test_serf_connection_large_request);
SUITE_ADD_TEST(suite, test_serf_ssl_handshake);
SUITE_ADD_TEST(suite, test_serf_ssl_trust_rootca);
SUITE_ADD_TEST(suite, test_serf_ssl_application_rejects_cert);
@@ -1896,6 +2019,7 @@
SUITE_ADD_TEST(suite, test_serf_ssl_no_servercert_callback_allok);
SUITE_ADD_TEST(suite, test_serf_ssl_no_servercert_callback_fail);
SUITE_ADD_TEST(suite, test_serf_ssl_large_response);
+ SUITE_ADD_TEST(suite, test_serf_ssl_large_request);
SUITE_ADD_TEST(suite, test_serf_ssl_client_certificate);
SUITE_ADD_TEST(suite, test_serf_ssl_expired_server_cert);
SUITE_ADD_TEST(suite, test_serf_ssl_future_server_cert);
Reply all
Reply to author
Forward
0 new messages