[serf] r1475 committed - In the test suite, separate the code of the test server from the clien...

0 views
Skip to first unread message

se...@googlecode.com

unread,
Jun 13, 2011, 5:51:36 AM6/13/11
to serf...@googlegroups.com
Revision: 1475
Author: lieven.govaerts
Date: Mon Jun 13 02:50:50 2011
Log: In the test suite, separate the code of the test server from the
client code.

* test/server/test_server.c
* test/server/test_server.h: New files.

* Makefile.in
* serfmake
* serf.mak: Also build server/test_server.c

* test/test_serf.h: Remove all declarations related to the test server.
Renamed test_server_create to test_server_setup.
Renamed test_server_destroy to test_server_teardown.

* test/test_util.c: Moved all code related to the test server to
test_server.c

* test/test_context.c
In calls to test_server_run, pass the new serv_ctx_t* instead of
a test_baton_t*.
Renamed test_server_create to test_server_setup.
Renamed test_server_destroy to test_server_teardown.

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

Added:
/trunk/test/server
/trunk/test/server/test_server.c
/trunk/test/server/test_server.h
Modified:
/trunk/Makefile.in
/trunk/serf.mak
/trunk/serfmake
/trunk/test/test_context.c
/trunk/test/test_serf.h
/trunk/test/test_util.c

