Add tests for TCP shutdown procedure and connection state handling.

This commit is contained in:
Sönke Ludwig 2020-03-17 14:23:17 +01:00
parent 3b44da604c
commit 5c4e8be20a
2 changed files with 110 additions and 3 deletions

View file

@ -64,7 +64,7 @@ void read(alias callback)(ref StreamSocket socket, ubyte[] buffer, IOMode mode)
} }
eventDriver.sockets.read(socket.m_fd, buffer, mode, &cb); eventDriver.sockets.read(socket.m_fd, buffer, mode, &cb);
} }
void cancelRead(ref StreamSocket socket) { eventDriver.sockets.cancelRead(socket.m_fd); } void cancelRead(ref StreamSocket socket) @safe nothrow { eventDriver.sockets.cancelRead(socket.m_fd); }
void waitForData(alias callback)(ref StreamSocket socket) void waitForData(alias callback)(ref StreamSocket socket)
{ {
void cb(StreamSocketFD, IOStatus status, size_t nbytes) @safe nothrow { void cb(StreamSocketFD, IOStatus status, size_t nbytes) @safe nothrow {
@ -79,8 +79,11 @@ void write(alias callback)(ref StreamSocket socket, const(ubyte)[] buffer, IOMod
} }
eventDriver.sockets.write(socket.m_fd, buffer, mode, &cb); eventDriver.sockets.write(socket.m_fd, buffer, mode, &cb);
} }
void cancelWrite(ref StreamSocket socket) { eventDriver.sockets.cancelWrite(socket.m_fd); } void cancelWrite(ref StreamSocket socket) @safe nothrow { eventDriver.sockets.cancelWrite(socket.m_fd); }
void shutdown(ref StreamSocket socket, bool shut_read = true, bool shut_write = true) { eventDriver.sockets.shutdown(socket.m_fd, shut_read, shut_write); } void shutdown(ref StreamSocket socket, bool shut_read = true, bool shut_write = true)
@safe nothrow {
eventDriver.sockets.shutdown(socket.m_fd, shut_read, shut_write);
}
struct StreamListenSocket { struct StreamListenSocket {

View file

@ -15,6 +15,15 @@ bool s_done;
void main() void main()
{ {
testBasicExchange();
testShutdown();
}
void testBasicExchange()
{
print("Basic test:");
print("");
// watchdog timer in case of starvation/deadlocks // watchdog timer in case of starvation/deadlocks
auto tm = eventDriver.timers.create(); auto tm = eventDriver.timers.create();
eventDriver.timers.set(tm, 10000.msecs, 0.msecs); eventDriver.timers.set(tm, 10000.msecs, 0.msecs);
@ -92,3 +101,98 @@ void main()
assert(s_done); assert(s_done);
s_done = false; s_done = false;
} }
void testShutdown()
{
static ubyte[10] srbuf, crbuf;
print("");
print("Shutdown test:");
print("");
// watchdog timer in case of starvation/deadlocks
auto tm = eventDriver.timers.create();
eventDriver.timers.set(tm, 10000.msecs, 0.msecs);
eventDriver.timers.wait(tm, (tm) { assert(false, "Test hung."); });
auto baddr = new InternetAddress(0x7F000001, 40001);
auto server = listenStream(baddr);
StreamSocket client;
StreamSocket incoming;
server.waitForConnections!((sock, addr) {
incoming = sock;
assert(incoming.state == ConnectionState.connected);
print("Server read");
ubyte[10] buf;
incoming.read!((rstatus, bytes) {
print("Server read done %s", bytes);
assert(rstatus == IOStatus.disconnected);
assert(bytes == 4);
assert(srbuf[0 .. 4] == [1, 2, 3, 4]);
assert(incoming.state == ConnectionState.passiveClose);
print("Server write 4 bytes");
incoming.write!((wstatus, bytes) {
print("Server write done");
assert(wstatus == IOStatus.ok);
assert(bytes == 4);
print("Shutdown server write");
incoming.shutdown(false, true);
assert(incoming.state == ConnectionState.closed);
print("Attempt server write after shutdown");
incoming.write!((wstatus, bytes) {
print("Attempted server write done");
assert(wstatus == IOStatus.disconnected);
assert(bytes == 0);
})([1], IOMode.all);
})([5, 6, 7, 8], IOMode.all);
})(srbuf, IOMode.all);
});
print("Connect...");
connectStream!((sock, status) {
client = sock;
assert(client.state == ConnectionState.connected);
print("Client write 4 bytes");
client.write!((wstatus, bytes) {
print("Client write done");
assert(wstatus == IOStatus.ok);
assert(bytes == 4);
print("Shutdown client write");
client.shutdown(false, true);
assert(client.state == ConnectionState.activeClose);
print("Attempt client write after shutdown");
client.write!((wstatus, bytes) {
print("Attempted client write done");
assert(wstatus == IOStatus.disconnected);
assert(bytes == 0);
print("Client read");
client.read!((rstatus, bytes) {
print("Client read done");
assert(rstatus == IOStatus.disconnected);
assert(bytes == 4);
assert(crbuf[0 .. 4] == [5, 6, 7, 8]);
assert(client.state == ConnectionState.closed);
destroy(client);
destroy(incoming);
destroy(server);
s_done = true;
eventDriver.timers.stop(tm);
})(crbuf, IOMode.all);
})([1], IOMode.all);
})([1, 2, 3, 4], IOMode.all);
})(baddr);
ExitReason er;
do er = eventDriver.core.processEvents(Duration.max);
while (er == ExitReason.idle);
assert(er == ExitReason.outOfWaiters);
assert(s_done);
s_done = false;
}