$search
00001 #!/usr/bin/env python 00002 # Software License Agreement (BSD License) 00003 # 00004 # Copyright (c) 2008, Willow Garage, Inc. 00005 # All rights reserved. 00006 # 00007 # Redistribution and use in source and binary forms, with or without 00008 # modification, are permitted provided that the following conditions 00009 # are met: 00010 # 00011 # * Redistributions of source code must retain the above copyright 00012 # notice, this list of conditions and the following disclaimer. 00013 # * Redistributions in binary form must reproduce the above 00014 # copyright notice, this list of conditions and the following 00015 # disclaimer in the documentation and/or other materials provided 00016 # with the distribution. 00017 # * Neither the name of Willow Garage, Inc. nor the names of its 00018 # contributors may be used to endorse or promote products derived 00019 # from this software without specific prior written permission. 00020 # 00021 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 # POSSIBILITY OF SUCH DAMAGE. 00033 # 00034 # Revision $Id$ 00035 00036 import roslib; roslib.load_manifest('test_rospy') 00037 00038 import os 00039 import sys 00040 import struct 00041 import unittest 00042 import time 00043 00044 # test rospy.names package 00045 class TestRospyNames(unittest.TestCase): 00046 00047 def test_scoped_name(self): 00048 from rospy.exceptions import ROSException 00049 from rospy.names import scoped_name 00050 tests = [ 00051 ['/', '/name', 'name'], 00052 ['/', '/ns/name', 'ns/name'], 00053 ['/ns', '/ns/name', 'ns/name'], 00054 ['/ns/node', '/ns/name', 'name'], 00055 ['/ns/', '/ns/name', 'ns/name'], 00056 ['/ns/ns2/', '/ns/name', 'name'], 00057 ] 00058 for caller_id, name, v in tests: 00059 val = scoped_name(caller_id, name) 00060 self.assertEquals(v, val, "failed on [%s] [%s]: %s"%(caller_id, name, val)) 00061 00062 fail = [ 00063 ['name', '/name'], 00064 ['~name', '/name'], 00065 ] 00066 00067 for caller_id, name in fail: 00068 try: 00069 scoped_name(caller_id, name) 00070 self.fail("should have failed on %s, %s"%(caller_id, name)) 00071 except ROSException: pass 00072 00073 def test_mappings(self): 00074 import roslib.names 00075 import rospy.names 00076 from rospy.names import get_mappings, get_resolved_mappings, initialize_mappings 00077 # get_mappings is initialized statically, so can't test anything other than it is empty 00078 self.assertEquals({}, get_mappings()) 00079 00080 # resolved mappings should be empty with no initialization 00081 self.assertEquals({}, get_resolved_mappings()) 00082 00083 # now, initialize mappings, shouldn't matter as there are no mappings 00084 initialize_mappings('foo') 00085 # should be empty now 00086 self.assertEquals({}, get_resolved_mappings()) 00087 00088 # manipulate mappings to test 00089 rospy.names._mappings = roslib.names.load_mappings(['__name:=newname', '__log:=blah', '_param:=value', 'foo:=bar','/baz:=a/b', '~car:=c/d/e']) 00090 # - param mapping should be removed 00091 self.assertEquals({'__name': 'newname', '__log': 'blah', 00092 'foo': 'bar', '/baz': 'a/b', '~car': 'c/d/e'}, get_mappings()) 00093 # - should be unaltered 00094 self.assertEquals({}, get_resolved_mappings()) 00095 initialize_mappings('/name') 00096 00097 # should be unchanged 00098 self.assertEquals({'__name': 'newname', '__log': 'blah', 00099 'foo': 'bar', '/baz': 'a/b', '~car': 'c/d/e'}, get_mappings()) 00100 # should be remapped 00101 self.assertEquals({'__name': 'newname', '__log': 'blah', 00102 '/foo': '/bar', '/baz': '/a/b', '/name/car':'/c/d/e'}, 00103 get_resolved_mappings()) 00104 00105 # try with namespaced node 00106 initialize_mappings('/ns/name') 00107 # should be remapped 00108 self.assertEquals({'__name': 'newname', '__log': 'blah', 00109 '/ns/foo': '/ns/bar', '/baz': '/ns/a/b', '/ns/name/car':'/ns/c/d/e'}, 00110 get_resolved_mappings()) 00111 00112 00113 00114 def test_canonicalize_name(self): 00115 from rospy.names import canonicalize_name 00116 tests = [ 00117 ('', ''), 00118 ('/', '/'), 00119 ('foo', 'foo'), 00120 ('/foo', '/foo'), 00121 ('/foo/', '/foo'), 00122 ('/foo/bar', '/foo/bar'), 00123 ('/foo/bar/', '/foo/bar'), 00124 ('/foo/bar//', '/foo/bar'), 00125 ('/foo//bar', '/foo/bar'), 00126 ('//foo/bar', '/foo/bar'), 00127 ('foo/bar', 'foo/bar'), 00128 ('foo//bar', 'foo/bar'), 00129 ('foo/bar/', 'foo/bar'), 00130 ('/foo/bar', '/foo/bar'), 00131 ] 00132 for t, v in tests: 00133 self.assertEquals(v, canonicalize_name(t)) 00134 00135 def test_ANYTYPE(self): 00136 from rospy.names import TOPIC_ANYTYPE, SERVICE_ANYTYPE 00137 self.assertEquals("*", TOPIC_ANYTYPE) 00138 self.assertEquals("*", SERVICE_ANYTYPE) 00139 00140 def test_resolve_name(self): 00141 from rospy.names import resolve_name 00142 # TODO: test with remappings 00143 tests = [ 00144 ('', '/', '/'), 00145 ('', None, '/'), #node_name defaults to / 00146 ('', '/node', '/'), 00147 ('', '/ns1/node', '/ns1/'), 00148 00149 ('foo', '', '/foo'), 00150 ('foo', None, '/foo'), 00151 ('foo/', '', '/foo'), 00152 ('/foo', '', '/foo'), 00153 ('/foo/', '', '/foo'), 00154 ('/foo', '/', '/foo'), 00155 ('/foo', None, '/foo'), 00156 ('/foo/', '/', '/foo'), 00157 ('/foo', '/bar', '/foo'), 00158 ('/foo/', '/bar', '/foo'), 00159 00160 ('foo', '/ns1/ns2', '/ns1/foo'), 00161 ('foo', '/ns1/ns2/', '/ns1/foo'), 00162 ('foo', '/ns1/ns2/ns3/', '/ns1/ns2/foo'), 00163 ('foo/', '/ns1/ns2', '/ns1/foo'), 00164 ('/foo', '/ns1/ns2', '/foo'), 00165 ('foo/bar', '/ns1/ns2', '/ns1/foo/bar'), 00166 ('foo//bar', '/ns1/ns2', '/ns1/foo/bar'), 00167 ('foo/bar', '/ns1/ns2/ns3', '/ns1/ns2/foo/bar'), 00168 ('foo//bar//', '/ns1/ns2/ns3', '/ns1/ns2/foo/bar'), 00169 00170 ('~foo', '/', '/foo'), 00171 ('~foo', '/node', '/node/foo'), 00172 ('~foo', '/ns1/ns2', '/ns1/ns2/foo'), 00173 ('~foo/', '/ns1/ns2', '/ns1/ns2/foo'), 00174 ('~foo/bar', '/ns1/ns2', '/ns1/ns2/foo/bar'), 00175 00176 ] 00177 for name, node_name, v in tests: 00178 self.assertEquals(v, resolve_name(name, node_name)) 00179 00180 def test_valid_name(self): 00181 # test with resolution 00182 from rospy.names import valid_name_validator_resolved, valid_name, ParameterInvalid 00183 validator = valid_name('param_name', True) 00184 tests = [ 00185 ('name', '/node', '/name'), 00186 ('/name', '/node', '/name'), 00187 ('~name', '/node', '/node/name'), 00188 # test unicode 00189 (u'~name', '/node', u'/node/name'), 00190 ] 00191 for name, caller_id, v in tests: 00192 self.assertEquals(v, valid_name_validator_resolved('p', name, caller_id), "failed on %s %s"%(name, caller_id)) 00193 self.assertEquals(v, validator(name, caller_id)) 00194 00195 # kwc: valid_name is currently very soft in the failures it 00196 # checks as it is targetted at catching parameter 00197 # misalignment. I would like to make it more strict in the 00198 # future. 00199 invalid = [ 00200 (1, '/node'), 00201 (None, '/node'), 00202 ('localhost:123', '/node'), 00203 ('Bob Barker', '/node'), 00204 # unicode 00205 (u'Bob Barker', '/node'), 00206 ] 00207 for name, caller_id in invalid: 00208 try: 00209 valid_name_validator_resolved('p', name, caller_id) 00210 self.fail("valid_name_validator_unresolved should have failed on : [%s], [%s]"%(name, caller_id)) 00211 except ParameterInvalid: pass 00212 try: 00213 validator(name, caller_id) 00214 self.fail("valid_name_validator_unresolved should have failed on : [%s], [%s]"%(name, caller_id)) 00215 except ParameterInvalid: pass 00216 00217 from rospy.names import valid_name_validator_unresolved 00218 validator = valid_name('param_name', False) 00219 tests = [ 00220 ('name', '/node', 'name'), 00221 ('/name', '/node', '/name'), 00222 ('~name', '/node', '~name'), 00223 # unicode 00224 (u'~name', '/node', u'~name'), 00225 ] 00226 for name, caller_id, v in tests: 00227 self.assertEquals(v, valid_name_validator_unresolved('p', name, caller_id), "failed on [%s] [%s]"%(name, caller_id)) 00228 self.assertEquals(v, validator(name, caller_id)) 00229 00230 for name, caller_id in invalid: 00231 try: 00232 valid_name_validator_unresolved('p', name, caller_id) 00233 self.fail("valid_name_validator_unresolved should have failed on : [%s], [%s]"%(name, caller_id)) 00234 except ParameterInvalid: pass 00235 try: 00236 validator(name, caller_id) 00237 self.fail("valid_name_validator_unresolved should have failed on : [%s], [%s]"%(name, caller_id)) 00238 except ParameterInvalid: pass 00239 00240 def test_global_name(self): 00241 from rospy.names import global_name, ParameterInvalid 00242 validator = global_name('param_name') 00243 tests = [ 00244 ('/', '/node', '/'), 00245 ('/name', '/node', '/name'), 00246 # unicode 00247 (u'/name', '/node', u'/name'), 00248 ] 00249 for name, caller_id, v in tests: 00250 self.assertEquals(v, validator(name, caller_id)) 00251 invalid = [ 00252 (1, '/node'), 00253 (None, '/node'), 00254 ('name', '/node'), 00255 ('~name', '/node'), 00256 ] 00257 for name, caller_id in invalid: 00258 try: 00259 validator(name, caller_id) 00260 self.fail("global_name should have failed on : [%s], [%s]"%(name, caller_id)) 00261 except ParameterInvalid: pass 00262 00263 def test_caller_id(self): 00264 from rospy.names import get_caller_id, get_name, _set_caller_id, get_namespace 00265 # test get_name, get_caller_id, and _set_caller_id 00266 try: 00267 self.assertEquals('/unnamed', get_name()) 00268 self.assertEquals('/', get_namespace()) 00269 _set_caller_id('/foo') 00270 self.assertEquals('/foo', get_name()) 00271 self.assertEquals('/', get_namespace()) 00272 _set_caller_id('/foo/bar') 00273 self.assertEquals('/foo/bar', get_name()) 00274 self.assertEquals('/foo/', get_namespace()) 00275 finally: 00276 _set_caller_id('/unnamed') 00277 00278 # older get_caller_id usage 00279 try: 00280 self.assertEquals('/unnamed', get_caller_id()) 00281 self.assertEquals('/', get_namespace()) 00282 _set_caller_id('/foo') 00283 self.assertEquals('/foo', get_caller_id()) 00284 self.assertEquals('/', get_namespace()) 00285 _set_caller_id('/foo/bar') 00286 self.assertEquals('/foo/bar', get_caller_id()) 00287 self.assertEquals('/foo/', get_namespace()) 00288 finally: 00289 _set_caller_id('/unnamed') 00290 00291 if __name__ == '__main__': 00292 import rostest 00293 rostest.unitrun('test_rospy', sys.argv[0], TestRospyNames, coverage_packages=['rospy.names'])