=======================================
--- /dev/null
+++ /trunk/test/server/test_server.c Mon Jun 13 02:50:50 2011
@@ -0,0 +1,358 @@
+/* Copyright 2011 Justin Erenkrantz and Greg Stein
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include <apr_poll.h>
+#include <apr_version.h>
+#include <stdlib.h>
+
+#include "serf.h"
+
+#include "test_server.h"
+
+struct serv_ctx_t {
+ /* Pool for resource allocation. */
+ apr_pool_t *pool;
+
+ apr_int32_t options;
+
+ /* Array of actions which server will replay when client connected. */
+ test_server_action_t *action_list;
+ /* Size of action_list array. */
+ apr_size_t action_count;
+ /* Index of current action. */
+ apr_size_t cur_action;
+
+ /* Array of messages the server will receive from the client. */
+ test_server_message_t *message_list;
+ /* Size of message_list array. */
+ apr_size_t message_count;
+ /* Index of current message. */
+ apr_size_t cur_message;
+
+ /* Number of messages received that the server didn't respond to yet.
*/
+ apr_size_t outstanding_responses;
+
+ /* Position in message buffer (incoming messages being read). */
+ apr_size_t message_buf_pos;
+
+ /* Position in action buffer. (outgoing messages being sent). */
+ apr_size_t action_buf_pos;
+
+ /* Address for server binding. */
+ apr_sockaddr_t *serv_addr;
+ apr_socket_t *serv_sock;
+
+ /* Accepted client socket. NULL if there is no client socket. */
+ apr_socket_t *client_sock;
+
+};
+
+/* Replay support functions */
+static void next_message(serv_ctx_t *servctx)
+{
+ servctx->cur_message++;
+}
+
+static void next_action(serv_ctx_t *servctx)
+{
+ servctx->cur_action++;
+ servctx->action_buf_pos = 0;
+}
+
+/* Verify received requests and take the necessary actions
+ (return a response, kill the connection ...) */
+static apr_status_t replay(serv_ctx_t *servctx,
+ apr_int16_t rtnevents,
+ apr_pool_t *pool)
+{
+ apr_status_t status = APR_SUCCESS;
+ test_server_action_t *action;
+
+ if (rtnevents & APR_POLLIN) {
+ if (servctx->message_list == NULL) {
+ /* we're not expecting any requests to reach this server! */
+ printf("Received request where none was expected\n");
+
+ return APR_EGENERAL;
+ }
+
+ if (servctx->cur_action >= servctx->action_count) {
+ char buf[128];
+ apr_size_t len = sizeof(buf);
+
+ status = apr_socket_recv(servctx->client_sock, buf, &len);
+ if (! APR_STATUS_IS_EAGAIN(status)) {
+ /* we're out of actions! */
+ printf("Received more requests than expected.\n");
+
+ return APR_EGENERAL;
+ }
+ return status;
+ }
+
+ action = &servctx->action_list[servctx->cur_action];
+
+ if (action->kind == SERVER_IGNORE_AND_KILL_CONNECTION) {
+ char buf[128];
+ apr_size_t len = sizeof(buf);
+
+ status = apr_socket_recv(servctx->client_sock, buf, &len);
+
+ if (status == APR_EOF) {
+ apr_socket_close(servctx->client_sock);
+ servctx->client_sock = NULL;
+ next_action(servctx);
+ return APR_SUCCESS;
+ }
+
+ return status;
+ }
+ else if (action->kind == SERVER_RECV ||
+ (action->kind == SERVER_RESPOND &&
+ servctx->outstanding_responses == 0)) {
+ apr_size_t msg_len, len;
+ char buf[128];
+ test_server_message_t *message;
+
+ 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);
+
+ status = apr_socket_recv(servctx->client_sock, buf, &len);
+ if (status != APR_SUCCESS)
+ return status;
+
+ 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");
+
+ return APR_EGENERAL;
+ }
+
+ 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 (rtnevents & APR_POLLOUT) {
+ action = &servctx->action_list[servctx->cur_action];
+
+ if (action->kind == SERVER_RESPOND &&
servctx->outstanding_responses) {
+ apr_size_t msg_len;
+ apr_size_t len;
+
+ msg_len = strlen(action->text);
+ len = msg_len - servctx->action_buf_pos;
+
+ status = apr_socket_send(servctx->client_sock,
+ action->text +
servctx->action_buf_pos, &len);
+ if (status != APR_SUCCESS)
+ return status;
+
+ if (servctx->options & TEST_SERVER_DUMP)
+ fwrite(action->text + servctx->action_buf_pos, len, 1,
stdout);
+
+ servctx->action_buf_pos += len;
+
+ if (servctx->action_buf_pos >= msg_len) {
+ next_action(servctx);
+ servctx->outstanding_responses--;
+ }
+ }
+ }
+ else if (action->kind == SERVER_KILL_CONNECTION ||
+ action->kind == SERVER_IGNORE_AND_KILL_CONNECTION) {
+ apr_socket_close(servctx->client_sock);
+ servctx->client_sock = NULL;
+ next_action(servctx);
+ }
+ else if (rtnevents & APR_POLLIN) {
+ /* ignore */
+ }
+ else {
+ printf("Unknown rtnevents: %d\n", rtnevents);
+ abort();
+ }
+
+ return status;
+}
+
+apr_status_t test_server_run(serv_ctx_t *servctx,
+ apr_short_interval_time_t duration,
+ apr_pool_t *pool)
+{
+ apr_status_t status;
+ apr_pollset_t *pollset;
+ apr_int32_t num;
+ const apr_pollfd_t *desc;
+
+ /* create a new pollset */
+ status = apr_pollset_create(&pollset, 32, pool, 0);
+ if (status != APR_SUCCESS)
+ return status;
+
+ /* Don't accept new connection while processing client connection. At
+ least for present time.*/
+ if (servctx->client_sock) {
+ apr_pollfd_t pfd = { pool, APR_POLL_SOCKET, APR_POLLIN |
APR_POLLOUT, 0,
+ { NULL }, NULL };
+ pfd.desc.s = servctx->client_sock;
+ status = apr_pollset_add(pollset, &pfd);
+ if (status != APR_SUCCESS)
+ goto cleanup;
+ }
+ else {
+ apr_pollfd_t pfd = { pool, APR_POLL_SOCKET, APR_POLLIN, 0,
+ { NULL }, NULL };
+ pfd.desc.s = servctx->serv_sock;
+ status = apr_pollset_add(pollset, &pfd);
+ if (status != APR_SUCCESS)
+ goto cleanup;
+ }
+
+ status = apr_pollset_poll(pollset, APR_USEC_PER_SEC >> 1, &num, &desc);
+ if (status != APR_SUCCESS)
+ goto cleanup;
+
+ while (num--) {
+ if (desc->desc.s == servctx->serv_sock) {
+ status = apr_socket_accept(&servctx->client_sock,
servctx->serv_sock,
+ servctx->pool);
+ if (status != APR_SUCCESS)
+ goto cleanup;
+
+ apr_socket_opt_set(servctx->client_sock, APR_SO_NONBLOCK, 1);
+ apr_socket_timeout_set(servctx->client_sock, 0);
+
+ status = APR_SUCCESS;
+ goto cleanup;
+ }
+
+ if (desc->desc.s == servctx->client_sock) {
+ /* Replay data to socket. */
+ status = replay(servctx, desc->rtnevents, pool);
+
+ if (APR_STATUS_IS_EOF(status)) {
+ apr_socket_close(servctx->client_sock);
+ servctx->client_sock = NULL;
+ }
+ else if (APR_STATUS_IS_EAGAIN(status)) {
+ status = APR_SUCCESS;
+ }
+ else if (status != APR_SUCCESS) {
+ /* Real error. */
+ goto cleanup;
+ }
+ }
+
+ desc++;
+ }
+
+cleanup:
+ apr_pollset_destroy(pollset);
+
+ return status;
+}
+
+/* Start a TCP server on port SERV_PORT in thread THREAD. srv_replay is a
array
+ of action to replay when connection started. replay_count is count of
+ actions in srv_replay. */
+apr_status_t test_start_server(serv_ctx_t **servctx_p,
+ apr_sockaddr_t *address,
+ test_server_message_t *message_list,
+ apr_size_t message_count,
+ test_server_action_t *action_list,
+ apr_size_t action_count,
+ apr_int32_t options,
+ apr_pool_t *pool)
+{
+ apr_status_t status;
+ apr_socket_t *serv_sock;
+ serv_ctx_t *servctx;
+
+ servctx = apr_pcalloc(pool, sizeof(*servctx));
+ *servctx_p = servctx;
+
+ servctx->serv_addr = address;
+ servctx->options = options;
+ servctx->pool = pool;
+ servctx->message_list = message_list;
+ servctx->message_count = message_count;
+ servctx->action_list = action_list;
+ servctx->action_count = action_count;
+
+ /* create server socket */
+#if APR_VERSION_AT_LEAST(1, 0, 0)
+ status = apr_socket_create(&serv_sock, APR_INET, SOCK_STREAM, 0, pool);
+#else
+ status = apr_socket_create(&serv_sock, APR_INET, SOCK_STREAM, pool);
+#endif
+
+ if (status != APR_SUCCESS)
+ return status;
+
+ apr_socket_opt_set(serv_sock, APR_SO_NONBLOCK, 1);
+ apr_socket_timeout_set(serv_sock, 0);
+ apr_socket_opt_set(serv_sock, APR_SO_REUSEADDR, 1);
+
+ status = apr_socket_bind(serv_sock, servctx->serv_addr);
+ if (status != APR_SUCCESS)
+ return status;
+
+ /* Start replay from first action. */
+ servctx->cur_action = 0;
+ servctx->action_buf_pos = 0;
+ servctx->outstanding_responses = 0;
+
+ /* listen for clients */
+ apr_socket_listen(serv_sock, SOMAXCONN);
+ if (status != APR_SUCCESS)
+ return status;
+
+ servctx->serv_sock = serv_sock;
+ servctx->client_sock = NULL;
+ return APR_SUCCESS;
+}
+
+apr_status_t test_server_destroy(serv_ctx_t *servctx, apr_pool_t *pool)
+{
+ apr_socket_close(servctx->serv_sock);
+
+ if (servctx->client_sock) {
+ apr_socket_close(servctx->client_sock);
+ }
+
+ return APR_SUCCESS;
+}
=======================================
--- /dev/null
+++ /trunk/test/server/test_server.h Mon Jun 13 02:50:50 2011
@@ -0,0 +1,95 @@
+/* Copyright 2011 Justin Erenkrantz and Greg Stein
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TEST_SERVER_H
+#define TEST_SERVER_H
+
+typedef struct serv_ctx_t serv_ctx_t;
+
+#define TEST_SERVER_DUMP 1
+
+/* Default port for our test server. */
+#define SERV_PORT 12345
+#define SERV_PORT_STR "12345"
+
+#define CRLF "\r\n"
+
+#define CHUNCKED_REQUEST(len, body)\
+ "GET / HTTP/1.1" CRLF\
+ "Transfer-Encoding: chunked" CRLF\
+ CRLF\
+ #len CRLF\
+ body CRLF\
+ "0" CRLF\
+ CRLF
+
+#define CHUNKED_RESPONSE(len, body)\
+ "HTTP/1.1 200 OK" CRLF\
+ "Transfer-Encoding: chunked" CRLF\
+ CRLF\
+ #len CRLF\
+ body CRLF\
+ "0" CRLF\
+ CRLF
+
+#define CHUNKED_EMPTY_RESPONSE\
+ "HTTP/1.1 200 OK" CRLF\
+ "Transfer-Encoding: chunked" CRLF\
+ CRLF\
+ "0" CRLF\
+ CRLF
+
+typedef struct
+{
+ enum {
+ SERVER_RECV,
+ SERVER_SEND,
+ SERVER_RESPOND,
+ SERVER_IGNORE_AND_KILL_CONNECTION,
+ SERVER_KILL_CONNECTION
+ } kind;
+
+ const char *text;
+} test_server_action_t;
+
+typedef struct
+{
+ const char *text;
+} test_server_message_t;
+
+apr_status_t test_start_server(serv_ctx_t **servctx_p,
+ apr_sockaddr_t *address,
+ test_server_message_t *message_list,
+ apr_size_t message_count,
+ test_server_action_t *action_list,
+ apr_size_t action_count,
+ apr_int32_t options,
+ apr_pool_t *pool);
+
+apr_status_t test_server_run(serv_ctx_t *servctx,
+ apr_short_interval_time_t duration,
+ apr_pool_t *pool);
+
+apr_status_t test_server_destroy(serv_ctx_t *servctx, apr_pool_t *pool);
+
+#ifndef APR_VERSION_AT_LEAST /* Introduced in APR 1.3.0 */
+#define APR_VERSION_AT_LEAST(major,minor,patch) \
+(((major) < APR_MAJOR_VERSION) \
+ || ((major) == APR_MAJOR_VERSION && (minor) < APR_MINOR_VERSION) \
+ || ((major) == APR_MAJOR_VERSION && (minor) == APR_MINOR_VERSION && \
+ (patch) <= APR_PATCH_VERSION))
+#endif /* APR_VERSION_AT_LEAST */
+
+#endif /* TEST_SERVER_H */
=======================================
--- /trunk/Makefile.in Sun Jun 5 02:19:58 2011
+++ /trunk/Makefile.in Mon Jun 13 02:50:50 2011
@@ -27,7 +27,7 @@

