def test_get_from_multiplexer_when_empty(): """Test that getting an envelope from the multiplexer when the input queue is empty raises an exception.""" connection = _make_dummy_connection() multiplexer = Multiplexer([connection]) with pytest.raises(aea.mail.base.Empty): multiplexer.get()
def run(): # Ensure the input and output files do not exist initially if os.path.isfile(INPUT_FILE): os.remove(INPUT_FILE) if os.path.isfile(OUTPUT_FILE): os.remove(OUTPUT_FILE) # create the connection and multiplexer objects configuration = ConnectionConfig( input_file=INPUT_FILE, output_file=OUTPUT_FILE, connection_id=StubConnection.connection_id, ) stub_connection = StubConnection(configuration=configuration, identity=Identity("some_agent", "some_address")) multiplexer = Multiplexer([stub_connection]) try: # Set the multiplexer running in a different thread t = Thread(target=multiplexer.connect) t.start() # Wait for everything to start up time.sleep(3) # Create a message inside an envelope and get the stub connection to pass it into the multiplexer message_text = ( "multiplexer,some_agent,fetchai/default:0.4.0,\x08\x01*\x07\n\x05hello," ) with open(INPUT_FILE, "w") as f: write_with_lock(f, message_text) # Wait for the envelope to get processed time.sleep(2) # get the envelope envelope = multiplexer.get() # type: Optional[Envelope] assert envelope is not None # Inspect its contents print( "Envelope received by Multiplexer: sender={}, to={}, protocol_id={}, message={}" .format(envelope.sender, envelope.to, envelope.protocol_id, envelope.message)) # Create a mirrored response envelope response_envelope = copy(envelope) response_envelope.to = envelope.sender response_envelope.sender = envelope.to # Send the envelope back multiplexer.put(response_envelope) # Read the output envelope generated by the multiplexer with open(OUTPUT_FILE, "r") as f: print("Envelope received from Multiplexer: " + f.readline()) finally: # Shut down the multiplexer multiplexer.disconnect() t.join()
def test_communication_direct(self): """Test communication direct (i.e. both clients registered to same peer).""" for i in range(len(PUBLIC_DHT_DELEGATE_URIS)): uri = PUBLIC_DHT_DELEGATE_URIS[i] peer_public_key = PUBLIC_DHT_PUBLIC_KEYS[i] multiplexers = [] try: temp_dir_1 = os.path.join(self.t, f"dir_{i}_1") os.mkdir(temp_dir_1) connection1 = _make_libp2p_client_connection( peer_public_key=peer_public_key, uri=uri, data_dir=temp_dir_1 ) multiplexer1 = Multiplexer([connection1]) multiplexer1.connect() multiplexers.append(multiplexer1) temp_dir_2 = os.path.join(self.t, f"dir_{i}_2") os.mkdir(temp_dir_2) connection2 = _make_libp2p_client_connection( peer_public_key=peer_public_key, uri=uri, data_dir=temp_dir_2 ) multiplexer2 = Multiplexer([connection2]) multiplexer2.connect() multiplexers.append(multiplexer2) addr_1 = connection1.address addr_2 = connection2.address msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) envelope = Envelope(to=addr_2, sender=addr_1, message=msg,) multiplexer1.put(envelope) delivered_envelope = multiplexer2.get(block=True, timeout=20) assert delivered_envelope is not None assert delivered_envelope.to == envelope.to assert delivered_envelope.sender == envelope.sender assert ( delivered_envelope.protocol_specification_id == envelope.protocol_specification_id ) assert delivered_envelope.message != envelope.message msg = DefaultMessage.serializer.decode(delivered_envelope.message) msg.to = delivered_envelope.to msg.sender = delivered_envelope.sender assert envelope.message == msg except Exception: raise finally: for mux in multiplexers: mux.disconnect()
def test_communication_direct(self): """Test communication direct.""" for maddr in PUBLIC_DHT_MADDRS: multiplexers = [] try: connection1 = _make_libp2p_connection(DEFAULT_PORT + 1, relay=False, entry_peers=[maddr]) multiplexer1 = Multiplexer([connection1]) self.log_files.append(connection1.node.log_file) multiplexer1.connect() multiplexers.append(multiplexer1) connection2 = _make_libp2p_connection(DEFAULT_PORT + 2, relay=False, entry_peers=[maddr]) multiplexer2 = Multiplexer([connection2]) self.log_files.append(connection2.node.log_file) multiplexer2.connect() multiplexers.append(multiplexer2) addr_1 = connection1.node.address addr_2 = connection2.node.address msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) envelope = Envelope( to=addr_2, sender=addr_1, protocol_id=DefaultMessage.protocol_id, message=msg, ) multiplexer1.put(envelope) delivered_envelope = multiplexer2.get(block=True, timeout=20) assert delivered_envelope is not None assert delivered_envelope.to == envelope.to assert delivered_envelope.sender == envelope.sender assert delivered_envelope.protocol_id == envelope.protocol_id assert delivered_envelope.message != envelope.message msg = DefaultMessage.serializer.decode( delivered_envelope.message) msg.to = delivered_envelope.to msg.sender = delivered_envelope.sender assert envelope.message == msg except Exception: raise finally: for mux in multiplexers: mux.disconnect()
def test_communication_indirect(self): assert (len(PUBLIC_DHT_DELEGATE_URIS) > 1), "Test requires at least 2 public dht node" for i in range(len(PUBLIC_DHT_DELEGATE_URIS)): connection1 = _make_libp2p_client_connection( uri=PUBLIC_DHT_DELEGATE_URIS[i]) multiplexer1 = Multiplexer([connection1]) multiplexer1.connect() addr_1 = connection1.address msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) for j in range(len(PUBLIC_DHT_DELEGATE_URIS)): if j == i: continue connection2 = _make_libp2p_client_connection( uri=PUBLIC_DHT_DELEGATE_URIS[j]) multiplexer2 = Multiplexer([connection2]) multiplexer2.connect() addr_2 = connection2.address envelope = Envelope( to=addr_2, sender=addr_1, protocol_id=DefaultMessage.protocol_id, message=msg, ) multiplexer1.put(envelope) delivered_envelope = multiplexer2.get(block=True, timeout=20) try: assert delivered_envelope is not None assert delivered_envelope.to == envelope.to assert delivered_envelope.sender == envelope.sender assert delivered_envelope.protocol_id == envelope.protocol_id assert delivered_envelope.message != envelope.message msg = DefaultMessage.serializer.decode( delivered_envelope.message) assert envelope.message == msg except Exception: multiplexer1.disconnect() raise finally: multiplexer2.disconnect() multiplexer1.disconnect()
def test_communication_direct(self): for uri in PUBLIC_DHT_DELEGATE_URIS: connection1 = _make_libp2p_client_connection(uri=uri) multiplexer1 = Multiplexer([connection1]) multiplexer1.connect() connection2 = _make_libp2p_client_connection(uri=uri) multiplexer2 = Multiplexer([connection2]) multiplexer2.connect() addr_1 = connection1.address addr_2 = connection2.address msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) envelope = Envelope( to=addr_2, sender=addr_1, protocol_id=DefaultMessage.protocol_id, message=msg, ) multiplexer1.put(envelope) delivered_envelope = multiplexer2.get(block=True, timeout=20) try: assert delivered_envelope is not None assert delivered_envelope.to == envelope.to assert delivered_envelope.sender == envelope.sender assert delivered_envelope.protocol_id == envelope.protocol_id assert delivered_envelope.message != envelope.message msg = DefaultMessage.serializer.decode( delivered_envelope.message) assert envelope.message == msg except Exception: raise finally: multiplexer1.disconnect() multiplexer2.disconnect()
class TestSimpleSearchResult: """Test that a simple search result return the expected result.""" def setup(self): """Set up the test.""" self.node = LocalNode() self.node.start() self.address_1 = "address" self.multiplexer = Multiplexer( [_make_local_connection( self.address_1, self.node, )]) self.multiplexer.connect() # register a service. self.dialogues = OefSearchDialogues(self.address_1) self.data_model = DataModel( "foobar", attributes=[ Attribute("foo", int, True), Attribute("bar", str, True) ], ) service_description = Description({ "foo": 1, "bar": "baz" }, data_model=self.data_model) register_service_request, self.sending_dialogue = self.dialogues.create( counterparty=str(OEFLocalConnection.connection_id), performative=OefSearchMessage.Performative.REGISTER_SERVICE, service_description=service_description, ) envelope = Envelope( to=register_service_request.to, sender=register_service_request.sender, message=register_service_request, ) self.multiplexer.put(envelope) @pytest.mark.flaky(reruns=MAX_FLAKY_RERUNS ) # TODO: check reasons!. quite unstable test def test_not_empty_search_result(self): """Test that the search result contains one entry after a successful registration.""" # build and send the request search_services_request, sending_dialogue = self.dialogues.create( counterparty=str(OEFLocalConnection.connection_id), performative=OefSearchMessage.Performative.SEARCH_SERVICES, query=Query(constraints=[], model=self.data_model), ) envelope = Envelope( to=search_services_request.to, sender=search_services_request.sender, message=search_services_request, ) self.multiplexer.put(envelope) # check the result response_envelope = self.multiplexer.get(block=True, timeout=2.0) assert (response_envelope.protocol_specification_id == OefSearchMessage.protocol_specification_id) search_result = cast(OefSearchMessage, response_envelope.message) response_dialogue = self.dialogues.update(search_result) assert response_dialogue == sending_dialogue assert search_result.performative == OefSearchMessage.Performative.SEARCH_RESULT assert search_result.agents == (self.address_1, ) def teardown(self): """Teardown the test.""" self.multiplexer.disconnect() self.node.stop()
class TestSearchServices: """Tests related to service search functionality.""" def setup(self): """Set the test up.""" self.connection = _make_oef_connection( FETCHAI_ADDRESS_ONE, oef_addr="127.0.0.1", oef_port=10000, ) self.multiplexer = Multiplexer([self.connection]) self.multiplexer.connect() self.oef_search_dialogues = OefSearchDialogues(FETCHAI_ADDRESS_ONE) def test_search_services_with_query_without_model(self): """Test that a search services request can be sent correctly. In this test, the query has no data model. """ search_query_empty_model = Query( [Constraint("foo", ConstraintType("==", "bar"))], model=None) oef_search_request, sending_dialogue = self.oef_search_dialogues.create( counterparty=str(self.connection.connection_id), performative=OefSearchMessage.Performative.SEARCH_SERVICES, query=search_query_empty_model, ) self.multiplexer.put( Envelope( to=oef_search_request.to, sender=oef_search_request.sender, protocol_id=oef_search_request.protocol_id, message=oef_search_request, )) envelope = self.multiplexer.get(block=True, timeout=5.0) oef_search_response = envelope.message oef_search_dialogue = self.oef_search_dialogues.update( oef_search_response) assert (oef_search_response.performative == OefSearchMessage.Performative.SEARCH_RESULT) assert oef_search_dialogue is not None assert oef_search_dialogue == sending_dialogue assert oef_search_response.agents == () def test_search_services_with_query_with_model(self): """Test that a search services request can be sent correctly. In this test, the query has a simple data model. """ data_model = DataModel("foobar", [Attribute("foo", str, True)]) search_query = Query( [Constraint("foo", ConstraintType("==", "bar"))], model=data_model) oef_search_request, sending_dialogue = self.oef_search_dialogues.create( counterparty=str(self.connection.connection_id), performative=OefSearchMessage.Performative.SEARCH_SERVICES, query=search_query, ) self.multiplexer.put( Envelope( to=oef_search_request.to, sender=oef_search_request.sender, protocol_id=oef_search_request.protocol_id, message=oef_search_request, )) envelope = self.multiplexer.get(block=True, timeout=5.0) oef_search_response = envelope.message oef_search_dialogue = self.oef_search_dialogues.update( oef_search_response) assert (oef_search_response.performative == OefSearchMessage.Performative.SEARCH_RESULT) assert oef_search_dialogue is not None assert oef_search_dialogue == sending_dialogue assert oef_search_response.agents == () def test_search_services_with_distance_query(self): """Test that a search services request can be sent correctly. In this test, the query has a simple data model. """ tour_eiffel = Location(48.8581064, 2.29447) attribute = Attribute("latlon", Location, True) data_model = DataModel("geolocation", [attribute]) search_query = Query( [ Constraint(attribute.name, ConstraintType("distance", (tour_eiffel, 1.0))) ], model=data_model, ) oef_search_request, sending_dialogue = self.oef_search_dialogues.create( counterparty=str(self.connection.connection_id), performative=OefSearchMessage.Performative.SEARCH_SERVICES, query=search_query, ) self.multiplexer.put( Envelope( to=oef_search_request.to, sender=oef_search_request.sender, protocol_id=oef_search_request.protocol_id, message=oef_search_request, )) envelope = self.multiplexer.get(block=True, timeout=5.0) oef_search_response = envelope.message oef_search_dialogue = self.oef_search_dialogues.update( oef_search_response) assert (oef_search_response.performative == OefSearchMessage.Performative.SEARCH_RESULT) assert oef_search_dialogue is not None assert oef_search_dialogue == sending_dialogue assert oef_search_response.agents == () def teardown(self): """Teardowm the test.""" self.multiplexer.disconnect()
def test_soef(): """Perform tests over real network.""" # First run OEF in a separate terminal: python scripts/oef/launch.py -c ./scripts/oef/launch_config.json crypto = FetchAICrypto() identity = Identity("", address=crypto.address) # create the connection and multiplexer objects configuration = ConnectionConfig( api_key="TwiCIriSl0mLahw17pyqoA", soef_addr="soef.fetch.ai", soef_port=9002, restricted_to_protocols={ PublicId.from_str("fetchai/oef_search:0.3.0") }, connection_id=SOEFConnection.connection_id, ) soef_connection = SOEFConnection( configuration=configuration, identity=identity, ) multiplexer = Multiplexer([soef_connection]) try: # Set the multiplexer running in a different thread t = Thread(target=multiplexer.connect) t.start() wait_for_condition(lambda: multiplexer.is_connected, timeout=5) # register an agent with location agent_location = Location(52.2057092, 2.1183431) service_instance = {"location": agent_location} service_description = Description( service_instance, data_model=models.AGENT_LOCATION_MODEL) message = OefSearchMessage( performative=OefSearchMessage.Performative.REGISTER_SERVICE, service_description=service_description, ) envelope = Envelope( to="soef", sender=crypto.address, protocol_id=message.protocol_id, message=message, ) logger.info("Registering agent at location=({},{}) by agent={}".format( agent_location.latitude, agent_location.longitude, crypto.address, )) multiplexer.put(envelope) # register personality pieces service_instance = {"piece": "genus", "value": "service"} service_description = Description( service_instance, data_model=models.AGENT_PERSONALITY_MODEL) message = OefSearchMessage( performative=OefSearchMessage.Performative.REGISTER_SERVICE, service_description=service_description, ) envelope = Envelope( to="soef", sender=crypto.address, protocol_id=message.protocol_id, message=message, ) logger.info("Registering agent personality") multiplexer.put(envelope) # register service key service_instance = {"key": "test", "value": "test"} service_description = Description( service_instance, data_model=models.SET_SERVICE_KEY_MODEL) message = OefSearchMessage( performative=OefSearchMessage.Performative.REGISTER_SERVICE, service_description=service_description, ) envelope = Envelope( to="soef", sender=crypto.address, protocol_id=message.protocol_id, message=message, ) logger.info("Registering agent service key") multiplexer.put(envelope) # find agents near me radius = 0.1 close_to_my_service = Constraint( "location", ConstraintType("distance", (agent_location, radius))) closeness_query = Query([close_to_my_service], model=models.AGENT_LOCATION_MODEL) message = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, query=closeness_query, ) envelope = Envelope( to="soef", sender=crypto.address, protocol_id=message.protocol_id, message=message, ) logger.info( "Searching for agents in radius={} of myself at location=({},{})". format( radius, agent_location.latitude, agent_location.longitude, )) multiplexer.put(envelope) wait_for_condition(lambda: not multiplexer.in_queue.empty(), timeout=20) # check for search results envelope = multiplexer.get() message = envelope.message assert len(message.agents) >= 0 # find agents near me with filter radius = 0.1 close_to_my_service = Constraint( "location", ConstraintType("distance", (agent_location, radius))) personality_filters = [ Constraint("genus", ConstraintType("==", "vehicle")), Constraint("classification", ConstraintType("==", "mobility.railway.train")), ] service_key_filters = [ Constraint("test", ConstraintType("==", "test")), ] closeness_query = Query([close_to_my_service] + personality_filters + service_key_filters) message = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, query=closeness_query, ) envelope = Envelope( to="soef", sender=crypto.address, protocol_id=message.protocol_id, message=message, ) logger.info( "Searching for agents in radius={} of myself at location=({},{}) with personality filters" .format( radius, agent_location.latitude, agent_location.longitude, )) time.sleep(3) # cause requests rate limit on server :( multiplexer.put(envelope) wait_for_condition(lambda: not multiplexer.in_queue.empty(), timeout=20) envelope = multiplexer.get() message = envelope.message assert len(message.agents) >= 0 # test ping command service_description = Description({}, data_model=models.PING_MODEL) message = OefSearchMessage( performative=OefSearchMessage.Performative.REGISTER_SERVICE, service_description=service_description, ) envelope = Envelope( to="soef", sender=crypto.address, protocol_id=message.protocol_id, message=message, ) logger.info("Registering agent service key") multiplexer.put(envelope) time.sleep(3) assert multiplexer.in_queue.empty() finally: # Shut down the multiplexer multiplexer.disconnect() t.join()
class TestStubConnectionReception: """Test that the stub connection is implemented correctly.""" def setup(self): """Set the test up.""" self.cwd = os.getcwd() self.tmpdir = Path(tempfile.mkdtemp()) d = self.tmpdir / "test_stub" d.mkdir(parents=True) self.input_file_path = d / "input_file.csv" self.output_file_path = d / "output_file.csv" self.connection = _make_stub_connection(self.input_file_path, self.output_file_path) self.multiplexer = Multiplexer([self.connection]) self.multiplexer.connect() os.chdir(self.tmpdir) def test_reception_a(self): """Test that the connection receives what has been enqueued in the input file.""" msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) expected_envelope = Envelope( to="any", sender="anys", message=msg, ) with open(self.input_file_path, "ab+") as f: write_envelope(expected_envelope, f) actual_envelope = self.multiplexer.get(block=True, timeout=3.0) assert expected_envelope.to == actual_envelope.to assert expected_envelope.sender == actual_envelope.sender assert (expected_envelope.protocol_specification_id == actual_envelope.protocol_specification_id) msg = DefaultMessage.serializer.decode(actual_envelope.message) msg.to = actual_envelope.to msg.sender = actual_envelope.sender assert expected_envelope.message == msg def test_reception_b(self): """Test that the connection receives what has been enqueued in the input file.""" # a message containing delimiters and newline characters msg = b"\x08\x02\x12\x011\x1a\x011 \x01:,\n*0x32468d\n,\nB8Ab795\n\n49B49C88DC991990E7910891,,dbd\n" protocol_specification_id = PublicId.from_str( "some_author/some_name:0.1.0") encoded_envelope = "{}{}{}{}{}{}{}{}".format( "any", SEPARATOR, "any", SEPARATOR, protocol_specification_id, SEPARATOR, msg.decode("utf-8"), SEPARATOR, ) encoded_envelope = encoded_envelope.encode("utf-8") with open(self.input_file_path, "ab+") as f: write_with_lock(f, encoded_envelope) actual_envelope = self.multiplexer.get(block=True, timeout=3.0) assert "any" == actual_envelope.to assert "any" == actual_envelope.sender assert protocol_specification_id == actual_envelope.protocol_specification_id assert msg == actual_envelope.message def test_reception_c(self): """Test that the connection receives what has been enqueued in the input file.""" encoded_envelope = b"0x5E22777dD831A459535AA4306AceC9cb22eC4cB5,default_oef,fetchai/oef_search:0.1.0,\x08\x02\x12\x011\x1a\x011 \x01:,\n*0x32468dB8Ab79549B49C88DC991990E7910891dbd," expected_envelope = Envelope( to="0x5E22777dD831A459535AA4306AceC9cb22eC4cB5", sender="default_oef", protocol_specification_id=OefSearchMessage. protocol_specification_id, message= b"\x08\x02\x12\x011\x1a\x011 \x01:,\n*0x32468dB8Ab79549B49C88DC991990E7910891dbd", ) with open(self.input_file_path, "ab+") as f: write_with_lock(f, encoded_envelope) actual_envelope = self.multiplexer.get(block=True, timeout=3.0) assert expected_envelope == actual_envelope def teardown(self): """Tear down the test.""" os.chdir(self.cwd) try: shutil.rmtree(self.tmpdir) except (OSError, IOError): pass self.multiplexer.disconnect()
def test_communication(): """Test that two multiplexer can communicate through the node.""" with LocalNode() as node: multiplexer1 = Multiplexer( [_make_local_connection("multiplexer1", node)]) multiplexer2 = Multiplexer( [_make_local_connection("multiplexer2", node)]) multiplexer1.connect() multiplexer2.connect() msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) envelope = Envelope( to="multiplexer2", sender="multiplexer1", protocol_id=DefaultMessage.protocol_id, message=msg, ) multiplexer1.put(envelope) msg = FipaMessage( performative=FipaMessage.Performative.CFP, dialogue_reference=(str(0), ""), message_id=1, target=0, query=Query([Constraint("something", ConstraintType(">", 1))]), ) envelope = Envelope( to="multiplexer2", sender="multiplexer1", protocol_id=FipaMessage.protocol_id, message=msg, ) multiplexer1.put(envelope) msg = FipaMessage( performative=FipaMessage.Performative.PROPOSE, dialogue_reference=(str(0), ""), message_id=2, target=1, proposal=Description({}), ) envelope = Envelope( to="multiplexer2", sender="multiplexer1", protocol_id=FipaMessage.protocol_id, message=msg, ) multiplexer1.put(envelope) msg = FipaMessage( performative=FipaMessage.Performative.ACCEPT, dialogue_reference=(str(0), ""), message_id=1, target=0, ) envelope = Envelope( to="multiplexer2", sender="multiplexer1", protocol_id=FipaMessage.protocol_id, message=msg, ) multiplexer1.put(envelope) msg = FipaMessage( performative=FipaMessage.Performative.DECLINE, dialogue_reference=(str(0), ""), message_id=1, target=0, ) envelope = Envelope( to="multiplexer2", sender="multiplexer1", protocol_id=FipaMessage.protocol_id, message=msg, ) multiplexer1.put(envelope) envelope = multiplexer2.get(block=True, timeout=1.0) msg = envelope.message assert envelope.protocol_id == DefaultMessage.protocol_id assert msg.content == b"hello" envelope = multiplexer2.get(block=True, timeout=1.0) msg = envelope.message assert envelope.protocol_id == FipaMessage.protocol_id assert msg.performative == FipaMessage.Performative.CFP envelope = multiplexer2.get(block=True, timeout=1.0) msg = envelope.message assert envelope.protocol_id == FipaMessage.protocol_id assert msg.performative == FipaMessage.Performative.PROPOSE envelope = multiplexer2.get(block=True, timeout=1.0) msg = envelope.message assert envelope.protocol_id == FipaMessage.protocol_id assert msg.performative == FipaMessage.Performative.ACCEPT envelope = multiplexer2.get(block=True, timeout=1.0) msg = envelope.message assert envelope.protocol_id == FipaMessage.protocol_id assert msg.performative == FipaMessage.Performative.DECLINE multiplexer1.disconnect() multiplexer2.disconnect()
class TestStubConnectionReception: """Test that the stub connection is implemented correctly.""" def setup(self): """Set the test up.""" self.cwd = os.getcwd() self.tmpdir = Path(tempfile.mkdtemp()) d = self.tmpdir / "test_stub" d.mkdir(parents=True) self.input_file_path = d / "input_file.csv" self.output_file_path = d / "output_file.csv" self.connection = _make_stub_connection(self.input_file_path, self.output_file_path) self.multiplexer = Multiplexer([self.connection]) self.multiplexer.connect() os.chdir(self.tmpdir) def test_reception_a(self): """Test that the connection receives what has been enqueued in the input file.""" msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) msg.counterparty = "any" expected_envelope = Envelope( to="any", sender="any", protocol_id=DefaultMessage.protocol_id, message=msg, ) with open(self.input_file_path, "ab+") as f: write_envelope(expected_envelope, f) actual_envelope = self.multiplexer.get(block=True, timeout=3.0) assert expected_envelope.to == actual_envelope.to assert expected_envelope.sender == actual_envelope.sender assert expected_envelope.protocol_id == actual_envelope.protocol_id msg = DefaultMessage.serializer.decode(actual_envelope.message) msg.counterparty = actual_envelope.to assert expected_envelope.message == msg def test_reception_b(self): """Test that the connection receives what has been enqueued in the input file.""" # a message containing delimiters and newline characters msg = b"\x08\x02\x12\x011\x1a\x011 \x01:,\n*0x32468d\n,\nB8Ab795\n\n49B49C88DC991990E7910891,,dbd\n" protocol_id = PublicId.from_str("some_author/some_name:0.1.0") encoded_envelope = "{}{}{}{}{}{}{}{}".format( "any", SEPARATOR, "any", SEPARATOR, protocol_id, SEPARATOR, msg.decode("utf-8"), SEPARATOR, ) encoded_envelope = encoded_envelope.encode("utf-8") with open(self.input_file_path, "ab+") as f: with lock_file(f): f.write(encoded_envelope) f.flush() actual_envelope = self.multiplexer.get(block=True, timeout=3.0) assert "any" == actual_envelope.to assert "any" == actual_envelope.sender assert protocol_id == actual_envelope.protocol_id assert msg == actual_envelope.message def test_reception_c(self): """Test that the connection receives what has been enqueued in the input file.""" encoded_envelope = b"0x5E22777dD831A459535AA4306AceC9cb22eC4cB5,default_oef,fetchai/oef_search:0.3.0,\x08\x02\x12\x011\x1a\x011 \x01:,\n*0x32468dB8Ab79549B49C88DC991990E7910891dbd," expected_envelope = Envelope( to="0x5E22777dD831A459535AA4306AceC9cb22eC4cB5", sender="default_oef", protocol_id=PublicId.from_str("fetchai/oef_search:0.3.0"), message= b"\x08\x02\x12\x011\x1a\x011 \x01:,\n*0x32468dB8Ab79549B49C88DC991990E7910891dbd", ) with open(self.input_file_path, "ab+") as f: with lock_file(f): f.write(encoded_envelope) f.flush() actual_envelope = self.multiplexer.get(block=True, timeout=3.0) assert expected_envelope == actual_envelope def test_reception_fails(self): """Test the case when an error occurs during the processing of a line.""" patch = mock.patch.object(aea.connections.stub.connection.logger, "error") mocked_logger_error = patch.start() with mock.patch( "aea.connections.stub.connection._decode", side_effect=Exception("an error."), ): _process_line(b"") mocked_logger_error.assert_called_with( "Error when processing a line. Message: an error.", exc_info=True) patch.stop() def teardown(self): """Tear down the test.""" os.chdir(self.cwd) try: shutil.rmtree(self.tmpdir) except (OSError, IOError): pass self.multiplexer.disconnect()
def test_communication_indirect(self): """Test communication indirect.""" assert len(PUBLIC_DHT_MADDRS) > 1, "Test requires at least 2 public dht node" for i in range(len(PUBLIC_DHT_MADDRS)): multiplexers = [] try: temp_dir_1 = os.path.join(self.t, f"dir_{i}__") os.mkdir(temp_dir_1) connection1 = _make_libp2p_connection( port=DEFAULT_PORT + 1, relay=False, entry_peers=[PUBLIC_DHT_MADDRS[i]], data_dir=temp_dir_1, ) multiplexer1 = Multiplexer([connection1]) self.log_files.append(connection1.node.log_file) multiplexer1.connect() multiplexers.append(multiplexer1) addr_1 = connection1.node.address for j in range(len(PUBLIC_DHT_MADDRS)): if j == i: continue temp_dir_2 = os.path.join(self.t, f"dir_{i}_{j}") os.mkdir(temp_dir_2) connection2 = _make_libp2p_connection( port=DEFAULT_PORT + 2, relay=False, entry_peers=[PUBLIC_DHT_MADDRS[j]], data_dir=temp_dir_2, ) multiplexer2 = Multiplexer([connection2]) self.log_files.append(connection2.node.log_file) multiplexer2.connect() multiplexers.append(multiplexer2) addr_2 = connection2.node.address msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) envelope = Envelope(to=addr_2, sender=addr_1, message=msg,) multiplexer1.put(envelope) delivered_envelope = multiplexer2.get(block=True, timeout=20) assert delivered_envelope is not None assert delivered_envelope.to == envelope.to assert delivered_envelope.sender == envelope.sender assert ( delivered_envelope.protocol_specification_id == envelope.protocol_specification_id ) assert delivered_envelope.message != envelope.message msg = DefaultMessage.serializer.decode(delivered_envelope.message) msg.to = delivered_envelope.to msg.sender = delivered_envelope.sender assert envelope.message == msg multiplexer2.disconnect() del multiplexers[-1] except Exception: raise finally: for mux in multiplexers: mux.disconnect()
def test_communication_indirect(self): assert len( PUBLIC_DHT_MADDRS) > 1, "Test requires at least 2 public dht node" for i in range(len(PUBLIC_DHT_MADDRS)): connection1 = _make_libp2p_connection( DEFAULT_PORT + 1, relay=False, entry_peers=[PUBLIC_DHT_MADDRS[i]]) multiplexer1 = Multiplexer([connection1]) self.log_files.append(connection1.node.log_file) multiplexer1.connect() addr_1 = connection1.node.address for j in range(len(PUBLIC_DHT_MADDRS)): if j == i: continue connection2 = _make_libp2p_connection( DEFAULT_PORT + 2, relay=False, entry_peers=[PUBLIC_DHT_MADDRS[j]], ) multiplexer2 = Multiplexer([connection2]) self.log_files.append(connection2.node.log_file) multiplexer2.connect() addr_2 = connection2.node.address msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) envelope = Envelope( to=addr_2, sender=addr_1, protocol_id=DefaultMessage.protocol_id, message=msg, ) multiplexer1.put(envelope) delivered_envelope = multiplexer2.get(block=True, timeout=20) try: assert delivered_envelope is not None assert delivered_envelope.to == envelope.to assert delivered_envelope.sender == envelope.sender assert delivered_envelope.protocol_id == envelope.protocol_id assert delivered_envelope.message != envelope.message msg = DefaultMessage.serializer.decode( delivered_envelope.message) assert envelope.message == msg except Exception: multiplexer1.disconnect() raise finally: multiplexer2.disconnect() multiplexer1.disconnect()
class TestLibp2pConnectionRelayNodeRestartIncomingEnvelopes( BaseTestLibp2pRelay): """Test that connection will reliably receive envelopes after its relay node restarted""" @libp2p_log_on_failure def setup(self): """Set the test up""" super().setup() temp_dir_gen = os.path.join(self.t, "temp_dir_gen") os.mkdir(temp_dir_gen) self.genesis = _make_libp2p_connection(data_dir=temp_dir_gen, port=DEFAULT_PORT + 1, build_directory=self.t) self.multiplexer_genesis = Multiplexer([self.genesis], protocols=[DefaultMessage]) self.multiplexer_genesis.connect() self.log_files.append(self.genesis.node.log_file) self.multiplexers.append(self.multiplexer_genesis) genesis_peer = self.genesis.node.multiaddrs[0] with open("node_key", "wb") as f: make_crypto(DEFAULT_LEDGER).dump(f) self.relay_key_path = "node_key" temp_dir_rel = os.path.join(self.t, "temp_dir_rel") os.mkdir(temp_dir_rel) self.relay = _make_libp2p_connection( data_dir=temp_dir_rel, port=DEFAULT_PORT + 2, entry_peers=[genesis_peer], node_key_file=self.relay_key_path, build_directory=self.t, ) self.multiplexer_relay = Multiplexer([self.relay], protocols=[DefaultMessage]) self.multiplexer_relay.connect() self.log_files.append(self.relay.node.log_file) self.multiplexers.append(self.multiplexer_relay) relay_peer = self.relay.node.multiaddrs[0] temp_dir_1 = os.path.join(self.t, "temp_dir_1") os.mkdir(temp_dir_1) self.connection = _make_libp2p_connection( data_dir=temp_dir_1, port=DEFAULT_PORT + 3, relay=False, entry_peers=[relay_peer], build_directory=self.t, ) self.multiplexer = Multiplexer([self.connection], protocols=[DefaultMessage]) self.multiplexer.connect() self.log_files.append(self.connection.node.log_file) self.multiplexers.append(self.multiplexer) temp_dir_2 = os.path.join(self.t, "temp_dir_2") os.mkdir(temp_dir_2) self.connection2 = _make_libp2p_connection( data_dir=temp_dir_2, port=DEFAULT_PORT + 4, relay=False, entry_peers=[relay_peer], build_directory=self.t, ) self.multiplexer2 = Multiplexer([self.connection2], protocols=[DefaultMessage]) self.multiplexer2.connect() self.log_files.append(self.connection2.node.log_file) self.multiplexers.append(self.multiplexer2) def test_connection_is_established(self): """Test connection established.""" assert self.relay.is_connected is True assert self.connection.is_connected is True assert self.connection2.is_connected is True def test_envelope_routed_from_peer_after_relay_restart(self): """Test envelope routed from third peer after relay restart.""" addr_1 = self.genesis.address addr_2 = self.connection.address msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) envelope = Envelope( to=addr_2, sender=addr_1, protocol_specification_id=DefaultMessage.protocol_specification_id, message=DefaultSerializer().encode(msg), ) self.multiplexer_genesis.put(envelope) delivered_envelope = self.multiplexer.get(block=True, timeout=20) assert delivered_envelope is not None assert delivered_envelope.to == envelope.to assert delivered_envelope.sender == envelope.sender assert (delivered_envelope.protocol_specification_id == envelope.protocol_specification_id) assert delivered_envelope.message_bytes == envelope.message_bytes self.multiplexer_relay.disconnect() self.change_state_and_wait(self.multiplexer_relay, expected_is_connected=False) # currently, multiplexer cannot be restarted self.multiplexer_relay = Multiplexer([self.relay], protocols=[DefaultMessage]) self.multiplexer_relay.connect() self.change_state_and_wait(self.multiplexer_relay, expected_is_connected=True) self.multiplexers.append(self.multiplexer_relay) msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"helloAfterRestart", ) envelope = Envelope( to=addr_2, sender=addr_1, protocol_specification_id=DefaultMessage.protocol_specification_id, message=DefaultSerializer().encode(msg), ) self.multiplexer_genesis.put(envelope) delivered_envelope = self.multiplexer.get(block=True, timeout=20) assert delivered_envelope is not None assert delivered_envelope.to == envelope.to assert delivered_envelope.sender == envelope.sender assert (delivered_envelope.protocol_specification_id == envelope.protocol_specification_id) assert delivered_envelope.message_bytes == envelope.message_bytes def test_envelope_routed_from_client_after_relay_restart(self): """Test envelope routed from third relay client after relay restart.""" addr_1 = self.connection.address addr_2 = self.connection2.address msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) envelope = Envelope( to=addr_1, sender=addr_2, protocol_specification_id=DefaultMessage.protocol_specification_id, message=DefaultSerializer().encode(msg), ) self.multiplexer2.put(envelope) delivered_envelope = self.multiplexer.get(block=True, timeout=20) assert delivered_envelope is not None assert delivered_envelope.to == envelope.to assert delivered_envelope.sender == envelope.sender assert (delivered_envelope.protocol_specification_id == envelope.protocol_specification_id) assert delivered_envelope.message_bytes == envelope.message_bytes self.multiplexer_relay.disconnect() self.change_state_and_wait(self.multiplexer_relay, expected_is_connected=False) # currently, multiplexer cannot be restarted self.multiplexer_relay = Multiplexer([self.relay], protocols=[DefaultMessage]) self.multiplexer_relay.connect() self.change_state_and_wait(self.multiplexer_relay, expected_is_connected=True) self.multiplexers.append(self.multiplexer_relay) msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"helloAfterRestart", ) envelope = Envelope( to=addr_1, sender=addr_2, protocol_specification_id=DefaultMessage.protocol_specification_id, message=DefaultSerializer().encode(msg), ) time.sleep(5) self.multiplexer2.put(envelope) delivered_envelope = self.multiplexer.get(block=True, timeout=20) assert delivered_envelope is not None assert delivered_envelope.to == envelope.to assert delivered_envelope.sender == envelope.sender assert (delivered_envelope.protocol_specification_id == envelope.protocol_specification_id) assert delivered_envelope.message_bytes == envelope.message_bytes
class TestLibp2pConnectionAgentMobility(BaseTestLibp2pRelay): """Test that connection will correctly route envelope to destination that changed its peer""" @libp2p_log_on_failure def setup(self): """Set the test up""" super().setup() temp_dir_gen = os.path.join(self.t, "temp_dir_gen") os.mkdir(temp_dir_gen) self.genesis = _make_libp2p_connection(data_dir=temp_dir_gen, port=DEFAULT_PORT) self.multiplexer_genesis = Multiplexer([self.genesis], protocols=[DefaultMessage]) self.log_files.append(self.genesis.node.log_file) self.multiplexer_genesis.connect() self.multiplexers.append(self.multiplexer_genesis) genesis_peer = self.genesis.node.multiaddrs[0] temp_dir_1 = os.path.join(self.t, "temp_dir_1") os.mkdir(temp_dir_1) self.connection1 = _make_libp2p_connection(data_dir=temp_dir_1, port=DEFAULT_PORT + 1, entry_peers=[genesis_peer]) self.multiplexer1 = Multiplexer([self.connection1], protocols=[DefaultMessage]) self.log_files.append(self.connection1.node.log_file) self.multiplexer1.connect() self.multiplexers.append(self.multiplexer1) self.connection_key = make_crypto(DEFAULT_LEDGER) temp_dir_2 = os.path.join(self.t, "temp_dir_2") os.mkdir(temp_dir_2) self.connection2 = _make_libp2p_connection( data_dir=temp_dir_2, port=DEFAULT_PORT + 2, entry_peers=[genesis_peer], agent_key=self.connection_key, ) self.multiplexer2 = Multiplexer([self.connection2], protocols=[DefaultMessage]) self.log_files.append(self.connection2.node.log_file) self.multiplexer2.connect() self.multiplexers.append(self.multiplexer2) def test_connection_is_established(self): """Test connection established.""" assert self.connection1.is_connected is True assert self.connection2.is_connected is True def test_envelope_routed_after_peer_changed(self): """Test envelope routed after peer changed.""" addr_1 = self.connection1.address addr_2 = self.connection2.address msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) envelope = Envelope( to=addr_2, sender=addr_1, protocol_specification_id=DefaultMessage.protocol_specification_id, message=DefaultSerializer().encode(msg), ) self.multiplexer1.put(envelope) delivered_envelope = self.multiplexer2.get(block=True, timeout=20) assert delivered_envelope is not None assert delivered_envelope.to == envelope.to assert delivered_envelope.sender == envelope.sender assert (delivered_envelope.protocol_specification_id == envelope.protocol_specification_id) assert delivered_envelope.message_bytes == envelope.message_bytes self.multiplexer2.disconnect() self.change_state_and_wait(self.multiplexer2, expected_is_connected=False) # currently, multiplexer cannot be restarted self.multiplexer2 = Multiplexer([self.connection2], protocols=[DefaultMessage]) self.multiplexer2.connect() self.change_state_and_wait(self.multiplexer2, expected_is_connected=True) self.multiplexers.append(self.multiplexer2) msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"helloAfterChangingPeer", ) envelope = Envelope( to=addr_2, sender=addr_1, protocol_specification_id=msg.protocol_specification_id, message=msg.encode(), ) self.multiplexer1.put(envelope) delivered_envelope = self.multiplexer2.get(block=True, timeout=20) assert delivered_envelope is not None assert delivered_envelope.to == envelope.to assert delivered_envelope.sender == envelope.sender assert (delivered_envelope.protocol_specification_id == envelope.protocol_specification_id) assert delivered_envelope.message_bytes == envelope.message_bytes