From bf62debe93d7e022ec13653eceac64706ed98a4a Mon Sep 17 00:00:00 2001 From: kdeme Date: Tue, 2 Apr 2019 17:48:20 +0200 Subject: [PATCH] Add test with failing disconnect handlers --- tests/p2p/test_failing_handler.nim | 93 ++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 tests/p2p/test_failing_handler.nim diff --git a/tests/p2p/test_failing_handler.nim b/tests/p2p/test_failing_handler.nim new file mode 100644 index 0000000..a5d7cf1 --- /dev/null +++ b/tests/p2p/test_failing_handler.nim @@ -0,0 +1,93 @@ +# +# Ethereum P2P +# (c) Copyright 2018 +# Status Research & Development GmbH +# +# Licensed under either of +# Apache License, version 2.0, (LICENSE-APACHEv2) +# MIT license (LICENSE-MIT) + +import + unittest, tables, chronos, eth/[keys, p2p], eth/p2p/[discovery, enode] + +var nextPort = 30303 + +proc localAddress(port: int): Address = + let port = Port(port) + result = Address(udpPort: port, tcpPort: port, ip: parseIpAddress("127.0.0.1")) + +proc startDiscoveryNode(privKey: PrivateKey, address: Address, + bootnodes: seq[ENode]): Future[DiscoveryProtocol] {.async.} = + result = newDiscoveryProtocol(privKey, address, bootnodes) + result.open() + await result.bootstrap() + +proc setupBootNode(): Future[ENode] {.async.} = + let + bootNodeKey = newPrivateKey() + bootNodeAddr = localAddress(30301) + bootNode = await startDiscoveryNode(bootNodeKey, bootNodeAddr, @[]) + result = initENode(bootNodeKey.getPublicKey, bootNodeAddr) + +template asyncTest(name, body: untyped) = + test name: + proc scenario {.async.} = body + waitFor scenario() + +type + network = ref object + count*: int + +p2pProtocol abc(version = 1, + shortName = "abc", + networkState = network): + + onPeerConnected do (peer: Peer): + peer.networkState.count += 1 + + onPeerDisconnected do (peer: Peer, reason: DisconnectionReason) {.gcsafe.}: + peer.networkState.count -= 1 + if true: + raise newException(UnsupportedProtocol, "Fake abc exception") + +p2pProtocol xyz(version = 1, + shortName = "xyz", + networkState = network): + + onPeerConnected do (peer: Peer): + peer.networkState.count += 1 + + onPeerDisconnected do (peer: Peer, reason: DisconnectionReason) {.gcsafe.}: + peer.networkState.count -= 1 + if true: + raise newException(UnsupportedProtocol, "Fake xyz exception") + +proc prepTestNode(): EthereumNode = + let keys1 = newKeyPair() + result = newEthereumNode(keys1, localAddress(nextPort), 1, nil, + addAllCapabilities = false) + nextPort.inc + result.addCapability abc + result.addCapability xyz + +suite "Failing handlers": + asyncTest "Failing disconnect handler": + let bootENode = waitFor setupBootNode() + var node1 = prepTestNode() + var node2 = prepTestNode() + # node2 listening and node1 not, to avoid many incoming vs outgoing + var node1Connected = node1.connectToNetwork(@[bootENode], false, true) + var node2Connected = node2.connectToNetwork(@[bootENode], true, true) + waitFor node1Connected + waitFor node2Connected + check: + node1.peerPool.connectedNodes.len() == 1 + node2.peerPool.connectedNodes.len() == 1 + + for peer in node1.peers(): + waitFor peer.disconnect(SubprotocolReason, true) + check: + # we want to check that even though the exceptions in the disconnect + # handlers, each handler still ran + node1.protocolState(abc).count == 0 + node1.protocolState(xyz).count == 0