nim-libp2p/tests/testidentify.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

102 lines
3.5 KiB
Nim

import unittest, options
import chronos, strutils
import ../libp2p/[protocols/identify,
multiaddress,
peerinfo,
peer,
connection,
multistream,
transports/transport,
transports/tcptransport,
crypto/crypto]
import ./helpers
when defined(nimHasUsed): {.used.}
suite "Identify":
teardown:
for tracker in testTrackers():
check tracker.isLeaked() == false
test "handle identify message":
proc testHandle(): Future[bool] {.async.} =
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
let remoteSecKey = PrivateKey.random(RSA)
let remotePeerInfo = PeerInfo.init(remoteSecKey,
[ma],
["/test/proto1/1.0.0",
"/test/proto2/1.0.0"])
var serverFut: Future[void]
let identifyProto1 = newIdentify(remotePeerInfo)
let msListen = newMultistream()
msListen.addHandler(IdentifyCodec, identifyProto1)
proc connHandler(conn: Connection): Future[void] {.async, gcsafe.} =
await msListen.handle(conn)
var transport1 = newTransport(TcpTransport)
serverFut = await transport1.listen(ma, connHandler)
let msDial = newMultistream()
let transport2: TcpTransport = newTransport(TcpTransport)
let conn = await transport2.dial(transport1.ma)
var peerInfo = PeerInfo.init(PrivateKey.random(RSA), [ma])
let identifyProto2 = newIdentify(peerInfo)
discard await msDial.select(conn, IdentifyCodec)
let id = await identifyProto2.identify(conn, remotePeerInfo)
check id.pubKey.get() == remoteSecKey.getKey()
check id.addrs[0] == ma
check id.protoVersion.get() == ProtoVersion
# check id.agentVersion.get() == AgentVersion
check id.protos == @["/test/proto1/1.0.0", "/test/proto2/1.0.0"]
await conn.close()
await transport1.close()
await serverFut
result = true
await transport2.close()
check:
waitFor(testHandle()) == true
test "handle failed identify":
proc testHandleError() {.async.} =
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
var remotePeerInfo = PeerInfo.init(PrivateKey.random(RSA), [ma])
let identifyProto1 = newIdentify(remotePeerInfo)
let msListen = newMultistream()
let done = newFuture[void]()
msListen.addHandler(IdentifyCodec, identifyProto1)
proc connHandler(conn: Connection): Future[void] {.async, gcsafe.} =
await msListen.handle(conn)
await conn.close()
done.complete()
let transport1: TcpTransport = newTransport(TcpTransport)
asyncCheck transport1.listen(ma, connHandler)
let msDial = newMultistream()
let transport2: TcpTransport = newTransport(TcpTransport)
let conn = await transport2.dial(transport1.ma)
var localPeerInfo = PeerInfo.init(PrivateKey.random(RSA), [ma])
let identifyProto2 = newIdentify(localPeerInfo)
try:
discard await msDial.select(conn, IdentifyCodec)
discard await identifyProto2.identify(conn, PeerInfo.init(PrivateKey.random(RSA)))
finally:
await done.wait(5000.millis) # when no issues will not wait that long!
await conn.close()
await transport2.close()
await transport1.close()
expect IdentityNoMatchError:
waitFor(testHandleError())