00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import os
00036 import sys
00037 import string
00038 import time
00039 try:
00040 from xmlrpc.client import ServerProxy
00041 except ImportError:
00042 from xmlrpclib import ServerProxy
00043
00044 import rospy
00045 import rosgraph
00046
00047 from rosclient import *
00048
00049 NODE_INTEGRATION_NAME = "node_integration_test"
00050
00051 _name = None
00052
00053
00054 def set_node_name(name):
00055 global _name
00056 _name = name
00057
00058
00059
00060
00061 def get_caller_id():
00062 if _name is None:
00063 raise Exception("set_node_name has not been called yet")
00064 ros_ns = os.environ.get(rosgraph.ROS_NAMESPACE, rosgraph.names.GLOBALNS)
00065 return rosgraph.names.ns_join(ros_ns, _name)
00066
00067 class _MasterTestCase(TestRosClient):
00068
00069 def __init__(self, *args):
00070 super(_MasterTestCase, self).__init__(*args)
00071 self.ns = os.environ.get(rosgraph.ROS_NAMESPACE, rosgraph.names.GLOBALNS)
00072 self.caller_id = get_caller_id()
00073
00074 def setUp(self):
00075 super(_MasterTestCase, self).setUp()
00076 self.master_uri = os.environ.get(rosgraph.ROS_MASTER_URI, None)
00077 self._checkUri(self.master_uri)
00078 self.master = ServerProxy(self.master_uri)
00079
00080
00081 def _checkUri(self, uri):
00082 import urlparse
00083 parsed = urlparse.urlparse(uri)
00084 self.assert_(parsed[0] in ['http', 'https'], 'protocol [%s] in [%s] invalid'%(parsed[0], uri))
00085 self.assert_(parsed[1], 'host missing [%s]'%uri)
00086 if not sys.version.startswith('2.4'):
00087 self.assert_(parsed.port, 'port missing/invalid [%s]'%uri)
00088
00089
00090 class MasterApiTestCase(_MasterTestCase):
00091
00092
00093 def _testGetMasterUri(self):
00094
00095 self.apiError(self.master.getMasterUri())
00096
00097 uri = self.apiSuccess(self.master.getMasterUri(self.caller_id))
00098 self._checkUri(uri)
00099
00100
00101 import urlparse
00102 parsed = urlparse.urlparse(uri)
00103 parsed2 = urlparse.urlparse(self.master_uri)
00104
00105 self.assertEquals(parsed.port, parsed2.port, "expected ports do not match")
00106
00107
00108 def _testGetPid(self):
00109
00110 self.apiError(self.master.getPid())
00111
00112 pid = self.apiSuccess(self.master.getPid(self.caller_id))
00113 self.assert_(pid > 0)
00114
00115
00116 def _testGetUri(self):
00117
00118 self.apiError(self.master.getUri())
00119
00120 uri = self.apiSuccess(self.master.getUri(self.caller_id))
00121 self.assert_(type(uri) == str)
00122
00123
00124 def _subTestRegisterServiceSuccess(self):
00125 master = self.master
00126
00127 caller_id = '/service_node'
00128 caller_api = 'http://localhost:4567/'
00129 service_base = '/service'
00130
00131
00132 for i in range(0, 10):
00133 service_name = "%s-%s"%(service_base, i)
00134 service_api = 'rosrpc://localhost:123%s/'%i
00135
00136 self.apiSuccess(master.registerService(caller_id, service_name, service_api, caller_api))
00137
00138 val = self.apiSuccess(master.lookupService(caller_id, service_name))
00139 self.assertEquals(service_api, val)
00140 val = self.apiSuccess(master.lookupNode(self.caller_id, caller_id))
00141 self.assertEquals(caller_api, val)
00142
00143 _, _, srvs = self.apiSuccess(master.getSystemState(self.caller_id))
00144 for j in range(0, i+1):
00145 jservice_name = "%s-%s"%(service_base, j)
00146 jentry = [jservice_name, [caller_id]]
00147 self.assert_(jentry in srvs, "master service list %s is missing %s"%(srvs, jentry))
00148
00149
00150
00151
00152
00153 def _testRegisterServiceSuccess(self):
00154 self._subTestRegisterServiceSuccess()
00155
00156 def _testUnregisterServiceSuccess(self):
00157 self._subTestRegisterServiceSuccess()
00158 master = self.master
00159 caller_id = '/service_node'
00160 caller_api = 'http://localhost:4567/'
00161 service_base = '/service'
00162
00163 for i in range(0, 10):
00164 service_name = "%s-%s"%(service_base, i)
00165 service_api = 'rosrpc://localhost:123%s/'%i
00166
00167
00168 code, msg, val = master.unregisterService(caller_id, service_name, service_api)
00169 self.assertEquals(code, 1, "code != 1, return message was [%s]"%msg)
00170
00171
00172 self.apiError(master.lookupService(self.caller_id, service_name), "master has a reference to unregistered service. message from master for unregister was [%s]"%msg)
00173
00174 if i < 9:
00175 val = self.apiSuccess(master.lookupNode(self.caller_id, caller_id))
00176 self.assertEquals(caller_api, val, "master prematurely invalidated node entry for [%s] (lookupNode)"%caller_id)
00177
00178 _, _, srvs = self.apiSuccess(master.getSystemState(self.caller_id))
00179 for j in range(0, i+1):
00180 jservice_name = "%s-%s"%(service_base, j)
00181 jentry = [jservice_name, [caller_id]]
00182 self.assert_(jentry not in srvs, "master service list %s should not have %s"%(srvs, jentry))
00183 for j in range(i+1, 10):
00184 jservice_name = "%s-%s"%(service_base, j)
00185 jentry = [jservice_name, [caller_id]]
00186 self.assert_(jentry in srvs, "master service list %s is missing %s"%(srvs, jentry))
00187
00188
00189
00190
00191
00192
00193 self.apiError(master.lookupNode(self.caller_id, caller_id), "master has a stale reference to unregistered service node API")
00194 _, _, srvs = self.apiSuccess(master.getSystemState(self.caller_id))
00195 srvs = [s for s in srvs if not s[0].startswith('/rosout/') and not s[0].endswith('/get_loggers') and not s[0].endswith('/set_logger_level')]
00196 self.assertEquals(0, len(srvs), "all services should have been unregistered: %s"%srvs)
00197
00198 def _testRegisterServiceInvalid(self):
00199 master = self.master
00200
00201 service = '/service'
00202 service_api = 'rosrpc://localhost:1234/'
00203 caller_api = 'http://localhost:4567/'
00204
00205
00206 self.apiError(master.registerService())
00207 self.apiError(master.registerService(self.caller_id, service))
00208 self.apiError(master.registerService(self.caller_id, service, service_api))
00209
00210
00211 self.apiError(master.registerService(self.caller_id, '', service_api, caller_api))
00212 self.apiError(master.registerService(self.caller_id, service, '', caller_api))
00213 self.apiError(master.registerService(self.caller_id, service, service_api, ''))
00214
00215 def _testUnregisterServiceInvalid(self):
00216 master = self.master
00217
00218 service = '/service'
00219 service_api = 'rosrpc://localhost:1234/'
00220
00221
00222 self.apiError(master.unregisterService())
00223 self.apiError(master.unregisterService(self.caller_id, service))
00224
00225
00226 self.apiError(master.unregisterService(self.caller_id, '', service_api))
00227 self.apiError(master.unregisterService(self.caller_id, service, ''))
00228
00229 def _testRegisterPublisherInvalid(self):
00230 master = self.master
00231
00232 topic = '/pub_topic'
00233 topic_type = 'test_rosmaster/String'
00234 caller_api = 'http://localhost:4567/'
00235
00236
00237 self.apiError(master.registerPublisher())
00238 self.apiError(master.registerPublisher(self.caller_id, topic))
00239 self.apiError(master.registerPublisher(self.caller_id, topic, topic_type))
00240
00241
00242 self.apiError(master.registerPublisher(self.caller_id, '', topic_type, caller_api))
00243 self.apiError(master.registerPublisher(self.caller_id, topic, '', caller_api))
00244 self.apiError(master.registerPublisher(self.caller_id, topic, topic_type, ''))
00245
00246 def _testUnregisterPublisherInvalid(self):
00247 master = self.master
00248
00249 topic = '/pub_topic'
00250 caller_api = 'http://localhost:4567/'
00251
00252
00253 self.apiError(master.unregisterPublisher())
00254 self.apiError(master.unregisterPublisher(self.caller_id, topic))
00255
00256
00257 self.apiError(master.unregisterPublisher(self.caller_id, '', caller_api))
00258 self.apiError(master.unregisterPublisher(self.caller_id, topic, ''))
00259
00260 def _testRegisterSubscriberInvalid(self):
00261 master = self.master
00262
00263 topic = '/sub_topic'
00264 topic_type = 'test_rosmaster/String'
00265 caller_api = 'http://localhost:4567/'
00266
00267
00268 self.apiError(master.registerSubscriber())
00269 self.apiError(master.registerSubscriber(self.caller_id, topic))
00270 self.apiError(master.registerSubscriber(self.caller_id, topic, topic_type))
00271
00272
00273 self.apiError(master.registerSubscriber(self.caller_id, '', topic_type, caller_api))
00274 self.apiError(master.registerSubscriber(self.caller_id, topic, '', caller_api))
00275 self.apiError(master.registerSubscriber(self.caller_id, topic, topic_type, ''))
00276
00277 def _testUnregisterSubscriberInvalid(self):
00278 master = self.master
00279
00280 topic = '/sub_topic'
00281 caller_api = 'http://localhost:4567/'
00282
00283
00284 self.apiError(master.registerSubscriber())
00285 self.apiError(master.registerSubscriber(self.caller_id, topic))
00286
00287
00288 self.apiError(master.unregisterSubscriber(self.caller_id, '', caller_api))
00289 self.apiError(master.unregisterSubscriber(self.caller_id, topic, ''))
00290
00291
00292 def _subTestRegisterPublisherSuccess(self):
00293 master = self.master
00294
00295 caller_id = '/pub_node'
00296 caller_api = 'http://localhost:4567/'
00297 topic_base = '/pub_topic'
00298 topic_type = 'test_rosmaster/String'
00299
00300
00301 for i in range(0, 10):
00302 topic_name = "%s-%s"%(topic_base, i)
00303
00304 self.apiSuccess(master.registerPublisher(caller_id, topic_name, topic_type, caller_api))
00305
00306
00307 val = self.apiSuccess(master.lookupNode(self.caller_id, caller_id))
00308 self.assertEquals(caller_api, val)
00309
00310 val = self.apiSuccess(master.getPublishedTopics(self.caller_id, '/'))
00311 self.assert_([topic_name, topic_type] in val, "master does not know topic type: %s"%val)
00312
00313 val = self.apiSuccess(master.getTopicTypes(self.caller_id))
00314 self.assert_([topic_name, topic_type] in val, "master does not know topic type: %s"%val)
00315
00316 pubs, _, _ = self.apiSuccess(master.getSystemState(self.caller_id))
00317 for j in range(0, i+1):
00318 jtopic_name = "%s-%s"%(topic_base, j)
00319 jentry = [jtopic_name, [caller_id]]
00320 self.assert_(jentry in pubs, "master pub/sub list %s is missing %s"%(pubs, jentry))
00321
00322
00323
00324
00325 def _testRegisterPublisherTypes(self):
00326 master = self.master
00327 caller_id = '/pub_node'
00328 caller_api = 'http://localhost:4567/'
00329 topic_name = '/type_test_pub_topic'
00330
00331
00332 val = self.apiSuccess(master.registerPublisher(caller_id, topic_name, '*', caller_api))
00333 self.assertEquals([], val)
00334 val = self.apiSuccess(master.getPublishedTopics(self.caller_id, '/'))
00335 self.assert_([topic_name, '*'] in val, "master is not reporting * as type: %s"%val)
00336
00337 val = self.apiSuccess(master.getTopicTypes(self.caller_id))
00338 self.assert_([topic_name, '*'] in val, "master is not reporting * as type: %s"%val)
00339
00340
00341 for t in ['test_rosmaster/String', '*']:
00342 val = self.apiSuccess(master.registerPublisher(caller_id, topic_name, t, caller_api))
00343 self.assertEquals([], val)
00344 val = self.apiSuccess(master.getPublishedTopics(self.caller_id, '/'))
00345 self.assert_([topic_name, 'test_rosmaster/String'] in val, "master is not reporting test_rosmaster/String as type: %s"%val)
00346
00347 val = self.apiSuccess(master.getTopicTypes(self.caller_id))
00348 self.assert_([topic_name, 'test_rosmaster/String'] in val, "master is not reporting test_rosmaster/String as type: %s"%val)
00349
00350
00351 def _testRegisterPublisherSuccess(self):
00352 self._subTestRegisterPublisherSuccess()
00353
00354
00355 master = self.master
00356 topic = '/pub_topic-0'
00357 type = 'test_rosmaster/String'
00358 pub_caller_api = 'http://localhost:4567/'
00359
00360 subs = []
00361 for i in range(5678, 5685):
00362 api = 'http://localhost:%s'%i
00363 subs.append(api)
00364 self.apiSuccess(master.registerSubscriber('/sub_node-%i'%i, topic, type, api))
00365 val = self.apiSuccess(master.registerPublisher('/pub_node', topic, type, pub_caller_api))
00366 self.assertEquals(subs, val)
00367
00368 def _testUnregisterPublisherSuccess(self):
00369 self._subTestRegisterPublisherSuccess()
00370 master = self.master
00371 caller_id = '/pub_node'
00372 caller_api = 'http://localhost:4567/'
00373 topic_base = '/pub_topic'
00374
00375 for i in range(0, 10):
00376 topic_name = "%s-%s"%(topic_base, i)
00377
00378
00379 code, msg, val = master.unregisterPublisher(caller_id, topic_name, caller_api)
00380 self.assertEquals(code, 1, "code != 1, return message was [%s]"%msg)
00381
00382
00383 if i < 9:
00384 val = self.apiSuccess(master.lookupNode(self.caller_id, caller_id))
00385 self.assertEquals(caller_api, val, "master prematurely invalidated node entry for [%s] (lookupNode)"%caller_id)
00386
00387 pubs, _, _ = self.apiSuccess(master.getSystemState(self.caller_id))
00388 for j in range(0, i+1):
00389 jtopic_name = "%s-%s"%(topic_base, j)
00390 jentry = [jtopic_name, [caller_id]]
00391 self.assert_(jentry not in pubs, "master pub/sub list %s should not have %s"%(pubs, jentry))
00392 for j in range(i+1, 10):
00393 jtopic_name = "%s-%s"%(topic_base, j)
00394 jentry = [jtopic_name, [caller_id]]
00395 self.assert_(jentry in pubs, "master pub/sub list %s is missing %s"%(pubs, jentry))
00396
00397
00398
00399
00400 self.apiError(master.lookupNode(self.caller_id, caller_id), "master has a stale reference to unregistered topic node API. pubs are %s"%pubs)
00401
00402
00403
00404 def _subTestRegisterSubscriberSimpleSuccess(self):
00405 master = self.master
00406
00407 caller_id = '/sub_node'
00408 caller_api = 'http://localhost:4567/'
00409 topic_base = '/sub_topic'
00410 topic_type = 'test_rosmaster/String'
00411
00412
00413 for i in range(0, 10):
00414 topic_name = "%s-%s"%(topic_base, i)
00415
00416 self.apiSuccess(master.registerSubscriber(caller_id, topic_name, topic_type, caller_api))
00417
00418
00419 val = self.apiSuccess(master.lookupNode(self.caller_id, caller_id))
00420 self.assertEquals(caller_api, val)
00421
00422
00423 val = self.apiSuccess(master.getTopicTypes(self.caller_id))
00424 self.assert_([topic_name, topic_type] in val, "master does not know topic type: %s"%val)
00425
00426 _, subs, _ = self.apiSuccess(master.getSystemState(self.caller_id))
00427 for j in range(0, i+1):
00428 jtopic_name = "%s-%s"%(topic_base, j)
00429 jentry = [jtopic_name, [caller_id]]
00430 self.assert_(jentry in subs, "master pub/sub list %s is missing %s"%(subs, jentry))
00431
00432
00433 def _testRegisterSubscriberSimpleSuccess(self):
00434 self._subTestRegisterSubscriberSimpleSuccess()
00435
00436 def _testUnregisterSubscriberSuccess(self):
00437 self._subTestRegisterSubscriberSimpleSuccess()
00438 master = self.master
00439 caller_id = '/sub_node'
00440 caller_api = 'http://localhost:4567/'
00441 topic_base = '/sub_topic'
00442
00443 for i in range(0, 10):
00444 topic_name = "%s-%s"%(topic_base, i)
00445
00446
00447 code, msg, val = master.unregisterSubscriber(caller_id, topic_name, caller_api)
00448 self.assertEquals(code, 1, "code != 1, return message was [%s]"%msg)
00449
00450
00451 if i < 9:
00452 val = self.apiSuccess(master.lookupNode(self.caller_id, caller_id))
00453 self.assertEquals(caller_api, val, "master prematurely invalidated node entry for [%s] (lookupNode)"%caller_id)
00454
00455 _, subs, _ = self.apiSuccess(master.getSystemState(self.caller_id))
00456 for j in range(0, i+1):
00457 jtopic_name = "%s-%s"%(topic_base, j)
00458 jentry = [jtopic_name, [caller_id]]
00459 self.assert_(jentry not in subs, "master pub/sub list %s should not have %s"%(subs, jentry))
00460 for j in range(i+1, 10):
00461 jtopic_name = "%s-%s"%(topic_base, j)
00462 jentry = [jtopic_name, [caller_id]]
00463 self.assert_(jentry in subs, "master pub/sub list %s is missing %s"%(subs, jentry))
00464
00465
00466 self.apiError(master.lookupNode(self.caller_id, caller_id), "master has a stale reference to unregistered topic node API. subs are %s"%subs)
00467
00468