Skip to content

Commit

Permalink
feat: test ping pong
Browse files Browse the repository at this point in the history
  • Loading branch information
gciatto committed Feb 20, 2023
1 parent 9279f41 commit 396ef6c
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 13 deletions.
34 changes: 33 additions & 1 deletion pyxmas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@
import spade
import spade.agent
import spade.behaviour
import spade.message
import random
import string
import asyncio
import time
import warnings


__all__ = ['System', 'Agent', 'Behaviour', 'enable_logging', 'logger', 'LOG_DEBUG', 'LOG_INFO', 'LOG_WARNING',
'LOG_ERROR', 'LOG_CRITICAL', 'LOG_FATAL']
'LOG_ERROR', 'LOG_CRITICAL', 'LOG_FATAL', 'random_string']


def random_string(length: int = 16):
return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(length))


class System:
Expand Down Expand Up @@ -59,6 +68,7 @@ def sync_await(self, sleep=0.1, timeout=None):
time.sleep(sleep)

def stop(self):
self.log(msg="Stopping...")
result = super().stop()
# def on_terminated(_):
# self._termination.set_result(None)
Expand All @@ -67,6 +77,10 @@ def stop(self):


class Behaviour(spade.behaviour.CyclicBehaviour):
def __init__(self):
super().__init__()
self._thread = random_string()

def log(self, level=LOG_INFO, msg="", *args, **kwargs):
logger.log(level, f"[{self.agent.jid}/{str(self)}] {msg}", *args, **kwargs)

Expand All @@ -76,3 +90,21 @@ def set_agent(self, agent) -> None:
if agent and agent != old_agent:
self.log(LOG_DEBUG, "Behaviour added")
return result

def new_message(self,
recipient: str,
payload: str,
thread: str = None,
metadata: str = None
) -> spade.message.Message:
sender = self.agent.jid
if isinstance(recipient, str) and "@" not in recipient:
recipient += f"@{self.agent.jid.domain}"
if thread is None:
thread = "#".join([str(sender), str(self), self._thread])
return spade.agent.Message(to=recipient, sender=str(sender), body=payload, thread=thread, metadata=metadata)


# DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.
# self._finished = locks.Event(loop=loop)
warnings.filterwarnings("ignore", category=DeprecationWarning)
19 changes: 11 additions & 8 deletions test/__init__.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
from typing import Dict, List
import pyxmas
import subprocess
import spade
import spade.behaviour as sb
import unittest

__all__ = ['XmppService', 'xmpp_service', 'random_string', 'TestAgent', 'RecordEventBehaviour',
__all__ = ['XmppService', 'xmpp_service', 'TestAgent', 'RecordEventBehaviour',
'SharedXmppServiceTestCase', 'IndividualXmppServiceTestCase']

_DEFAULT_DOMAIN = 'localhost'

pyxmas.enable_logging()


def random_string(length: int = 16):
import random
import string
return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(length))


class XmppService:
docker = 'docker'

Expand Down Expand Up @@ -109,7 +104,7 @@ def xmpp_service(domain: str = _DEFAULT_DOMAIN):

class TestAgent(pyxmas.Agent):
def __init__(self, name: str,
password: str = random_string(),
password: str = pyxmas.random_string(),
domain: str = _DEFAULT_DOMAIN,
service: XmppService = None,
events=None):
Expand All @@ -130,6 +125,9 @@ def xmpp_service(self):
def observable_events(self):
if self.is_alive():
raise RuntimeError("Agent is still alive")
for e in self._events:
if isinstance(e, Exception):
raise e
return self._events

def record_observable_event(self, message):
Expand All @@ -155,6 +153,7 @@ def setUpClass(cls):
@classmethod
def tearDownClass(cls):
cls.xmpp_service.stop()
spade.quit_spade()


class IndividualXmppServiceTestCase(unittest.TestCase):
Expand All @@ -168,5 +167,9 @@ def setUp(self):
def tearDown(self):
self.xmpp_service.stop()

@classmethod
def tearDownClass(cls):
spade.quit_spade()


xmpp_service().stop()
76 changes: 72 additions & 4 deletions test/test_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,81 @@ async def setup(self):
self.add_behaviour(self.RecordEventThenStopBehaviour("hello"))


class PingerAgent(test.TestAgent):
class PingPongStop(pyxmas.Behaviour):
async def on_end(self) -> None:
await self.agent.stop()

async def run(self) -> None:
try:
message = self.new_message(recipient='ponger', payload='ping')
self.log(msg=f"Sending message {message}")
await self.send(message)
self.log(msg=f"Sent message {message}")
self.agent.record_observable_event('sent_ping')
self.log(msg=f"Receiving message matching {self.template}")
pong = await self.receive(timeout=100)
self.log(msg=f'Received message {pong}')
self.agent.record_observable_event(f'received_{pong.body}')
except Exception as e:
self.log(msg=str(e))
self.agent.record_observable_event(e)
finally:
self.kill()

def __init__(self, name, service=None):
super().__init__(name, service=service)

async def setup(self):
await super().setup()
self.add_behaviour(self.PingPongStop())


class PongerAgent(test.TestAgent):
class PongPingStop(pyxmas.Behaviour):
async def on_end(self) -> None:
await self.agent.stop()

async def run(self) -> None:
try:
self.log(msg=f"Receiving message matching {self.template}")
ping = await self.receive(timeout=100)
self.log(msg=f'Received message {ping}')
self.agent.record_observable_event(f'received_{ping.body}')
pong = ping.make_reply()
pong.body = 'pong'
self.log(msg=f"Sending message {pong}")
await self.send(pong)
self.log(msg=f"Sent message {pong}")
self.agent.record_observable_event(f'sent_pong')
except Exception as e:
self.log(msg=str(e))
self.agent.record_observable_event(e)
finally:
self.kill()

def __init__(self, name, service=None):
super().__init__(name, service=service)

async def setup(self):
await super().setup()
self.add_behaviour(self.PongPingStop())


class TestExample(test.SharedXmppServiceTestCase):

def test_hello(self):
with pyxmas.System():
with HelloAgent("alice") as agent:
agent.sync_await()
self.assertEqual(agent.observable_events, ["hello"])
with HelloAgent("alice") as agent:
agent.sync_await()
self.assertEqual(["hello"], agent.observable_events)

def test_ping_pong(self):
with PongerAgent("ponger") as ponger:
with PingerAgent("pinger") as pinger:
pinger.sync_await()
ponger.sync_await()
self.assertEqual(["sent_ping", "received_pong"], pinger.observable_events)
self.assertEqual(["received_ping", "sent_pong"], ponger.observable_events)


if __name__ == '__main__':
Expand Down

0 comments on commit 396ef6c

Please sign in to comment.