def test_drop_messages_from_outbox(self): """Test the drop_messages_from_outbox method.""" assert self.get_quantity_in_outbox() == 0 self.drop_messages_from_outbox(5) assert self.get_quantity_in_outbox() == 0 dummy_message_1 = DefaultMessage( performative=DefaultMessage.Performative.BYTES, content="dummy_2") dummy_message_1.to = "some_to_1" dummy_message_1.sender = "some_sender_1" self.skill.skill_context.outbox.put_message(dummy_message_1) dummy_message_2 = DefaultMessage( performative=DefaultMessage.Performative.BYTES, content="dummy_2") dummy_message_2.to = "some_to_2" dummy_message_2.sender = "some_sender_2" self.skill.skill_context.outbox.put_message(dummy_message_2) dummy_message_3 = DefaultMessage( performative=DefaultMessage.Performative.BYTES, content="dummy_2") dummy_message_3.to = "some_to_3" dummy_message_3.sender = "some_sender_3" self.skill.skill_context.outbox.put_message(dummy_message_3) assert self.get_quantity_in_outbox() == 3 self.drop_messages_from_outbox(2) assert self.get_quantity_in_outbox() == 1 assert self.get_message_from_outbox() == dummy_message_3
def test_communication_server_client(self): """Test that envelopes can be sent from a server to a client.""" msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) expected_envelope = Envelope( to=self.client_addr_1, sender=self.server_addr, message=msg, ) self.server_multiplexer.put(expected_envelope) actual_envelope = self.client_1_multiplexer.get(block=True, timeout=5.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) assert expected_envelope.message != actual_envelope.message msg = DefaultMessage.serializer.decode(actual_envelope.message) msg.to = actual_envelope.to msg.sender = actual_envelope.sender assert expected_envelope.message == msg msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) expected_envelope = Envelope( to=self.client_addr_2, sender=self.server_addr, message=msg, ) self.server_multiplexer.put(expected_envelope) actual_envelope = self.client_2_multiplexer.get(block=True, timeout=5.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) assert expected_envelope.message != actual_envelope.message msg = DefaultMessage.serializer.decode(actual_envelope.message) msg.to = actual_envelope.to msg.sender = actual_envelope.sender assert expected_envelope.message == msg
def test_outbox_put(): """Tests that an envelope is putted into the queue.""" agent_address = "Agent0" receiver_address = "Agent1" msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) msg.to = receiver_address msg.sender = agent_address dummy_connection = _make_dummy_connection() multiplexer = Multiplexer([dummy_connection]) outbox = OutBox(multiplexer) inbox = InBox(multiplexer) multiplexer.connect() envelope = Envelope( to=receiver_address, sender=agent_address, message=msg, ) outbox.put(envelope) wait_for_condition(lambda: inbox.empty(), 15, "Inbox must not be empty after putting an envelope") multiplexer.disconnect()
def test_envelope_routed(self): """Test envelope routed.""" addr_1 = self.connection1.node.address addr_2 = self.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, ) 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_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
def send_unsupported_protocol(self, envelope: Envelope) -> None: """ Handle the received envelope in case the protocol is not supported. :param envelope: the envelope :return: None """ self.context.logger.warning( "Unsupported protocol: {}. You might want to add a handler for this protocol." .format(envelope.protocol_specification_id)) encoded_protocol_specification_id = base64.b85encode( str.encode(str(envelope.protocol_specification_id))) encoded_envelope = base64.b85encode(envelope.encode()) reply = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.ERROR, error_code=DefaultMessage.ErrorCode.UNSUPPORTED_PROTOCOL, error_msg="Unsupported protocol.", error_data={ "protocol_id": encoded_protocol_specification_id, "envelope": encoded_envelope, }, ) reply.sender = self.context.agent_address reply.to = envelope.sender self.context.outbox.put_message(message=reply)
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 send_unsupported_skill(self, envelope: Envelope) -> None: """ Handle the received envelope in case the skill is not supported. :param envelope: the envelope :return: None """ if envelope.skill_id is None: self.context.logger.warning( "Cannot handle envelope: no active handler registered for the protocol_specification_id='{}'." .format(envelope.protocol_specification_id)) else: self.context.logger.warning( "Cannot handle envelope: no active handler registered for the protocol_specification_id='{}' and skill_id='{}'." .format(envelope.protocol_specification_id, envelope.skill_id)) encoded_envelope = base64.b85encode(envelope.encode()) reply = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.ERROR, error_code=DefaultMessage.ErrorCode.UNSUPPORTED_SKILL, error_msg="Unsupported skill.", error_data={"envelope": encoded_envelope}, ) reply.sender = self.context.agent_address reply.to = envelope.sender self.context.outbox.put_message(message=reply)
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_get_message_from_outbox(self): """Test the get_message_from_outbox method.""" assert self.get_message_from_outbox() is None dummy_message_1 = DefaultMessage( performative=DefaultMessage.Performative.BYTES, content="dummy_1") dummy_message_1.to = "some_to_1" dummy_message_1.sender = "some_sender_1" self.skill.skill_context.outbox.put_message(dummy_message_1) dummy_message_2 = DefaultMessage( performative=DefaultMessage.Performative.BYTES, content="dummy_2") dummy_message_2.to = "some_to_2" dummy_message_2.sender = "some_sender_2" self.skill.skill_context.outbox.put_message(dummy_message_2) assert self.get_message_from_outbox() == dummy_message_1 assert self.get_message_from_outbox() == dummy_message_2
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_get_quantity_in_outbox(self): """Test the get_quantity_in_outbox method.""" assert self.get_quantity_in_outbox() == 0 dummy_message = DefaultMessage( performative=DefaultMessage.Performative.BYTES, content="dummy") dummy_message.to = "some_to" dummy_message.sender = "some_sender" self.skill.skill_context.outbox.put_message(dummy_message) assert self.get_quantity_in_outbox() == 1
def test_react(): """Tests income messages.""" with LocalNode() as node: agent_name = "MyAgent" private_key_path = os.path.join(CUR_PATH, "data", DEFAULT_PRIVATE_KEY_FILE) builder = AEABuilder() builder.set_name(agent_name) builder.add_private_key(DEFAULT_LEDGER, private_key_path) builder.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")) builder.add_connection( Path(ROOT_DIR, "packages", "fetchai", "connections", "local")) local_connection_id = OEFLocalConnection.connection_id builder.set_default_connection(local_connection_id) builder.add_skill(Path(CUR_PATH, "data", "dummy_skill")) agent = builder.build(connection_ids=[local_connection_id]) # This is a temporary workaround to feed the local node to the OEF Local connection # TODO remove it. local_connection = agent.resources.get_connection(local_connection_id) local_connection._local_node = node msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) msg.to = agent.identity.address msg.sender = agent.identity.address envelope = Envelope( to=msg.to, sender=msg.sender, protocol_id=msg.protocol_id, message=msg, ) with run_in_thread(agent.start, timeout=20, on_exit=agent.stop): wait_for_condition(lambda: agent.is_running, timeout=20) agent.outbox.put(envelope) default_protocol_public_id = DefaultMessage.protocol_id dummy_skill_public_id = DUMMY_SKILL_PUBLIC_ID handler = agent.resources.get_handler(default_protocol_public_id, dummy_skill_public_id) assert handler is not None, "Handler is not set." wait_for_condition( lambda: len(handler.handled_messages) > 0, timeout=20, error_msg="The message is not inside the handled_messages.", )
def make_test_envelope(to_="any", sender_="sender") -> Envelope: """Create a test envelope.""" msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) msg.to = to_ msg.sender = sender_ envelope = Envelope( to=to_, sender=sender_, protocol_id=DefaultMessage.protocol_id, message=msg, ) return envelope
def test_assert_quantity_in_outbox(self): """Test the assert_quantity_in_outbox method.""" with pytest.raises( AssertionError, match= f"Invalid number of messages in outbox. Expected {1}. Found {0}.", ): self.assert_quantity_in_outbox(1) dummy_message = DefaultMessage( performative=DefaultMessage.Performative.BYTES, content="dummy") dummy_message.to = "some_to" dummy_message.sender = "some_sender" self.skill.skill_context.outbox.put_message(dummy_message) self.assert_quantity_in_outbox(1)
def test_assert_quantity_in_decision_making_queue(self): """Test the assert_quantity_in_decision_making_queue method.""" with pytest.raises( AssertionError, match= f"Invalid number of messages in decision maker queue. Expected {1}. Found {0}.", ): self.assert_quantity_in_decision_making_queue(1) dummy_message = DefaultMessage( performative=DefaultMessage.Performative.BYTES, content="dummy_1") dummy_message.to = "some_to_1" dummy_message.sender = "some_sender_1" self.skill.skill_context.decision_maker_message_queue.put( dummy_message) self.assert_quantity_in_decision_making_queue(1)
def test_send_message(self): """Test that the messages in the outbox are posted on the output 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, ) self.multiplexer.put(expected_envelope) time.sleep(0.1) with open(self.output_file_path, "rb+") as f: lines = f.readlines() assert len(lines) == 2 line = lines[0] + lines[1] to, sender, protocol_specification_id, message, end = line.strip( ).split("{}".format(SEPARATOR).encode("utf-8"), maxsplit=4) to = to.decode("utf-8") sender = sender.decode("utf-8") protocol_specification_id = PublicId.from_str( protocol_specification_id.decode("utf-8")) assert end in [b"", b"\n"] actual_envelope = Envelope( to=to, sender=sender, protocol_specification_id=protocol_specification_id, message=message, ) 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_storage_access_from_handler(): """Test storage access from handler component.""" builder = AEABuilder() builder.set_name("aea_1") builder.add_private_key(DEFAULT_LEDGER) skill_context = SkillContext() handler = THandler(name="behaviour", skill_context=skill_context) test_skill = Skill( SkillConfig(name="test_skill", author="fetchai"), skill_context=skill_context, handlers={"handler": handler}, behaviours={}, ) builder.add_component_instance(test_skill) builder.set_storage_uri("sqlite://:memory:") aea = builder.build() skill_context.set_agent_context(aea.context) aea.runtime._threaded = True aea.runtime.start() msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) msg.to = aea.identity.address msg.sender = aea.identity.address envelope = Envelope(to=msg.to, sender=msg.sender, message=msg,) try: wait_for_condition(lambda: aea.is_running, timeout=10) aea.runtime.multiplexer.in_queue.put(envelope) wait_for_condition(lambda: handler.counter > 0, timeout=10) col = skill_context.storage.get_sync_collection(handler.COL_NAME) assert col.get(handler.OBJ_ID) == handler.OBJ_BODY finally: aea.runtime.stop() aea.runtime.wait_completed(sync=True, timeout=10)
async def test_threaded_mode(): """Test InBox OutBox objects in threaded mode.""" connection_1 = _make_dummy_connection() connections = [connection_1] multiplexer = AsyncMultiplexer(connections, threaded=True) msg = DefaultMessage( performative=DefaultMessage.Performative.BYTES, content=b"", ) msg.to = "to" msg.sender = "sender" context = EnvelopeContext(connection_id=connection_1.connection_id) envelope = Envelope( to="to", sender="sender", message=msg, context=context, ) try: await multiplexer.connect() await asyncio.sleep(0.5) inbox = InBox(multiplexer) outbox = OutBox(multiplexer) assert inbox.empty() assert outbox.empty() outbox.put(envelope) received = await inbox.async_get() assert received == envelope assert inbox.empty() assert outbox.empty() outbox.put_message(msg, context=context) await inbox.async_wait() received = inbox.get_nowait() assert received == envelope finally: await multiplexer.disconnect()
def test_outbox_put_message(): """Tests that an envelope is created from the message is in the queue.""" agent_address = "Agent0" receiver_address = "Agent1" msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) msg.to = receiver_address msg.sender = agent_address dummy_connection = _make_dummy_connection() multiplexer = Multiplexer([dummy_connection]) outbox = OutBox(multiplexer) inbox = InBox(multiplexer) multiplexer.connect() outbox.put_message(msg) time.sleep(0.5) assert not inbox.empty( ), "Inbox will not be empty after putting a message." multiplexer.disconnect()
def send_decoding_error(self, envelope: Envelope) -> None: """ Handle a decoding error. :param envelope: the envelope :return: None """ self.context.logger.warning( "Decoding error for envelope: {}. Protocol_id='{}' and message='{!r}' are inconsistent." .format(envelope, envelope.protocol_id, envelope.message)) encoded_envelope = base64.b85encode(envelope.encode()) reply = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.ERROR, error_code=DefaultMessage.ErrorCode.DECODING_ERROR, error_msg="Decoding error.", error_data={"envelope": encoded_envelope}, ) reply.sender = self.context.agent_address reply.to = envelope.sender self.context.outbox.put_message(message=reply)
def test_star_routing_connectivity(self): """Test star routing connectivity.""" addrs = [conn.node.address for conn in self.connections] for source in range(len(self.multiplexers)): for destination in range(len(self.multiplexers)): if destination == source: continue msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) envelope = Envelope( to=addrs[destination], sender=addrs[source], protocol_id=DefaultMessage.protocol_id, message=msg, ) self.multiplexers[source].put(envelope) delivered_envelope = self.multiplexers[destination].get( block=True, timeout=10) 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.sender = delivered_envelope.sender msg.to = delivered_envelope.to assert envelope.message == msg
def test_communication_indirect(self): """Test communication indirect.""" assert (len(PUBLIC_DHT_DELEGATE_URIS) > 1), "Test requires at least 2 public dht node" for i in range(len(PUBLIC_DHT_DELEGATE_URIS)): multiplexers = [] try: connection1 = _make_libp2p_client_connection( uri=PUBLIC_DHT_DELEGATE_URIS[i]) multiplexer1 = Multiplexer([connection1]) multiplexer1.connect() multiplexers.append(multiplexer1) addr_1 = connection1.address 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() multiplexers.append(multiplexer2) 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) 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 multiplexer2.disconnect() del multiplexers[-1] except Exception: raise finally: for mux in multiplexers: mux.disconnect()
def test_initialize_aea_programmatically(): """Test that we can initialize an AEA programmatically.""" with LocalNode() as node: agent_name = "MyAgent" private_key_path = os.path.join(CUR_PATH, "data", DEFAULT_PRIVATE_KEY_FILE) builder = AEABuilder() builder.set_name(agent_name) builder.add_private_key(DEFAULT_LEDGER, private_key_path) builder.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")) builder.add_connection( Path(ROOT_DIR, "packages", "fetchai", "connections", "local")) local_connection_id = OEFLocalConnection.connection_id builder.set_default_connection(local_connection_id) builder.add_skill(Path(CUR_PATH, "data", "dummy_skill")) aea = builder.build(connection_ids=[local_connection_id]) local_connection = aea.resources.get_connection(local_connection_id) local_connection._local_node = node expected_message = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) expected_message.to = aea.identity.address expected_message.sender = aea.identity.address envelope = Envelope( to=expected_message.to, sender=expected_message.sender, protocol_id=expected_message.protocol_id, message=expected_message, ) with run_in_thread(aea.start, timeout=5, on_exit=aea.stop): wait_for_condition(lambda: aea.is_running, timeout=10) aea.outbox.put(envelope) dummy_skill_id = DUMMY_SKILL_PUBLIC_ID dummy_behaviour_name = "dummy" dummy_behaviour = aea.resources.get_behaviour( dummy_skill_id, dummy_behaviour_name) wait_for_condition(lambda: dummy_behaviour is not None, timeout=10) wait_for_condition(lambda: dummy_behaviour.nb_act_called > 0, timeout=10) # TODO the previous code caused an error: # _pickle.PicklingError: Can't pickle <class 'tasks.DummyTask'>: import of module 'tasks' failed dummy_task = DummyTask() task_id = aea.enqueue_task(dummy_task) async_result = aea.get_task_result(task_id) expected_dummy_task = async_result.get(10.0) wait_for_condition( lambda: expected_dummy_task.nb_execute_called > 0, timeout=10) dummy_handler = aea.resources.get_handler( DefaultMessage.protocol_id, dummy_skill_id) dummy_handler_alt = aea.resources._handler_registry.fetch( (dummy_skill_id, "dummy")) wait_for_condition(lambda: dummy_handler == dummy_handler_alt, timeout=10) wait_for_condition(lambda: dummy_handler is not None, timeout=10) wait_for_condition( lambda: len(dummy_handler.handled_messages) == 1, timeout=10) wait_for_condition( lambda: dummy_handler.handled_messages[0] == expected_message, timeout=10, )
def test_initialize_aea_programmatically_build_resources(): """Test that we can initialize the agent by building the resource object.""" try: temp = tempfile.mkdtemp(prefix="test_aea_resources") with LocalNode() as node: agent_name = "MyAgent" private_key_path = os.path.join(CUR_PATH, "data", DEFAULT_PRIVATE_KEY_FILE) wallet = Wallet({DEFAULT_LEDGER: private_key_path}) identity = Identity(agent_name, address=wallet.addresses[DEFAULT_LEDGER]) connection = _make_local_connection(agent_name, node) resources = Resources() aea = AEA( identity, wallet, resources=resources, default_connection=connection.public_id, ) default_protocol = Protocol.from_dir( str(Path("packages", "fetchai", "protocols", "default"))) resources.add_protocol(default_protocol) resources.add_connection(connection) error_skill = Skill.from_dir( str(Path("packages", "fetchai", "skills", "error")), agent_context=aea.context, ) dummy_skill = Skill.from_dir(str( Path(CUR_PATH, "data", "dummy_skill")), agent_context=aea.context) resources.add_skill(dummy_skill) resources.add_skill(error_skill) default_protocol_id = DefaultMessage.protocol_id expected_message = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) expected_message.to = agent_name expected_message.sender = agent_name with run_in_thread(aea.start, timeout=5, on_exit=aea.stop): wait_for_condition(lambda: aea.is_running, timeout=10) aea.outbox.put( Envelope( to=agent_name, sender=agent_name, protocol_id=default_protocol_id, message=expected_message, )) dummy_skill_id = DUMMY_SKILL_PUBLIC_ID dummy_behaviour_name = "dummy" dummy_behaviour = aea.resources.get_behaviour( dummy_skill_id, dummy_behaviour_name) wait_for_condition(lambda: dummy_behaviour is not None, timeout=10) wait_for_condition(lambda: dummy_behaviour.nb_act_called > 0, timeout=10) dummy_task = DummyTask() task_id = aea.enqueue_task(dummy_task) async_result = aea.get_task_result(task_id) expected_dummy_task = async_result.get(10.0) wait_for_condition( lambda: expected_dummy_task.nb_execute_called > 0, timeout=10) dummy_handler_name = "dummy" dummy_handler = aea.resources._handler_registry.fetch( (dummy_skill_id, dummy_handler_name)) dummy_handler_alt = aea.resources.get_handler( DefaultMessage.protocol_id, dummy_skill_id) wait_for_condition(lambda: dummy_handler == dummy_handler_alt, timeout=10) wait_for_condition(lambda: dummy_handler is not None, timeout=10) wait_for_condition( lambda: len(dummy_handler.handled_messages) == 1, timeout=10) wait_for_condition( lambda: dummy_handler.handled_messages[0] == expected_message, timeout=10, ) finally: Path(temp).rmdir()
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_handle(): """Tests handle method of an agent.""" with LocalNode() as node: agent_name = "MyAgent" private_key_path = os.path.join(CUR_PATH, "data", DEFAULT_PRIVATE_KEY_FILE) builder = AEABuilder() builder.set_name(agent_name) builder.add_private_key(DEFAULT_LEDGER, private_key_path) builder.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")) builder.add_connection( Path(ROOT_DIR, "packages", "fetchai", "connections", "local")) local_connection_id = OEFLocalConnection.connection_id builder.set_default_connection(local_connection_id) builder.add_skill(Path(CUR_PATH, "data", "dummy_skill")) aea = builder.build(connection_ids=[local_connection_id]) # This is a temporary workaround to feed the local node to the OEF Local connection # TODO remove it. local_connection = aea.resources.get_connection(local_connection_id) local_connection._local_node = node msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) msg.to = aea.identity.address msg.sender = aea.identity.address encoded_msg = DefaultSerializer.encode(msg) envelope = Envelope( to=msg.to, sender=msg.sender, protocol_id=UNKNOWN_PROTOCOL_PUBLIC_ID, message=msg, ) with run_in_thread(aea.start, timeout=5): wait_for_condition(lambda: aea.is_running, timeout=10) dummy_skill = aea.resources.get_skill(DUMMY_SKILL_PUBLIC_ID) dummy_handler = dummy_skill.handlers["dummy"] aea.outbox.put(envelope) wait_for_condition( lambda: len(dummy_handler.handled_messages) == 1, timeout=1, ) # DECODING ERROR envelope = Envelope( to=aea.identity.address, sender=aea.identity.address, protocol_id=DefaultMessage.protocol_id, message=b"", ) # send envelope via localnode back to agent/bypass `outbox` put consistency checks aea.outbox._multiplexer.put(envelope) """ inbox twice cause first message is invalid. generates error message and it accepted """ wait_for_condition( lambda: len(dummy_handler.handled_messages) == 2, timeout=1, ) # UNSUPPORTED SKILL msg = FipaMessage( performative=FipaMessage.Performative.ACCEPT, message_id=1, dialogue_reference=(str(0), ""), target=0, ) msg.to = aea.identity.address msg.sender = aea.identity.address envelope = Envelope( to=msg.to, sender=msg.sender, protocol_id=msg.protocol_id, message=msg, ) # send envelope via localnode back to agent aea.outbox.put(envelope) wait_for_condition( lambda: len(dummy_handler.handled_messages) == 3, timeout=2, ) # DECODING OK envelope = Envelope( to=msg.to, sender=msg.sender, protocol_id=DefaultMessage.protocol_id, message=encoded_msg, ) # send envelope via localnode back to agent/bypass `outbox` put consistency checks aea.outbox._multiplexer.put(envelope) wait_for_condition( lambda: len(dummy_handler.handled_messages) == 4, timeout=1, ) aea.stop()