diff --git a/osbrain/helper.py b/osbrain/helper.py index 0fa7062..fd052ae 100644 --- a/osbrain/helper.py +++ b/osbrain/helper.py @@ -195,21 +195,21 @@ def wait_agent_attr(agent, name='received', length=None, data=None, value=None, return False -def wait_agent_condition(agent, condition, *args, timeout=3, **kwargs): +def wait_condition(condition, *args, negate=False, timeout=3, **kwargs): """ - Wait for an agent's condition to be true. + Wait for a condition to be true. - The condition is passed as a function which must take, at least, the - actual agent as a parameter, and must evaluate to a boolean result. + The condition is passed as a callable and must evaluate to a boolean + result. Parameters ---------- - agent : Proxy - A proxy to the agent. condition : Callable A function that evaluates the desired condition. timeout : float, default is 3 After this number of seconds the function will return `False`. + negate : bool, default is False + Negate the condition (wait for the condition to be false instead). Returns ------- @@ -218,13 +218,38 @@ def wait_agent_condition(agent, condition, *args, timeout=3, **kwargs): """ t0 = time.time() while True: - if agent.execute_as_method(condition, *args, **kwargs): + if condition(*args, **kwargs) != negate: return True if time.time() - t0 > timeout: return False time.sleep(0.01) +def wait_agent_condition(agent, condition, *args, timeout=3, **kwargs): + """ + Wait for an agent's condition to be true. + + The condition is passed as a function which must take, at least, the + actual agent as a parameter, and must evaluate to a boolean result. + + Parameters + ---------- + agent : Proxy + A proxy to the agent. + condition : Callable + A function that evaluates the desired condition. + timeout : float, default is 3 + After this number of seconds the function will return `False`. + + Returns + ------- + bool + Whether the specified condition was True. + """ + return wait_condition(agent.execute_as_method, condition, *args, + timeout=timeout, **kwargs) + + def last_received_endswith(agent, tail): """ Check if the agent's last received message ends with `tail`. diff --git a/osbrain/tests/test_agent_ipc_sockets.py b/osbrain/tests/test_agent_ipc_sockets.py index 68f174b..8e353c2 100644 --- a/osbrain/tests/test_agent_ipc_sockets.py +++ b/osbrain/tests/test_agent_ipc_sockets.py @@ -6,6 +6,7 @@ from osbrain import run_agent from osbrain import run_nameserver from osbrain.helper import agent_dies +from osbrain.helper import wait_condition from common import nsproxy # pragma: no flakes @@ -30,10 +31,10 @@ def test_agent_close_ipc_socket_agent_kill(nsproxy): """ agent = run_agent('name') address = agent.bind('PUSH') - agent.kill() + agent.oneway.kill() assert agent_dies('name', nsproxy, timeout=3) - assert not address.address.exists() + assert wait_condition(lambda x: not x.exists(), address.address) def test_agent_close_ipc_socket_agent_blocked_nameserver_shutdown(): diff --git a/osbrain/tests/test_helper.py b/osbrain/tests/test_helper.py index 339535e..2d704db 100644 --- a/osbrain/tests/test_helper.py +++ b/osbrain/tests/test_helper.py @@ -1,6 +1,7 @@ """ Test file for functionality implemented in `osbrain/tests/common.py`. """ +from threading import Timer import time import pytest @@ -12,12 +13,27 @@ from osbrain.helper import attribute_match_all from osbrain.helper import last_received_endswith from osbrain.helper import wait_agent_attr +from osbrain.helper import wait_condition from osbrain.helper import wait_agent_condition from common import nsproxy # pragma: no flakes from common import agent_logger # pragma: no flakes +class SugarAddict(): + def __init__(self): + self.glucose = 0 + + def feed_candy(self): + self.glucose += 1 + + def happy(self): + return bool(self.glucose) + + def sad(self): + return not bool(self.glucose) + + def test_agent_dies(nsproxy): """ The function `agent_dies` should return `False` if the agent does not die @@ -145,6 +161,32 @@ def set_received_method(self, value): assert wait_agent_attr(a0, value=42, timeout=2.) +@pytest.mark.parametrize('delay,timeout,result', [ + (1, 0.5, False), + (0.5, 1, True), +]) +def test_wait_condition(delay, timeout, result): + """ + Test the `wait_agent_condition` function. + """ + kid = SugarAddict() + Timer(delay, kid.feed_candy).start() + assert wait_condition(kid.happy, timeout=timeout) == result + + +@pytest.mark.parametrize('delay,timeout,result', [ + (1, 0.5, False), + (0.5, 1, True), +]) +def test_wait_condition_negate(delay, timeout, result): + """ + Test the negated `wait_agent_condition` function. + """ + kid = SugarAddict() + Timer(delay, kid.feed_candy).start() + assert wait_condition(kid.sad, negate=True, timeout=timeout) == result + + def test_wait_agent_condition(nsproxy): """ Test `wait_agent_condition` function.