More extensive test-callback-stack. Fails on windows now.

This commit is contained in:
Bert Belder 2011-05-04 17:10:33 +02:00
parent b87f07dee4
commit 9d9c242a24
3 changed files with 130 additions and 15 deletions

View File

@ -28,45 +28,159 @@
#include "task.h"
const char MESSAGE[] = "Failure is for the weak. Everyone dies alone.";
oio_handle client;
oio_req connect_req, write_req, timeout_req, shutdown_req;
int nested = 0;
int close_cb_called = 0;
int connect_cb_called = 0;
int write_cb_called = 0;
int timeout_cb_called = 0;
int bytes_received = 0;
int shutdown_cb_called = 0;
void close_cb(oio_handle *handle, int status) {
void close_cb(oio_handle* handle, int status) {
ASSERT(status == 0);
ASSERT(nested == 0 && "oio_close_cb must be called from a fresh stack");
ASSERT(nested == 0 && "close_cb must be called from a fresh stack");
close_cb_called++;
}
void shutdown_cb(oio_req* req, int status) {
ASSERT(status == 0);
ASSERT(nested == 0 && "shutdown_cb must be called from a fresh stack");
shutdown_cb_called++;
}
void read_cb(oio_handle* handle, int nread, oio_buf buf) {
ASSERT(nested == 0 && "read_cb must be called from a fresh stack");
if (nread == -1) {
ASSERT(oio_last_error().code == OIO_EOF);
nested++;
if (oio_close(handle)) {
FATAL("oio_close failed");
}
nested--;
return;
}
bytes_received += nread;
free(buf.base);
/* We call shutdown here because when bytes_received == sizeof MESSAGE */
/* there will be no more data sent nor received, so here it would be */
/* possible for a backend to to call shutdown_cb immediately and *not* */
/* from a fresh stack. */
if (bytes_received == sizeof MESSAGE) {
nested++;
oio_req_init(&shutdown_req, handle, shutdown_cb);
if (oio_shutdown(&shutdown_req)) {
FATAL("oio_shutdown failed");
}
nested--;
}
}
void timeout_cb(oio_req* req, int64_t skew, int status) {
ASSERT(status == 0);
ASSERT(nested == 0 && "timeout_cb must be called from a fresh stack");
nested++;
if (oio_read_start(&client, read_cb)) {
FATAL("oio_read_start failed");
}
nested--;
timeout_cb_called++;
}
void write_cb(oio_req* req, int status) {
ASSERT(status == 0);
ASSERT(nested == 0 && "write_cb must be called from a fresh stack");
/* After the data has been sent, we're going to wait for a while, then */
/* start reading. This makes us certain that the message has been echoed */
/* back to our receive buffer when we start reading. This maximizes the */
/* tempation for the backend to use dirty stack for calling read_cb. */
nested++;
oio_req_init(&timeout_req, NULL, timeout_cb);
if (oio_timeout(&timeout_req, 500)) {
FATAL("oio_timeout failed");
}
nested--;
write_cb_called++;
}
void connect_cb(oio_req* req, int status) {
oio_buf buf;
ASSERT(status == 0);
ASSERT(nested == 0 && "connect_cb must be called from a fresh stack");
nested++;
buf.base = (char*) &MESSAGE;
buf.len = sizeof MESSAGE;
oio_req_init(&write_req, req->handle, write_cb);
if (oio_write(&write_req, &buf, 1)) {
FATAL("oio_write failed");
}
nested--;
connect_cb_called++;
}
static oio_buf alloc_cb(oio_handle* handle, size_t size) {
oio_buf buf = {0, 0};
FATAL("alloc should not be called");
oio_buf buf;
buf.len = size;
buf.base = (char*) malloc(size);
ASSERT(buf.base);
return buf;
}
TEST_IMPL(close_cb_stack) {
oio_handle handle;
TEST_IMPL(callback_stack) {
struct sockaddr_in addr = oio_ip4_addr("127.0.0.1", TEST_PORT);
oio_init(alloc_cb);
if (oio_tcp_init(&handle, &close_cb, NULL)) {
if (oio_tcp_init(&client, &close_cb, NULL)) {
FATAL("oio_tcp_init failed");
}
nested++;
if (oio_close(&handle)) {
FATAL("oio_close failed");
oio_req_init(&connect_req, &client, connect_cb);
if (oio_connect(&connect_req, (struct sockaddr*) &addr)) {
FATAL("oio_connect failed");
}
nested--;
oio_run();
ASSERT(nested == 0);
ASSERT(close_cb_called == 1 && "oio_close_cb must be called exactly once");
ASSERT(connect_cb_called == 1 && "connect_cb must be called exactly once");
ASSERT(write_cb_called == 1 && "write_cb must be called exactly once");
ASSERT(timeout_cb_called == 1 && "timeout_cb must be called exactly once");
ASSERT(bytes_received == sizeof MESSAGE);
ASSERT(shutdown_cb_called == 1 && "shutdown_cb must be called exactly once");
ASSERT(close_cb_called == 1 && "close_cb must be called exactly once");
return 0;
}

View File

@ -28,7 +28,7 @@ TEST_DECLARE (bind_error_addrnotavail_2)
TEST_DECLARE (bind_error_fault)
TEST_DECLARE (bind_error_inval)
TEST_DECLARE (connection_fail)
TEST_DECLARE (close_cb_stack)
TEST_DECLARE (callback_stack)
TEST_DECLARE (timeout)
TEST_DECLARE (fail_always)
TEST_DECLARE (pass_always)
@ -55,7 +55,8 @@ TASK_LIST_START
TEST_ENTRY (connection_fail)
TEST_ENTRY (close_cb_stack)
TEST_ENTRY (callback_stack)
TEST_HELPER (callback_stack, echo_server)
TEST_ENTRY (timeout)

View File

@ -129,7 +129,7 @@ void pinger_on_connect(oio_req *req, int status) {
ASSERT(status == 0);
pinger_write_ping(pinger);
oio_read_start(req->handle, pinger_read_cb);
}