• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Protocol Buffers - Google's data interchange format
2# Copyright 2008 Google Inc.  All rights reserved.
3#
4# Use of this source code is governed by a BSD-style
5# license that can be found in the LICENSE file or at
6# https://developers.google.com/open-source/licenses/bsd
7
8"""Test for google.protobuf.internal.wire_format."""
9
10__author__ = 'robinson@google.com (Will Robinson)'
11
12import unittest
13
14from google.protobuf import message
15from google.protobuf.internal import wire_format
16
17
18class WireFormatTest(unittest.TestCase):
19
20  def testPackTag(self):
21    field_number = 0xabc
22    tag_type = 2
23    self.assertEqual((field_number << 3) | tag_type,
24                     wire_format.PackTag(field_number, tag_type))
25    PackTag = wire_format.PackTag
26    # Number too high.
27    self.assertRaises(message.EncodeError, PackTag, field_number, 6)
28    # Number too low.
29    self.assertRaises(message.EncodeError, PackTag, field_number, -1)
30
31  def testUnpackTag(self):
32    # Test field numbers that will require various varint sizes.
33    for expected_field_number in (1, 15, 16, 2047, 2048):
34      for expected_wire_type in range(6):  # Highest-numbered wiretype is 5.
35        field_number, wire_type = wire_format.UnpackTag(
36            wire_format.PackTag(expected_field_number, expected_wire_type))
37        self.assertEqual(expected_field_number, field_number)
38        self.assertEqual(expected_wire_type, wire_type)
39
40    self.assertRaises(TypeError, wire_format.UnpackTag, None)
41    self.assertRaises(TypeError, wire_format.UnpackTag, 'abc')
42    self.assertRaises(TypeError, wire_format.UnpackTag, 0.0)
43    self.assertRaises(TypeError, wire_format.UnpackTag, object())
44
45  def testZigZagEncode(self):
46    Z = wire_format.ZigZagEncode
47    self.assertEqual(0, Z(0))
48    self.assertEqual(1, Z(-1))
49    self.assertEqual(2, Z(1))
50    self.assertEqual(3, Z(-2))
51    self.assertEqual(4, Z(2))
52    self.assertEqual(0xfffffffe, Z(0x7fffffff))
53    self.assertEqual(0xffffffff, Z(-0x80000000))
54    self.assertEqual(0xfffffffffffffffe, Z(0x7fffffffffffffff))
55    self.assertEqual(0xffffffffffffffff, Z(-0x8000000000000000))
56
57    self.assertRaises(TypeError, Z, None)
58    self.assertRaises(TypeError, Z, 'abcd')
59    self.assertRaises(TypeError, Z, 0.0)
60    self.assertRaises(TypeError, Z, object())
61
62  def testZigZagDecode(self):
63    Z = wire_format.ZigZagDecode
64    self.assertEqual(0, Z(0))
65    self.assertEqual(-1, Z(1))
66    self.assertEqual(1, Z(2))
67    self.assertEqual(-2, Z(3))
68    self.assertEqual(2, Z(4))
69    self.assertEqual(0x7fffffff, Z(0xfffffffe))
70    self.assertEqual(-0x80000000, Z(0xffffffff))
71    self.assertEqual(0x7fffffffffffffff, Z(0xfffffffffffffffe))
72    self.assertEqual(-0x8000000000000000, Z(0xffffffffffffffff))
73
74    self.assertRaises(TypeError, Z, None)
75    self.assertRaises(TypeError, Z, 'abcd')
76    self.assertRaises(TypeError, Z, 0.0)
77    self.assertRaises(TypeError, Z, object())
78
79  def NumericByteSizeTestHelper(self, byte_size_fn, value, expected_value_size):
80    # Use field numbers that cause various byte sizes for the tag information.
81    for field_number, tag_bytes in ((15, 1), (16, 2), (2047, 2), (2048, 3)):
82      expected_size = expected_value_size + tag_bytes
83      actual_size = byte_size_fn(field_number, value)
84      self.assertEqual(expected_size, actual_size,
85                       'byte_size_fn: %s, field_number: %d, value: %r\n'
86                       'Expected: %d, Actual: %d'% (
87          byte_size_fn, field_number, value, expected_size, actual_size))
88
89  def testByteSizeFunctions(self):
90    # Test all numeric *ByteSize() functions.
91    NUMERIC_ARGS = [
92        # Int32ByteSize().
93        [wire_format.Int32ByteSize, 0, 1],
94        [wire_format.Int32ByteSize, 127, 1],
95        [wire_format.Int32ByteSize, 128, 2],
96        [wire_format.Int32ByteSize, -1, 10],
97        # Int64ByteSize().
98        [wire_format.Int64ByteSize, 0, 1],
99        [wire_format.Int64ByteSize, 127, 1],
100        [wire_format.Int64ByteSize, 128, 2],
101        [wire_format.Int64ByteSize, -1, 10],
102        # UInt32ByteSize().
103        [wire_format.UInt32ByteSize, 0, 1],
104        [wire_format.UInt32ByteSize, 127, 1],
105        [wire_format.UInt32ByteSize, 128, 2],
106        [wire_format.UInt32ByteSize, wire_format.UINT32_MAX, 5],
107        # UInt64ByteSize().
108        [wire_format.UInt64ByteSize, 0, 1],
109        [wire_format.UInt64ByteSize, 127, 1],
110        [wire_format.UInt64ByteSize, 128, 2],
111        [wire_format.UInt64ByteSize, wire_format.UINT64_MAX, 10],
112        # SInt32ByteSize().
113        [wire_format.SInt32ByteSize, 0, 1],
114        [wire_format.SInt32ByteSize, -1, 1],
115        [wire_format.SInt32ByteSize, 1, 1],
116        [wire_format.SInt32ByteSize, -63, 1],
117        [wire_format.SInt32ByteSize, 63, 1],
118        [wire_format.SInt32ByteSize, -64, 1],
119        [wire_format.SInt32ByteSize, 64, 2],
120        # SInt64ByteSize().
121        [wire_format.SInt64ByteSize, 0, 1],
122        [wire_format.SInt64ByteSize, -1, 1],
123        [wire_format.SInt64ByteSize, 1, 1],
124        [wire_format.SInt64ByteSize, -63, 1],
125        [wire_format.SInt64ByteSize, 63, 1],
126        [wire_format.SInt64ByteSize, -64, 1],
127        [wire_format.SInt64ByteSize, 64, 2],
128        # Fixed32ByteSize().
129        [wire_format.Fixed32ByteSize, 0, 4],
130        [wire_format.Fixed32ByteSize, wire_format.UINT32_MAX, 4],
131        # Fixed64ByteSize().
132        [wire_format.Fixed64ByteSize, 0, 8],
133        [wire_format.Fixed64ByteSize, wire_format.UINT64_MAX, 8],
134        # SFixed32ByteSize().
135        [wire_format.SFixed32ByteSize, 0, 4],
136        [wire_format.SFixed32ByteSize, wire_format.INT32_MIN, 4],
137        [wire_format.SFixed32ByteSize, wire_format.INT32_MAX, 4],
138        # SFixed64ByteSize().
139        [wire_format.SFixed64ByteSize, 0, 8],
140        [wire_format.SFixed64ByteSize, wire_format.INT64_MIN, 8],
141        [wire_format.SFixed64ByteSize, wire_format.INT64_MAX, 8],
142        # FloatByteSize().
143        [wire_format.FloatByteSize, 0.0, 4],
144        [wire_format.FloatByteSize, 1000000000.0, 4],
145        [wire_format.FloatByteSize, -1000000000.0, 4],
146        # DoubleByteSize().
147        [wire_format.DoubleByteSize, 0.0, 8],
148        [wire_format.DoubleByteSize, 1000000000.0, 8],
149        [wire_format.DoubleByteSize, -1000000000.0, 8],
150        # BoolByteSize().
151        [wire_format.BoolByteSize, False, 1],
152        [wire_format.BoolByteSize, True, 1],
153        # EnumByteSize().
154        [wire_format.EnumByteSize, 0, 1],
155        [wire_format.EnumByteSize, 127, 1],
156        [wire_format.EnumByteSize, 128, 2],
157        [wire_format.EnumByteSize, wire_format.UINT32_MAX, 5],
158        ]
159    for args in NUMERIC_ARGS:
160      self.NumericByteSizeTestHelper(*args)
161
162    # Test strings and bytes.
163    for byte_size_fn in (wire_format.StringByteSize, wire_format.BytesByteSize):
164      # 1 byte for tag, 1 byte for length, 3 bytes for contents.
165      self.assertEqual(5, byte_size_fn(10, 'abc'))
166      # 2 bytes for tag, 1 byte for length, 3 bytes for contents.
167      self.assertEqual(6, byte_size_fn(16, 'abc'))
168      # 2 bytes for tag, 2 bytes for length, 128 bytes for contents.
169      self.assertEqual(132, byte_size_fn(16, 'a' * 128))
170
171    # Test UTF-8 string byte size calculation.
172    # 1 byte for tag, 1 byte for length, 8 bytes for content.
173    self.assertEqual(10, wire_format.StringByteSize(
174        5, b'\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82'.decode('utf-8')))
175
176    class MockMessage(object):
177      def __init__(self, byte_size):
178        self.byte_size = byte_size
179      def ByteSize(self):
180        return self.byte_size
181
182    message_byte_size = 10
183    mock_message = MockMessage(byte_size=message_byte_size)
184    # Test groups.
185    # (2 * 1) bytes for begin and end tags, plus message_byte_size.
186    self.assertEqual(2 + message_byte_size,
187                     wire_format.GroupByteSize(1, mock_message))
188    # (2 * 2) bytes for begin and end tags, plus message_byte_size.
189    self.assertEqual(4 + message_byte_size,
190                     wire_format.GroupByteSize(16, mock_message))
191
192    # Test messages.
193    # 1 byte for tag, plus 1 byte for length, plus contents.
194    self.assertEqual(2 + mock_message.byte_size,
195                     wire_format.MessageByteSize(1, mock_message))
196    # 2 bytes for tag, plus 1 byte for length, plus contents.
197    self.assertEqual(3 + mock_message.byte_size,
198                     wire_format.MessageByteSize(16, mock_message))
199    # 2 bytes for tag, plus 2 bytes for length, plus contents.
200    mock_message.byte_size = 128
201    self.assertEqual(4 + mock_message.byte_size,
202                     wire_format.MessageByteSize(16, mock_message))
203
204
205    # Test message set item byte size.
206    # 4 bytes for tags, plus 1 byte for length, plus 1 byte for type_id,
207    # plus contents.
208    mock_message.byte_size = 10
209    self.assertEqual(mock_message.byte_size + 6,
210                     wire_format.MessageSetItemByteSize(1, mock_message))
211
212    # 4 bytes for tags, plus 2 bytes for length, plus 1 byte for type_id,
213    # plus contents.
214    mock_message.byte_size = 128
215    self.assertEqual(mock_message.byte_size + 7,
216                     wire_format.MessageSetItemByteSize(1, mock_message))
217
218    # 4 bytes for tags, plus 2 bytes for length, plus 2 byte for type_id,
219    # plus contents.
220    self.assertEqual(mock_message.byte_size + 8,
221                     wire_format.MessageSetItemByteSize(128, mock_message))
222
223    # Too-long varint.
224    self.assertRaises(message.EncodeError,
225                      wire_format.UInt64ByteSize, 1, 1 << 128)
226
227
228if __name__ == '__main__':
229  unittest.main()
230