TEST_SUITE_OBJECTS = test/CuTest.lo test/test_all.lo test/test_util.lo \
test/test_buckets.lo test/test_context.lo \
- test/test_ssl.lo
+ test/test_ssl.lo test/server/test_server.lo

PROGRAMS = $(TEST_OBJECTS:.lo=) test/test_all

=======================================
--- /trunk/serf.mak Sun Jun 5 02:19:58 2011
+++ /trunk/serf.mak Mon Jun 13 02:50:50 2011
@@ -145,6 +145,7 @@
"$(INTDIR)\test_context.obj" \
"$(INTDIR)\test_buckets.obj" \
"$(INTDIR)\test_ssl.obj" \
+ "$(INTDIR)\server\test_server.obj" \

TEST_LIBS = user32.lib advapi32.lib gdi32.lib ws2_32.lib

=======================================
--- /trunk/serfmake Sun Jun 5 02:19:58 2011
+++ /trunk/serfmake Mon Jun 13 02:50:50 2011
@@ -49,6 +49,7 @@
('test', 'test_context'),
('test', 'test_buckets'),
('test', 'test_ssl'),
+ ('test/server', 'test_server'),
]

TEST_HDR_FILES = [
=======================================
--- /trunk/test/test_context.c Sat Sep 18 09:32:34 2010
+++ /trunk/test/test_context.c Mon Jun 13 02:50:50 2011
@@ -23,6 +23,7 @@
#include "serf.h"

#include "test_serf.h"
+#include "server/test_server.h"

typedef struct {
serf_response_acceptor_t acceptor;
@@ -184,10 +185,10 @@
handled_requests = apr_array_make(test_pool, 2, sizeof(int));

/* Set up a test context with a server */
- status = test_server_create(&tb,
- message_list, 2,
- action_list, 2, 0, NULL, NULL, NULL,
- test_pool);
+ status = test_server_setup(&tb,
+ message_list, 2,
+ action_list, 2, 0, NULL, NULL, NULL,
+ test_pool);
CuAssertIntEquals(tc, APR_SUCCESS, status);

handler_ctx.method = "GET";
@@ -221,7 +222,7 @@
{
apr_pool_clear(iter_pool);

- status = test_server_run(tb, 0, iter_pool);
+ status = test_server_run(tb->servctx, 0, iter_pool);
if (APR_STATUS_IS_TIMEUP(status))
status = APR_SUCCESS;
CuAssertIntEquals(tc, APR_SUCCESS, status);
@@ -250,7 +251,7 @@
CuAssertIntEquals(tc, i + 1, req_nr);
}

- test_server_destroy(tb, test_pool);
+ test_server_teardown(tb, test_pool);
test_teardown(test_pool);
}

@@ -285,10 +286,10 @@
handled_requests = apr_array_make(test_pool, 3, sizeof(int));

/* Set up a test context with a server */
- status = test_server_create(&tb,
- message_list, 3,
- action_list, 3, 0, NULL, NULL, NULL,
- test_pool);
+ status = test_server_setup(&tb,
+ message_list, 3,
+ action_list, 3, 0, NULL, NULL, NULL,
+ test_pool);
CuAssertIntEquals(tc, APR_SUCCESS, status);

handler_ctx.method = "GET";
@@ -328,7 +329,7 @@
{
apr_pool_clear(iter_pool);

- status = test_server_run(tb, 0, iter_pool);
+ status = test_server_run(tb->servctx, 0, iter_pool);
if (APR_STATUS_IS_TIMEUP(status))
status = APR_SUCCESS;
CuAssertIntEquals(tc, APR_SUCCESS, status);
@@ -360,7 +361,7 @@
CuAssertIntEquals(tc, i + 1, req_nr);
}

- test_server_destroy(tb, test_pool);
+ test_server_teardown(tb, test_pool);
test_teardown(test_pool);
}

