test_genmsg_py.py
Go to the documentation of this file.
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 import os
00035 import sys
00036 import struct
00037 import unittest
00038 from cStringIO import StringIO
00039 import time
00040 import random
00041 import math
00042 
00043 from roslib.message import SerializationError
00044         
00045 class TestGenmsgPy(unittest.TestCase):
00046 
00047     def test_PythonKeyword(self):
00048         from test_rospy.msg import PythonKeyword
00049         # the md5sum is pulled from the c++ message generator. The
00050         # test here is that the Python msg generator didn't
00051         # accidentally mutate a md5sum based on a message that has its
00052         # fieldname remapped.
00053         self.assertEquals(PythonKeyword._md5sum, "1330d6bbfad8e75334346fec949d5133")
00054                           
00055     ## Utility for testing roundtrip serialization
00056     ## @param orig Message to test roundtrip serialization of
00057     ## @param blank Uninitialized instance of message to deserialize into
00058     ## @param float bool: if True, use almostEquals instead of equals
00059     ## comparison. This variant assumes only data field is named
00060     ## 'data'
00061     def _test_ser_deser(self, orig, blank, float=False):
00062         b = StringIO()
00063         orig.serialize(b)
00064         blank.deserialize(b.getvalue())
00065         if not float:
00066             self.assertEquals(orig, blank, str(orig)+" != "+str(blank))
00067         else:
00068             self.assertAlmostEquals(orig.data, blank.data, 5)
00069 
00070     ## #2133/2152
00071     def test_test_rospy_TransitiveImport(self):
00072         from test_rospy.msg import TransitiveImport
00073         m = TransitiveImport()
00074         # invoking serialize should be enough to expose issue. The bug
00075         # was that genmsg_py was failing to include the imports of
00076         # embedded messages. Because messages are flattened, this
00077         # causes ImportErrors.
00078         self._test_ser_deser(m, TransitiveImport())        
00079 
00080     def test_test_rospy_TestFixedArray(self):
00081         from test_rospy.msg import TestFixedArray
00082         m = TestFixedArray()
00083         self.assertEquals([0.], m.f32_1)
00084         self.assertEquals([0., 0., 0.], m.f32_3)        
00085         self.assertEquals([0.], m.f64_1)
00086         self.assertEquals([0., 0., 0.], m.f64_3)        
00087         self.assertEquals([0], m.i8_1)
00088         self.assertEquals([0, 0, 0], m.i8_3)        
00089         self.assertEquals(chr(0), m.u8_1)
00090         self.assertEquals(chr(0)*3, m.u8_3)        
00091         self.assertEquals([0], m.i32_1)
00092         self.assertEquals([0, 0, 0], m.i32_3)        
00093         self.assertEquals([0], m.u32_1)
00094         self.assertEquals([0, 0, 0], m.u32_3)
00095         self.assertEquals([''], m.s_1)
00096         self.assertEquals(['', '', ''], m.s_3)
00097 
00098         self._test_ser_deser(m, TestFixedArray())
00099 
00100         m = TestFixedArray(i32_1 = [1])
00101         c = TestFixedArray()
00102         self._test_ser_deser(m, c)
00103         self.assertEquals((1,), c.i32_1)
00104 
00105         m = TestFixedArray(i32_3 = [-3, 2, 10])
00106         c = TestFixedArray()
00107         self._test_ser_deser(m, c)
00108         self.assertEquals((-3, 2, 10), c.i32_3)
00109         
00110         m = TestFixedArray(u32_1 = [1234])
00111         c = TestFixedArray()
00112         self._test_ser_deser(m, c)
00113         self.assertEquals((1234,), c.u32_1)
00114         
00115         m = TestFixedArray(u32_3 = [3, 2, 10])
00116         c = TestFixedArray()
00117         self._test_ser_deser(m, c)
00118         self.assertEquals((3, 2, 10), c.u32_3)
00119         
00120         # this could potentially fail due to floating point lossiness
00121         m,c = TestFixedArray(f32_1 = [2.]), TestFixedArray()
00122         self._test_ser_deser(m, c)
00123         self.assertEquals((2.,), c.f32_1)
00124         
00125         m,c = TestFixedArray(f32_3 = [1., 2., 3.]), TestFixedArray()
00126         self._test_ser_deser(m, c)
00127         self.assertEquals((1., 2., 3.), c.f32_3)
00128         
00129         m,c = TestFixedArray(u8_1 = 'x'), TestFixedArray()
00130         self._test_ser_deser(m, c)
00131         self.assertEquals('x', c.u8_1)
00132 
00133         m,c = TestFixedArray(u8_3 = 'xyz'), TestFixedArray()
00134         self._test_ser_deser(m, c)
00135         self.assertEquals('xyz', c.u8_3)
00136 
00137         m,c = TestFixedArray(s_1 = ['']), TestFixedArray()
00138         self._test_ser_deser(m, c)
00139         self.assertEquals([''], c.s_1)
00140 
00141         m,c = TestFixedArray(s_1 = ['blah blah blah']), TestFixedArray()
00142         self._test_ser_deser(m, c)
00143         self.assertEquals(['blah blah blah',], c.s_1)
00144 
00145         m = TestFixedArray(s_3 = ['', 'x', 'xyz'])
00146         c = TestFixedArray()
00147         self._test_ser_deser(m, c)
00148         self.assertEquals(['', 'x', 'xyz'], c.s_3)
00149 
00150         for v in [True, False]:
00151             m = TestFixedArray(b_1 = [v])
00152             c = TestFixedArray()
00153             self._test_ser_deser(m, c)
00154             self.assertEquals([v], c.b_1)
00155 
00156         m = TestFixedArray(b_3 = [True, False, True])
00157         c = TestFixedArray()
00158         self._test_ser_deser(m, c)
00159         self.assertEquals([True, False, True], c.b_3)
00160         
00161         #TODO: enable tests for auto-convert of uint8[] to string
00162         
00163     def test_test_rospy_TestConstants(self):
00164         from test_rospy.msg import TestConstants
00165         self.assertEquals(-123.0, TestConstants.A)
00166         self.assertEquals(124.0, TestConstants.B)
00167         self.assertEquals(125.0, TestConstants.C)
00168         self.assertEquals(123, TestConstants.X)
00169         self.assertEquals(-123, TestConstants.Y)
00170         self.assertEquals(124, TestConstants.Z)
00171         self.assertEquals("'hi", TestConstants.SINGLEQUOTE)
00172         self.assertEquals('"hello" there', TestConstants.DOUBLEQUOTE)
00173         self.assertEquals('"hello" \'goodbye\'', TestConstants.MULTIQUOTE)
00174         self.assertEquals('foo', TestConstants.FOO) 
00175         self.assertEquals('"#comments" are ignored, and leading and trailing whitespace removed',TestConstants.EXAMPLE)
00176         self.assertEquals('strip', TestConstants.WHITESPACE)
00177         self.assertEquals('', TestConstants.EMPTY)
00178 
00179         self.assertEquals(True, TestConstants.TRUE)
00180         self.assertEquals(False, TestConstants.FALSE)        
00181         
00182     def test_std_msgs_empty(self):
00183         from std_msgs.msg import Empty
00184         self.assertEquals(Empty(), Empty())
00185         self._test_ser_deser(Empty(), Empty())
00186 
00187     def test_std_msgs_Bool(self):
00188         from std_msgs.msg import Bool
00189         self.assertEquals(Bool(), Bool())
00190         self._test_ser_deser(Bool(), Bool())
00191         # default value should be False
00192         self.assertEquals(False, Bool().data)
00193         # test various constructor permutations
00194         for v in [True, False]:
00195             self.assertEquals(Bool(v), Bool(v))
00196             self.assertEquals(Bool(v), Bool(data=v))
00197             self.assertEquals(Bool(data=v), Bool(data=v))
00198         self.assertNotEquals(Bool(True), Bool(False))            
00199 
00200         self._test_ser_deser(Bool(True), Bool())
00201         self._test_ser_deser(Bool(False), Bool())
00202 
00203         # validate type cast to bool
00204         blank = Bool()
00205         b = StringIO()
00206         Bool(True).serialize(b)
00207         blank.deserialize(b.getvalue())
00208         self.assert_(blank.data)
00209         self.assert_(type(blank.data) == bool)        
00210 
00211         b = StringIO()
00212         Bool(True).serialize(b)
00213         blank.deserialize(b.getvalue())
00214         self.assert_(blank.data)
00215         self.assert_(type(blank.data) == bool)
00216         
00217         
00218     def test_std_msgs_String(self):
00219         from std_msgs.msg import String
00220         self.assertEquals(String(), String())
00221         self.assertEquals('', String().data)
00222         # default value should be empty string
00223         self.assertEquals(String(''), String())
00224         self.assertEquals(String(''), String(''))
00225         self.assertEquals(String('foo'), String('foo'))
00226         self.assertEquals(String('foo'), String(data='foo'))
00227         self.assertEquals(String(data='foo'), String(data='foo'))
00228         
00229         self.assertNotEquals(String('foo'), String('bar'))
00230         self.assertNotEquals(String('foo'), String(data='bar'))
00231         self.assertNotEquals(String(data='foo'), String(data='bar'))
00232         
00233         self._test_ser_deser(String(''), String())
00234         self._test_ser_deser(String('a man a plan a canal panama'), String())
00235 
00236     def test_std_msgs_SignedInt(self):
00237         from std_msgs.msg import Int8, Int16, Int32, Int64
00238         for cls in [Int8, Int16, Int32, Int64]:
00239             v = random.randint(1, 127)
00240             self.assertEquals(cls(), cls())
00241             self.assertEquals(0, cls().data)
00242             self.assertEquals(cls(), cls(0))
00243             self.assertEquals(cls(0), cls(0))        
00244             self.assertEquals(cls(v), cls(v))
00245             self.assertEquals(cls(-v), cls(-v))
00246             self.assertEquals(cls(v), cls(data=v))        
00247             self.assertEquals(cls(data=v), cls(data=v))
00248         
00249             self.assertNotEquals(cls(v), cls())
00250             self.assertNotEquals(cls(data=v), cls(data=-v))
00251             self.assertNotEquals(cls(data=v), cls(data=v-1))            
00252             self.assertNotEquals(cls(data=v), cls(v-1))
00253             self.assertNotEquals(cls(v), cls(v-1))
00254             
00255             self._test_ser_deser(cls(), cls())
00256             self._test_ser_deser(cls(0), cls())
00257             self._test_ser_deser(cls(-v), cls())
00258             self._test_ser_deser(cls(v), cls())
00259 
00260         # rospy currently does not spot negative overflow due to the fact that Python's struct doesn't either
00261         widths = [(8, Int8), (16, Int16), (32, Int32), (64, Int64)]
00262         for w, cls in widths:
00263             maxp = long(math.pow(2, w-1)) - 1
00264             maxn = -long(math.pow(2, w-1)) + 1
00265             self._test_ser_deser(cls(maxp), cls())
00266             self._test_ser_deser(cls(maxn), cls())
00267             try:
00268                 cls(maxp+1)._check_types()
00269                 self.fail("check_types should have noted width error[%s]: %s, %s"%(w, maxp+1, cls.__name__))
00270             except SerializationError: pass
00271             try:
00272                 cls(maxn-1)._check_types()
00273                 self.fail("check_types should have noted width error[%s]: %s, %s"%(w, maxn-1, cls.__name__))
00274             except SerializationError: pass
00275             
00276     def test_std_msgs_UnsignedInt(self):
00277         from std_msgs.msg import UInt8, UInt16, UInt32, UInt64
00278         for cls in [UInt8, UInt16, UInt32, UInt64]:
00279             v = random.randint(1, 127)
00280             self.assertEquals(cls(), cls())
00281             self.assertEquals(0, cls().data)
00282             self.assertEquals(cls(), cls(0))
00283             self.assertEquals(cls(0), cls(0))        
00284             self.assertEquals(cls(v), cls(v))
00285             self.assertEquals(cls(v), cls(data=v))        
00286             self.assertEquals(cls(data=v), cls(data=v))
00287         
00288             self.assertNotEquals(cls(v), cls())
00289             self.assertNotEquals(cls(data=v), cls(data=-v))
00290             self.assertNotEquals(cls(data=v), cls(data=v-1))            
00291             self.assertNotEquals(cls(data=v), cls(v-1))
00292             self.assertNotEquals(cls(v), cls(v-1))
00293             
00294             self._test_ser_deser(cls(), cls())
00295             self._test_ser_deser(cls(0), cls())
00296             self._test_ser_deser(cls(v), cls())
00297 
00298             try:
00299                 cls(-1)._check_types()
00300                 self.fail("check_types should have noted sign error[%s]: %s"%(w, cls.__name__))
00301             except SerializationError: pass
00302 
00303         # rospy currently does not spot negative overflow due to the fact that Python's struct doesn't either
00304         widths = [(8, UInt8), (16, UInt16), (32, UInt32), (64, UInt64)]
00305         for w, cls in widths:
00306             maxp = long(math.pow(2, w)) - 1
00307             self._test_ser_deser(cls(maxp), cls())
00308             try:
00309                 cls(maxp+1)._check_types()
00310                 self.fail("check_types should have noted width error[%s]: %s, %s"%(w, maxp+1, cls.__name__))
00311             except SerializationError: pass
00312             
00313     def test_std_msgs_Float(self):
00314         from std_msgs.msg import Float32, Float64
00315         for cls in [Float32, Float64]:
00316             self.assertEquals(cls(), cls())
00317             self.assertEquals(0., cls().data)
00318             self.assertEquals(cls(), cls(0.))
00319             self.assertEquals(cls(0.), cls(0.))        
00320             self.assertEquals(cls(1.), cls(1.))
00321             self.assertEquals(cls(1.), cls(data=1.))        
00322             self.assertEquals(cls(data=1.), cls(data=1.))
00323             self.assertEquals(cls(math.pi), cls(math.pi))
00324             self.assertEquals(cls(math.pi), cls(data=math.pi))        
00325             self.assertEquals(cls(data=math.pi), cls(data=math.pi))
00326         
00327             self.assertNotEquals(cls(1.), cls())
00328             self.assertNotEquals(cls(math.pi), cls())
00329             self.assertNotEquals(cls(data=math.pi), cls(data=-math.pi))
00330             self.assertNotEquals(cls(data=math.pi), cls(data=math.pi-1))            
00331             self.assertNotEquals(cls(data=math.pi), cls(math.pi-1))
00332             self.assertNotEquals(cls(math.pi), cls(math.pi-1))
00333             
00334             self._test_ser_deser(cls(), cls())
00335             self._test_ser_deser(cls(0.), cls())
00336             self._test_ser_deser(cls(1.), cls(), float=True)
00337             self._test_ser_deser(cls(math.pi), cls(), float=True)
00338 
00339     def test_std_msgs_MultiArray(self):
00340         # multiarray is good test of embed plus array type
00341         from std_msgs.msg import Int32MultiArray, MultiArrayDimension, MultiArrayLayout, UInt8MultiArray
00342         
00343         dims = [MultiArrayDimension('foo', 1, 2), MultiArrayDimension('bar', 3, 4),\
00344                     MultiArrayDimension('foo2', 5, 6), MultiArrayDimension('bar2', 7, 8)]
00345         for d in dims:
00346             self.assertEquals(d, d)
00347 
00348         # there was a bug with UInt8 arrays, so this is a regression
00349         # test. the buff was with the uint8[] type consistency
00350         buff = StringIO()
00351         self.assertEquals(UInt8MultiArray(),UInt8MultiArray())
00352         self.assertEquals('',UInt8MultiArray().data)        
00353         UInt8MultiArray().serialize(buff)
00354         self.assertEquals(UInt8MultiArray(layout=MultiArrayLayout()),UInt8MultiArray())
00355         UInt8MultiArray(layout=MultiArrayLayout()).serialize(buff)
00356         data = ''.join([chr(i) for i in range(0, 100)])
00357         v = UInt8MultiArray(data=data)
00358         self._test_ser_deser(UInt8MultiArray(data=data),UInt8MultiArray())
00359         
00360         self.assertEquals(Int32MultiArray(),Int32MultiArray())
00361         self.assertEquals(Int32MultiArray(layout=MultiArrayLayout()),Int32MultiArray())
00362         self.assertEquals(Int32MultiArray(layout=MultiArrayLayout(), data=[1, 2, 3]),Int32MultiArray(data=[1, 2, 3]))
00363         self.assertEquals(Int32MultiArray(layout=MultiArrayLayout(), data=[1, 2, 3]),\
00364                               Int32MultiArray(layout=MultiArrayLayout(),data=[1, 2, 3]))
00365         self.assertEquals(Int32MultiArray(layout=MultiArrayLayout(dim=[]), data=[1, 2, 3]),\
00366                               Int32MultiArray(layout=MultiArrayLayout(),data=[1, 2, 3]))
00367         self.assertEquals(Int32MultiArray(layout=MultiArrayLayout([], 0), data=[1, 2, 3]),\
00368                               Int32MultiArray(layout=MultiArrayLayout(),data=[1, 2, 3]))
00369         self.assertEquals(Int32MultiArray(layout=MultiArrayLayout(dim=[], data_offset=0), data=[1, 2, 3]),\
00370                               Int32MultiArray(layout=MultiArrayLayout(),data=[1, 2, 3]))
00371         self.assertEquals(Int32MultiArray(layout=MultiArrayLayout(dim=dims, data_offset=0), data=[1, 2, 3]),\
00372                               Int32MultiArray(layout=MultiArrayLayout(dim=dims),data=[1, 2, 3]))
00373         self.assertEquals(Int32MultiArray(layout=MultiArrayLayout(dims, 10), data=[1, 2, 3]),\
00374                               Int32MultiArray(layout=MultiArrayLayout(dim=dims,data_offset=10),data=[1, 2, 3]))
00375 
00376 
00377         self.assertNotEquals(Int32MultiArray(data=[1, 2, 3]),Int32MultiArray(data=[4,5,6]))
00378         self.assertNotEquals(Int32MultiArray(layout=MultiArrayLayout([], 1), data=[1, 2, 3]),\
00379                                  Int32MultiArray(layout=MultiArrayLayout([], 0),data=[1, 2, 3]))
00380         self.assertNotEquals(Int32MultiArray(layout=MultiArrayLayout([], 1), data=[1, 2, 3]),\
00381                                  Int32MultiArray(layout=MultiArrayLayout(dim=[]),data=[1, 2, 3]))
00382         self.assertNotEquals(Int32MultiArray(layout=MultiArrayLayout(dims, 10), data=[1, 2, 3]),\
00383                                  Int32MultiArray(layout=MultiArrayLayout(dim=dims,data_offset=11),data=[1, 2, 3]))
00384         self.assertNotEquals(Int32MultiArray(layout=MultiArrayLayout(dim=dims, data_offset=10), data=[1, 2, 3]),\
00385                                  Int32MultiArray(layout=MultiArrayLayout(dim=dims[1:],data_offset=10),data=[1, 2, 3]))
00386         
00387 
00388         self._test_ser_deser(Int32MultiArray(),Int32MultiArray())
00389         self._test_ser_deser(Int32MultiArray(layout=MultiArrayLayout()),Int32MultiArray())
00390         self._test_ser_deser(Int32MultiArray(data=[1, 2, 3]),Int32MultiArray())


test_rospy
Author(s): Ken Conley/kwc@willowgarage.com
autogenerated on Sat Dec 28 2013 17:36:20