nim-libp2p/tests/testtransport.nim
Jacek Sieka ccd019b328
use stream directly in chronosstream (#163)
* use stream directly in chronosstream

for now, chronos.AsyncStream is not used to provide any features on top
of chronos.Stream, so in order to simplify the code, chronosstream can
be used directly.

In particular, the exception handling is broken in the current
chronosstream - opening and closing the stream is simplified this way as
well.

A future implementation that actually takes advantage of the AsyncStream
features would wrap AsyncStream instead as a separate lpstream
implementation, leaving this one as-is.

* work around chronos exception type issue
2020-05-08 22:10:06 +02:00

190 lines
6.1 KiB
Nim

{.used.}
import unittest
import chronos
import ../libp2p/[connection,
transports/transport,
transports/tcptransport,
multiaddress,
wire]
import ./helpers
suite "TCP transport":
teardown:
for tracker in testTrackers():
check tracker.isLeaked() == false
test "test listener: handle write":
proc testListener(): Future[bool] {.async, gcsafe.} =
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
let handlerWait = newFuture[void]()
proc connHandler(conn: Connection) {.async, gcsafe.} =
await conn.write(cstring("Hello!"), 6)
await conn.close()
handlerWait.complete()
let transport: TcpTransport = newTransport(TcpTransport)
asyncCheck transport.listen(ma, connHandler)
let streamTransport = await connect(transport.ma)
let msg = await streamTransport.read(6)
await handlerWait.wait(5000.millis) # when no issues will not wait that long!
await streamTransport.closeWait()
await transport.close()
result = cast[string](msg) == "Hello!"
check:
waitFor(testListener()) == true
test "test listener: handle read":
proc testListener(): Future[bool] {.async.} =
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
let handlerWait = newFuture[void]()
proc connHandler(conn: Connection) {.async, gcsafe.} =
let msg = await conn.read(6)
check cast[string](msg) == "Hello!"
await conn.close()
handlerWait.complete()
let transport: TcpTransport = newTransport(TcpTransport)
asyncCheck await transport.listen(ma, connHandler)
let streamTransport: StreamTransport = await connect(transport.ma)
let sent = await streamTransport.write("Hello!", 6)
await handlerWait.wait(5000.millis) # when no issues will not wait that long!
await streamTransport.closeWait()
await transport.close()
result = sent == 6
check:
waitFor(testListener()) == true
test "test dialer: handle write":
proc testDialer(address: TransportAddress): Future[bool] {.async.} =
let handlerWait = newFuture[void]()
proc serveClient(server: StreamServer,
transp: StreamTransport) {.async, gcsafe.} =
var wstream = newAsyncStreamWriter(transp)
await wstream.write("Hello!")
await wstream.finish()
await wstream.closeWait()
await transp.closeWait()
server.stop()
server.close()
handlerWait.complete()
var server = createStreamServer(address, serveClient, {ReuseAddr})
server.start()
let ma: MultiAddress = MultiAddress.init(server.sock.getLocalAddress())
let transport: TcpTransport = newTransport(TcpTransport)
let conn = await transport.dial(ma)
let msg = await conn.read(6)
result = cast[string](msg) == "Hello!"
await handlerWait.wait(5000.millis) # when no issues will not wait that long!
await conn.close()
await transport.close()
server.stop()
server.close()
await server.join()
check:
waitFor(testDialer(initTAddress("0.0.0.0:0"))) == true
test "test dialer: handle write":
proc testDialer(address: TransportAddress): Future[bool] {.async, gcsafe.} =
let handlerWait = newFuture[void]()
proc serveClient(server: StreamServer,
transp: StreamTransport) {.async, gcsafe.} =
var rstream = newAsyncStreamReader(transp)
let msg = await rstream.read(6)
check cast[string](msg) == "Hello!"
await rstream.closeWait()
await transp.closeWait()
server.stop()
server.close()
handlerWait.complete()
var server = createStreamServer(address, serveClient, {ReuseAddr})
server.start()
let ma: MultiAddress = MultiAddress.init(server.sock.getLocalAddress())
let transport: TcpTransport = newTransport(TcpTransport)
let conn = await transport.dial(ma)
await conn.write(cstring("Hello!"), 6)
result = true
await handlerWait.wait(5000.millis) # when no issues will not wait that long!
await conn.close()
await transport.close()
server.stop()
server.close()
await server.join()
check:
waitFor(testDialer(initTAddress("0.0.0.0:0"))) == true
test "e2e: handle write":
proc testListenerDialer(): Future[bool] {.async.} =
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
let handlerWait = newFuture[void]()
proc connHandler(conn: Connection) {.async, gcsafe.} =
await conn.write(cstring("Hello!"), 6)
await conn.close()
handlerWait.complete()
let transport1: TcpTransport = newTransport(TcpTransport)
asyncCheck transport1.listen(ma, connHandler)
let transport2: TcpTransport = newTransport(TcpTransport)
let conn = await transport2.dial(transport1.ma)
let msg = await conn.read(6)
await handlerWait.wait(5000.millis) # when no issues will not wait that long!
await conn.close()
await transport2.close()
await transport1.close()
result = cast[string](msg) == "Hello!"
check:
waitFor(testListenerDialer()) == true
test "e2e: handle read":
proc testListenerDialer(): Future[bool] {.async.} =
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
let handlerWait = newFuture[void]()
proc connHandler(conn: Connection) {.async, gcsafe.} =
let msg = await conn.read(6)
check cast[string](msg) == "Hello!"
await conn.close()
handlerWait.complete()
let transport1: TcpTransport = newTransport(TcpTransport)
asyncCheck transport1.listen(ma, connHandler)
let transport2: TcpTransport = newTransport(TcpTransport)
let conn = await transport2.dial(transport1.ma)
await conn.write(cstring("Hello!"), 6)
await handlerWait.wait(5000.millis) # when no issues will not wait that long!
await conn.close()
await transport2.close()
await transport1.close()
result = true
check:
waitFor(testListenerDialer()) == true