mirror of
https://github.com/gsi-upm/soil
synced 2024-11-22 03:02:28 +00:00
Add test cases for 'ASK'
This commit is contained in:
parent
a1262edd2a
commit
b2d48cb4df
@ -52,11 +52,11 @@ class EventedAgent(BaseAgent):
|
|||||||
def tell(self, msg, sender=None):
|
def tell(self, msg, sender=None):
|
||||||
self._inbox.append(Tell(timestamp=self.now, payload=msg, sender=sender))
|
self._inbox.append(Tell(timestamp=self.now, payload=msg, sender=sender))
|
||||||
|
|
||||||
def ask(self, msg, timeout=None):
|
def ask(self, msg, timeout=None, **kwargs):
|
||||||
ask = Ask(timestamp=self.now, payload=msg)
|
ask = Ask(timestamp=self.now, payload=msg, sender=self)
|
||||||
self._inbox.append(ask)
|
self._inbox.append(ask)
|
||||||
expiration = float('inf') if timeout is None else self.now + timeout
|
expiration = float('inf') if timeout is None else self.now + timeout
|
||||||
return ask.replied(expiration=expiration)
|
return ask.replied(expiration=expiration, **kwargs)
|
||||||
|
|
||||||
def check_messages(self):
|
def check_messages(self):
|
||||||
changed = False
|
changed = False
|
||||||
|
@ -38,7 +38,7 @@ class BaseEnvironment(Model):
|
|||||||
self,
|
self,
|
||||||
id="unnamed_env",
|
id="unnamed_env",
|
||||||
seed="default",
|
seed="default",
|
||||||
schedule=None,
|
schedule_class=time.TimedActivation,
|
||||||
dir_path=None,
|
dir_path=None,
|
||||||
interval=1,
|
interval=1,
|
||||||
agent_class=None,
|
agent_class=None,
|
||||||
@ -58,9 +58,11 @@ class BaseEnvironment(Model):
|
|||||||
|
|
||||||
self.dir_path = dir_path or os.getcwd()
|
self.dir_path = dir_path or os.getcwd()
|
||||||
|
|
||||||
if schedule is None:
|
if schedule_class is None:
|
||||||
schedule = time.TimedActivation(self)
|
schedule_class = time.TimedActivation
|
||||||
self.schedule = schedule
|
else:
|
||||||
|
schedule_class = serialization.deserialize(schedule_class)
|
||||||
|
self.schedule = schedule_class(self)
|
||||||
|
|
||||||
self.agent_class = agent_class or agentmod.BaseAgent
|
self.agent_class = agent_class or agentmod.BaseAgent
|
||||||
|
|
||||||
|
10
soil/time.py
10
soil/time.py
@ -192,3 +192,13 @@ class TimedActivation(BaseScheduler):
|
|||||||
self.logger.debug(f"Updating time step: {self.time} -> {next_time}")
|
self.logger.debug(f"Updating time step: {self.time} -> {next_time}")
|
||||||
|
|
||||||
self.time = next_time
|
self.time = next_time
|
||||||
|
|
||||||
|
|
||||||
|
class ShuffledTimedActivation(TimedActivation):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, shuffle=True, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class OrderedTimedActivation(TimedActivation):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, shuffle=False, **kwargs)
|
||||||
|
@ -103,7 +103,19 @@ class TestAgents(TestCase):
|
|||||||
An agent should be able to ask another agent, and wait for a response.
|
An agent should be able to ask another agent, and wait for a response.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# #Results depend on ordering (agents are shuffled), so force the first agent
|
# There are two agents, they try to send pings
|
||||||
|
# This is arguably a very contrived example. In practice, the or
|
||||||
|
# There should be a delay of one step between agent 0 and 1
|
||||||
|
# On the first step:
|
||||||
|
# Agent 0 sends a PING, but blocks before a PONG
|
||||||
|
# Agent 1 detects the PING, responds with a PONG, and blocks after its own PING
|
||||||
|
# After that step, every agent can both receive (there are pending messages) and send.
|
||||||
|
# In each step, for each agent, one message is sent, and another one is received
|
||||||
|
# (although not necessarily in that order).
|
||||||
|
|
||||||
|
# Results depend on ordering (agents are normally shuffled)
|
||||||
|
# so we force the timedactivation not to be shuffled
|
||||||
|
|
||||||
pings = []
|
pings = []
|
||||||
pongs = []
|
pongs = []
|
||||||
responses = []
|
responses = []
|
||||||
@ -114,46 +126,37 @@ class TestAgents(TestCase):
|
|||||||
target = self.model.agents[target_id]
|
target = self.model.agents[target_id]
|
||||||
print('starting')
|
print('starting')
|
||||||
while True:
|
while True:
|
||||||
print('Pings: ', pings, responses or not pings, self.model.schedule._queue)
|
if pongs or not pings: #First agent, or anyone after that
|
||||||
if pongs or not pings:
|
|
||||||
pings.append(self.now)
|
pings.append(self.now)
|
||||||
response = yield target.ask('PING')
|
response = yield target.ask('PING')
|
||||||
responses.append(response)
|
responses.append(response)
|
||||||
else:
|
else:
|
||||||
print('NOT sending ping')
|
print('NOT sending ping')
|
||||||
print('Checking msgs')
|
print('Checking msgs')
|
||||||
# Do not advance until we have received a message.
|
# Do not block if we have already received a PING
|
||||||
# warning: it will wait at least until the next time in the simulation
|
if not self.check_messages():
|
||||||
yield self.received(check=True)
|
yield self.received()
|
||||||
print('done')
|
print('done')
|
||||||
|
|
||||||
def on_receive(self, msg, sender=None):
|
def on_receive(self, msg, sender=None):
|
||||||
if msg == 'PING':
|
if msg == 'PING':
|
||||||
pongs.append(self.now)
|
pongs.append(self.now)
|
||||||
return 'PONG'
|
return 'PONG'
|
||||||
|
raise Exception("This should never happen")
|
||||||
|
|
||||||
e = environment.EventedEnvironment()
|
e = environment.EventedEnvironment(schedule_class=stime.OrderedTimedActivation)
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
e.add_agent(agent_class=Ping)
|
e.add_agent(agent_class=Ping)
|
||||||
assert e.now == 0
|
assert e.now == 0
|
||||||
|
|
||||||
# There should be a delay of one step between agent 0 and 1
|
|
||||||
# On the first step:
|
|
||||||
# Agent 0 sends a PING, but blocks before a PONG
|
|
||||||
# Agent 1 sends a PONG, and blocks after its PING
|
|
||||||
# After that step, every agent can both receive (there are pending messages) and then send.
|
|
||||||
|
|
||||||
e.step()
|
for i in range(5):
|
||||||
assert e.now == 1
|
e.step()
|
||||||
assert pings == [0]
|
time = i + 1
|
||||||
assert pongs == []
|
assert e.now == time
|
||||||
|
assert len(pings) == 2 * time
|
||||||
e.step()
|
assert len(pongs) == (2 * time) - 1
|
||||||
assert e.now == 2
|
# Every step between 0 and t appears twice
|
||||||
assert pings == [0, 1]
|
assert sum(pings) == sum(range(time)) * 2
|
||||||
assert pongs == [1]
|
# It is the same as pings, without the leading 0
|
||||||
|
assert sum(pongs) == sum(range(time)) * 2
|
||||||
e.step()
|
|
||||||
assert e.now == 3
|
|
||||||
assert pings == [0, 1, 2]
|
|
||||||
assert pongs == [1, 2]
|
|
||||||
|
Loading…
Reference in New Issue
Block a user