$search
00001 # Software License Agreement (BSD License) 00002 # 00003 # Copyright (c) 2009, Willow Garage, Inc. 00004 # All rights reserved. 00005 # 00006 # Redistribution and use in source and binary forms, with or without 00007 # modification, are permitted provided that the following conditions 00008 # are met: 00009 # 00010 # * Redistributions of source code must retain the above copyright 00011 # notice, this list of conditions and the following disclaimer. 00012 # * Redistributions in binary form must reproduce the above 00013 # copyright notice, this list of conditions and the following 00014 # disclaimer in the documentation and/or other materials provided 00015 # with the distribution. 00016 # * Neither the name of Willow Garage, Inc. nor the names of its 00017 # contributors may be used to endorse or promote products derived 00018 # from this software without specific prior written permission. 00019 # 00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00024 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00031 # POSSIBILITY OF SUCH DAMAGE. 00032 00033 PKG = 'test_roslib_comm' 00034 import roslib; roslib.load_manifest(PKG) 00035 00036 import os 00037 import sys 00038 import unittest 00039 00040 import rosunit 00041 00042 class MsgSpecTest(unittest.TestCase): 00043 00044 def setUp(self): 00045 # for coverage 00046 reload(roslib.msgs) 00047 00048 def test_verbose(self): 00049 import roslib.msgs 00050 self.failIf(roslib.msgs.is_verbose()) 00051 roslib.msgs.set_verbose(True) 00052 self.assert_(roslib.msgs.is_verbose()) 00053 roslib.msgs.set_verbose(False) 00054 self.failIf(roslib.msgs.is_verbose()) 00055 00056 def test_base_msg_type(self): 00057 import roslib.msgs 00058 tests = [(None, None), ('String', 'String'), ('std_msgs/String', 'std_msgs/String'), 00059 ('String[10]', 'String'), ('string[10]', 'string'), ('std_msgs/String[10]', 'std_msgs/String'), 00060 ] 00061 for val, res in tests: 00062 self.assertEquals(res, roslib.msgs.base_msg_type(val)) 00063 00064 def test_resolve_type(self): 00065 from roslib.msgs import resolve_type 00066 for t in ['string', 'string[]', 'string[14]', 'int32', 'int32[]']: 00067 bt = roslib.msgs.base_msg_type(t) 00068 self.assertEquals(t, resolve_type(t, PKG)) 00069 00070 self.assertEquals('foo/string', resolve_type('foo/string', PKG)) 00071 self.assertEquals('std_msgs/Header', resolve_type('Header', 'roslib')) 00072 self.assertEquals('std_msgs/Header', resolve_type('std_msgs/Header', 'roslib')) 00073 self.assertEquals('std_msgs/Header', resolve_type('Header', 'stereo_msgs')) 00074 self.assertEquals('std_msgs/String', resolve_type('String', 'std_msgs')) 00075 self.assertEquals('std_msgs/String', resolve_type('std_msgs/String', 'std_msgs')) 00076 self.assertEquals('std_msgs/String', resolve_type('std_msgs/String', PKG)) 00077 self.assertEquals('std_msgs/String[]', resolve_type('std_msgs/String[]', PKG)) 00078 00079 def test_parse_type(self): 00080 tests = [ 00081 ('a', ('a', False, None)), 00082 ('int8', ('int8', False, None)), 00083 ('std_msgs/String', ('std_msgs/String', False, None)), 00084 ('a[]', ('a', True, None)), 00085 ('int8[]', ('int8', True, None)), 00086 ('std_msgs/String[]', ('std_msgs/String', True, None)), 00087 ('a[1]', ('a', True, 1)), 00088 ('int8[1]', ('int8', True, 1)), 00089 ('std_msgs/String[1]', ('std_msgs/String', True, 1)), 00090 ('a[11]', ('a', True, 11)), 00091 ('int8[11]', ('int8', True, 11)), 00092 ('std_msgs/String[11]', ('std_msgs/String', True, 11)), 00093 ] 00094 for val, res in tests: 00095 self.assertEquals(res, roslib.msgs.parse_type(val)) 00096 00097 fail = ['a[1][2]', 'a[][]', '', None, 'a[', 'a[[1]', 'a[1]]'] 00098 for f in fail: 00099 try: 00100 roslib.msgs.parse_type(f) 00101 self.fail("should have failed on " +f) 00102 except roslib.msgs.MsgSpecException, e: pass 00103 00104 def test_Constant(self): 00105 import random 00106 import roslib.msgs 00107 vals = [random.randint(0, 1000) for i in xrange(0, 3)] 00108 type_, name, val = [str(x) for x in vals] 00109 x = roslib.msgs.Constant(type_, name, val, str(val)) 00110 self.assertEquals(type_, x.type) 00111 self.assertEquals(name, x.name) 00112 self.assertEquals(val, x.val) 00113 self.assertEquals(roslib.msgs.Constant(type_, name, val, str(val)), x) 00114 00115 self.assertNotEquals(1, x) 00116 self.assertNotEquals(roslib.msgs.Constant('baz', name, val, str(val)), x) 00117 self.assertNotEquals(roslib.msgs.Constant(type_, 'foo', val, str(val)), x) 00118 self.assertNotEquals(roslib.msgs.Constant(type_, name, 'foo', 'foo'), x) 00119 00120 # tripwire 00121 self.assert_(repr(x)) 00122 self.assert_(str(x)) 00123 00124 try: 00125 roslib.msgs.Constant(None, name, val, str(val)) 00126 except: pass 00127 try: 00128 roslib.msgs.Constant(type_, None, val, str(val)) 00129 except: pass 00130 try: 00131 roslib.msgs.Constant(type_, name, None, 'None') 00132 except: pass 00133 try: 00134 roslib.msgs.Constant(type_, name, val, None) 00135 except: pass 00136 00137 try: 00138 x.foo = 'bar' 00139 self.fail('Constant should not allow arbitrary attr assignment') 00140 except: pass 00141 00142 def test_MsgSpec(self): 00143 def sub_test_MsgSpec(types, names, constants, text, has_header): 00144 m = MsgSpec(types, names, constants, text) 00145 self.assertEquals(m.types, types) 00146 self.assertEquals(m.names, names) 00147 self.assertEquals(m.text, text) 00148 self.assertEquals(has_header, m.has_header()) 00149 self.assertEquals(m.constants, constants) 00150 self.assertEquals(zip(types, names), m.fields()) 00151 self.assertEquals(m, MsgSpec(types, names, constants, text)) 00152 return m 00153 00154 from roslib.msgs import MsgSpec 00155 # allow empty msg 00156 empty = sub_test_MsgSpec([], [], [], '', False) 00157 self.assertEquals([], empty.fields()) 00158 00159 # one-field 00160 one_field = sub_test_MsgSpec(['int32'], ['x'], [], 'int32 x', False) 00161 # make sure that equals tests every declared field 00162 self.assertEquals(one_field, MsgSpec(['int32'], ['x'], [], 'int32 x')) 00163 self.assertNotEquals(one_field, MsgSpec(['uint32'], ['x'], [], 'int32 x')) 00164 self.assertNotEquals(one_field, MsgSpec(['int32'], ['y'], [], 'int32 x')) 00165 self.assertNotEquals(one_field, MsgSpec(['int32'], ['x'], [], 'uint32 x')) 00166 # test against __ne__ as well 00167 self.assert_(one_field != MsgSpec(['int32'], ['x'], [], 'uint32 x')) 00168 #test strify 00169 self.assertEquals("int32 x", str(one_field).strip()) 00170 00171 # test variations of multiple fields and headers 00172 two_fields = sub_test_MsgSpec(['int32', 'string'], ['x', 'str'], [], 'int32 x\nstring str', False) 00173 one_header = sub_test_MsgSpec(['Header'], ['header'], [], 'Header header', True) 00174 header_and_fields = sub_test_MsgSpec(['Header', 'int32', 'string'], ['header', 'x', 'str'], [], 'Header header\nint32 x\nstring str', True) 00175 embed_types = sub_test_MsgSpec(['Header', 'std_msgs/Int32', 'string'], ['header', 'x', 'str'], [], 'Header header\nstd_msgs/Int32 x\nstring str', True) 00176 #test strify 00177 self.assertEquals("int32 x\nstring str", str(two_fields).strip()) 00178 00179 # types and names mismatch 00180 try: 00181 MsgSpec(['int32', 'int32'], ['intval'], [], 'int32 intval\int32 y') 00182 self.fail("types and names must align") 00183 except: pass 00184 00185 # test (not) equals against non msgspec 00186 self.failIf(one_field == 1) 00187 self.assert_(one_field != 1) 00188 #TODO: test flatten 00189 00190 # test that repr doesn't throw an error 00191 [repr(x) for x in [empty, one_field, one_header, two_fields, embed_types]] 00192 00193 def test_init(self): 00194 import roslib.msgs 00195 roslib.msgs._initialized = False 00196 roslib.msgs._init() 00197 self.assert_(roslib.msgs._initialized) 00198 # test repeated initialization 00199 roslib.msgs._init() 00200 00201 def test___convert_val(self): 00202 from roslib.msgs import _convert_val, MsgSpecException 00203 self.assertEquals(0., _convert_val('float32', '0.0')) 00204 self.assertEquals(0., _convert_val('float64', '0.0')) 00205 00206 self.assertEquals('fo o', _convert_val('string', ' fo o ')) 00207 00208 self.assertEquals(1, _convert_val('byte', '1')) 00209 self.assertEquals(1, _convert_val('char', '1')) 00210 self.assertEquals(1, _convert_val('int8', '1')) 00211 self.assertEquals(12, _convert_val('int16', '12')) 00212 self.assertEquals(-13, _convert_val('int32', '-13')) 00213 self.assertEquals(14, _convert_val('int64', '14')) 00214 self.assertEquals(0, _convert_val('uint8', '0')) 00215 self.assertEquals(18, _convert_val('uint16', '18')) 00216 self.assertEquals(19, _convert_val('uint32', '19')) 00217 self.assertEquals(20, _convert_val('uint64', '20')) 00218 00219 width_fail = [('int8', '129'), ('uint8', '256'), 00220 ('int16', '35536'), ('uint16', '-1'),('uint16', '65536'), 00221 ('int32', '3000000000'),('int32', '-2700000000'), 00222 ('uint32', '-1'),('uint32', '41000000000'), 00223 ('uint64', '-1')] 00224 for t, v in width_fail: 00225 try: 00226 _convert_val(t, v) 00227 self.fail("should have failed width check: %s, %s"%(t, v)) 00228 except MsgSpecException: pass 00229 type_fail = [('int32', 'f'), ('float32', 'baz')] 00230 for t, v in type_fail: 00231 try: 00232 _convert_val(t, v) 00233 self.fail("should have failed type check: %s, %s"%(t, v)) 00234 except ValueError: pass 00235 try: 00236 _convert_val('foo', '1') 00237 self.fail("should have failed invalid type") 00238 except MsgSpecException: pass 00239 00240 def test_load_by_type(self): 00241 from roslib.msgs import load_by_type 00242 name, msgspec = load_by_type('std_msgs/String') 00243 self.assertEquals('std_msgs/String', name) 00244 self.assertEquals(['data'], msgspec.names) 00245 self.assertEquals(['string'], msgspec.types) 00246 00247 00248 def test_load_package_dependencies(self): 00249 import roslib.msgs 00250 # in order to do this test, we have to observe some inner state 00251 roslib.msgs.reinit() 00252 self.failIf(PKG in roslib.msgs._loaded_packages) 00253 self.failIf('std_msgs' in roslib.msgs._loaded_packages) 00254 roslib.msgs.load_package_dependencies(PKG) 00255 00256 self.assert_('std_msgs' in roslib.msgs._loaded_packages, roslib.msgs._loaded_packages) 00257 # should load deps only, not package itself 00258 self.failIf(PKG in roslib.msgs._loaded_packages) 00259 00260 spec = roslib.msgs.get_registered('std_msgs/String') 00261 self.assert_('data' in spec.names) # make sure we have an actual std_msgs msg 00262 00263 # we don't have a test that properly exercises the recursive 00264 # differences, but we need to at least test that branch of code 00265 roslib.msgs.reinit() 00266 self.failIf(PKG in roslib.msgs._loaded_packages) 00267 self.failIf('std_msgs' in roslib.msgs._loaded_packages) 00268 roslib.msgs.load_package_dependencies(PKG, load_recursive=True) 00269 self.assert_('std_msgs' in roslib.msgs._loaded_packages, roslib.msgs._loaded_packages) 00270 # should load deps only, not package itself 00271 self.failIf(PKG in roslib.msgs._loaded_packages) 00272 00273 spec = roslib.msgs.get_registered('std_msgs/String') 00274 self.assert_('data' in spec.names) # make sure we have an actual std_msgs msg 00275 00276 def test_load_package(self): 00277 import roslib.msgs 00278 # in order to do this test, we have to observe some inner state 00279 roslib.msgs.reinit() 00280 self.failIf(PKG in roslib.msgs._loaded_packages) 00281 self.failIf('std_msgs' in roslib.msgs._loaded_packages) 00282 roslib.msgs.load_package(PKG) 00283 00284 self.assert_(PKG in roslib.msgs._loaded_packages) 00285 # - shouldn't load deps 00286 self.failIf('std_msgs' in roslib.msgs._loaded_packages, roslib.msgs._loaded_packages) 00287 00288 self.failIf(roslib.msgs.is_registered('std_msgs/String')) 00289 spec = roslib.msgs.get_registered('%s/FillSimple'%(PKG)) 00290 self.assertEquals(['i32', 'str', 'i32_array', 'b'], spec.names) # make sure we have an actual msg 00291 00292 def test_list_msg_types(self): 00293 import roslib.msgs 00294 types1 = roslib.msgs.list_msg_types('rosgraph_msgs', False) 00295 types2 = roslib.msgs.list_msg_types('rosgraph_msgs', True) 00296 00297 self.assert_('Clock' in types1, types1) 00298 self.assert_('Log' in types1, types1) 00299 00300 types1 = roslib.msgs.list_msg_types('std_msgs', False) 00301 types2 = roslib.msgs.list_msg_types('std_msgs', True) 00302 # std_msgs has no message deps, so this should be equivalent 00303 self.assertEquals(types1, types2) 00304 00305 self.assert_('Header' in types1, types1) 00306 self.assert_('Header' in types2, types2) 00307 self.assert_('String' in types1, types1) 00308 self.assert_('String' in types2, types2) 00309 self.assert_('Int32' in types1, types1) 00310 self.assert_('Int32' in types2, types2) 00311 00312 # test loading dependencies. we depend on std_msgs 00313 types1 = roslib.msgs.list_msg_types(PKG, False) 00314 types2 = roslib.msgs.list_msg_types(PKG, True) 00315 00316 self.assert_('std_msgs/Header' in types2, types2) 00317 self.assert_('std_msgs/Header' not in types1, types1) 00318 self.assert_('std_msgs/Int32' in types2, types2) 00319 self.assert_('std_msgs/Int32' not in types1, types1) 00320 00321 # std_msgs depends on roslib, so these should be different 00322 self.assertNotEquals(types1, types2) 00323 00324 def test_msg_file(self): 00325 import roslib.msgs 00326 f = roslib.msgs.msg_file('rosgraph_msgs', 'Log') 00327 self.assert_(os.path.isfile(f)) 00328 self.assert_(f.endswith('rosgraph_msgs/msg/Log.msg')) 00329 00330 # msg_file should return paths even for non-existent resources 00331 f = roslib.msgs.msg_file('roslib', 'Fake') 00332 self.failIf(os.path.isfile(f)) 00333 self.assert_(f.endswith('roslib/msg/Fake.msg')) 00334 00335 def test_is_valid_msg_type(self): 00336 import roslib.msgs 00337 vals = [ 00338 #basic 00339 'F', 'f', 'Foo', 'Foo1', 00340 'std_msgs/String', 00341 # arrays 00342 'Foo[]', 'Foo[1]', 'Foo[10]', 00343 ] 00344 for v in vals: 00345 self.assert_(roslib.msgs.is_valid_msg_type(v), "roslib.msgs.is_valid_msg_type should have returned True for '%s'"%v) 00346 00347 # bad cases 00348 vals = [None, '', '#', '%', 'Foo%', 'Woo Woo', 00349 '/', '/String', 00350 'Foo[f]', 'Foo[1d]', 'Foo[-1]', 'Foo[1:10]', 'Foo[', 'Foo]', 'Foo[]Bar'] 00351 for v in vals: 00352 self.failIf(roslib.msgs.is_valid_msg_type(v), "roslib.msgs.is_valid_msg_type should have returned False for '%s'"%v) 00353 00354 def test_is_valid_constant_type(self): 00355 import roslib.msgs 00356 valid = ['int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32', 'int64', \ 00357 'uint64', 'float32', 'float64', 'char', 'byte', 'string'] 00358 invalid = [ 00359 'std_msgs/String', '/', 'String', 00360 'time', 'duration','header', 00361 ] 00362 for v in valid: 00363 self.assert_(roslib.msgs.is_valid_constant_type(v), "roslib.msgs.is_valid_constant_type should have returned True for '%s'"%v) 00364 for v in invalid: 00365 self.failIf(roslib.msgs.is_valid_constant_type(v), "roslib.msgs.is_valid_constant_type should have returned False for '%s'"%v) 00366 00367 00368 if __name__ == '__main__': 00369 rosunit.unitrun(PKG, 'test_roslib_msgs', MsgSpecTest, coverage_packages=['roslib.msgs']) 00370