@@ -424,12 +425,12 @@
handled_requests = apr_array_make(test_pool, NUM_REQUESTS,
sizeof(int));

/* Set up a test context with a server. */
- status = test_server_create(&tb,
- message_list, 10,
- action_list, 12,
- 0,
- NULL, NULL, NULL,
- test_pool);
+ status = test_server_setup(&tb,
+ message_list, 10,
+ action_list, 12,
+ 0,
+ NULL, NULL, NULL,
+ test_pool);
CuAssertIntEquals(tc, APR_SUCCESS, status);

for (i = 0 ; i < NUM_REQUESTS ; i++) {
@@ -455,7 +456,7 @@
}

while (1) {
- status = test_server_run(tb, 0, test_pool);
+ status = test_server_run(tb->servctx, 0, test_pool);
if (APR_STATUS_IS_TIMEUP(status))
status = APR_SUCCESS;
CuAssertIntEquals(tc, APR_SUCCESS, status);
@@ -484,7 +485,7 @@
CuAssertIntEquals(tc, NUM_REQUESTS, handled_requests->nelts);

/* Cleanup */
- test_server_destroy(tb, test_pool);
+ test_server_teardown(tb, test_pool);
test_teardown(test_pool);
}
#undef NUM_REQUESTS
@@ -525,11 +526,11 @@
handled_requests = apr_array_make(test_pool, numrequests, sizeof(int));

/* Set up a test context with a server, no messages expected. */
- status = test_server_create(&tb_server,
- NULL, 0,
- NULL, 0, 0,
- "http://localhost:" SERV_PORT_STR, NULL,
- NULL, test_pool);
+ status = test_server_setup(&tb_server,
+ NULL, 0,
+ NULL, 0, 0,
+ "http://localhost:" SERV_PORT_STR, NULL,
+ NULL, test_pool);
CuAssertIntEquals(tc, APR_SUCCESS, status);

/* Set up another test context for the proxy server */
@@ -538,11 +539,11 @@
test_pool);
CuAssertIntEquals(tc, APR_SUCCESS, status);

- status = test_server_create(&tb_proxy,
- message_list, 1,
- action_list_proxy, 1, 0,
- NULL, proxy_address, NULL,
- test_pool);
+ status = test_server_setup(&tb_proxy,
+ message_list, 1,
+ action_list_proxy, 1, 0,
+ NULL, proxy_address, NULL,
+ test_pool);

CuAssertIntEquals(tc, APR_SUCCESS, status);

