def test_error_decoding_error(self): """Test the decoding error.""" self.my_aea._inbox._history = [] msg = FipaMessage( message_id=1, dialogue_reference=(str(0), ""), target=0, performative=FipaMessage.Performative.ACCEPT, ) msg.counterparty = self.address envelope = Envelope( to=self.address, sender=self.address, protocol_id=DefaultMessage.protocol_id, message=msg, ) self.my_error_handler.send_decoding_error(envelope) wait_for_condition(lambda: len(self.my_aea._inbox._history) >= 1, timeout=5) envelope = self.my_aea._inbox._history[-1] msg = envelope.message assert msg.performative == DefaultMessage.Performative.ERROR assert msg.error_code == DefaultMessage.ErrorCode.DECODING_ERROR
def test_storage_access_from_behaviour(): """Test storage access from behaviour component.""" builder = AEABuilder() builder.set_name("aea_1") builder.add_private_key(DEFAULT_LEDGER) skill_context = SkillContext() behaviour = TBehaviour(name="behaviour", skill_context=skill_context) test_skill = Skill( SkillConfig(name="test_skill", author="fetchai"), skill_context=skill_context, handlers={}, behaviours={"behaviour": behaviour}, ) 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() try: wait_for_condition(lambda: aea.is_running, timeout=10) wait_for_condition(lambda: behaviour.counter > 0, timeout=10) col = skill_context.storage.get_sync_collection(behaviour.COL_NAME) assert col.get(behaviour.OBJ_ID) == behaviour.OBJ_BODY finally: aea.runtime.stop() aea.runtime.wait_completed(sync=True, timeout=10)
def test_error_unsupported_skill(self): """Test the unsupported skill.""" msg = FipaMessage( message_id=1, dialogue_reference=(str(0), ""), target=0, performative=FipaMessage.Performative.ACCEPT, ) msg.counterparty = self.address msg.sender = self.address envelope = Envelope( to=msg.counterparty, sender=msg.sender, protocol_id=msg.protocol_id, message=msg, ) self.my_error_handler.send_unsupported_skill(envelope=envelope) wait_for_condition(lambda: len(self.my_aea._inbox._history) >= 1, timeout=5) envelope = self.my_aea._inbox._history[-1] msg = envelope.message assert msg.performative == DefaultMessage.Performative.ERROR assert msg.error_code == DefaultMessage.ErrorCode.UNSUPPORTED_SKILL
def setup(self): """Test the initialisation of the AEA.""" private_key_path = os.path.join(CUR_PATH, "data", DEFAULT_PRIVATE_KEY_FILE) self.wallet = Wallet({DEFAULT_LEDGER: private_key_path}) self.agent_name = "Agent0" self.connection = _make_dummy_connection() self.identity = Identity(self.agent_name, address=self.wallet.addresses[DEFAULT_LEDGER]) self.address = self.identity.address self.my_aea = AEA( self.identity, self.wallet, timeout=0.1, resources=Resources(), default_connection=self.connection.public_id, ) self.my_aea.resources.add_connection(self.connection) self.my_aea._inbox = InboxWithHistory(self.my_aea.multiplexer) self.skill_context = SkillContext(self.my_aea._context) logger_name = "aea.{}.skills.{}.{}".format( self.my_aea._context.agent_name, "fetchai", "error") self.skill_context._logger = logging.getLogger(logger_name) self.my_error_handler = ErrorHandler(name="error", skill_context=self.skill_context) self.t = Thread(target=self.my_aea.start) self.t.start() wait_for_condition( lambda: self.my_aea._main_loop and self.my_aea._main_loop. is_running, 10)
def test_run_agent(): """Test that we can set up and then run the agent.""" with LocalNode() as node: agent_name = "dummyagent" agent_address = "some_address" identity = Identity(agent_name, address=agent_address) oef_local_connection = _make_local_connection(agent_address, node) oef_local_connection._local_node = node agent = DummyAgent(identity, [oef_local_connection], loop=asyncio.new_event_loop()) agent_thread = Thread(target=agent.start) assert agent.state == RuntimeStates.stopped agent_thread.start() try: wait_for_condition( lambda: agent.state == RuntimeStates.starting, timeout=10, error_msg="Agent state must be 'starting'", ) wait_for_condition( lambda: agent.state == RuntimeStates.running, timeout=10, error_msg="Agent state must be 'running'", ) finally: agent.stop() assert agent.state == RuntimeStates.stopped agent_thread.join()
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()
async def test_wrong_dialogue(self): """Test that at the beginning, the search request returns an empty search result.""" query = Query(constraints=[Constraint("foo", ConstraintType("==", 1))], model=None) # build and send the request search_services_request = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, message_id=2, target=1, dialogue_reference=self.dialogues. new_self_initiated_dialogue_reference(), query=query, ) search_services_request.to = str(OEFLocalConnection.connection_id) # the incorrect message cannot be sent into a dialogue, so this is omitted. search_services_request.sender = self.address_1 envelope = Envelope( to=search_services_request.to, sender=search_services_request.sender, message=search_services_request, ) with unittest.mock.patch.object( self.node, "_handle_oef_message", side_effect=self.node._handle_oef_message) as mock_handle: with unittest.mock.patch.object(self.node.logger, "warning") as mock_logger: self.multiplexer.put(envelope) wait_for_condition(lambda: mock_handle.called, timeout=1.0) mock_logger.assert_any_call( AnyStringWith("Could not create dialogue for message="))
def test_start_stop(self): """Test agents started stopped.""" runner = AEARunner([self.aea1, self.aea2], self.RUNNER_MODE) runner.start(True) wait_for_condition(lambda: runner.is_running, timeout=5) time.sleep(1) runner.stop() assert not runner.is_running
def test_stop_policy(self): """Test stop multiplexer on exception.""" with patch.object(self.connection, "send", side_effect=self.exception): self.multiplexer._exception_policy = ExceptionPolicyEnum.stop_and_exit self.multiplexer.put(self.envelope) time.sleep(1) wait_for_condition( lambda: self.multiplexer.connection_status.is_disconnected, timeout=5)
def test_agent_actually_running(self): """Test MultiAgentManager starts agent correctly and agent perform acts.""" self.test_add_agent() agent_alias = self.manager.get_agent_alias(self.agent_name) behaviour = agent_alias.agent.resources.get_behaviour( self.echo_skill_id, "echo") assert behaviour with patch.object(behaviour, "act") as act_mock: self.manager.start_all_agents() wait_for_condition(lambda: act_mock.call_count > 0, timeout=10)
def test_loop_start_stop(self): """Test loop start and stopped properly.""" agent_loop = self.AGENT_LOOP_CLASS(self.FAKE_AGENT_CLASS(), threaded=True) agent_loop.start() wait_for_condition(lambda: agent_loop.is_running, timeout=10) agent_loop.stop() agent_loop.wait_completed(sync=True) assert not agent_loop.is_running, agent_loop.state
def test_react(): """Tests income messages.""" with LocalNode() as node: agent_name = "MyAgent" private_key_path = os.path.join(CUR_PATH, "data", "fet_private_key.txt") builder = AEABuilder() builder.set_name(agent_name) builder.add_private_key(FETCHAI, private_key_path) builder.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")) builder.add_connection( Path(ROOT_DIR, "packages", "fetchai", "connections", "local")) builder.set_default_connection( PublicId.from_str("fetchai/local:0.1.0")) builder.add_skill(Path(CUR_PATH, "data", "dummy_skill")) agent = builder.build( connection_ids=[PublicId.from_str("fetchai/local:0.1.0")]) # This is a temporary workaround to feed the local node to the OEF Local connection # TODO remove it. list(agent._connections)[0]._local_node = node msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) msg.counterparty = agent.identity.address message_bytes = DefaultSerializer().encode(msg) envelope = Envelope( to=agent.identity.address, sender=agent.identity.address, protocol_id=DefaultMessage.protocol_id, message=message_bytes, ) with run_in_thread(agent.start, timeout=20, on_exit=agent.stop): wait_for_condition( lambda: agent._main_loop and agent._main_loop.is_running, timeout=10) 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: msg in handler.handled_messages, timeout=10, error_msg="The message is not inside the handled_messages.", ) agent.stop()
def test_propagate_policy(self): """Test propagate exception.""" assert self.multiplexer._exception_policy == ExceptionPolicyEnum.propagate with patch.object(self.connection, "send", side_effect=self.exception): self.multiplexer.put(self.envelope) time.sleep(1) wait_for_condition(lambda: self.multiplexer._send_loop_task.done(), timeout=5) assert self.multiplexer._send_loop_task.exception( ) == self.exception
def test_double_stop(self): """Test runtime double stop do nothing.""" self.runtime.start() wait_for_condition(lambda: self.runtime.is_running, timeout=20) self.runtime.stop() self.runtime.wait_completed(sync=True) assert self.runtime.is_stopped self.runtime.stop() self.runtime.wait_completed(sync=True) assert self.runtime.is_stopped
def test_handle_envelope(self): """Test one envelope handling.""" handler = CountHandler.make() agent = self.FAKE_AGENT_CLASS(handlers=[handler]) agent_loop = self.AGENT_LOOP_CLASS(agent) handler.setup() with run_in_thread(agent_loop.start, timeout=10): wait_for_condition(lambda: agent_loop.is_running, timeout=10) agent.put_inbox("msg") wait_for_condition(lambda: handler.counter == 1, timeout=2) agent_loop.stop()
def test_start_stop(self) -> None: """Test agents started stopped.""" try: runner = AEALauncher([self.agent_name_1, self.agent_name_2], self.RUNNER_MODE) runner.start(True) wait_for_condition(lambda: runner.is_running, timeout=10) assert runner.num_failed == 0 finally: runner.stop() assert not runner.is_running assert runner.num_failed == 0
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 test_new_behaviours(self): """Test new behaviours are added.""" agent = self.FAKE_AGENT_CLASS() agent_loop = self.AGENT_LOOP_CLASS(agent) agent_loop.NEW_BEHAVIOURS_PROCESS_SLEEP = 0.5 with run_in_thread(agent_loop.start, timeout=5): wait_for_condition(lambda: agent_loop.is_running, timeout=10) wait_for_condition( lambda: agent.filter._handle_new_behaviours.call_count >= 2, timeout=agent_loop.NEW_BEHAVIOURS_PROCESS_SLEEP * 3, ) agent_loop.stop()
def test_internal_messages(self): """Test internal meesages are processed.""" agent = self.FAKE_AGENT_CLASS() agent_loop = self.AGENT_LOOP_CLASS(agent) with run_in_thread(agent_loop.start, timeout=5): wait_for_condition(lambda: agent_loop.is_running, timeout=10) agent.put_internal_message("msg") wait_for_condition( lambda: agent.filter._process_internal_message.called is True, timeout=5, ) agent_loop.stop()
def test_start_stop(): """Tests the act function of the AEA.""" 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_skill(Path(CUR_PATH, "data", "dummy_skill")) agent = builder.build() with run_in_thread(agent.start, timeout=20): wait_for_condition(lambda: agent.is_running, timeout=20) agent.stop()
def test_stop_agent(self, *args): """Test stop agent.""" self.test_start_all() wait_for_condition(lambda: self.manager.list_agents(running_only=True), timeout=10) self.manager.stop_all_agents() assert not self.manager.list_agents(running_only=True) with pytest.raises(ValueError, match=" is not running!"): self.manager.stop_agent(self.agent_name) with pytest.raises(ValueError, match=" is not running!"): self.manager.stop_agents([self.agent_name])
def test_internal_messages(self): """Test internal meesages are processed.""" agent = self.FAKE_AGENT_CLASS() agent_loop = self.AGENT_LOOP_CLASS(agent, threaded=True) agent_loop.start() wait_for_condition(lambda: agent_loop.is_running, timeout=10) agent.put_internal_message("msg") wait_for_condition( lambda: agent.filter.handle_internal_message.called is True, timeout=5, ) agent_loop.stop() agent_loop.wait_completed(sync=True)
def test_remove_running_agent(self, *args): """Test fail on remove running agent.""" self.test_start_all() with pytest.raises(ValueError, match="Agent is running. stop it first!"): self.manager.remove_agent(self.agent_name) self.manager.stop_all_agents() wait_for_condition( lambda: self.agent_name not in self.manager.list_agents( running_only=True), timeout=5, ) self.manager.remove_agent(self.agent_name) assert self.agent_name not in self.manager.list_agents()
def test_start_stop(): """Tests the act function of the AEA.""" agent_name = "MyAgent" private_key_path = os.path.join(CUR_PATH, "data", "fet_private_key.txt") builder = AEABuilder() builder.set_name(agent_name) builder.add_private_key(FETCHAI, private_key_path) builder.add_skill(Path(CUR_PATH, "data", "dummy_skill")) agent = builder.build() with run_in_thread(agent.start, timeout=20): wait_for_condition( lambda: agent._main_loop and agent._main_loop.is_running, timeout=10) agent.stop()
def test_stop_with_stopped_exception(self): """Test runtime stopped by stopruntime exception.""" behaviour = self.agent.resources.get_behaviour(DUMMY_SKILL_PUBLIC_ID, "dummy") with patch.object( behaviour, "act", side_effect=_StopRuntime(reraise=ValueError("expected"))): self.runtime.start() wait_for_condition(lambda: self.runtime.is_running, timeout=20) time.sleep(1) assert self.runtime.is_stopped with pytest.raises(ValueError, match="expected"): self.runtime.wait_completed(timeout=10, sync=True)
def test_new_behaviours(self): """Test new behaviours are added.""" agent = self.FAKE_AGENT_CLASS() agent_loop = self.AGENT_LOOP_CLASS(agent, threaded=True) agent_loop.NEW_BEHAVIOURS_PROCESS_SLEEP = 0.5 agent_loop.start() wait_for_condition(lambda: agent_loop.is_running, timeout=10) wait_for_condition( lambda: agent.filter.handle_new_handlers_and_behaviours.call_count >= 2, timeout=agent_loop.NEW_BEHAVIOURS_PROCESS_SLEEP * 3, ) agent_loop.stop() agent_loop.wait_completed(sync=True)
def test_behaviour_act(self): """Test behaviour act called by schedule.""" tick_interval = 0.1 behaviour = CountBehaviour.make(tick_interval=tick_interval) behaviour.setup() agent = self.FAKE_AGENT_CLASS(behaviours=[behaviour]) agent_loop = self.AGENT_LOOP_CLASS(agent, threaded=True) agent_loop.start() wait_for_condition(lambda: agent_loop.is_running, timeout=10) wait_for_condition(lambda: behaviour.counter >= 1, timeout=tick_interval * 2) agent_loop.stop() agent_loop.wait_completed(sync=True)
def test_exception_handling(self): """Test erro callback works.""" self.test_add_agent() agent_alias = self.manager.get_agent_alias(self.agent_name) behaviour = agent_alias.agent.resources.get_behaviour( self.echo_skill_id, "echo") callback_mock = Mock() self.manager.add_error_callback(callback_mock) assert behaviour with patch.object(behaviour, "act", side_effect=ValueError("expected")): self.manager.start_all_agents() wait_for_condition(lambda: callback_mock.call_count > 0, timeout=10)
def test_run_agent(): """Test that we can set up and then run the agent.""" with LocalNode() as node: agent_name = "dummyagent" agent_address = "some_address" identity = Identity(agent_name, address=agent_address) oef_local_connection = _make_local_connection(agent_address, node) oef_local_connection._local_node = node agent = DummyAgent( identity, [oef_local_connection], ) assert agent.name == identity.name assert agent.tick == 0 assert (agent.agent_state == AgentState.INITIATED ), "Agent state must be 'initiated'" agent.multiplexer.connect() assert (agent.agent_state == AgentState.CONNECTED ), "Agent state must be 'connected'" assert isinstance(agent.inbox, InBox) assert isinstance(agent.outbox, OutBox) agent.multiplexer.disconnect() import asyncio agent = DummyAgent(identity, [oef_local_connection], loop=asyncio.new_event_loop()) agent_thread = Thread(target=agent.start) agent_thread.start() try: wait_for_condition( lambda: agent._main_loop and agent._main_loop.is_running, timeout=5, error_msg="Agent loop not started!'", ) wait_for_condition( lambda: agent.agent_state == AgentState.RUNNING, timeout=5, error_msg="Agent state must be 'running'", ) finally: agent.stop() agent_thread.join()
def test_behaviour_act(self): """Test behaviour act called by schedule.""" tick_interval = 0.1 behaviour = CountBehaviour.make(tick_interval=tick_interval) behaviour.setup() agent = self.FAKE_AGENT_CLASS(behaviours=[behaviour]) agent_loop = self.AGENT_LOOP_CLASS(agent) with run_in_thread(agent_loop.start, timeout=5): wait_for_condition(lambda: agent_loop.is_running, timeout=10) # test behaviour called wait_for_condition(lambda: behaviour.counter >= 1, timeout=tick_interval * 2) agent_loop.stop()