async def test_last_msg_time(monkeypatch): alice_multiplexer, bob_multiplexer = MultiplexerPairFactory() async with alice_multiplexer.multiplex(): async with bob_multiplexer.multiplex(): assert alice_multiplexer.last_msg_time == 0 assert bob_multiplexer.last_msg_time == 0 alice_stream = alice_multiplexer.stream_protocol_messages( P2PProtocolV5) bob_stream = bob_multiplexer.stream_protocol_messages( P2PProtocolV5) alice_p2p_protocol = alice_multiplexer.get_protocol_by_type( P2PProtocolV5) bob_p2p_protocol = bob_multiplexer.get_protocol_by_type( P2PProtocolV5) now = time.monotonic() monkeypatch.setattr(time, 'monotonic', lambda: now) alice_p2p_protocol.send(Ping(None)) cmd = await asyncio.wait_for(bob_stream.asend(None), timeout=DEFAULT_TIMEOUT) assert isinstance(cmd, Ping) assert bob_multiplexer.last_msg_time == now bob_p2p_protocol.send(Pong(None)) cmd = await asyncio.wait_for(alice_stream.asend(None), timeout=DEFAULT_TIMEOUT) assert isinstance(cmd, Pong) assert alice_multiplexer.last_msg_time == now
async def test_stream_protocol_messages(request, event_loop, monkeypatch): alice_multiplexer, bob_multiplexer = MultiplexerPairFactory() await run_multiplexers([alice_multiplexer, bob_multiplexer], request, event_loop) alice_p2p_protocol = alice_multiplexer.get_protocol_by_type(P2PProtocolV5) alice_p2p_protocol.send(Ping(None)) alice_p2p_protocol.send(Pong(None)) monkeypatch.setattr(bob_multiplexer, '_stream_idle_timeout', 0.1) stream = bob_multiplexer.stream_protocol_messages(P2PProtocolV5) cmd = await asyncio.wait_for(stream.asend(None), timeout=DEFAULT_TIMEOUT) assert isinstance(cmd, Ping) cmd = await asyncio.wait_for(stream.asend(None), timeout=DEFAULT_TIMEOUT) assert isinstance(cmd, Pong) # Stopping streaming on bob's multiplexer should cause stream_protocol_messages() to # terminate. stop_streaming_task = asyncio.create_task(bob_multiplexer.stop_streaming()) try: cmd = await asyncio.wait_for(stream.asend(None), timeout=DEFAULT_TIMEOUT) except StopAsyncIteration: pass assert stop_streaming_task.done()
def test_multiplexer_pair_factory(): alice_remote, bob_remote = NodeFactory.create_batch(2) alice_multiplexer, bob_multiplexer = MultiplexerPairFactory( alice_remote=alice_remote, bob_remote=bob_remote, ) assert alice_multiplexer.remote == bob_remote assert bob_multiplexer.remote == alice_remote assert alice_multiplexer.get_base_protocol().version == DEVP2P_V5 assert bob_multiplexer.get_base_protocol().version == DEVP2P_V5
async def test_multiplexer_p2p_and_two_more_protocols(): alice_multiplexer, bob_multiplexer = MultiplexerPairFactory( protocol_types=(SecondProtocol, ThirdProtocol), ) async with alice_multiplexer.multiplex(): async with bob_multiplexer.multiplex(): alice_p2p_stream = alice_multiplexer.stream_protocol_messages(P2PProtocolV5) bob_p2p_stream = bob_multiplexer.stream_protocol_messages(P2PProtocolV5) alice_second_stream = alice_multiplexer.stream_protocol_messages(SecondProtocol) bob_second_stream = bob_multiplexer.stream_protocol_messages(SecondProtocol) alice_third_stream = alice_multiplexer.stream_protocol_messages(ThirdProtocol) bob_third_stream = bob_multiplexer.stream_protocol_messages(ThirdProtocol) alice_p2p_protocol = alice_multiplexer.get_protocol_by_type(P2PProtocolV5) alice_second_protocol = alice_multiplexer.get_protocol_by_type(SecondProtocol) alice_third_protocol = alice_multiplexer.get_protocol_by_type(ThirdProtocol) bob_p2p_protocol = bob_multiplexer.get_protocol_by_type(P2PProtocolV5) bob_second_protocol = bob_multiplexer.get_protocol_by_type(SecondProtocol) bob_third_protocol = bob_multiplexer.get_protocol_by_type(ThirdProtocol) alice_second_protocol.send_cmd(CommandA) alice_third_protocol.send_cmd(CommandC) alice_p2p_protocol.send_ping() alice_second_protocol.send_cmd(CommandB) alice_third_protocol.send_cmd(CommandD) cmd, _ = await asyncio.wait_for(bob_p2p_stream.asend(None), timeout=0.1) assert isinstance(cmd, Ping) bob_second_protocol.send_cmd(CommandA) bob_third_protocol.send_cmd(CommandC) bob_p2p_protocol.send_pong() bob_second_protocol.send_cmd(CommandB) bob_third_protocol.send_cmd(CommandD) cmd, _ = await asyncio.wait_for(alice_p2p_stream.asend(None), timeout=0.1) assert isinstance(cmd, Pong) cmd_1, _ = await asyncio.wait_for(bob_third_stream.asend(None), timeout=0.1) # noqa: E501 cmd_2, _ = await asyncio.wait_for(bob_third_stream.asend(None), timeout=0.1) # noqa: E501 cmd_3, _ = await asyncio.wait_for(bob_second_stream.asend(None), timeout=0.1) # noqa: E501 cmd_4, _ = await asyncio.wait_for(bob_second_stream.asend(None), timeout=0.1) # noqa: E501 cmd_5, _ = await asyncio.wait_for(alice_third_stream.asend(None), timeout=0.1) # noqa: E501 cmd_6, _ = await asyncio.wait_for(alice_third_stream.asend(None), timeout=0.1) # noqa: E501 cmd_7, _ = await asyncio.wait_for(alice_second_stream.asend(None), timeout=0.1) # noqa: E501 cmd_8, _ = await asyncio.wait_for(alice_second_stream.asend(None), timeout=0.1) # noqa: E501 assert isinstance(cmd_1, CommandC) assert isinstance(cmd_2, CommandD) assert isinstance(cmd_3, CommandA) assert isinstance(cmd_4, CommandB) assert isinstance(cmd_5, CommandC) assert isinstance(cmd_6, CommandD) assert isinstance(cmd_7, CommandA) assert isinstance(cmd_8, CommandB)
async def test_multiplexer_pair_factory_with_different_p2p_versions( alice_p2p_version, bob_p2p_version, expected_base_protocol_class, ): alice_multiplexer, bob_multiplexer = MultiplexerPairFactory( alice_p2p_version=alice_p2p_version, bob_p2p_version=bob_p2p_version, ) alice_base_protocol = alice_multiplexer.get_base_protocol() bob_base_protocol = bob_multiplexer.get_base_protocol() assert type(alice_base_protocol) is expected_base_protocol_class assert type(bob_base_protocol) is expected_base_protocol_class assert alice_base_protocol.version == expected_base_protocol_class.version assert bob_base_protocol.version == expected_base_protocol_class.version
async def test_multiplexer_only_p2p_protocol(): alice_multiplexer, bob_multiplexer = MultiplexerPairFactory() async with alice_multiplexer.multiplex(): async with bob_multiplexer.multiplex(): alice_stream = alice_multiplexer.stream_protocol_messages(P2PProtocolV5) bob_stream = bob_multiplexer.stream_protocol_messages(P2PProtocolV5) alice_p2p_protocol = alice_multiplexer.get_protocol_by_type(P2PProtocolV5) bob_p2p_protocol = bob_multiplexer.get_protocol_by_type(P2PProtocolV5) alice_p2p_protocol.send_ping() cmd, _ = await asyncio.wait_for(bob_stream.asend(None), timeout=0.1) assert isinstance(cmd, Ping) bob_p2p_protocol.send_pong() cmd, _ = await asyncio.wait_for(alice_stream.asend(None), timeout=0.1)
async def test_streaming_error(monkeypatch): alice, _ = MultiplexerPairFactory() msg = "Multiplexing error" exc = Exception(msg) async def multiplexing(): alice._started_streaming.set() raise exc monkeypatch.setattr(alice, '_do_multiplexing', multiplexing) await alice.stream_in_background() with pytest.raises(Exception, match=msg): await alice.wait_streaming_finished() assert alice.get_streaming_error() == exc with pytest.raises(Exception, match=msg): alice.raise_if_streaming_error()
async def test_multiplexer_only_p2p_protocol(request, event_loop): alice_multiplexer, bob_multiplexer = MultiplexerPairFactory() await run_multiplexers([alice_multiplexer, bob_multiplexer], request, event_loop) alice_stream = alice_multiplexer.stream_protocol_messages(P2PProtocolV5) bob_stream = bob_multiplexer.stream_protocol_messages(P2PProtocolV5) alice_p2p_protocol = alice_multiplexer.get_protocol_by_type(P2PProtocolV5) bob_p2p_protocol = bob_multiplexer.get_protocol_by_type(P2PProtocolV5) alice_p2p_protocol.send(Ping(None)) cmd = await asyncio.wait_for(bob_stream.asend(None), timeout=DEFAULT_TIMEOUT) assert isinstance(cmd, Ping) bob_p2p_protocol.send(Pong(None)) cmd = await asyncio.wait_for(alice_stream.asend(None), timeout=DEFAULT_TIMEOUT)
async def test_multiplexer_p2p_and_paragon_protocol(): alice_multiplexer, bob_multiplexer = MultiplexerPairFactory( protocol_types=(SecondProtocol, ), ) async with alice_multiplexer.multiplex(): async with bob_multiplexer.multiplex(): alice_p2p_stream = alice_multiplexer.stream_protocol_messages( P2PProtocolV5) bob_p2p_stream = bob_multiplexer.stream_protocol_messages( P2PProtocolV5) alice_second_stream = alice_multiplexer.stream_protocol_messages( SecondProtocol) bob_second_stream = bob_multiplexer.stream_protocol_messages( SecondProtocol) alice_p2p_protocol = alice_multiplexer.get_protocol_by_type( P2PProtocolV5) alice_second_protocol = alice_multiplexer.get_protocol_by_type( SecondProtocol) bob_p2p_protocol = bob_multiplexer.get_protocol_by_type( P2PProtocolV5) bob_second_protocol = bob_multiplexer.get_protocol_by_type( SecondProtocol) alice_second_protocol.send(CommandA(None)) alice_p2p_protocol.send(Ping(None)) alice_second_protocol.send(CommandB(None)) cmd = await asyncio.wait_for(bob_p2p_stream.asend(None), timeout=DEFAULT_TIMEOUT) assert isinstance(cmd, Ping) bob_second_protocol.send(CommandA(None)) bob_p2p_protocol.send(Pong(None)) bob_second_protocol.send(CommandB(None)) cmd = await asyncio.wait_for(alice_p2p_stream.asend(None), timeout=DEFAULT_TIMEOUT) assert isinstance(cmd, Pong) cmd_1 = await asyncio.wait_for(bob_second_stream.asend(None), timeout=DEFAULT_TIMEOUT ) # noqa: E501 cmd_2 = await asyncio.wait_for(bob_second_stream.asend(None), timeout=DEFAULT_TIMEOUT ) # noqa: E501 cmd_3 = await asyncio.wait_for(alice_second_stream.asend(None), timeout=DEFAULT_TIMEOUT ) # noqa: E501 cmd_4 = await asyncio.wait_for(alice_second_stream.asend(None), timeout=DEFAULT_TIMEOUT ) # noqa: E501 assert isinstance(cmd_1, CommandA) assert isinstance(cmd_2, CommandB) assert isinstance(cmd_3, CommandA) assert isinstance(cmd_4, CommandB)
async def test_connection_get_protocol_for_command_type(): multiplexer, _ = MultiplexerPairFactory(protocol_types=(SecondProtocol, SharedProtocol), ) second_proto = multiplexer.get_protocol_by_type(SecondProtocol) shared_proto = multiplexer.get_protocol_by_type(SharedProtocol) proto_for_command_A = multiplexer.get_protocol_for_command_type(CommandA) assert proto_for_command_A is second_proto proto_for_command_C = multiplexer.get_protocol_for_command_type(CommandC) assert proto_for_command_C is shared_proto with pytest.raises(UnknownProtocol): multiplexer.get_protocol_for_command_type(CommandD) with pytest.raises(ValidationError): multiplexer.get_protocol_for_command_type(CommandB)
async def test_stream_in_background(): alice, _ = MultiplexerPairFactory() assert not alice.is_streaming assert not alice.is_closing with pytest.raises(Exception): await alice.wait_streaming() await alice.stream_in_background() assert alice.is_streaming await alice.stop_streaming() assert not alice.is_streaming assert alice.is_closing assert isinstance(alice.get_streaming_error(), asyncio.CancelledError) with pytest.raises(asyncio.CancelledError): await alice.wait_streaming_finished() with pytest.raises(asyncio.CancelledError): alice.raise_if_streaming_error()
async def test_multiplexer_properties(): multiplexer, _ = MultiplexerPairFactory(protocol_types=(SecondProtocol, ThirdProtocol), ) transport = multiplexer.get_transport() base_protocol = multiplexer.get_protocol_by_type(P2PProtocolV5) second_protocol = multiplexer.get_protocol_by_type(SecondProtocol) third_protocol = multiplexer.get_protocol_by_type(ThirdProtocol) assert multiplexer.get_base_protocol() is base_protocol assert multiplexer.get_protocols() == (base_protocol, second_protocol, third_protocol) assert multiplexer.get_protocol_by_type(P2PProtocolV5) is base_protocol assert multiplexer.get_protocol_by_type(SecondProtocol) is second_protocol assert multiplexer.get_protocol_by_type(ThirdProtocol) is third_protocol assert multiplexer.has_protocol(P2PProtocolV5) is True assert multiplexer.has_protocol(SecondProtocol) is True assert multiplexer.has_protocol(ThirdProtocol) is True assert multiplexer.has_protocol(UnsupportedProtocol) is False assert multiplexer.has_protocol(base_protocol) is True assert multiplexer.has_protocol(second_protocol) is True assert multiplexer.has_protocol(third_protocol) is True assert multiplexer.has_protocol(UnsupportedProtocol(transport, 16, False)) is False assert multiplexer.remote is transport.remote
async def test_multiplexer_p2p_and_two_more_protocols(request, event_loop): alice_multiplexer, bob_multiplexer = MultiplexerPairFactory( protocol_types=(SecondProtocol, ThirdProtocol), ) await run_multiplexers([alice_multiplexer, bob_multiplexer], request, event_loop) alice_p2p_stream = alice_multiplexer.stream_protocol_messages( P2PProtocolV5) bob_p2p_stream = bob_multiplexer.stream_protocol_messages(P2PProtocolV5) alice_second_stream = alice_multiplexer.stream_protocol_messages( SecondProtocol) bob_second_stream = bob_multiplexer.stream_protocol_messages( SecondProtocol) alice_third_stream = alice_multiplexer.stream_protocol_messages( ThirdProtocol) bob_third_stream = bob_multiplexer.stream_protocol_messages(ThirdProtocol) alice_p2p_protocol = alice_multiplexer.get_protocol_by_type(P2PProtocolV5) alice_second_protocol = alice_multiplexer.get_protocol_by_type( SecondProtocol) alice_third_protocol = alice_multiplexer.get_protocol_by_type( ThirdProtocol) bob_p2p_protocol = bob_multiplexer.get_protocol_by_type(P2PProtocolV5) bob_second_protocol = bob_multiplexer.get_protocol_by_type(SecondProtocol) bob_third_protocol = bob_multiplexer.get_protocol_by_type(ThirdProtocol) alice_second_protocol.send(CommandA(None)) alice_third_protocol.send(CommandC(None)) alice_p2p_protocol.send(Ping(None)) alice_second_protocol.send(CommandB(None)) alice_third_protocol.send(CommandD(None)) cmd = await asyncio.wait_for(bob_p2p_stream.asend(None), timeout=DEFAULT_TIMEOUT) assert isinstance(cmd, Ping) bob_second_protocol.send(CommandA(None)) bob_third_protocol.send(CommandC(None)) bob_p2p_protocol.send(Pong(None)) bob_second_protocol.send(CommandB(None)) bob_third_protocol.send(CommandD(None)) cmd = await asyncio.wait_for(alice_p2p_stream.asend(None), timeout=DEFAULT_TIMEOUT) assert isinstance(cmd, Pong) cmd_1 = await asyncio.wait_for(bob_third_stream.asend(None), timeout=DEFAULT_TIMEOUT) # noqa: E501 cmd_2 = await asyncio.wait_for(bob_third_stream.asend(None), timeout=DEFAULT_TIMEOUT) # noqa: E501 cmd_3 = await asyncio.wait_for(bob_second_stream.asend(None), timeout=DEFAULT_TIMEOUT) # noqa: E501 cmd_4 = await asyncio.wait_for(bob_second_stream.asend(None), timeout=DEFAULT_TIMEOUT) # noqa: E501 cmd_5 = await asyncio.wait_for(alice_third_stream.asend(None), timeout=DEFAULT_TIMEOUT) # noqa: E501 cmd_6 = await asyncio.wait_for(alice_third_stream.asend(None), timeout=DEFAULT_TIMEOUT) # noqa: E501 cmd_7 = await asyncio.wait_for(alice_second_stream.asend(None), timeout=DEFAULT_TIMEOUT) # noqa: E501 cmd_8 = await asyncio.wait_for(alice_second_stream.asend(None), timeout=DEFAULT_TIMEOUT) # noqa: E501 assert isinstance(cmd_1, CommandC) assert isinstance(cmd_2, CommandD) assert isinstance(cmd_3, CommandA) assert isinstance(cmd_4, CommandB) assert isinstance(cmd_5, CommandC) assert isinstance(cmd_6, CommandD) assert isinstance(cmd_7, CommandA) assert isinstance(cmd_8, CommandB)