async def test_peer_subscriber_filters_messages(request, event_loop): async with ParagonPeerPairFactory() as (peer, remote): get_sum_subscriber = GetSumSubscriber() all_subscriber = AllSubscriber() peer.add_subscriber(get_sum_subscriber) peer.add_subscriber(all_subscriber) remote.sub_proto.send_broadcast_data(b'value-a') remote.sub_proto.send_broadcast_data(b'value-b') remote.sub_proto.send_get_sum(7, 8) remote.sub_proto.send_get_sum(1234, 4321) remote.sub_proto.send_broadcast_data(b'value-b') # Should only be able to get two messages from the `get_sum` subscriber for _ in range(2): await asyncio.wait_for(get_sum_subscriber.msg_queue.get(), timeout=1) # Should be able to get five messages fromt he all subscriber for _ in range(5): await asyncio.wait_for(all_subscriber.msg_queue.get(), timeout=1) # Should now timeout on both queues with pytest.raises(asyncio.TimeoutError): await asyncio.wait_for(get_sum_subscriber.msg_queue.get(), timeout=0.01) with pytest.raises(asyncio.TimeoutError): await asyncio.wait_for(all_subscriber.msg_queue.get(), timeout=0.01)
async def test_stops_if_behavior_crashes(monkeypatch): def init(self): self.add_child_behavior(CrashingLogic().as_behavior(always)) monkeypatch.setattr(ParagonAPI, '__init__', init) async with ParagonPeerPairFactory() as (alice, _): await asyncio.wait_for(alice.ready.wait(), timeout=0.5) assert alice.manager.is_cancelled
async def test_cancels_on_received_disconnect(): async with ParagonPeerPairFactory() as (alice, bob): # Here we send only a Disconnect msg because we want to ensure that will cause bob to # cancel itself even if alice accidentally leaves her connection open. If we used # alice.cancel() to send the Disconnect msg, alice would also close its connection, # causing bob to detect it, close its own and cause the peer to be cancelled. alice._p2p_api.disconnect(DisconnectReason.CLIENT_QUITTING) await asyncio.wait_for(bob.connection.manager.wait_finished(), timeout=1) assert bob.connection.is_closing assert bob.remote_disconnect_reason == DisconnectReason.CLIENT_QUITTING
async def test_propagates_behavior_crashes(monkeypatch): def init(self): self.add_child_behavior(CrashingLogic().as_behavior(always)) monkeypatch.setattr(ParagonAPI, '__init__', init) with pytest.raises(BehaviorCrash): async with ParagonPeerPairFactory() as (alice, _): await asyncio.wait_for(alice.manager.wait_finished(), timeout=0.5) assert alice.manager.is_cancelled
async def test_disconnect_on_cancellation(): got_disconnect = asyncio.Event() async def _handle_disconnect(conn, cmd): got_disconnect.set() async with ParagonPeerPairFactory() as (alice, bob): bob.connection.add_command_handler(Disconnect, _handle_disconnect) await alice.manager.stop() await asyncio.wait_for(got_disconnect.wait(), timeout=1) assert bob.remote_disconnect_reason == DisconnectReason.CLIENT_QUITTING
async def test_event_bus_requests_against_peer_pool(request, event_loop, event_bus): async with ParagonPeerPairFactory() as (alice, bob): peer_pool = ParagonMockPeerPoolWithConnectedPeers([alice, bob]) async with run_peer_pool_event_server(event_bus, peer_pool): await event_bus.wait_until_any_endpoint_subscribed_to( PeerCountRequest) res = await event_bus.request(PeerCountRequest()) assert res.peer_count == 2
async def test_connection_factory_with_ParagonPeer(): async with ParagonPeerPairFactory() as (alice, bob): got_ping = asyncio.Event() got_pong = asyncio.Event() async def handle_ping(conn, msg): got_ping.set() bob.p2p_api.send_pong() async def handle_pong(conn, msg): got_pong.set() alice.connection.add_command_handler(Pong, handle_pong) bob.connection.add_command_handler(Ping, handle_ping) alice.p2p_api.send_ping() await asyncio.wait_for(got_ping.wait(), timeout=1) await asyncio.wait_for(got_pong.wait(), timeout=1)
async def test_closes_connection_on_cancellation(): async with ParagonPeerPairFactory() as (alice, _): await alice.manager.stop() await alice.connection.manager.wait_finished() assert alice.connection.is_closing
async def alice_and_bob(): async with ParagonPeerPairFactory() as (alice, bob): yield (alice, bob)
async def test_closes_connection_on_cancellation(): async with ParagonPeerPairFactory() as (alice, _): await alice.cancel() await asyncio.wait_for(alice.connection.events.cleaned_up.wait(), timeout=1) assert alice.connection.is_closing