From d6c0cb95cca66f6cf69308110c1e85ab1f0f53da Mon Sep 17 00:00:00 2001 From: Joshua Morton Date: Wed, 30 Aug 2017 03:13:00 -0400 Subject: [PATCH 1/3] Add a timeout to node spin up. Also makes the node spin up use threads which is probably a slightly nicer api overall. --- pyrostest/ros_test.py | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/pyrostest/ros_test.py b/pyrostest/ros_test.py index b300135..20e7d64 100644 --- a/pyrostest/ros_test.py +++ b/pyrostest/ros_test.py @@ -32,6 +32,11 @@ class NoMessage(Exception): """ pass +class NoNode(Exception): + """A node was expected, but could not be found in time. + """ + pass + def _resolve_location(binary_name): """Find the location of a mock node to run. """ @@ -129,15 +134,28 @@ def kill_proc(): self._message = msg return self._message - -def _await_node(topic, prefix, rosmaster_uri): - """Helper to block until a node is availible in ROS. - """ +def _check_is_availible(topic, prefix, rosmaster_uri, event): no_ns = topic.split('/')[-1] while not any(nn.split('/')[-1].startswith(''.join([prefix, '_', no_ns])) for nn in pyrostest.rostest_utils.my_get_node_names(uri=rosmaster_uri)): time.sleep(.1) + event.set() + + +def _await_node(topic, prefix, rosmaster_uri, timeout): + """Helper to block until a node is availible in ROS. + """ + is_accessed = threading.Event() + bg = threading.Thread(name='wait for node', target=_check_is_availible, + args=(topic, prefix, rosmaster_uri, is_accessed)) + bg.start() + is_accessed.wait(timeout) + bg.kill() + if not is_accessed.isSet(): + raise NoNode() + + class RosTest(unittest.TestCase): @@ -153,12 +171,13 @@ def __init__(self, *args, **kwargs): self.LAUNCHER = dict() @contextlib.contextmanager - def check_topic(self, topic, rosmsg_type, timeout=10): + def check_topic(self, topic, rosmsg_type, timeout=10, node_timeout=10): """Context manager that monitors a rostopic and gets a message sent to it. """ test_node = MockSubscriber(topic, rosmsg_type, timeout=timeout) - _await_node(topic, 'mock_subscribe', self.rosmaster_uri) + _await_node(topic, 'mock_subscribe', self.rosmaster_uri, + timeout=node_timeout) try: yield test_node @@ -166,11 +185,12 @@ def check_topic(self, topic, rosmsg_type, timeout=10): test_node.kill() @contextlib.contextmanager - def mock_pub(self, topic, rosmsg_type, queue_size=1): + def mock_pub(self, topic, rosmsg_type, queue_size=1, node_timeout=10): """Mocks a node and cleans it up when done. """ pub = MockPublisher(topic, rosmsg_type, queue_size) - _await_node(topic, 'mock_publish', self.rosmaster_uri) + _await_node(topic, 'mock_publish', self.rosmaster_uri, + timeout=node_timeout) try: yield pub finally: From 5309cae9a2a510d882fc6c0cfc04ca4da28f89f9 Mon Sep 17 00:00:00 2001 From: Joshua Morton Date: Sat, 2 Sep 2017 01:04:56 -0400 Subject: [PATCH 2/3] Improved error message and removed bug. --- pyrostest/ros_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrostest/ros_test.py b/pyrostest/ros_test.py index 20e7d64..2e44b52 100644 --- a/pyrostest/ros_test.py +++ b/pyrostest/ros_test.py @@ -151,9 +151,9 @@ def _await_node(topic, prefix, rosmaster_uri, timeout): args=(topic, prefix, rosmaster_uri, is_accessed)) bg.start() is_accessed.wait(timeout) - bg.kill() if not is_accessed.isSet(): - raise NoNode() + raise NoNode('No node was created for "{}", in namespace "{}"').format( + topic, prefix) From cf6115086806c4477779fe7dae3aa09d23299bbf Mon Sep 17 00:00:00 2001 From: Joshua Morton Date: Sat, 2 Sep 2017 16:04:01 -0400 Subject: [PATCH 3/3] Bump Version. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index dc04b5f..2b86456 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ setup( name='pyrostest', - version='0.1.10', + version='0.1.11', description='The most lit ros testing framework', long_description=long_description, packages=['pyrostest'],