def setUp(self): 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 setUp(self): 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 = TestRosInterface.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.strpub = rospy.Publisher('/test/string', String, queue_size=1) self.emppub = rospy.Publisher('/test/empty', Empty, queue_size=1) self.interface = RosInterface(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.interface.expose_services([servicename]) # every added service should be in the list of args self.assertTrue(servicename in self.interface.services_args) # service backend has not been created since the update didn't run yet self.assertTrue(servicename not in self.interface.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[0]: dt = self.interface.update() # TODO : improve that by providing an easier interface for it. # every exposed service should remain in the list of args ( in case regex match another service ) self.assertTrue(servicename in self.interface.services_args) # make sure the service backend has been created self.assertTrue(servicename in self.interface.services.keys())
def appear_disappear(): # create the publisher and then try exposing the topic again, simulating # it coming online before expose call. nonexistent_pub = TopicBack._create_pub(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: dt = self.interface.update() self.assertEqual(dt.removed, []) # nothing removed 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.interface.topics_args) # topic backend has been created self.assertTrue(topicname in self.interface.topics.keys()) # up to here possible sequences should have been already tested by previous tests # Now comes our actual disappearance / withholding test TopicBack._remove_pub(nonexistent_pub) # every added topic should be in the list of args self.assertTrue(topicname in self.interface.topics_args) # the backend should STILL be there self.assertTrue(topicname in self.interface.topics.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: dt = self.interface.update() self.assertEqual(dt.added, []) # nothing added 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.interface.topics_args) # make sure the topic backend should NOT be there any longer self.assertTrue(topicname not in self.interface.topics.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.interface.services_args) # the backend should not have been created self.assertTrue(servicename not in self.interface.services.keys()) # First update should not change state dt = self.interface.update() 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.interface.services_args) # the backend should not have been created self.assertTrue(servicename not in self.interface.services.keys()) self.interface.expose_services([servicename]) # every added service should be in the list of args self.assertTrue(servicename in self.interface.services_args) # the backend should not have been created self.assertTrue(servicename not in self.interface.services.keys()) dt = self.interface.update() 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.interface.services_args) # make sure the service backend has STILL not been created self.assertTrue(servicename not in self.interface.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: dt = self.interface.update() self.assertEqual(dt.removed, []) # nothing removed 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.interface.services_args) # make sure the service backend has been created self.assertTrue(servicename in self.interface.services.keys()) finally: nonexistent_srv.shutdown('testing complete')
def test_topic_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.interface.topics_args) # the backend should not have been created self.assertTrue(topicname not in self.interface.topics.keys()) # First update should not change state dt = self.interface.update() 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.interface.topics_args) # the backend should not have been created self.assertTrue(topicname not in self.interface.topics.keys()) self.interface.expose_topics([topicname]) # every added topic should be in the list of args self.assertTrue(topicname in self.interface.topics_args) # the backend should not have been created self.assertTrue(topicname not in self.interface.topics.keys()) dt = self.interface.update() 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.interface.topics_args) # make sure the topic backend has STILL not been created self.assertTrue(topicname not in self.interface.topics.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: dt = self.interface.update() self.assertEqual(dt.removed, []) # nothing removed 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.interface.topics_args) # make sure the topic backend has been created self.assertTrue(topicname in self.interface.topics.keys()) nonexistent_pub.unregister() # https://github.com/ros/ros_comm/issues/111 ( topic is still registered on master... )
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.interface.services_args) # the backend should not have been created self.assertTrue(servicename not in self.interface.services.keys()) # First update should not change state dt = self.interface.update() 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.interface.services_args) # the backend should not have been created self.assertTrue(servicename not in self.interface.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.interface.services_available: dt = self.interface.update() self.assertEqual(dt.added, []) # nothing added (not exposed yet) self.assertEqual(dt.removed, []) # nothing removed # every added service should be in the list of args self.assertTrue(servicename not in self.interface.services_args) # the backend should not have been created self.assertTrue(servicename not in self.interface.services.keys()) # here we are sure the interface knows the service is available # it will be exposed right now self.interface.expose_services([servicename]) # every exposed service should remain in the list of args ( in case regex match another service ) self.assertTrue(servicename in self.interface.services_args) # make sure the service backend has been created self.assertTrue(servicename in self.interface.services.keys()) finally: nonexistent_srv.shutdown('testing complete')
def test_topic_appear_update_expose(self): """ Test topic exposing functionality for a topic which already exists in the ros environment. Normal usecase Sequence : (UPDATE?) -> APPEAR -> UPDATE -> EXPOSE (-> UPDATE?) :return: """ topicname = '/test/nonexistent1' # every added topic should be in the list of args self.assertTrue(topicname not in self.interface.topics_args) # the backend should not have been created self.assertTrue(topicname not in self.interface.topics.keys()) # First update should not change state dt = self.interface.update() 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.interface.topics_args) # the backend should not have been created self.assertTrue(topicname not in self.interface.topics.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 nonexistent_pub.resolved_name not in self.interface.topics_available: dt = self.interface.update() self.assertEqual(dt.added, []) # nothing added (not exposed yet) self.assertEqual(dt.removed, []) # nothing removed self.assertTrue(not t.timed_out) # TODO : do we need a test with subscriber ? # every added topic should be in the list of args self.assertTrue(topicname not in self.interface.topics_args) # the backend should not have been created self.assertTrue(topicname not in self.interface.topics.keys()) self.interface.expose_topics([topicname]) # every exposed topic should remain in the list of args ( in case regex match another topic ) self.assertTrue(topicname in self.interface.topics_args) # make sure the topic backend has been created self.assertTrue(topicname in self.interface.topics.keys()) nonexistent_pub.unregister() # https://github.com/ros/ros_comm/issues/111 ( topic is still registered on master... )
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 = zmp.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 = zmp.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())
def test_rosnode_services( self): # Here we check that this node actually discovers topics # 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 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 = zmp.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_service_disappear_update_withhold(self): """ Test service exposing functionality for a service which already exists in the ros environment. Normal usecase Sequence : (UPDATE? ->) DISAPPEAR -> UPDATE -> WITHHOLD (-> UPDATE ?) :return: """ servicename = '/test/absentsrv1' # service should not be in the list of args self.assertTrue(servicename not in self.interface.services_args) # the backend should not have been created self.assertTrue(servicename not in self.interface.services.keys()) self.interface.expose_services([servicename]) # every added service should be in the list of args self.assertTrue(servicename in self.interface.services_args) # service backend has NOT been created yet self.assertTrue(servicename not in self.interface.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: dt = self.interface.update() self.assertTrue(nonexistent_srv.resolved_name in dt.added) # nonexistent added self.assertEqual(dt.removed, []) # nothing removed # service should be in the list of args self.assertTrue(servicename in self.interface.services_args) # the backend should have been created self.assertTrue(servicename in self.interface.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.interface.services_args) # the backend should STILL be there self.assertTrue(servicename in self.interface.services.keys()) # Note the service implementation should take care of possible errors in this case # wait here until service actually disappear from cache proxy with timeout(5) as t: while not t.timed_out and nonexistent_srv.resolved_name not in dt.removed: dt = self.interface.update() self.assertEqual(dt.added, []) # nothing added self.assertTrue(nonexistent_srv.resolved_name in dt.removed) # nonexistent_srv removed # every exposed service should remain in the list of args ( in case regex match another service ) self.assertTrue(servicename in self.interface.services_args) # make sure the service backend should NOT be there any longer self.assertTrue(servicename not in self.interface.services.keys()) # TODO : test that coming back actually works self.interface.expose_services([]) # every withhold service should NOT be in the list of args self.assertTrue(servicename not in self.interface.services_args) # service backend has not been created self.assertTrue(servicename not in self.interface.services.keys()) dt = self.interface.update() self.assertEqual(dt.added, []) # nothing added self.assertEqual(dt.removed, []) # nothing removed # every withhold service should NOT be in the list of args self.assertTrue(servicename not in self.interface.services_args) # make sure the service backend has been created self.assertTrue(servicename not in self.interface.services.keys())
def test_topic_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.interface.topics_args) # the backend should not have been created self.assertTrue(topicname not in self.interface.topics.keys()) # First update should not change state dt = self.interface.update() 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.interface.topics_args) # the backend should not have been created self.assertTrue(topicname not in self.interface.topics.keys()) dt = self.interface.expose_topics([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.interface.topics_args) # topic backend has not been created self.assertTrue(topicname not in self.interface.topics.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: dt = self.interface.update() self.assertEqual(dt.removed, []) # nothing removed 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.interface.topics_args) # topic backend has been created self.assertTrue(topicname in self.interface.topics.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.interface.topics_args) # the backend should STILL be there self.assertTrue(topicname in self.interface.topics.keys()) # Note the Topic implementation should take care of possible errors in this case self.interface.expose_topics([]) # every withhold topic should NOT be in the list of args self.assertTrue(topicname not in self.interface.topics_args) # topic backend should NOT be there any longer self.assertTrue(topicname not in self.interface.topics.keys())
def test_topic_withhold_update_disappear(self): """ Test topic witholding 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.interface.topics_args) # the backend should not have been created self.assertTrue(topicname not in self.interface.topics.keys()) # First update should not change state dt = self.interface.update() 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.interface.topics_args) # the backend should not have been created self.assertTrue(topicname not in self.interface.topics.keys()) # create the publisher and then try exposing the topic again, simulating # it coming online before expose call. nonexistent_pub = TopicBack._create_pub(topicname, Empty, queue_size=1) with timeout(5) as t: while not t.timed_out and topicname not in self.interface.topics_available: dt = self.interface.update() self.assertEqual(dt.added, []) # nothing added (not exposed) self.assertEqual(dt.removed, []) # nothing removed # 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.interface.topics_args) # the backend should not have been created self.assertTrue(topicname not in self.interface.topics.keys()) # Here we are sure the internal state has topic_name registered # will be exposed right away dt = self.interface.expose_topics([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.interface.topics_args) # make sure the topic backend has been created self.assertTrue(topicname in self.interface.topics.keys()) dt = self.interface.update() 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.interface.topics_args) # topic backend should STILL be there self.assertTrue(topicname in self.interface.topics.keys()) dt = self.interface.expose_topics([]) 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.interface.topics_args) # topic backend should be GONE self.assertTrue(topicname not in self.interface.topics.keys()) dt = self.interface.update() 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.interface.topics_args) # topic backend should be GONE self.assertTrue(topicname not in self.interface.topics.keys()) TopicBack._remove_pub(nonexistent_pub) dt = self.interface.update() 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.interface.topics_args) # topic backend should be GONE self.assertTrue(topicname not in self.interface.topics.keys())