@@ -573,12 +574,12 @@
{
apr_pool_clear(iter_pool);

- status = test_server_run(tb_server, 0, iter_pool);
+ status = test_server_run(tb_server->servctx, 0, iter_pool);
if (APR_STATUS_IS_TIMEUP(status))
status = APR_SUCCESS;
CuAssertIntEquals(tc, APR_SUCCESS, status);

- status = test_server_run(tb_proxy, 0, iter_pool);
+ status = test_server_run(tb_proxy->servctx, 0, iter_pool);
if (APR_STATUS_IS_TIMEUP(status))
status = APR_SUCCESS;
CuAssertIntEquals(tc, APR_SUCCESS, status);
@@ -610,7 +611,7 @@
CuAssertIntEquals(tc, i + 1, req_nr);
}

- test_server_destroy(tb_server, test_pool);
+ test_server_teardown(tb_server, test_pool);
test_teardown(test_pool);
}

@@ -696,10 +697,10 @@
handled_requests = apr_array_make(test_pool, RCVD_REQUESTS,
sizeof(int));

/* Set up a test context with a server. */
- status = test_server_create(&tb,
- message_list, 7,
- action_list, 7, 0, NULL, NULL, NULL,
- test_pool);
+ status = test_server_setup(&tb,
+ message_list, 7,
+ action_list, 7, 0, NULL, NULL, NULL,
+ test_pool);
CuAssertIntEquals(tc, APR_SUCCESS, status);

for (i = 0 ; i < SEND_REQUESTS ; i++) {
@@ -726,7 +727,7 @@
}

while (1) {
- status = test_server_run(tb, 0, test_pool);
+ status = test_server_run(tb->servctx, 0, test_pool);
if (APR_STATUS_IS_TIMEUP(status))
status = APR_SUCCESS;
CuAssertIntEquals(tc, APR_SUCCESS, status);
@@ -755,7 +756,7 @@
CuAssertIntEquals(tc, RCVD_REQUESTS, handled_requests->nelts);

/* Cleanup */
- test_server_destroy(tb, test_pool);
+ test_server_teardown(tb, test_pool);
test_teardown(test_pool);
}
#undef SEND_REQUESTS
@@ -852,10 +853,10 @@
handled_requests = apr_array_make(test_pool, RCVD_REQUESTS,
sizeof(int));

/* Set up a test context with a server. */
- status = test_server_create(&tb,
- message_list, 7,
- action_list, 7, 0, NULL, NULL, NULL,
- test_pool);
+ status = test_server_setup(&tb,
+ message_list, 7,
+ action_list, 7, 0, NULL, NULL, NULL,
+ test_pool);
CuAssertIntEquals(tc, APR_SUCCESS, status);

for (i = 0 ; i < SEND_REQUESTS ; i++) {
@@ -882,7 +883,7 @@
}

while (1) {
- status = test_server_run(tb, 0, test_pool);
+ status = test_server_run(tb->servctx, 0, test_pool);
if (APR_STATUS_IS_TIMEUP(status))
status = APR_SUCCESS;
CuAssertIntEquals(tc, APR_SUCCESS, status);
@@ -911,7 +912,7 @@
CuAssertIntEquals(tc, RCVD_REQUESTS, handled_requests->nelts);

/* Cleanup */
- test_server_destroy(tb, test_pool);
+ test_server_teardown(tb, test_pool);
test_teardown(test_pool);
}
#undef SEND_REQUESTS
@@ -976,10 +977,10 @@
handled_requests = apr_array_make(test_pool, NUM_REQUESTS,
sizeof(int));

/* Set up a test context with a server. */
- status = test_server_create(&tb,
- message_list, 5,
- action_list, 5, 0, NULL, NULL,
- progress_conn_setup, test_pool);
+ status = test_server_setup(&tb,
+ message_list, 5,
+ action_list, 5, 0, NULL, NULL,
+ progress_conn_setup, test_pool);
CuAssertIntEquals(tc, APR_SUCCESS, status);

/* Set up the progress callback. */
@@ -1010,7 +1011,7 @@
}

while (1) {
- status = test_server_run(tb, 0, test_pool);
+ status = test_server_run(tb->servctx, 0, test_pool);
if (APR_STATUS_IS_TIMEUP(status))
status = APR_SUCCESS;
CuAssertIntEquals(tc, APR_SUCCESS, status);
@@ -1043,7 +1044,7 @@
CuAssertTrue(tc, pb->read > 0);

/* Cleanup */
- test_server_destroy(tb, test_pool);
+ test_server_teardown(tb, test_pool);
test_teardown(test_pool);
}
#undef NUM_REQUESTS
=======================================
--- /trunk/test/test_serf.h Sat Sep 18 09:32:34 2010
+++ /trunk/test/test_serf.h Mon Jun 13 02:50:50 2011
@@ -23,6 +23,7 @@
#include <apr_uri.h>

#include "serf.h"
+#include "server/test_server.h"

/** These macros are provided by APR itself from version 1.3.
* Definitions are provided here for when using older versions of APR.
@@ -47,51 +48,6 @@

/* Test setup declarations */

