From 5cb4479534bbbe3b7002828161185c9b189a1e27 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Tue, 5 Nov 2019 17:06:54 -0800 Subject: [PATCH 1/6] Modify the ``KademliaServer`` so that lack of port lets the OS choose a free one --- libp2p/kademlia/network.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libp2p/kademlia/network.py b/libp2p/kademlia/network.py index f0a4991e..f93ca09e 100644 --- a/libp2p/kademlia/network.py +++ b/libp2p/kademlia/network.py @@ -55,7 +55,7 @@ class KademliaServer: def _create_protocol(self): return self.protocol_class(self.node, self.storage, self.ksize) - async def listen(self, port, interface="0.0.0.0"): + async def listen(self, port=0, interface="0.0.0.0"): """ Start listening on the given port. @@ -65,8 +65,15 @@ class KademliaServer: listen = loop.create_datagram_endpoint( self._create_protocol, local_addr=(interface, port) ) - log.info("Node %i listening on %s:%i", self.node.xor_id, interface, port) self.transport, self.protocol = await listen + socket = self.transport.get_extra_info("socket") + self.address = socket.getsockname() + log.info( + "Node %i listening on %s:%i", + self.node.xor_id, + self.address[0], + self.address[1], + ) # finally, schedule refreshing table self.refresh_table() From 94984be4dfe40ecafe67c0a7502c2edf8b90ebfd Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Tue, 5 Nov 2019 17:08:18 -0800 Subject: [PATCH 2/6] Avoid hard-coding ports where it is not relevant for Kademlia tests --- tests/host/test_routed_host.py | 4 ++-- tests/kademlia/test_basic.py | 6 +++--- tests/kademlia/test_providers.py | 6 +++--- tests/utils.py | 7 +++++-- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/tests/host/test_routed_host.py b/tests/host/test_routed_host.py index 7791d62d..25fa4f9a 100644 --- a/tests/host/test_routed_host.py +++ b/tests/host/test_routed_host.py @@ -14,7 +14,7 @@ from tests.utils import ( @pytest.mark.asyncio async def test_host_routing_success(): - routers = await set_up_routers([5678, 5679]) + routers = await set_up_routers() transports = [["/ip4/127.0.0.1/tcp/0"], ["/ip4/127.0.0.1/tcp/0"]] transport_disc_opt_list = zip(transports, routers) (host_a, host_b) = await set_up_nodes_by_transport_and_disc_opt( @@ -43,7 +43,7 @@ async def test_host_routing_success(): @pytest.mark.asyncio async def test_host_routing_fail(): - routers = await set_up_routers([5678, 5679]) + routers = await set_up_routers() transports = [["/ip4/127.0.0.1/tcp/0"], ["/ip4/127.0.0.1/tcp/0"]] transport_disc_opt_list = zip(transports, routers) (host_a, host_b) = await set_up_nodes_by_transport_and_disc_opt( diff --git a/tests/kademlia/test_basic.py b/tests/kademlia/test_basic.py index 9c308083..655d4717 100644 --- a/tests/kademlia/test_basic.py +++ b/tests/kademlia/test_basic.py @@ -6,15 +6,15 @@ from libp2p.kademlia.network import KademliaServer @pytest.mark.asyncio async def test_example(): node_a = KademliaServer() - await node_a.listen(5678) + await node_a.listen() node_b = KademliaServer() - await node_b.listen(5679) + await node_b.listen() # Bootstrap the node by connecting to other known nodes, in this case # replace 123.123.123.123 with the IP of another node and optionally # give as many ip/port combos as you can for other nodes. - await node_b.bootstrap([("127.0.0.1", 5678)]) + await node_b.bootstrap([node_a.address]) # set a value for the key "my-key" on the network value = "my-value" diff --git a/tests/kademlia/test_providers.py b/tests/kademlia/test_providers.py index f58e9455..45993d92 100644 --- a/tests/kademlia/test_providers.py +++ b/tests/kademlia/test_providers.py @@ -6,11 +6,11 @@ from libp2p.kademlia.network import KademliaServer @pytest.mark.asyncio async def test_example(): node_a = KademliaServer() - await node_a.listen(5801) + await node_a.listen() node_b = KademliaServer() - await node_b.listen(5802) - await node_b.bootstrap([("127.0.0.1", 5801)]) + await node_b.listen() + await node_b.bootstrap([node_a.address]) key = "hello" value = "world" diff --git a/tests/utils.py b/tests/utils.py index 67e9668f..eb5e9d88 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -45,7 +45,10 @@ async def set_up_nodes_by_transport_and_disc_opt(transport_disc_opt_list): return tuple(nodes_list) -async def set_up_routers(router_confs): +async def set_up_routers(router_confs=[0, 0]): + """ + The default ``router_confs`` selects two free ports local to this machine. + """ bootstrap_node = KademliaServer() await bootstrap_node.listen(router_confs[0]) @@ -54,7 +57,7 @@ async def set_up_routers(router_confs): node = KademliaServer() await node.listen(port) - await node.bootstrap_node(("127.0.0.1", router_confs[0])) + await node.bootstrap_node(bootstrap_node.address) routers.append(KadmeliaPeerRouter(node)) return routers From 17ba328e1aa3a03b0eac00313526bf4d6924edd7 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Tue, 5 Nov 2019 17:08:35 -0800 Subject: [PATCH 3/6] Add `pytest-xdist` plugin to parallelize tests --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index f9c2668d..626e9d80 100644 --- a/setup.py +++ b/setup.py @@ -8,6 +8,7 @@ extras_require = { "factory-boy>=2.12.0,<3.0.0", "pytest>=4.6.3,<5.0.0", "pytest-asyncio>=0.10.0,<1.0.0", + "pytest-xdist>=1.30.0", ], "lint": [ "mypy>=0.701,<1.0", From c8a5f6f8d7432256ecbde4ba95a6ad2b81bdfee8 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Tue, 5 Nov 2019 17:24:52 -0800 Subject: [PATCH 4/6] Run `docformatter` over changes --- tests/utils.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/utils.py b/tests/utils.py index eb5e9d88..4dbe2010 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -46,9 +46,8 @@ async def set_up_nodes_by_transport_and_disc_opt(transport_disc_opt_list): async def set_up_routers(router_confs=[0, 0]): - """ - The default ``router_confs`` selects two free ports local to this machine. - """ + """The default ``router_confs`` selects two free ports local to this + machine.""" bootstrap_node = KademliaServer() await bootstrap_node.listen(router_confs[0]) From c30d9ce397bdef3610cc64ad9d7933eef8088f00 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Tue, 5 Nov 2019 17:50:43 -0800 Subject: [PATCH 5/6] Fix linter error from merge in #315. --- libp2p/host/ping.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/libp2p/host/ping.py b/libp2p/host/ping.py index f47e83d8..46a28e06 100644 --- a/libp2p/host/ping.py +++ b/libp2p/host/ping.py @@ -13,9 +13,8 @@ logger = logging.getLogger("libp2p.host.ping") async def _handle_ping(stream: INetStream, peer_id: PeerID) -> bool: - """ - Return a boolean indicating if we expect more pings from the peer at ``peer_id``. - """ + """Return a boolean indicating if we expect more pings from the peer at + ``peer_id``.""" try: payload = await asyncio.wait_for(stream.read(PING_LENGTH), RESP_TIMEOUT) except asyncio.TimeoutError as error: @@ -40,10 +39,8 @@ async def _handle_ping(stream: INetStream, peer_id: PeerID) -> bool: async def handle_ping(stream: INetStream) -> None: - """ - ``handle_ping`` responds to incoming ping requests until one side - errors or closes the ``stream``. - """ + """``handle_ping`` responds to incoming ping requests until one side errors + or closes the ``stream``.""" peer_id = stream.muxed_conn.peer_id while True: From fbdd52cfdca35170939fbe680dfd42793da79b7e Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Wed, 6 Nov 2019 11:25:12 -0800 Subject: [PATCH 6/6] Go with immutable datatype in lieu of mutable datatype --- tests/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utils.py b/tests/utils.py index 4dbe2010..965338a6 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -45,7 +45,7 @@ async def set_up_nodes_by_transport_and_disc_opt(transport_disc_opt_list): return tuple(nodes_list) -async def set_up_routers(router_confs=[0, 0]): +async def set_up_routers(router_confs=(0, 0)): """The default ``router_confs`` selects two free ports local to this machine.""" bootstrap_node = KademliaServer()