async def test_message_all_peers(pubsubs_fsub, monkeypatch): peer_ids = [ID(b"\x12\x20" + i.to_bytes(32, "big")) for i in range(10)] mock_peers = {peer_id: FakeNetStream() for peer_id in peer_ids} monkeypatch.setattr(pubsubs_fsub[0], "peers", mock_peers) empty_rpc = rpc_pb2.RPC() empty_rpc_bytes = empty_rpc.SerializeToString() empty_rpc_bytes_len_prefixed = encode_varint_prefixed(empty_rpc_bytes) await pubsubs_fsub[0].message_all_peers(empty_rpc_bytes) for stream in mock_peers.values(): assert (await stream.read()) == empty_rpc_bytes_len_prefixed
async def test_message_all_peers(monkeypatch, security_protocol): async with PubsubFactory.create_batch_with_floodsub( 1, security_protocol=security_protocol ) as pubsubs_fsub, net_stream_pair_factory( security_protocol=security_protocol) as stream_pair: peer_id = IDFactory() mock_peers = {peer_id: stream_pair[0]} with monkeypatch.context() as m: m.setattr(pubsubs_fsub[0], "peers", mock_peers) empty_rpc = rpc_pb2.RPC() empty_rpc_bytes = empty_rpc.SerializeToString() empty_rpc_bytes_len_prefixed = encode_varint_prefixed( empty_rpc_bytes) await pubsubs_fsub[0].message_all_peers(empty_rpc_bytes) assert (await stream_pair[1].read(MAX_READ_LEN) ) == empty_rpc_bytes_len_prefixed
def generate_RPC_packet(origin_id, topics, msg_content, msg_id): """ Generate RPC packet to send over wire :param origin_id: peer id of the message origin :param topics: list of topics :param msg_content: string of content in data :param msg_id: seqno for the message """ packet = rpc_pb2.RPC() message = rpc_pb2.Message( from_id=origin_id.encode('utf-8'), seqno=msg_id, data=msg_content.encode('utf-8'), ) for topic in topics: message.topicIDs.extend([topic.encode('utf-8')]) packet.publish.extend([message]) return packet
async def test_continuously_read_stream(pubsubs_fsub, monkeypatch): stream = FakeNetStream() await pubsubs_fsub[0].subscribe(TESTING_TOPIC) event_push_msg = asyncio.Event() event_handle_subscription = asyncio.Event() event_handle_rpc = asyncio.Event() async def mock_push_msg(msg_forwarder, msg): event_push_msg.set() def mock_handle_subscription(origin_id, sub_message): event_handle_subscription.set() async def mock_handle_rpc(rpc, sender_peer_id): event_handle_rpc.set() monkeypatch.setattr(pubsubs_fsub[0], "push_msg", mock_push_msg) monkeypatch.setattr( pubsubs_fsub[0], "handle_subscription", mock_handle_subscription ) monkeypatch.setattr(pubsubs_fsub[0].router, "handle_rpc", mock_handle_rpc) async def wait_for_event_occurring(event): try: await asyncio.wait_for(event.wait(), timeout=1) except asyncio.TimeoutError as error: event.clear() raise asyncio.TimeoutError( f"Event {event} is not set before the timeout. " "This indicates the mocked functions are not called properly." ) from error else: event.clear() # Kick off the task `continuously_read_stream` task = asyncio.ensure_future(pubsubs_fsub[0].continuously_read_stream(stream)) # Test: `push_msg` is called when publishing to a subscribed topic. publish_subscribed_topic = rpc_pb2.RPC( publish=[rpc_pb2.Message(topicIDs=[TESTING_TOPIC])] ) await stream.write( encode_varint_prefixed(publish_subscribed_topic.SerializeToString()) ) await wait_for_event_occurring(event_push_msg) # Make sure the other events are not emitted. with pytest.raises(asyncio.TimeoutError): await wait_for_event_occurring(event_handle_subscription) with pytest.raises(asyncio.TimeoutError): await wait_for_event_occurring(event_handle_rpc) # Test: `push_msg` is not called when publishing to a topic-not-subscribed. publish_not_subscribed_topic = rpc_pb2.RPC( publish=[rpc_pb2.Message(topicIDs=["NOT_SUBSCRIBED"])] ) await stream.write( encode_varint_prefixed(publish_not_subscribed_topic.SerializeToString()) ) with pytest.raises(asyncio.TimeoutError): await wait_for_event_occurring(event_push_msg) # Test: `handle_subscription` is called when a subscription message is received. subscription_msg = rpc_pb2.RPC(subscriptions=[rpc_pb2.RPC.SubOpts()]) await stream.write(encode_varint_prefixed(subscription_msg.SerializeToString())) await wait_for_event_occurring(event_handle_subscription) # Make sure the other events are not emitted. with pytest.raises(asyncio.TimeoutError): await wait_for_event_occurring(event_push_msg) with pytest.raises(asyncio.TimeoutError): await wait_for_event_occurring(event_handle_rpc) # Test: `handle_rpc` is called when a control message is received. control_msg = rpc_pb2.RPC(control=rpc_pb2.ControlMessage()) await stream.write(encode_varint_prefixed(control_msg.SerializeToString())) await wait_for_event_occurring(event_handle_rpc) # Make sure the other events are not emitted. with pytest.raises(asyncio.TimeoutError): await wait_for_event_occurring(event_push_msg) with pytest.raises(asyncio.TimeoutError): await wait_for_event_occurring(event_handle_subscription) task.cancel()
async def test_continuously_read_stream(monkeypatch, nursery, security_protocol): async def wait_for_event_occurring(event): await trio.hazmat.checkpoint() with trio.fail_after(0.1): await event.wait() class Events(NamedTuple): push_msg: trio.Event handle_subscription: trio.Event handle_rpc: trio.Event @contextmanager def mock_methods(): event_push_msg = trio.Event() event_handle_subscription = trio.Event() event_handle_rpc = trio.Event() async def mock_push_msg(msg_forwarder, msg): event_push_msg.set() await trio.hazmat.checkpoint() def mock_handle_subscription(origin_id, sub_message): event_handle_subscription.set() async def mock_handle_rpc(rpc, sender_peer_id): event_handle_rpc.set() await trio.hazmat.checkpoint() with monkeypatch.context() as m: m.setattr(pubsubs_fsub[0], "push_msg", mock_push_msg) m.setattr(pubsubs_fsub[0], "handle_subscription", mock_handle_subscription) m.setattr(pubsubs_fsub[0].router, "handle_rpc", mock_handle_rpc) yield Events(event_push_msg, event_handle_subscription, event_handle_rpc) async with PubsubFactory.create_batch_with_floodsub( 1, security_protocol=security_protocol ) as pubsubs_fsub, net_stream_pair_factory( security_protocol=security_protocol) as stream_pair: await pubsubs_fsub[0].subscribe(TESTING_TOPIC) # Kick off the task `continuously_read_stream` nursery.start_soon(pubsubs_fsub[0].continuously_read_stream, stream_pair[0]) # Test: `push_msg` is called when publishing to a subscribed topic. publish_subscribed_topic = rpc_pb2.RPC( publish=[rpc_pb2.Message(topicIDs=[TESTING_TOPIC])]) with mock_methods() as events: await stream_pair[1].write( encode_varint_prefixed( publish_subscribed_topic.SerializeToString())) await wait_for_event_occurring(events.push_msg) # Make sure the other events are not emitted. with pytest.raises(trio.TooSlowError): await wait_for_event_occurring(events.handle_subscription) with pytest.raises(trio.TooSlowError): await wait_for_event_occurring(events.handle_rpc) # Test: `push_msg` is not called when publishing to a topic-not-subscribed. publish_not_subscribed_topic = rpc_pb2.RPC( publish=[rpc_pb2.Message(topicIDs=["NOT_SUBSCRIBED"])]) with mock_methods() as events: await stream_pair[1].write( encode_varint_prefixed( publish_not_subscribed_topic.SerializeToString())) with pytest.raises(trio.TooSlowError): await wait_for_event_occurring(events.push_msg) # Test: `handle_subscription` is called when a subscription message is received. subscription_msg = rpc_pb2.RPC(subscriptions=[rpc_pb2.RPC.SubOpts()]) with mock_methods() as events: await stream_pair[1].write( encode_varint_prefixed(subscription_msg.SerializeToString())) await wait_for_event_occurring(events.handle_subscription) # Make sure the other events are not emitted. with pytest.raises(trio.TooSlowError): await wait_for_event_occurring(events.push_msg) with pytest.raises(trio.TooSlowError): await wait_for_event_occurring(events.handle_rpc) # Test: `handle_rpc` is called when a control message is received. control_msg = rpc_pb2.RPC(control=rpc_pb2.ControlMessage()) with mock_methods() as events: await stream_pair[1].write( encode_varint_prefixed(control_msg.SerializeToString())) await wait_for_event_occurring(events.handle_rpc) # Make sure the other events are not emitted. with pytest.raises(trio.TooSlowError): await wait_for_event_occurring(events.push_msg) with pytest.raises(trio.TooSlowError): await wait_for_event_occurring(events.handle_subscription)