-#define CRLF "\r\n"
-
-#define CHUNCKED_REQUEST(len, body)\
- "GET / HTTP/1.1" CRLF\
- "Transfer-Encoding: chunked" CRLF\
- CRLF\
- #len CRLF\
- body CRLF\
- "0" CRLF\
- CRLF
-
-#define CHUNKED_RESPONSE(len, body)\
- "HTTP/1.1 200 OK" CRLF\
- "Transfer-Encoding: chunked" CRLF\
- CRLF\
- #len CRLF\
- body CRLF\
- "0" CRLF\
- CRLF
-
-#define CHUNKED_EMPTY_RESPONSE\
- "HTTP/1.1 200 OK" CRLF\
- "Transfer-Encoding: chunked" CRLF\
- CRLF\
- "0" CRLF\
- CRLF
-
-typedef struct
-{
- enum {
- SERVER_RECV,
- SERVER_SEND,
- SERVER_RESPOND,
- SERVER_IGNORE_AND_KILL_CONNECTION,
- SERVER_KILL_CONNECTION
- } kind;
-
- const char *text;
-} test_server_action_t;
-
-typedef struct
-{
- const char *text;
-} test_server_message_t;
-
typedef struct {
/* Pool for resource allocation. */
apr_pool_t *pool;
@@ -99,75 +55,28 @@
serf_context_t *context;
serf_connection_t *connection;
serf_bucket_alloc_t *bkt_alloc;
- apr_int32_t options;
-
- /* Array of actions which server will replay when client connected. */
- test_server_action_t *action_list;
- /* Size of action_list array. */
- apr_size_t action_count;
- /* Index of current action. */
- apr_size_t cur_action;
-
- /* Array of messages the server will receive from the client. */
- test_server_message_t *message_list;
- /* Size of message_list array. */
- apr_size_t message_count;
- /* Index of current message. */
- apr_size_t cur_message;
-
- /* Number of messages received that the server didn't respond to yet.
*/
- apr_size_t outstanding_responses;
-
- /* Position in message buffer (incoming messages being read). */
- apr_size_t message_buf_pos;
-
- /* Position in action buffer. (outgoing messages being sent). */
- apr_size_t action_buf_pos;
-
- /* Address for server binding. */
- apr_sockaddr_t *serv_addr;
- apr_socket_t *serv_sock;
-
- /* Accepted client socket. NULL if there is no client socket. */
- apr_socket_t *client_sock;
+
+ serv_ctx_t *servctx;

/* An extra baton which can be freely used by tests. */
void *user_baton;

} test_baton_t;

-#define TEST_SERVER_DUMP 1
-
-/* Default port for our test server. */
-#define SERV_PORT 12345
-#define SERV_PORT_STR "12345"
-
-apr_status_t test_server_create(test_baton_t **tb,
- test_server_message_t *message_list,
- apr_size_t message_count,
- test_server_action_t *action_list,
- apr_size_t action_count,
- apr_int32_t options,
- const char *host_url,
- apr_sockaddr_t *address,
- serf_connection_setup_t conn_setup,
- apr_pool_t *pool);
-
-apr_status_t test_server_run(test_baton_t *tb,
- apr_short_interval_time_t duration,
- apr_pool_t *pool);
-
-apr_status_t test_server_destroy(test_baton_t *tb, apr_pool_t *pool);
+apr_status_t test_server_setup(test_baton_t **tb_p,
+ test_server_message_t *message_list,
+ apr_size_t message_count,
+ test_server_action_t *action_list,
+ apr_size_t action_count,
+ apr_int32_t options,
+ const char *host_url,
+ apr_sockaddr_t *servaddr,
+ serf_connection_setup_t conn_setup,
+ apr_pool_t *pool);
+
+apr_status_t test_server_teardown(test_baton_t *tb, apr_pool_t *pool);

apr_pool_t *test_setup();
void test_teardown(apr_pool_t *test_pool);

-#ifndef APR_VERSION_AT_LEAST /* Introduced in APR 1.3.0 */
-#define APR_VERSION_AT_LEAST(major,minor,patch) \
-(((major) < APR_MAJOR_VERSION) \
- || ((major) == APR_MAJOR_VERSION && (minor) < APR_MINOR_VERSION) \
- || ((major) == APR_MAJOR_VERSION && (minor) == APR_MINOR_VERSION && \
- (patch) <= APR_PATCH_VERSION))
-#endif /* APR_VERSION_AT_LEAST */
-
#endif /* TEST_SERF_H */
=======================================
--- /trunk/test/test_util.c Sat Sep 18 09:32:34 2010
+++ /trunk/test/test_util.c Mon Jun 13 02:50:50 2011
@@ -15,17 +15,25 @@

#include "apr.h"
#include "apr_pools.h"
-#include <apr_poll.h>
-#include <apr_version.h>
#include <stdlib.h>

#include "serf.h"

#include "test_serf.h"
+#include "server/test_server.h"
+


/*****************************************************************************/
-/* Server setup functions
+/* Server setup function(s)
*/
+
+static apr_status_t get_server_address(apr_sockaddr_t **address,
+ apr_pool_t *pool)
+{
+ return apr_sockaddr_info_get(address,
+ "localhost", APR_INET, SERV_PORT, 0,
+ pool);
+}

/* Default implementation of a serf_connection_closed_t callback. */
static void default_closed_connection(serf_connection_t *conn,
@@ -51,290 +59,16 @@
return APR_SUCCESS;
}

