def test_unregister(): container = Container() container.reset() agent = make_connected_agent() agent2 = make_connected_agent(jid="agent2@server") assert container.has_agent(str(agent.jid)) assert container.has_agent(str(agent2.jid)) container.unregister(agent.jid) assert not container.has_agent(str(agent.jid)) assert container.has_agent(str(agent2.jid))
def test_send_message_to_outer_with_container(): class SendBehaviour(OneShotBehaviour): async def run(self): message = Message(to="to@outerhost") await self.send(message) self.kill() container = Container() container.reset() agent = make_connected_agent() agent.start(auto_register=False) behaviour = SendBehaviour() behaviour._xmpp_send = CoroutineMock() agent.add_behaviour(behaviour) behaviour.join() assert container.has_agent(str(agent.jid)) assert not container.has_agent("to@outerhost") assert behaviour._xmpp_send.await_count == 1 msg_arg = behaviour._xmpp_send.await_args[0][0] assert msg_arg.to == aioxmpp.JID.fromstr("to@outerhost") agent.stop()
def test_stop_agent_with_blocking_await(): agent1 = make_connected_agent() agent1.value = 1000 class StopBehav(OneShotBehaviour): async def run(self): await asyncio.sleep(0.5) await self.agent.stop() class DummyBehav(OneShotBehaviour): async def run(self): await self.receive(timeout=1000000) self.agent.value = 2000 stopbehah = StopBehav() dummybehav = DummyBehav() agent1.add_behaviour(dummybehav) agent1.add_behaviour(stopbehah) future1 = agent1.start(auto_register=False) future1.result() stopbehah.join() assert not agent1.is_alive() assert agent1.value == 1000
def test_fsm_bad_state(): class StateOne(State): async def run(self): self.set_next_state("BAD_STATE") self.kill() class StateTwo(State): async def run(self): pass class BadFSMBehaviour(FSMBehaviour): async def on_end(self): self.kill() fsm_ = BadFSMBehaviour() state_one = StateOne() state_two = StateTwo() fsm_.add_state(STATE_ONE, state_one, initial=True) fsm_.add_state(STATE_TWO, state_two) fsm_.add_transition(STATE_ONE, STATE_TWO) agent = make_connected_agent() agent.start(auto_register=False) assert fsm_.current_state == STATE_ONE agent.add_behaviour(fsm_) wait_for_behaviour_is_killed(state_one) assert fsm_.current_state == STATE_ONE wait_for_behaviour_is_killed(fsm_) assert fsm_.is_killed() agent.stop()
def test_join_inside_behaviour(): class Behav1(OneShotBehaviour): async def run(self): class Behav2(OneShotBehaviour): async def run(self): self.agent.behav2 = True behav2 = Behav2() self.agent.add_behaviour(behav2) await behav2.join() self.agent.behav1 = True agent = make_connected_agent() agent.behav1 = False agent.behav2 = False behav1 = Behav1() agent.add_behaviour(behav1) future = agent.start(auto_register=False) future.result() behav1.join() assert agent.behav1 assert agent.behav2 agent.stop()
def test_join_inside_behaviour_with_timeout(): class Behav1(OneShotBehaviour): async def run(self): class Behav2(OneShotBehaviour): async def run(self): await asyncio.sleep(1) behav2 = Behav2() self.agent.add_behaviour(behav2) with pytest.raises(TimeoutError): await behav2.join(timeout=0.001) self.agent.behav1 = True agent = make_connected_agent() agent.behav1 = False behav1 = Behav1() agent.add_behaviour(behav1) future = agent.start(auto_register=False) future.result() behav1.join() assert agent.behav1 agent.stop()
def test_set_exit_code_behaviour(): class TestCyclicBehaviour(CyclicBehaviour): async def run(self): self.exit_code = 1024 agent.event.wait() self.kill() agent = make_connected_agent() behaviour = TestCyclicBehaviour() agent.event = Event() agent.start(auto_register=False) agent.add_behaviour(behaviour) with pytest.raises(BehaviourNotFinishedException): assert behaviour.exit_code agent.event.set() wait_for_behaviour_is_killed(behaviour) agent.stop() assert behaviour.exit_code == 1024 assert not agent.is_alive()
def test_receive_with_timeout(): class RecvBehaviour(OneShotBehaviour): async def run(self): self.agent.recv_msg = await self.receive(5.0) self.kill() agent = make_connected_agent() msg = Message(body="received body") template = Template(body="received body") behaviour = RecvBehaviour() agent.add_behaviour(behaviour, template) assert behaviour.mailbox_size() == 0 agent.start(auto_register=False) agent._message_received(msg.prepare()) assert agent.is_alive() assert agent.has_behaviour(behaviour) wait_for_behaviour_is_killed(behaviour) assert agent.recv_msg.body == "received body" assert agent.recv_msg == msg agent.stop()
def test_fsm_behaviour(fsm): agent = make_connected_agent() agent.sync1_behaviour = asyncio.Event() agent.sync2_behaviour = asyncio.Event() agent.start(auto_register=False) assert len(fsm._transitions) == 2 assert fsm.current_state == STATE_ONE agent.add_behaviour(fsm) wait_for_behaviour_is_killed(fsm.state_one) assert fsm.current_state == STATE_ONE assert agent.state == STATE_ONE agent.loop.call_soon_threadsafe(agent.sync1_behaviour.set) wait_for_behaviour_is_killed(fsm.state_two) assert fsm.current_state == STATE_TWO assert agent.state == STATE_TWO agent.loop.call_soon_threadsafe(agent.sync2_behaviour.set) wait_for_behaviour_is_killed(fsm.state_three) assert fsm.current_state == STATE_THREE assert agent.state == STATE_THREE agent.stop()
def test_on_start_on_end(): class TestOneShotBehaviour(OneShotBehaviour): async def on_start(self): self.agent.on_start_flag = True async def run(self): pass async def on_end(self): self.agent.on_end_flag = True self.kill() agent = make_connected_agent() agent.on_start_flag = False agent.on_end_flag = False behaviour = TestOneShotBehaviour() agent.add_behaviour(behaviour) assert agent.on_start_flag is False assert agent.on_end_flag is False agent.start(auto_register=False) wait_for_behaviour_is_killed(behaviour) assert agent.on_start_flag is True assert agent.on_end_flag is True agent.stop()
def test_send_message(message): class SendBehaviour(OneShotBehaviour): async def run(self): await self.send(message) self.kill() agent = make_connected_agent() agent.start(auto_register=False) agent.aiothread.client = MagicMock() agent.client.send = CoroutineMock() behaviour = SendBehaviour() agent.add_behaviour(behaviour) wait_for_behaviour_is_killed(behaviour) assert agent.client.send.await_count == 1 msg_arg = agent.client.send.await_args[0][0] assert msg_arg.body[None] == "message body" assert msg_arg.to == aioxmpp.JID.fromstr("to@localhost") thread_found = False for data in msg_arg.xep0004_data: if data.title == SPADE_X_METADATA: for field in data.fields: if field.var == "_thread_node": assert field.values[0] == "thread-id" thread_found = True assert thread_found agent.stop()
def test_fsm_behaviour(fsm): agent = make_connected_agent() future = agent.start(auto_register=False) future.result() agent.sync1_behaviour = asyncio.Event(loop=agent.loop) agent.sync2_behaviour = asyncio.Event(loop=agent.loop) agent.state = None assert len(fsm._transitions) == 2 assert fsm.current_state == STATE_ONE agent.add_behaviour(fsm) assert fsm.current_state == STATE_ONE assert not fsm.state_one.is_done() wait_for_behaviour_is_killed(fsm.state_one) assert agent.state == STATE_ONE agent.loop.call_soon_threadsafe(agent.sync1_behaviour.set) fsm.state_one.join() assert fsm.current_state == STATE_TWO assert not fsm.state_two.is_done() wait_for_behaviour_is_killed(fsm.state_two) assert agent.state == STATE_TWO agent.loop.call_soon_threadsafe(agent.sync2_behaviour.set) fsm.state_two.join() assert fsm.current_state == STATE_THREE wait_for_behaviour_is_killed(fsm.state_three) assert agent.state == STATE_THREE fsm.state_three.join() agent.stop()
def test_create_agent_from_another_agent(): class DummyBehav(OneShotBehaviour): async def run(self): self.agent.done = True class CreateBehav(OneShotBehaviour): async def run(self): self.agent.agent2 = make_connected_agent(loop=self.agent.loop) self.agent.agent2.done = False self.agent.agent2.add_behaviour(DummyBehav()) await self.agent.agent2.async_start(auto_register=True) agent1 = make_connected_agent() agent1.agent2 = None agent1.add_behaviour(CreateBehav()) agent1.start(auto_register=False) while not agent1.agent2: time.sleep(0.01) assert agent1.agent2.is_alive() assert agent1.agent2.done agent1.agent2.stop() agent1.stop()
def test_receive_with_timeout(): class RecvBehaviour(OneShotBehaviour): async def run(self): self.agent.recv_msg = await self.receive(5.0) self.kill() agent = make_connected_agent() msg = Message(body="received body") template = Template(body="received body") behaviour = RecvBehaviour() agent.add_behaviour(behaviour, template) assert behaviour.mailbox_size() == 0 future = agent.start(auto_register=False) future.result() agent._message_received(msg.prepare()) assert agent.is_alive() assert agent.has_behaviour(behaviour) behaviour.join() assert agent.recv_msg.body == "received body" assert agent.recv_msg == msg agent.stop()
def test_client(): agent = make_connected_agent() assert agent.client is None future = agent.start() future.result() assert type(agent.client) == PresenceManagedClient
def test_send_message(message): class SendBehaviour(OneShotBehaviour): async def run(self): await self.send(message) self.kill() agent = make_connected_agent() future = agent.start(auto_register=False) future.result() agent.client = MagicMock() agent.client.send = CoroutineMock() behaviour = SendBehaviour() agent.add_behaviour(behaviour) behaviour.join() assert agent.client.send.await_count == 1 msg_arg = agent.client.send.await_args[0][0] assert msg_arg.body[None] == "message body" assert msg_arg.to == aioxmpp.JID.fromstr("to@localhost") thread_found = False for data in msg_arg.xep0004_data: if data.title == SPADE_X_METADATA: for field in data.fields: if field.var == "_thread_node": assert field.values[0] == "thread-id" thread_found = True assert thread_found agent.stop()
def test_create_agent_from_another_agent(): class DummyBehav(OneShotBehaviour): async def run(self): self.agent._done = True self.kill() class CreateBehav(OneShotBehaviour): async def run(self): self.agent.agent2 = make_connected_agent() self.agent.agent2._done = False self.agent.agent2.add_behaviour(DummyBehav()) await self.agent.agent2.start(auto_register=False) self.kill() agent1 = make_connected_agent() agent1.agent2 = None agent1.add_behaviour(CreateBehav()) future = agent1.start(auto_register=False) assert future.result() is None assert agent1.is_alive() agent1.behaviours[0].join() agent1.agent2.behaviours[0].join() assert agent1.agent2.is_alive() assert agent1.agent2._done agent1.agent2.stop() agent1.stop()
def test_timeout_behaviour_zero(): class TestTimeoutBehaviour(TimeoutBehaviour): async def run(self): self.agent.delay = datetime.datetime.now() self.kill() agent = make_connected_agent() future = agent.start(auto_register=False) future.result() start_at = datetime.datetime.now() + datetime.timedelta(seconds=0) behaviour = TestTimeoutBehaviour(start_at=start_at) assert behaviour._timeout == start_at assert not behaviour._timeout_triggered agent.add_behaviour(behaviour) behaviour.join() assert agent.delay >= start_at assert behaviour._timeout_triggered assert behaviour.is_done() agent.stop()
def test_check_server(): agent = make_connected_agent() agent.start(auto_register=False) port = random.randint(5000, 9999) agent.web.start(hostname="0.0.0.0", port=port) # wait for web server to be up counter = 0 while counter < 4: if agent.web.server is not None: break counter += 1 time.sleep(0.1) assert agent.web.server is not None response = requests.get(f"http://localhost:{port}/spade") sel = Selector(text=response.text) assert sel.css("title::text").get() == "fake agent" assert sel.css("img::attr(src)").get() == agent.avatar assert sel.css("ul.products-list > li").getall() == [] agent.stop()
def test_fsm_fail_on_end(): class StateOne(State): async def run(self): pass async def on_end(self): raise Exception fsm_ = FSMBehaviour() state_one = StateOne() fsm_.add_state(STATE_ONE, state_one, initial=True) agent = make_connected_agent() future = agent.start(auto_register=False) future.result() agent.add_behaviour(fsm_) fsm_.join() assert fsm_.is_killed() assert type(fsm_.exit_code) == Exception agent.stop()
def test_submit_send(): agent = make_connected_agent() class DummyBehav(OneShotBehaviour): async def run(self): msg_to_send = Message(to="fake@jid", body="BODY", metadata={"performative": "TEST"}) coro = self.send(msg_to_send) self.agent.submit(coro) self.kill() template = Template(to="fake@jid") behah = DummyBehav() agent.add_behaviour(behah, template=template) future = agent.start(auto_register=False) future.result() behah.join() assert behah.queue.qsize() == 1 msg = behah.queue.get_nowait() assert str(msg.to) == "fake@jid" assert msg.body == "BODY" assert msg.metadata == {"performative": "TEST"}
def test_fsm_bad_state(): class StateOne(State): async def run(self): self.set_next_state("BAD_STATE") self.kill() class StateTwo(State): async def run(self): pass class BadFSMBehaviour(FSMBehaviour): async def on_end(self): self.kill() fsm_ = BadFSMBehaviour() state_one = StateOne() state_two = StateTwo() fsm_.add_state(STATE_ONE, state_one, initial=True) fsm_.add_state(STATE_TWO, state_two) fsm_.add_transition(STATE_ONE, STATE_TWO) agent = make_connected_agent() agent.start(auto_register=False) assert fsm_.current_state == STATE_ONE agent.add_behaviour(fsm_) state_one.join() assert fsm_.current_state == STATE_ONE fsm_.join() assert fsm_.is_killed() agent.stop()
def test_on_start_on_end(): class TestOneShotBehaviour(OneShotBehaviour): async def on_start(self): self.agent.on_start_flag = True async def run(self): pass async def on_end(self): self.agent.on_end_flag = True self.kill() agent = make_connected_agent() agent.on_start_flag = False agent.on_end_flag = False behaviour = TestOneShotBehaviour() agent.add_behaviour(behaviour) assert agent.on_start_flag is False assert agent.on_end_flag is False agent.start(auto_register=False) behaviour.join() assert agent.on_start_flag is True assert agent.on_end_flag is True agent.stop()
def test_set_exit_code_behaviour(): class TestCyclicBehaviour(CyclicBehaviour): async def run(self): self.exit_code = 1024 agent.event.wait() self.kill() agent = make_connected_agent() behaviour = TestCyclicBehaviour() agent.event = Event() future = agent.start(auto_register=False) future.result() agent.add_behaviour(behaviour) with pytest.raises(BehaviourNotFinishedException): assert behaviour.exit_code agent.event.set() behaviour.join() future = agent.stop() future.result() assert behaviour.exit_code == 1024 assert not agent.is_alive()
def test_setup(): agent = make_connected_agent() agent.setup = CoroutineMock() future = agent.start(auto_register=False) assert future.result() is None agent.setup.assert_called_once() agent.stop()
def test_connected_agent(): agent = make_connected_agent() assert agent.is_alive() is False agent.start(auto_register=False) assert agent.is_alive() is True agent.stop() assert agent.is_alive() is False
def test_register(): agent = make_connected_agent() agent.register = Mock() agent.start(auto_register=True) assert len(agent.register.mock_calls) == 1 agent.stop()
def test_register(): agent = make_connected_agent() agent.register = Mock() future = agent.start(auto_register=True) assert future.result() is None assert len(agent._async_register.mock_calls) == 1 agent.stop()
def test_connected_agent_with_loop(): loop = asyncio.new_event_loop() agent = make_connected_agent(loop=loop) assert agent.is_alive() is False agent.start(auto_register=False) assert agent.is_alive() is True agent.stop() assert agent.is_alive() is False
def test_remove_behaviour_not_added(): class EmptyBehaviour(CyclicBehaviour): async def run(self): pass agent = make_connected_agent() behaviour = EmptyBehaviour() with pytest.raises(ValueError): agent.remove_behaviour(behaviour)
def test_connected_agent(): agent = make_connected_agent() assert agent.is_alive() is False future = agent.start(auto_register=False) assert future.result() is None assert agent.is_alive() is True future = agent.stop() future.result() assert agent.is_alive() is False
def test_use_container(): container = Container() container.reset() agent = make_connected_agent() assert agent.container == Container() assert container.has_agent(str(agent.jid)) assert container.get_agent(str(agent.jid)) == agent agent.stop()
def test_remove_behaviour(): class EmptyBehaviour(CyclicBehaviour): async def run(self): pass agent = make_connected_agent() behaviour = EmptyBehaviour() agent.add_behaviour(behaviour) assert agent.has_behaviour(behaviour) agent.remove_behaviour(behaviour) assert not agent.has_behaviour(behaviour)
async def test_find_behaviour(): class EmptyOneShotBehaviour(OneShotBehaviour): async def run(self): pass agent = make_connected_agent() behaviour = EmptyOneShotBehaviour() agent.add_behaviour(behaviour) found_behaviour = agent.web.find_behaviour("OneShotBehaviour/EmptyOneShotBehaviour") assert found_behaviour == behaviour agent.stop()
def test_use_container_false(): container = Container() container.reset() agent = make_connected_agent(use_container=False) assert agent.container is None assert not container.has_agent(str(agent.jid)) with pytest.raises(KeyError): container.get_agent(str(agent.jid)) agent.stop()
async def test_find_behaviour(): class EmptyOneShotBehaviour(OneShotBehaviour): async def run(self): pass agent = make_connected_agent() behaviour = EmptyOneShotBehaviour() agent.add_behaviour(behaviour) found_behaviour = agent.web.find_behaviour( "OneShotBehaviour/EmptyOneShotBehaviour") assert found_behaviour == behaviour agent.stop()
def test_web(): agent = make_connected_agent() future = agent.start(auto_register=False) future.result() agent.web.start(port=10000) assert agent.web.app is not None counter = 0 while counter < 4: if agent.web.server is not None: break counter += 1 time.sleep(0.1) assert agent.web.server is not None agent.stop()
def test_kill_behaviour(): class TestCyclicBehaviour(CyclicBehaviour): async def run(self): self.kill() agent = make_connected_agent() behaviour = TestCyclicBehaviour() agent.start(auto_register=False) agent.add_behaviour(behaviour) behaviour.join() assert behaviour.is_killed() assert behaviour.exit_code == 0 agent.stop()
def test_join_with_long_timeout(): class WaitBehav(OneShotBehaviour): async def run(self): await asyncio.sleep(0) agent = make_connected_agent() agent.i = None behaviour = WaitBehav() agent.add_behaviour(behaviour) agent.start(auto_register=False) behaviour.join(timeout=100) assert behaviour.is_done() agent.stop()
def test_receive_without_behaviours(): agent = make_connected_agent() aiomsg = aioxmpp.Message(type_=aioxmpp.MessageType.CHAT) msg = Message.from_node(aiomsg) assert agent.traces.len() == 0 future = agent.start(auto_register=False) assert future.result() is None with LogCapture() as log: agent._message_received(aiomsg) log.check_present(('spade.Agent', 'WARNING', f"No behaviour matched for message: {msg}")) assert agent.traces.len() == 1 assert msg in agent.traces.store[0] agent.stop()
def test_multiple_templates(): class Template1Behaviour(OneShotBehaviour): async def run(self): self.agent.msg1 = await self.receive(timeout=2) class Template2Behaviour(OneShotBehaviour): async def run(self): self.agent.msg2 = await self.receive(timeout=2) class Template3Behaviour(OneShotBehaviour): async def run(self): self.agent.msg3 = await self.receive(timeout=2) self.kill() agent = make_connected_agent() template1 = Template() template1.set_metadata("performative", "template1") agent.add_behaviour(Template1Behaviour(), template1) template2 = Template() template2.set_metadata("performative", "template2") agent.add_behaviour(Template2Behaviour(), template2) template3 = Template() template3.set_metadata("performative", "template3") behaviour = Template3Behaviour() agent.add_behaviour(behaviour, template3) msg1 = Message(metadata={"performative": "template1"}).prepare() msg2 = Message(metadata={"performative": "template2"}).prepare() msg3 = Message(metadata={"performative": "template3"}).prepare() future = agent.start(auto_register=False) future.result() agent._message_received(msg1) agent._message_received(msg2) agent._message_received(msg3) behaviour.join() assert agent.msg1.get_metadata("performative") == "template1" assert agent.msg2.get_metadata("performative") == "template2" assert agent.msg3.get_metadata("performative") == "template3" agent.stop()
def test_join_with_timeout(): class WaitBehav(OneShotBehaviour): async def run(self): await asyncio.sleep(100) agent = make_connected_agent() agent.i = None behaviour = WaitBehav() agent.add_behaviour(behaviour) agent.start(auto_register=False) with pytest.raises(TimeoutError): behaviour.join(timeout=0.01) assert not behaviour.is_done() agent.stop()
def test_on_run_exception(): class TestOneShotBehaviour(OneShotBehaviour): async def run(self): result = 1 / 0 self.agent.flag = True agent = make_connected_agent() agent.flag = False behaviour = TestOneShotBehaviour() agent.add_behaviour(behaviour) agent.start(auto_register=False) behaviour.join() assert type(behaviour.exit_code) == ZeroDivisionError assert not agent.flag agent.stop()
def test_set_get(): class SendBehaviour(OneShotBehaviour): async def run(self): self.set("key", "value") assert self.get("key") == "value" self.kill() agent = make_connected_agent() future = agent.start(auto_register=False) future.result() behaviour = SendBehaviour() agent.add_behaviour(behaviour) behaviour.join() assert agent.get("key") == "value" agent.stop()