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