-static apr_status_t get_server_address(apr_sockaddr_t **address,
- apr_pool_t *pool)
-{
- return apr_sockaddr_info_get(address,
- "localhost", APR_INET, SERV_PORT, 0,
- pool);
-}
-
-static void next_message(test_baton_t *tb)
-{
- tb->cur_message++;
-}
-
-static void next_action(test_baton_t *tb)
-{
- tb->cur_action++;
- tb->action_buf_pos = 0;
-}
-
-static apr_status_t replay(test_baton_t *tb,
- apr_int16_t rtnevents,
- apr_pool_t *pool)
-{
- apr_status_t status = APR_SUCCESS;
- test_server_action_t *action;
-
- if (rtnevents & APR_POLLIN) {
- if (tb->message_list == NULL) {
- /* we're not expecting any requests to reach this server! */
- printf("Received request where none was expected\n");
-
- return APR_EGENERAL;
- }
-
- if (tb->cur_action >= tb->action_count) {
- char buf[128];
- apr_size_t len = sizeof(buf);
-
- status = apr_socket_recv(tb->client_sock, buf, &len);
- if (! APR_STATUS_IS_EAGAIN(status)) {
- /* we're out of actions! */
- printf("Received more requests than expected.\n");
-
- return APR_EGENERAL;
- }
- return status;
- }
-
- action = &tb->action_list[tb->cur_action];
-
- if (action->kind == SERVER_IGNORE_AND_KILL_CONNECTION) {
- char buf[128];
- apr_size_t len = sizeof(buf);
-
- status = apr_socket_recv(tb->client_sock, buf, &len);
-
- if (status == APR_EOF) {
- apr_socket_close(tb->client_sock);
- tb->client_sock = NULL;
- next_action(tb);
- return APR_SUCCESS;
- }
-
- return status;
- }
- else if (action->kind == SERVER_RECV ||
- (action->kind == SERVER_RESPOND &&
- tb->outstanding_responses == 0)) {
- apr_size_t msg_len, len;
- char buf[128];
- test_server_message_t *message;
-
- message = &tb->message_list[tb->cur_message];
- msg_len = strlen(message->text);
-
- len = msg_len - tb->message_buf_pos;
- if (len > sizeof(buf))
- len = sizeof(buf);
-
- status = apr_socket_recv(tb->client_sock, buf, &len);
- if (status != APR_SUCCESS)
- return status;
-
- if (tb->options & TEST_SERVER_DUMP)
- fwrite(buf, len, 1, stdout);
-
- if (strncmp(buf, message->text + tb->message_buf_pos, len) !=
0) {
- /* ## TODO: Better diagnostics. */
- printf("Expected: (\n");
- fwrite(message->text + tb->message_buf_pos, len, 1,
stdout);
- printf(")\n");
- printf("Actual: (\n");
- fwrite(buf, len, 1, stdout);
- printf(")\n");
-
- return APR_EGENERAL;
- }
-
- tb->message_buf_pos += len;
-
- if (tb->message_buf_pos >= msg_len) {
- next_message(tb);
- tb->message_buf_pos -= msg_len;
- if (action->kind == SERVER_RESPOND)
- tb->outstanding_responses++;
- if (action->kind == SERVER_RECV)
- next_action(tb);
- }
- }
- }
- if (rtnevents & APR_POLLOUT) {
- action = &tb->action_list[tb->cur_action];
-
- if (action->kind == SERVER_RESPOND && tb->outstanding_responses) {
- apr_size_t msg_len;
- apr_size_t len;
-
- msg_len = strlen(action->text);
- len = msg_len - tb->action_buf_pos;
-
- status = apr_socket_send(tb->client_sock,
- action->text + tb->action_buf_pos,
&len);
- if (status != APR_SUCCESS)
- return status;
-
- if (tb->options & TEST_SERVER_DUMP)
- fwrite(action->text + tb->action_buf_pos, len, 1, stdout);
-
- tb->action_buf_pos += len;
-
- if (tb->action_buf_pos >= msg_len) {
- next_action(tb);
- tb->outstanding_responses--;
- }
- }
- }
- else if (action->kind == SERVER_KILL_CONNECTION ||
- action->kind == SERVER_IGNORE_AND_KILL_CONNECTION) {
- apr_socket_close(tb->client_sock);
- tb->client_sock = NULL;
- next_action(tb);
- }
- else if (rtnevents & APR_POLLIN) {
- /* ignore */
- }
- else {
- printf("Unknown rtnevents: %d\n", rtnevents);
- abort();
- }
-
- return status;
-}
-
-apr_status_t test_server_run(test_baton_t *tb,
- apr_short_interval_time_t duration,
- apr_pool_t *pool)
-{
- apr_status_t status;
- apr_pollset_t *pollset;
- apr_int32_t num;
- const apr_pollfd_t *desc;
-
- /* create a new pollset */
- status = apr_pollset_create(&pollset, 32, pool, 0);
- if (status != APR_SUCCESS)
- return status;
-
- /* Don't accept new connection while processing client connection. At
- least for present time.*/
- if (tb->client_sock) {
- apr_pollfd_t pfd = { pool, APR_POLL_SOCKET, APR_POLLIN |
APR_POLLOUT, 0,
- { NULL }, NULL };
- pfd.desc.s = tb->client_sock;
- status = apr_pollset_add(pollset, &pfd);
- if (status != APR_SUCCESS)
- goto cleanup;
- }
- else {
- apr_pollfd_t pfd = { pool, APR_POLL_SOCKET, APR_POLLIN, 0,
- { NULL }, NULL };
- pfd.desc.s = tb->serv_sock;
- status = apr_pollset_add(pollset, &pfd);
- if (status != APR_SUCCESS)
- goto cleanup;
- }
-
- status = apr_pollset_poll(pollset, APR_USEC_PER_SEC >> 1, &num, &desc);
- if (status != APR_SUCCESS)
- goto cleanup;
-
- while (num--) {
- if (desc->desc.s == tb->serv_sock) {
- status = apr_socket_accept(&tb->client_sock, tb->serv_sock,
- tb->pool);
- if (status != APR_SUCCESS)
- goto cleanup;
-
- apr_socket_opt_set(tb->client_sock, APR_SO_NONBLOCK, 1);
- apr_socket_timeout_set(tb->client_sock, 0);
-
- status = APR_SUCCESS;
- goto cleanup;
- }
-
- if (desc->desc.s == tb->client_sock) {
- /* Replay data to socket. */
- status = replay(tb, desc->rtnevents, pool);
-
- if (APR_STATUS_IS_EOF(status)) {
- apr_socket_close(tb->client_sock);
- tb->client_sock = NULL;
- }
- else if (APR_STATUS_IS_EAGAIN(status)) {
- status = APR_SUCCESS;
- }
- else if (status != APR_SUCCESS) {
- /* Real error. */
- goto cleanup;
- }
- }
-
- desc++;
- }
-
-cleanup:
- apr_pollset_destroy(pollset);
-
- return status;
-}
-
-/* Start a TCP server on port SERV_PORT in thread THREAD. srv_replay is a
array
- of action to replay when connection started. replay_count is count of
- actions in srv_replay. */
-static apr_status_t prepare_server(test_baton_t *tb,
- apr_pool_t *pool)
-{
- apr_status_t status;
- apr_socket_t *serv_sock;
-
- /* create server socket */
-#if APR_VERSION_AT_LEAST(1, 0, 0)
- status = apr_socket_create(&serv_sock, APR_INET, SOCK_STREAM, 0, pool);
-#else
- status = apr_socket_create(&serv_sock, APR_INET, SOCK_STREAM, pool);
-#endif
-
- if (status != APR_SUCCESS)
- return status;
-
- apr_socket_opt_set(serv_sock, APR_SO_NONBLOCK, 1);
- apr_socket_timeout_set(serv_sock, 0);
- apr_socket_opt_set(serv_sock, APR_SO_REUSEADDR, 1);
-
- status = apr_socket_bind(serv_sock, tb->serv_addr);
- if (status != APR_SUCCESS)
- return status;
-
- /* Start replay from first action. */
- tb->cur_action = 0;
- tb->action_buf_pos = 0;
- tb->outstanding_responses = 0;
-
- /* listen for clients */
- apr_socket_listen(serv_sock, SOMAXCONN);
- if (status != APR_SUCCESS)
- return status;
-
- tb->serv_sock = serv_sock;
- tb->client_sock = NULL;
- return APR_SUCCESS;
-}
-
-/*****************************************************************************/
-
-apr_status_t test_server_create(test_baton_t **tb_p,
- test_server_message_t *message_list,
- apr_size_t message_count,
- test_server_action_t *action_list,
- apr_size_t action_count,
- apr_int32_t options,
- const char *host_url,
- apr_sockaddr_t *address,
- serf_connection_setup_t conn_setup,
- apr_pool_t *pool)
+apr_status_t test_server_setup(test_baton_t **tb_p,
+ test_server_message_t *message_list,
+ apr_size_t message_count,
+ test_server_action_t *action_list,
+ apr_size_t action_count,
+ apr_int32_t options,
+ const char *host_url,
+ apr_sockaddr_t *servaddr,
+ serf_connection_setup_t conn_setup,
+ apr_pool_t *pool)
{
apr_status_t status;
test_baton_t *tb;
@@ -342,17 +76,13 @@
tb = apr_pcalloc(pool, sizeof(*tb));
*tb_p = tb;

- if (address) {
- tb->serv_addr = address;
- }
- else {
- status = get_server_address(&tb->serv_addr, pool);
+ if (!servaddr) {
+ status = get_server_address(&servaddr, pool);
if (status != APR_SUCCESS)
return status;
}

tb->pool = pool;
- tb->options = options;
tb->context = serf_context_create(pool);
tb->bkt_alloc = serf_bucket_allocator_create(pool, NULL, NULL);
if (host_url) {
@@ -363,7 +93,7 @@

status = serf_connection_create2(&tb->connection, tb->context,
url,
- conn_setup ? conn_setup :
+ conn_setup ? conn_setup :
default_conn_setup,
tb,
default_closed_connection,
@@ -373,36 +103,30 @@
return status;
} else {
tb->connection = serf_connection_create(tb->context,
- tb->serv_addr,
- conn_setup ? conn_setup :
+ servaddr,
+ conn_setup ? conn_setup :
default_conn_setup,
tb,
default_closed_connection,
tb,
pool);
}
- tb->message_list = message_list;
- tb->message_count = message_count;
- tb->action_list = action_list;
- tb->action_count = action_count;

/* Prepare a server. */
- status = prepare_server(tb, pool);
+ status = test_start_server(&tb->servctx, servaddr,
+ message_list, message_count,
+ action_list, action_count, options, pool);
if (status != APR_SUCCESS)
return status;

return APR_SUCCESS;
}

-apr_status_t test_server_destroy(test_baton_t *tb, apr_pool_t *pool)
+apr_status_t test_server_teardown(test_baton_t *tb, apr_pool_t *pool)
{
serf_connection_close(tb->connection);

- apr_socket_close(tb->serv_sock);
-
- if (tb->client_sock) {
- apr_socket_close(tb->client_sock);
- }
+ test_server_destroy(tb->servctx, pool);

return APR_SUCCESS;
}

Reply all
Reply to author
Forward
0 new messages