def appear_disappear(): # create the publisher and then try exposing the topic again, simulating # it coming online before expose call. nonexistent_pub = rospy.Subscriber(topicname, Empty, queue_size=1) with Timeout(5) as t: dt = DiffTuple([], []) while not t.timed_out and nonexistent_pub.resolved_name not in dt.added: subscribers, topic_types = self.get_system_state() dt = self.subscriber_if_pool.update( subscribers, topic_types) self.assertEqual(dt.removed, []) # nothing removed time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) self.assertTrue(nonexistent_pub.resolved_name in dt.added) # detected # TODO : do we need a test with subscriber ? # every added topic should be in the list of args self.assertTrue( topicname in self.subscriber_if_pool.subscribers_args) # topic backend has been created self.assertTrue( topicname in self.subscriber_if_pool.subscribers.keys()) # up to here possible sequences should have been already tested by previous tests # Now comes our actual disappearance / withholding test nonexistent_pub.unregister() # every added topic should be in the list of args self.assertTrue( topicname in self.subscriber_if_pool.subscribers_args) # the backend should STILL be there self.assertTrue( topicname in self.subscriber_if_pool.subscribers.keys()) # Note the Topic implementation should take care of possible errors in this case with Timeout(5) as t: dt = DiffTuple([], []) while not t.timed_out and topicname not in dt.removed: subscribers, topic_types = self.get_system_state() dt = self.subscriber_if_pool.update( subscribers, topic_types) self.assertEqual(dt.added, []) # nothing added time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) self.assertTrue(topicname in dt.removed) # detected lost # every exposed topic should remain in the list of args ( in case regex match another topic ) self.assertTrue( topicname in self.subscriber_if_pool.subscribers_args) # make sure the topic backend should NOT be there any longer self.assertTrue( topicname not in self.subscriber_if_pool.subscribers.keys())
def setUp(self): # we need to speed fast enough for the tests to not fail on timeout... rospy.set_param('/connection_cache/spin_freq', 2) # 2 Hz self.connection_cache_node = roslaunch.core.Node( 'rocon_python_comms', 'connection_cache.py', name='connection_cache', remap_args=[ ('~list', '/pyros_ros/connections_list'), ('~diff', '/pyros_ros/connections_diff'), ]) try: self.connection_cache_proc = self.launch.launch( self.connection_cache_node) except roslaunch.RLException as rlexc: raise nose.SkipTest( "Connection Cache Node not found (part of rocon_python_comms pkg). Skipping test." ) node_api = None with Timeout(5) as t: while not t.timed_out and node_api is None: node_api = rosnode.get_api_uri(rospy.get_master(), 'connection_cache') assert node_api is not None # make sure the connection cache node is started before moving on. super(TestPyrosROSCache, self).setUp(enable_cache=True)
def test_service_appear_expose_update(self): """ Test service exposing functionality for a service which already exists in the ros environment. Simple Normal usecase Sequence : APPEAR -> EXPOSE -> UPDATE :return: """ servicename = '/test/empsrv' dt = self.service_if_pool.expose_services([servicename]) # every added service should be in the list of args self.assertTrue(servicename in self.service_if_pool.services_args) # service backend has not been created since the update didn't run yet self.assertTrue(servicename not in self.service_if_pool.services.keys()) # NOTE : We need to wait to make sure the tests nodes are started... with Timeout(5) as t: while not t.timed_out and servicename not in dt.added: services, service_types = self.get_system_state() dt = self.service_if_pool.update(services, service_types) time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) # every exposed service should remain in the list of args ( in case regex match another service ) self.assertTrue(servicename in self.service_if_pool.services_args) # make sure the service backend has been created self.assertTrue(servicename in self.service_if_pool.services.keys()) # cleaning up self.service_if_pool.expose_services([]) # service should not be in the list of args any longer self.assertTrue(servicename not in self.service_if_pool.services_args) # service backend has been removed self.assertTrue(servicename not in self.service_if_pool.services.keys())
def test_rosnode_subscribers( self): # Here we check that this node actually discovers topics # Starting underlying system before rospy.set_param('/string_sub/topic_name', '~test_str_topic' ) # private topic name to not mess things up too much rospy.set_param('/string_sub/test_message', 'testing topic discovery') string_sub_node = roslaunch.core.Node('pyros_test', 'string_sub_node.py', name='string_sub') string_sub_process = self.launch.launch(string_sub_node) try: # Starting PyrosROS with preconfigured subscribers, rosn = PyrosROS( kwargs={ 'subscribers': ['/string_sub/test_str_topic'], 'enable_cache': self.enable_cache }) # careful assuming the topic fullname here try: nose.tools.assert_true(not rosn.is_alive()) rosn.start() nose.tools.assert_true(rosn.is_alive()) print("Discovering subscribers Service...") subscribers = pyzmp.discover( "subscribers", 5) # we wait a bit to let it time to start nose.tools.assert_true(subscribers is not None) print("subscribers providers : {svc}".format( svc=subscribers.providers)) nose.tools.assert_equal(len(subscribers.providers), 1) nose.tools.assert_true( rosn.name in [p[0] for p in subscribers.providers]) res = subscribers.call() # What we get here is non deterministic # however we can wait for topic to be detected to make sure we get it after some time with Timeout(15) as t: while not t.timed_out and not '/string_sub/test_str_topic' in res.keys( ): rospy.rostime.wallsleep(1) res = subscribers.call() nose.tools.assert_true( '/string_sub/test_str_topic' in res.keys( )) # test_topic has been created, detected and exposed finally: # finishing PyrosROS process if rosn is not None and rosn.is_alive(): rosn.shutdown() nose.tools.assert_true(not rosn.is_alive()) finally: # finishing string_pub_process if string_sub_process is not None and string_sub_process.is_alive( ): string_sub_process.stop() nose.tools.assert_true(not string_sub_process.is_alive())
def setUp(self): # first we setup our publishers and our node (used by rospy.resolve_name calls to remap topics) self.strpub = rospy.Publisher('/test/string', String, queue_size=1) self.emppub = rospy.Publisher('/test/empty', Empty, queue_size=1) self._master = rospy.get_master() self.service_if_pool = RosServiceIfPool() # we need to speed fast enough for the tests to not fail on timeout... rospy.set_param('/connection_cache/spin_freq', 2) # 2 Hz self.connection_cache_node = roslaunch.core.Node('rocon_python_comms', 'connection_cache.py', name='connection_cache', remap_args=[('~list', rospy.resolve_name('~connections_list')), ( '~diff', rospy.resolve_name('~connections_diff'))]) # Easier to remap the node topic to the proxy ones, instead of the opposite, since there is no dynamic remapping. # However for normal usecase, remapping the proxy handles is preferable. try: self.connection_cache_proc = self.launch.launch(self.connection_cache_node) except roslaunch.RLException as rlexc: raise nose.SkipTest("Connection Cache Node not found (part of rocon_python_comms pkg). Skipping test.") assert self.connection_cache_proc.is_alive() # wait for node to be started node_api = None with Timeout(5) as t: while not t.timed_out and node_api is None: node_api = rosnode.get_api_uri(rospy.get_master(), 'connection_cache') assert node_api is not None # make sure the connection cache node is started before moving on. self.connection_cache = connection_cache_proxy_create()
def test_service_update_disappear_withhold(self): """ Test service exposing functionality for a service which already exists in the ros environment. Simple Normal usecase Sequence : UPDATE -> DISAPPEAR -> WITHHOLD :return: """ servicename = '/test/absentsrv1' # every added service should be in the list of args self.assertTrue(servicename not in self.service_if_pool.services_args) # the backend should not have been created self.assertTrue(servicename not in self.service_if_pool.services.keys()) self.service_if_pool.expose_services([servicename]) # every added service should be in the list of args self.assertTrue(servicename in self.service_if_pool.services_args) # service backend has not been created self.assertTrue(servicename not in self.service_if_pool.services.keys()) dt = DiffTuple([], []) # create the service and then try updating again, simulating # it coming online after expose call. nonexistent_srv = rospy.Service(servicename, EmptySrv, srv_cb) try: # wait here until service actually appear in cache proxy with Timeout(5) as t: while not t.timed_out and nonexistent_srv.resolved_name not in dt.added: services, service_types = self.get_system_state() dt = self.service_if_pool.update(services, service_types) self.assertEqual(dt.removed, []) # nothing removed time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) self.assertTrue(nonexistent_srv.resolved_name in dt.added) # nonexistent_srv added self.assertEqual(dt.removed, []) # nothing removed # every added service should be in the list of args self.assertTrue(servicename in self.service_if_pool.services_args) # service backend has been created self.assertTrue(servicename in self.service_if_pool.services.keys()) # up to here possible sequences should have been already tested by previous tests # Now comes our actual disappearance / withholding test finally: nonexistent_srv.shutdown('testing disappearing service') # every added service should be in the list of args self.assertTrue(servicename in self.service_if_pool.services_args) # the backend should STILL be there self.assertTrue(servicename in self.service_if_pool.services.keys()) # Note the service implementation should take care of possible errors in this case self.service_if_pool.expose_services([]) # every withhold service should NOT be in the list of args self.assertTrue(servicename not in self.service_if_pool.services_args) # service backend should NOT be there any longer self.assertTrue(servicename not in self.service_if_pool.services.keys())
def test_service_expose_appear_update(self): """ Test basic service adding functionality for a service which does not yet exist in the ros environment ( + corner cases ) Sequence : (UPDATE? ->) -> EXPOSE -> (UPDATE? ->) APPEAR -> UPDATE :return: """ servicename = '/test/absentsrv1' # every added service should be in the list of args self.assertTrue(servicename not in self.service_if_pool.services_args) # the backend should not have been created self.assertTrue(servicename not in self.service_if_pool.services.keys()) # First update should not change state services, service_types = self.get_system_state() dt = self.service_if_pool.update(services, service_types) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # every added service should be in the list of args self.assertTrue(servicename not in self.service_if_pool.services_args) # the backend should not have been created self.assertTrue(servicename not in self.service_if_pool.services.keys()) self.service_if_pool.expose_services([servicename]) # every added service should be in the list of args self.assertTrue(servicename in self.service_if_pool.services_args) # the backend should not have been created self.assertTrue(servicename not in self.service_if_pool.services.keys()) services, service_types = self.get_system_state() dt = self.service_if_pool.update(services, service_types) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # make sure the service is STILL in the list of args self.assertTrue(servicename in self.service_if_pool.services_args) # make sure the service backend has STILL not been created self.assertTrue(servicename not in self.service_if_pool.services.keys()) # create the service and then try updating again, simulating # it coming online after expose call. nonexistent_srv = rospy.Service(servicename, EmptySrv, srv_cb) try: with Timeout(5) as t: dt = DiffTuple([], []) while not t.timed_out and nonexistent_srv.resolved_name not in dt.added: services, service_types = self.get_system_state() dt = self.service_if_pool.update(services, service_types) self.assertEqual(dt.removed, []) # nothing removed time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) self.assertTrue(nonexistent_srv.resolved_name in dt.added) # nonexistent_srv added # every exposed service should remain in the list of args ( in case regex match another service ) self.assertTrue(servicename in self.service_if_pool.services_args) # make sure the service backend has been created self.assertTrue(servicename in self.service_if_pool.services.keys()) finally: nonexistent_srv.shutdown('testing complete')
def test_param_expose_appear_update(self): """ Test basic param adding functionality for a param which does not yet exist in the ros environment ( + corner cases ) Sequence : (UPDATE? ->) -> EXPOSE -> (UPDATE? ->) APPEAR -> UPDATE :return: """ paramname = '/test/absentparam1' # every added param should be in the list of args self.assertTrue(paramname not in self.param_if_pool.params_args) # the backend should not have been created self.assertTrue(paramname not in self.param_if_pool.params.keys()) # First update should not change state params = self.get_system_state() dt = self.param_if_pool.update(params) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # every added param should be in the list of args self.assertTrue(paramname not in self.param_if_pool.params_args) # the backend should not have been created self.assertTrue(paramname not in self.param_if_pool.params.keys()) self.param_if_pool.expose_params([paramname]) # every added param should be in the list of args self.assertTrue(paramname in self.param_if_pool.params_args) # the backend should not have been created self.assertTrue(paramname not in self.param_if_pool.params.keys()) params = self.get_system_state() dt = self.param_if_pool.update(params) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # make sure the param is STILL in the list of args self.assertTrue(paramname in self.param_if_pool.params_args) # make sure the param backend has STILL not been created self.assertTrue(paramname not in self.param_if_pool.params.keys()) # create the param and then try updating again, simulating # it coming online after expose call. rospy.set_param(paramname, 'param_value') try: with Timeout(5) as t: dt = DiffTuple([], []) while not t.timed_out and paramname not in dt.added: params = self.get_system_state() dt = self.param_if_pool.update(params) self.assertEqual(dt.removed, []) # nothing removed time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) self.assertTrue(paramname in dt.added) # nonexistent_srv added # every exposed param should remain in the list of args ( in case regex match another service ) self.assertTrue(paramname in self.param_if_pool.params_args) # make sure the param backend has been created self.assertTrue(paramname in self.param_if_pool.params.keys()) finally: rospy.delete_param(paramname)
def test_param_appear_update_expose(self): """ Test param exposing functionality for a param which already exists in the ros environment. Normal usecase Sequence : (UPDATE?) -> APPEAR -> UPDATE -> EXPOSE (-> UPDATE?) :return: """ paramname = '/test/absentparam1' # every added param should be in the list of args self.assertTrue(paramname not in self.param_if_pool.params_args) # the backend should not have been created self.assertTrue(paramname not in self.param_if_pool.params.keys()) # First update should not change state params = self.get_system_state() dt = self.param_if_pool.update(params) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # every added param should be in the list of args self.assertTrue(paramname not in self.param_if_pool.params_args) # the backend should not have been created self.assertTrue(paramname not in self.param_if_pool.params.keys()) # create the param and then try exposing the param again, simulating # it coming online before expose call. rospy.set_param(paramname, 'param_value') try: with Timeout(5) as t: while not t.timed_out and paramname not in self.param_if_pool.params_available: params = self.get_system_state() dt = self.param_if_pool.update(params) self.assertEqual(dt.added, []) # nothing added (not exposed yet) self.assertEqual(dt.removed, []) # nothing removed time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) # every added param should be in the list of args self.assertTrue(paramname not in self.param_if_pool.params_args) # the backend should not have been created self.assertTrue(paramname not in self.param_if_pool.params.keys()) # here we are sure the interface knows the service is available # it will be exposed right now dt = self.param_if_pool.expose_params([paramname]) self.assertTrue(paramname in dt.added) # paramname added self.assertEqual(dt.removed, []) # nothing removed # every exposed param should remain in the list of args ( in case regex match another param ) self.assertTrue(paramname in self.param_if_pool.params_args) # make sure the service backend has been created self.assertTrue(paramname in self.param_if_pool.params.keys()) finally: rospy.delete_param(paramname)
def test_service_appear_update_expose(self): """ Test service exposing functionality for a service which already exists in the ros environment. Normal usecase Sequence : (UPDATE?) -> APPEAR -> UPDATE -> EXPOSE (-> UPDATE?) :return: """ servicename = '/test/absentsrv1' # every added service should be in the list of args self.assertTrue(servicename not in self.service_if_pool.services_args) # the backend should not have been created self.assertTrue(servicename not in self.service_if_pool.services.keys()) # First update should not change state services, service_types = self.get_system_state() dt = self.service_if_pool.update(services, service_types) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # every added service should be in the list of args self.assertTrue(servicename not in self.service_if_pool.services_args) # the backend should not have been created self.assertTrue(servicename not in self.service_if_pool.services.keys()) # create the service and then try exposing the service again, simulating # it coming online before expose call. nonexistent_srv = rospy.Service(servicename, EmptySrv, srv_cb) try: with Timeout(5) as t: while not t.timed_out and nonexistent_srv.resolved_name not in self.service_if_pool.services_available: services, service_types = self.get_system_state() dt = self.service_if_pool.update(services, service_types) self.assertEqual(dt.added, []) # nothing added (not exposed yet) self.assertEqual(dt.removed, []) # nothing removed time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) # every added service should be in the list of args self.assertTrue(servicename not in self.service_if_pool.services_args) # the backend should not have been created self.assertTrue(servicename not in self.service_if_pool.services.keys()) # here we are sure the interface knows the service is available # it will be exposed right now dt = self.service_if_pool.expose_services([servicename]) self.assertTrue(servicename in dt.added) # servicename added self.assertEqual(dt.removed, []) # nothing removed # every exposed service should remain in the list of args ( in case regex match another service ) self.assertTrue(servicename in self.service_if_pool.services_args) # make sure the service backend has been created self.assertTrue(servicename in self.service_if_pool.services.keys()) finally: nonexistent_srv.shutdown('testing complete')
def test_subscriber_appear_expose_update(self): """ Test topic exposing functionality for a topic which already exists in the ros environment. Simple Normal usecase Sequence : APPEAR -> EXPOSE -> UPDATE :return: """ topicname = '/test/string' self.subscriber_if_pool.expose_subscribers([topicname]) # every added topic should be in the list of args self.assertTrue(topicname in self.subscriber_if_pool.subscribers_args) # topic backend has not been created since the update didn't run yet self.assertTrue( topicname not in self.subscriber_if_pool.subscribers.keys()) dt = DiffTuple([], []) # NOTE : We need to wait to make sure the tests nodes are started... with Timeout(5) as t: while not t.timed_out and topicname not in dt.added: subscribers, topic_types = self.get_system_state() dt = self.subscriber_if_pool.update(subscribers, topic_types) time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) self.assertTrue(topicname in dt.added) # has been detected # every exposed topic should remain in the list of args ( in case regex match another topic ) self.assertTrue(topicname in self.subscriber_if_pool.subscribers_args) # make sure the topic backend has been created self.assertTrue( topicname in self.subscriber_if_pool.subscribers.keys()) # cleaning up self.subscriber_if_pool.expose_subscribers([]) # every added topic should be in the list of args self.assertTrue( topicname not in self.subscriber_if_pool.subscribers_args) # topic backend has not been created since the update didn't run yet self.assertTrue( topicname not in self.subscriber_if_pool.subscribers.keys())
def test_publisher_update_disappear_withhold(self): """ Test topic exposing functionality for a topic which already exists in the ros environment. Simple Normal usecase Sequence : UPDATE -> DISAPPEAR -> WITHHOLD :return: """ topicname = '/test/nonexistent5' # every added topic should be in the list of args self.assertTrue( topicname not in self.publisher_if_pool.publishers_args) # the backend should not have been created self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) # First update should not change state publishers, topic_types = self.get_system_state() dt = self.publisher_if_pool.update(publishers, topic_types) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # every added topic should be in the list of args self.assertTrue( topicname not in self.publisher_if_pool.publishers_args) # the backend should not have been created self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) dt = self.publisher_if_pool.expose_publishers([topicname]) self.assertEqual(dt.added, []) # nothing added yet ( not existing ) self.assertEqual(dt.removed, []) # nothing removed # every added topic should be in the list of args self.assertTrue(topicname in self.publisher_if_pool.publishers_args) # topic backend has not been created self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) # create the publisher and then try exposing the topic again, simulating # it coming online before expose call. nonexistent_pub = rospy.Publisher(topicname, Empty, queue_size=1) with Timeout(5) as t: dt = DiffTuple([], []) while not t.timed_out and nonexistent_pub.resolved_name not in dt.added: publishers, topic_types = self.get_system_state() dt = self.publisher_if_pool.update(publishers, topic_types) self.assertEqual(dt.removed, []) # nothing removed time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) self.assertTrue(nonexistent_pub.resolved_name in dt.added) # added now because it just appeared self.assertEqual(dt.removed, []) # nothing removed # TODO : do we need a test with subscriber ? # every added topic should be in the list of args self.assertTrue(topicname in self.publisher_if_pool.publishers_args) # topic backend has been created self.assertTrue(topicname in self.publisher_if_pool.publishers.keys()) # up to here possible sequences should have been already tested by previous tests # Now comes our actual disappearrence / withholding test nonexistent_pub.unregister( ) # https://github.com/ros/ros_comm/issues/111 ( topic is still registered on master... ) # TODO : test disappear ( how ? ) # every added topic should be in the list of args self.assertTrue(topicname in self.publisher_if_pool.publishers_args) # the backend should STILL be there self.assertTrue(topicname in self.publisher_if_pool.publishers.keys()) # Note the Topic implementation should take care of possible errors in this case self.publisher_if_pool.expose_publishers([]) # every withhold topic should NOT be in the list of args self.assertTrue( topicname not in self.publisher_if_pool.publishers_args) # topic backend should NOT be there any longer self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys())
def test_publisher_withhold_update_disappear(self): """ Test topic withholding functionality for a topic which doesnt exists anymore in the ros environment. Normal usecase Sequence : (-> UPDATE ?) -> WITHHOLD -> UPDATE -> DISAPPEAR (-> UPDATE ?) :return: """ topicname = '/test/nonexistent3' # every added topic should be in the list of args self.assertTrue( topicname not in self.publisher_if_pool.publishers_args) # the backend should not have been created self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) # First update should not change state publishers, topic_types = self.get_system_state() dt = self.publisher_if_pool.update(publishers, topic_types) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # every added topic should be in the list of args self.assertTrue( topicname not in self.publisher_if_pool.publishers_args) # the backend should not have been created self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) # create the publisher and then try exposing the topic again, simulating # it coming online before expose call. nonexistent_pub = rospy.Publisher(topicname, Empty, queue_size=1) with Timeout(5) as t: while not t.timed_out and topicname not in self.publisher_if_pool.publishers_available: publishers, topic_types = self.get_system_state() dt = self.publisher_if_pool.update(publishers, topic_types) self.assertEqual(dt.added, []) # nothing added (not exposed) self.assertEqual(dt.removed, []) # nothing removed time.sleep(0.1) # to avoid spinning out of control # TODO : do we need a test with subscriber ? self.assertTrue(not t.timed_out) # topic should be in the list of args yet (not exposed) self.assertTrue( topicname not in self.publisher_if_pool.publishers_args) # the backend should not have been created self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) # Here we are sure the internal state has topic_name registered # will be exposed right away dt = self.publisher_if_pool.expose_publishers([topicname]) self.assertTrue(topicname in dt.added) # detected and added self.assertEqual(dt.removed, []) # nothing removed # every exposed topic should remain in the list of args ( in case regex match another topic ) self.assertTrue(topicname in self.publisher_if_pool.publishers_args) # make sure the topic backend has been created self.assertTrue(topicname in self.publisher_if_pool.publishers.keys()) publishers, topic_types = self.get_system_state() dt = self.publisher_if_pool.update(publishers, topic_types) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # every withhold topic should STILL be in the list of args self.assertTrue(topicname in self.publisher_if_pool.publishers_args) # topic backend should STILL be there self.assertTrue(topicname in self.publisher_if_pool.publishers.keys()) dt = self.publisher_if_pool.expose_publishers([]) self.assertTrue(topicname in dt.removed) # removed self.assertEqual(dt.added, []) # nothing added # every withhold topic should NOT be in the list of args self.assertTrue( topicname not in self.publisher_if_pool.publishers_args) # topic backend should be GONE self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) publishers, topic_types = self.get_system_state() dt = self.publisher_if_pool.update(publishers, topic_types) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # every withhold topic should NOT be in the list of args self.assertTrue( topicname not in self.publisher_if_pool.publishers_args) # topic backend should be GONE self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) nonexistent_pub.unregister() publishers, topic_types = self.get_system_state() dt = self.publisher_if_pool.update(publishers, topic_types) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # every withhold topic should NOT be in the list of args self.assertTrue( topicname not in self.publisher_if_pool.publishers_args) # topic backend should be GONE self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) # Waiting a bit until the system state is back as expected (with connection cache this can be delayed) with Timeout(5) as t: while not t.timed_out and not topicname in self.publisher_if_pool.publishers_available: time.sleep(1)
def test_publisher_expose_appear_update(self): """ Test basic topic adding functionality for a topic which does not yet exist in the ros environment ( + corner cases ) Sequence : (UPDATE? ->) -> EXPOSE -> (UPDATE? ->) APPEAR -> UPDATE :return: """ topicname = '/test/nonexistent2' # every added topic should be in the list of args self.assertTrue( topicname not in self.publisher_if_pool.publishers_args) # the backend should not have been created self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) # First update should not change state publishers, topic_types = self.get_system_state() dt = self.publisher_if_pool.update(publishers, topic_types) self.assertTrue(topicname not in dt.added) # not detected # every added topic should be in the list of args self.assertTrue( topicname not in self.publisher_if_pool.publishers_args) # the backend should not have been created self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) self.publisher_if_pool.expose_publishers([topicname]) # every added topic should be in the list of args self.assertTrue(topicname in self.publisher_if_pool.publishers_args) # the backend should not have been created self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) publishers, topic_types = self.get_system_state() dt = self.publisher_if_pool.update(publishers, topic_types) self.assertTrue(topicname not in dt.added) # not detected # make sure the topic is STILL in the list of args self.assertTrue(topicname in self.publisher_if_pool.publishers_args) # make sure the topic backend has STILL not been created self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys()) # create the publisher and then try updating again, simulating # it coming online after expose call. nonexistent_pub = rospy.Publisher(topicname, Empty, queue_size=1) with Timeout(5) as t: while not t.timed_out and topicname not in dt.added: publishers, topic_types = self.get_system_state() dt = self.publisher_if_pool.update(publishers, topic_types) self.assertEqual(dt.removed, []) # nothing removed time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) self.assertTrue(topicname in dt.added) # detected # TODO : do we need a test with subscriber ? # every exposed topic should remain in the list of args ( in case regex match another topic ) self.assertTrue(topicname in self.publisher_if_pool.publishers_args) # make sure the topic backend has been created self.assertTrue(topicname in self.publisher_if_pool.publishers.keys()) # removing publisher nonexistent_pub.unregister( ) # https://github.com/ros/ros_comm/issues/111 ( topic is still registered on master... ) # and update should be enough to cleanup with Timeout(5) as t: while not t.timed_out and not topicname in dt.removed: publishers, topic_types = self.get_system_state() dt = self.publisher_if_pool.update(publishers, topic_types) self.assertEqual(dt.added, []) # nothing added time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) self.assertTrue(topicname in dt.removed) self.assertTrue( topicname not in self.publisher_if_pool.publishers_available) # every exposed topic should still be in the list of args self.assertTrue(topicname in self.publisher_if_pool.publishers_args) # the backend should not be there any longer self.assertTrue( topicname not in self.publisher_if_pool.publishers.keys())
def test_service_withhold_update_disappear(self): """ Test service witholding functionality for a service which doesnt exists anymore in the ros environment. Normal usecase. Sequence : (-> UPDATE ?) -> WITHHOLD -> UPDATE -> DISAPPEAR (-> UPDATE ?) :return: """ servicename = '/test/absentsrv1' # every added service should be in the list of args self.assertTrue(servicename not in self.service_if_pool.services_args) # the backend should not have been created self.assertTrue(servicename not in self.service_if_pool.services.keys()) self.service_if_pool.expose_services([servicename]) # every added service should be in the list of args self.assertTrue(servicename in self.service_if_pool.services_args) # service backend has NOT been created yet self.assertTrue(servicename not in self.service_if_pool.services.keys()) dt = DiffTuple([], []) # create the service and then try updating again, simulating # it coming online after expose call. nonexistent_srv = rospy.Service(servicename, EmptySrv, srv_cb) try: # wait here until service actually appear in cache proxy with Timeout(5) as t: while not t.timed_out and nonexistent_srv.resolved_name not in dt.added: services, service_types = self.get_system_state() dt = self.service_if_pool.update(services, service_types) self.assertEqual(dt.removed, []) # nothing removed time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) self.assertTrue(nonexistent_srv.resolved_name in dt.added) # nonexistent_srv added self.assertEqual(dt.removed, []) # nothing removed # every withhold service should STILL be in the list of args self.assertTrue(servicename in self.service_if_pool.services_args) # service backend has been created self.assertTrue(servicename in self.service_if_pool.services.keys()) dt = self.service_if_pool.expose_services([]) self.assertEqual(dt.added, []) # nothing added self.assertTrue(nonexistent_srv.resolved_name in dt.removed) # nonexistent_srv removed # every withhold service should NOT be in the list of args self.assertTrue(servicename not in self.service_if_pool.services_args) # service backend should be GONE self.assertTrue(servicename not in self.service_if_pool.services.keys()) services, service_types = self.get_system_state() dt = self.service_if_pool.update(services, service_types) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # every withhold service should STILL NOT be in the list of args self.assertTrue(servicename not in self.service_if_pool.services_args) # service backend should be GONE self.assertTrue(servicename not in self.service_if_pool.services.keys()) finally: nonexistent_srv.shutdown('testing disappearing service') services, service_types = self.get_system_state() dt = self.service_if_pool.update(services, service_types) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nonexistent_srv already removed # every withhold service should STILL NOT be in the list of args self.assertTrue(servicename not in self.service_if_pool.services_args) # service backend should be GONE self.assertTrue(servicename not in self.service_if_pool.services.keys())
def test_rosnode_services( self): # Here we check that this node actually discovers services # Starting underlying system before rospy.set_param( '/string_echo/topic_name', '~topic') # private names to not mess things up too much rospy.set_param('/string_echo/echo_topic_name', '~echo_topic') rospy.set_param('/string_echo/echo_service_name', '~echo_service') string_echo_node = roslaunch.core.Node('pyros_test', 'echo.py', name='string_echo') try: string_echo_process = self.launch.launch(string_echo_node) except roslaunch.RLException as rlexc: logging.error( "pyros_test is needed to run this test. Please verify that it is installed in your ROS environment" ) raise try: # Starting PyrosROS with preconfigured services to expose rosn = PyrosROS( kwargs={ 'services': ['/string_echo/echo_service'], 'enable_cache': self.enable_cache }) # careful assuming the service fullname here try: nose.tools.assert_true(not rosn.is_alive()) rosn.start() nose.tools.assert_true(rosn.is_alive()) print("Discovering services Service...") services = pyzmp.discover( "services", 5) # we wait a bit to let it time to start nose.tools.assert_true(services is not None) print("services providers : {svc}".format( svc=services.providers)) nose.tools.assert_equal(len(services.providers), 1) nose.tools.assert_true( rosn.name in [p[0] for p in services.providers]) res = services.call() # What we get here is non deterministic # however we can wait for service to be detected to make sure we get it after some time with Timeout(5) as t: while not t.timed_out and not '/string_echo/echo_service' in res.keys( ): rospy.rostime.wallsleep(1) res = services.call() nose.tools.assert_true('/string_echo/echo_service' in res.keys( )) # echo_service has been created, detected and exposed finally: # finishing PyrosROS process if rosn is not None and rosn.is_alive(): rosn.shutdown() nose.tools.assert_true(not rosn.is_alive()) finally: # finishing string_pub_process if string_echo_process is not None and string_echo_process.is_alive( ): string_echo_process.stop() nose.tools.assert_true(not string_echo_process.is_alive())
def test_param_disappear_update_withhold(self): """ Test param exposing functionality for a param which already exists in the ros environment. Normal usecase Sequence : (UPDATE? ->) DISAPPEAR -> UPDATE -> WITHHOLD (-> UPDATE ?) :return: """ paramname = '/test/absentparam1' # param should not be in the list of args self.assertTrue(paramname not in self.param_if_pool.params_args) # the backend should not have been created self.assertTrue(paramname not in self.param_if_pool.params.keys()) self.param_if_pool.expose_params([paramname]) # every added param should be in the list of args self.assertTrue(paramname in self.param_if_pool.params_args) # param backend has NOT been created yet self.assertTrue(paramname not in self.param_if_pool.params.keys()) # create the param and then try updating again, simulating # it coming online after expose call. rospy.set_param(paramname, 'param_value') try: params = self.get_system_state() dt = self.param_if_pool.update(params) self.assertTrue(paramname in dt.added) # paramname added self.assertEqual(dt.removed, []) # nothing removed # param should be in the list of args self.assertTrue(paramname in self.param_if_pool.params_args) # the backend should have been created self.assertTrue(paramname in self.param_if_pool.params.keys()) # up to here possible sequences should have been already tested by previous tests # Now comes our actual disappearance / withholding test finally: rospy.delete_param(paramname) # every added param should be in the list of args self.assertTrue(paramname in self.param_if_pool.params_args) # the backend should STILL be there self.assertTrue(paramname in self.param_if_pool.params.keys()) # Note the param implementation should take care of possible errors in this case # wait here until param actually disappear from cache proxy with Timeout(5) as t: while not t.timed_out and paramname not in dt.removed: params = self.get_system_state() dt = self.param_if_pool.update(params) self.assertEqual(dt.added, []) # nothing added time.sleep(0.1) # to avoid spinning out of control self.assertTrue(not t.timed_out) self.assertTrue(paramname in dt.removed) # nonexistent_srv removed # every exposed param should remain in the list of args ( in case regex match another service ) self.assertTrue(paramname in self.param_if_pool.params_args) # make sure the param backend should NOT be there any longer self.assertTrue(paramname not in self.param_if_pool.params.keys()) # TODO : test that coming back actually works self.param_if_pool.expose_params([]) # every withhold param should NOT be in the list of args self.assertTrue(paramname not in self.param_if_pool.params_args) # param backend has not been created self.assertTrue(paramname not in self.param_if_pool.params.keys()) params = self.get_system_state() dt = self.param_if_pool.update(params) self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # every withhold param should NOT be in the list of args self.assertTrue(paramname not in self.param_if_pool.params_args) # make sure the param backend has been created self.assertTrue(paramname not in self.param_if_pool.params.keys())
def test_rosnode_services_setup( self ): # Here we check that this node actually provides all the services rosn = PyrosROS() try: nose.tools.assert_true(not rosn.is_alive()) rosn.start() nose.tools.assert_true(rosn.is_alive()) print("Discovering services Service...") services = pyzmp.discover( "services", 5) # we wait a bit to let it time to start nose.tools.assert_true(services is not None) print("services providers : {svc}".format(svc=services.providers)) nose.tools.assert_equal(len(services.providers), 1) nose.tools.assert_true( rosn.name in [p[0] for p in services.providers]) res = services.call() nose.tools.assert_true('echo_service' not in res.keys( )) # test_topic has not been created, detected or exposed print("Discovering setup Service...") setup = pyzmp.discover("setup", 5) # we wait a bit to let it time to start nose.tools.assert_true(setup is not None) print("setup providers : {svc}".format(svc=setup.providers)) nose.tools.assert_equal(len(setup.providers), 1) nose.tools.assert_true( rosn.name in [p[0] for p in setup.providers]) rospy.set_param( '/string_echo/topic_name', '~topic') # private names to not mess things up too much rospy.set_param('/string_echo/echo_topic_name', '~echo_topic') rospy.set_param('/string_echo/echo_service_name', '~echo_service') string_echo_node = roslaunch.core.Node('pyros_test', 'echo.py', name='string_echo') string_echo_process = self.launch.launch(string_echo_node) try: new_config = setup.call( kwargs={ 'services': ['/string_echo/echo_service'], 'topics': [], 'params': [], 'enable_cache': self.enable_cache, }) # What we get here is non deterministic # however we can wait for topic to be detected to make sure we get it after some time res = services.call() with Timeout(5) as t: while not t.timed_out and not '/string_echo/echo_service' in res.keys( ): rospy.rostime.wallsleep(1) res = services.call() nose.tools.assert_true('/string_echo/echo_service' in res.keys( )) # test_topic has been created, detected and exposed finally: # finishing all processes if string_echo_process is not None and string_echo_process.is_alive( ): string_echo_process.stop() nose.tools.assert_true(not string_echo_process.is_alive()) finally: # finishing PyrosROS process if rosn is not None and rosn.is_alive(): rosn.shutdown() nose.tools.assert_true(not rosn.is_alive())