Home | History | Annotate | Download | only in internal
      1 #! /usr/bin/python
      2 #
      3 # Protocol Buffers - Google's data interchange format
      4 # Copyright 2008 Google Inc.  All rights reserved.
      5 # http://code.google.com/p/protobuf/
      6 #
      7 # Redistribution and use in source and binary forms, with or without
      8 # modification, are permitted provided that the following conditions are
      9 # met:
     10 #
     11 #     * Redistributions of source code must retain the above copyright
     12 # notice, this list of conditions and the following disclaimer.
     13 #     * Redistributions in binary form must reproduce the above
     14 # copyright notice, this list of conditions and the following disclaimer
     15 # in the documentation and/or other materials provided with the
     16 # distribution.
     17 #     * Neither the name of Google Inc. nor the names of its
     18 # contributors may be used to endorse or promote products derived from
     19 # this software without specific prior written permission.
     20 #
     21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32 
     33 """Test for google.protobuf.internal.wire_format."""
     34 
     35 __author__ = 'robinson (at] google.com (Will Robinson)'
     36 
     37 import unittest
     38 from google.protobuf import message
     39 from google.protobuf.internal import wire_format
     40 
     41 
     42 class WireFormatTest(unittest.TestCase):
     43 
     44   def testPackTag(self):
     45     field_number = 0xabc
     46     tag_type = 2
     47     self.assertEqual((field_number << 3) | tag_type,
     48                      wire_format.PackTag(field_number, tag_type))
     49     PackTag = wire_format.PackTag
     50     # Number too high.
     51     self.assertRaises(message.EncodeError, PackTag, field_number, 6)
     52     # Number too low.
     53     self.assertRaises(message.EncodeError, PackTag, field_number, -1)
     54 
     55   def testUnpackTag(self):
     56     # Test field numbers that will require various varint sizes.
     57     for expected_field_number in (1, 15, 16, 2047, 2048):
     58       for expected_wire_type in range(6):  # Highest-numbered wiretype is 5.
     59         field_number, wire_type = wire_format.UnpackTag(
     60             wire_format.PackTag(expected_field_number, expected_wire_type))
     61         self.assertEqual(expected_field_number, field_number)
     62         self.assertEqual(expected_wire_type, wire_type)
     63 
     64     self.assertRaises(TypeError, wire_format.UnpackTag, None)
     65     self.assertRaises(TypeError, wire_format.UnpackTag, 'abc')
     66     self.assertRaises(TypeError, wire_format.UnpackTag, 0.0)
     67     self.assertRaises(TypeError, wire_format.UnpackTag, object())
     68 
     69   def testZigZagEncode(self):
     70     Z = wire_format.ZigZagEncode
     71     self.assertEqual(0, Z(0))
     72     self.assertEqual(1, Z(-1))
     73     self.assertEqual(2, Z(1))
     74     self.assertEqual(3, Z(-2))
     75     self.assertEqual(4, Z(2))
     76     self.assertEqual(0xfffffffe, Z(0x7fffffff))
     77     self.assertEqual(0xffffffff, Z(-0x80000000))
     78     self.assertEqual(0xfffffffffffffffe, Z(0x7fffffffffffffff))
     79     self.assertEqual(0xffffffffffffffff, Z(-0x8000000000000000))
     80 
     81     self.assertRaises(TypeError, Z, None)
     82     self.assertRaises(TypeError, Z, 'abcd')
     83     self.assertRaises(TypeError, Z, 0.0)
     84     self.assertRaises(TypeError, Z, object())
     85 
     86   def testZigZagDecode(self):
     87     Z = wire_format.ZigZagDecode
     88     self.assertEqual(0, Z(0))
     89     self.assertEqual(-1, Z(1))
     90     self.assertEqual(1, Z(2))
     91     self.assertEqual(-2, Z(3))
     92     self.assertEqual(2, Z(4))
     93     self.assertEqual(0x7fffffff, Z(0xfffffffe))
     94     self.assertEqual(-0x80000000, Z(0xffffffff))
     95     self.assertEqual(0x7fffffffffffffff, Z(0xfffffffffffffffe))
     96     self.assertEqual(-0x8000000000000000, Z(0xffffffffffffffff))
     97 
     98     self.assertRaises(TypeError, Z, None)
     99     self.assertRaises(TypeError, Z, 'abcd')
    100     self.assertRaises(TypeError, Z, 0.0)
    101     self.assertRaises(TypeError, Z, object())
    102 
    103   def NumericByteSizeTestHelper(self, byte_size_fn, value, expected_value_size):
    104     # Use field numbers that cause various byte sizes for the tag information.
    105     for field_number, tag_bytes in ((15, 1), (16, 2), (2047, 2), (2048, 3)):
    106       expected_size = expected_value_size + tag_bytes
    107       actual_size = byte_size_fn(field_number, value)
    108       self.assertEqual(expected_size, actual_size,
    109                        'byte_size_fn: %s, field_number: %d, value: %r\n'
    110                        'Expected: %d, Actual: %d'% (
    111           byte_size_fn, field_number, value, expected_size, actual_size))
    112 
    113   def testByteSizeFunctions(self):
    114     # Test all numeric *ByteSize() functions.
    115     NUMERIC_ARGS = [
    116         # Int32ByteSize().
    117         [wire_format.Int32ByteSize, 0, 1],
    118         [wire_format.Int32ByteSize, 127, 1],
    119         [wire_format.Int32ByteSize, 128, 2],
    120         [wire_format.Int32ByteSize, -1, 10],
    121         # Int64ByteSize().
    122         [wire_format.Int64ByteSize, 0, 1],
    123         [wire_format.Int64ByteSize, 127, 1],
    124         [wire_format.Int64ByteSize, 128, 2],
    125         [wire_format.Int64ByteSize, -1, 10],
    126         # UInt32ByteSize().
    127         [wire_format.UInt32ByteSize, 0, 1],
    128         [wire_format.UInt32ByteSize, 127, 1],
    129         [wire_format.UInt32ByteSize, 128, 2],
    130         [wire_format.UInt32ByteSize, wire_format.UINT32_MAX, 5],
    131         # UInt64ByteSize().
    132         [wire_format.UInt64ByteSize, 0, 1],
    133         [wire_format.UInt64ByteSize, 127, 1],
    134         [wire_format.UInt64ByteSize, 128, 2],
    135         [wire_format.UInt64ByteSize, wire_format.UINT64_MAX, 10],
    136         # SInt32ByteSize().
    137         [wire_format.SInt32ByteSize, 0, 1],
    138         [wire_format.SInt32ByteSize, -1, 1],
    139         [wire_format.SInt32ByteSize, 1, 1],
    140         [wire_format.SInt32ByteSize, -63, 1],
    141         [wire_format.SInt32ByteSize, 63, 1],
    142         [wire_format.SInt32ByteSize, -64, 1],
    143         [wire_format.SInt32ByteSize, 64, 2],
    144         # SInt64ByteSize().
    145         [wire_format.SInt64ByteSize, 0, 1],
    146         [wire_format.SInt64ByteSize, -1, 1],
    147         [wire_format.SInt64ByteSize, 1, 1],
    148         [wire_format.SInt64ByteSize, -63, 1],
    149         [wire_format.SInt64ByteSize, 63, 1],
    150         [wire_format.SInt64ByteSize, -64, 1],
    151         [wire_format.SInt64ByteSize, 64, 2],
    152         # Fixed32ByteSize().
    153         [wire_format.Fixed32ByteSize, 0, 4],
    154         [wire_format.Fixed32ByteSize, wire_format.UINT32_MAX, 4],
    155         # Fixed64ByteSize().
    156         [wire_format.Fixed64ByteSize, 0, 8],
    157         [wire_format.Fixed64ByteSize, wire_format.UINT64_MAX, 8],
    158         # SFixed32ByteSize().
    159         [wire_format.SFixed32ByteSize, 0, 4],
    160         [wire_format.SFixed32ByteSize, wire_format.INT32_MIN, 4],
    161         [wire_format.SFixed32ByteSize, wire_format.INT32_MAX, 4],
    162         # SFixed64ByteSize().
    163         [wire_format.SFixed64ByteSize, 0, 8],
    164         [wire_format.SFixed64ByteSize, wire_format.INT64_MIN, 8],
    165         [wire_format.SFixed64ByteSize, wire_format.INT64_MAX, 8],
    166         # FloatByteSize().
    167         [wire_format.FloatByteSize, 0.0, 4],
    168         [wire_format.FloatByteSize, 1000000000.0, 4],
    169         [wire_format.FloatByteSize, -1000000000.0, 4],
    170         # DoubleByteSize().
    171         [wire_format.DoubleByteSize, 0.0, 8],
    172         [wire_format.DoubleByteSize, 1000000000.0, 8],
    173         [wire_format.DoubleByteSize, -1000000000.0, 8],
    174         # BoolByteSize().
    175         [wire_format.BoolByteSize, False, 1],
    176         [wire_format.BoolByteSize, True, 1],
    177         # EnumByteSize().
    178         [wire_format.EnumByteSize, 0, 1],
    179         [wire_format.EnumByteSize, 127, 1],
    180         [wire_format.EnumByteSize, 128, 2],
    181         [wire_format.EnumByteSize, wire_format.UINT32_MAX, 5],
    182         ]
    183     for args in NUMERIC_ARGS:
    184       self.NumericByteSizeTestHelper(*args)
    185 
    186     # Test strings and bytes.
    187     for byte_size_fn in (wire_format.StringByteSize, wire_format.BytesByteSize):
    188       # 1 byte for tag, 1 byte for length, 3 bytes for contents.
    189       self.assertEqual(5, byte_size_fn(10, 'abc'))
    190       # 2 bytes for tag, 1 byte for length, 3 bytes for contents.
    191       self.assertEqual(6, byte_size_fn(16, 'abc'))
    192       # 2 bytes for tag, 2 bytes for length, 128 bytes for contents.
    193       self.assertEqual(132, byte_size_fn(16, 'a' * 128))
    194 
    195     # Test UTF-8 string byte size calculation.
    196     # 1 byte for tag, 1 byte for length, 8 bytes for content.
    197     self.assertEqual(10, wire_format.StringByteSize(
    198         5, unicode('\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82', 'utf-8')))
    199 
    200     class MockMessage(object):
    201       def __init__(self, byte_size):
    202         self.byte_size = byte_size
    203       def ByteSize(self):
    204         return self.byte_size
    205 
    206     message_byte_size = 10
    207     mock_message = MockMessage(byte_size=message_byte_size)
    208     # Test groups.
    209     # (2 * 1) bytes for begin and end tags, plus message_byte_size.
    210     self.assertEqual(2 + message_byte_size,
    211                      wire_format.GroupByteSize(1, mock_message))
    212     # (2 * 2) bytes for begin and end tags, plus message_byte_size.
    213     self.assertEqual(4 + message_byte_size,
    214                      wire_format.GroupByteSize(16, mock_message))
    215 
    216     # Test messages.
    217     # 1 byte for tag, plus 1 byte for length, plus contents.
    218     self.assertEqual(2 + mock_message.byte_size,
    219                      wire_format.MessageByteSize(1, mock_message))
    220     # 2 bytes for tag, plus 1 byte for length, plus contents.
    221     self.assertEqual(3 + mock_message.byte_size,
    222                      wire_format.MessageByteSize(16, mock_message))
    223     # 2 bytes for tag, plus 2 bytes for length, plus contents.
    224     mock_message.byte_size = 128
    225     self.assertEqual(4 + mock_message.byte_size,
    226                      wire_format.MessageByteSize(16, mock_message))
    227 
    228 
    229     # Test message set item byte size.
    230     # 4 bytes for tags, plus 1 byte for length, plus 1 byte for type_id,
    231     # plus contents.
    232     mock_message.byte_size = 10
    233     self.assertEqual(mock_message.byte_size + 6,
    234                      wire_format.MessageSetItemByteSize(1, mock_message))
    235 
    236     # 4 bytes for tags, plus 2 bytes for length, plus 1 byte for type_id,
    237     # plus contents.
    238     mock_message.byte_size = 128
    239     self.assertEqual(mock_message.byte_size + 7,
    240                      wire_format.MessageSetItemByteSize(1, mock_message))
    241 
    242     # 4 bytes for tags, plus 2 bytes for length, plus 2 byte for type_id,
    243     # plus contents.
    244     self.assertEqual(mock_message.byte_size + 8,
    245                      wire_format.MessageSetItemByteSize(128, mock_message))
    246 
    247     # Too-long varint.
    248     self.assertRaises(message.EncodeError,
    249                       wire_format.UInt64ByteSize, 1, 1 << 128)
    250 
    251 
    252 if __name__ == '__main__':
    253   unittest.main()
    254