PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/python/google/protobuf/internal/decoder_test.py

https://bitbucket.org/Abd4llA/test
Python | 250 lines | 191 code | 10 blank | 49 comment | 6 complexity | a54d0def4949ef28d71242b51231eedf MD5 | raw file
  1. # Protocol Buffers - Google's data interchange format
  2. # Copyright 2008 Google Inc. All rights reserved.
  3. # http://code.google.com/p/protobuf/
  4. #
  5. # Redistribution and use in source and binary forms, with or without
  6. # modification, are permitted provided that the following conditions are
  7. # met:
  8. #
  9. # * Redistributions of source code must retain the above copyright
  10. # notice, this list of conditions and the following disclaimer.
  11. # * Redistributions in binary form must reproduce the above
  12. # copyright notice, this list of conditions and the following disclaimer
  13. # in the documentation and/or other materials provided with the
  14. # distribution.
  15. # * Neither the name of Google Inc. nor the names of its
  16. # contributors may be used to endorse or promote products derived from
  17. # this software without specific prior written permission.
  18. #
  19. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. """Test for google.protobuf.internal.decoder."""
  31. __author__ = 'robinson@google.com (Will Robinson)'
  32. import struct
  33. import unittest
  34. from google.protobuf.internal import wire_format
  35. from google.protobuf.internal import encoder
  36. from google.protobuf.internal import decoder
  37. import logging
  38. from google.protobuf.internal import input_stream
  39. from google.protobuf import message
  40. import mox
  41. class DecoderTest(unittest.TestCase):
  42. def setUp(self):
  43. self.mox = mox.Mox()
  44. self.mock_stream = self.mox.CreateMock(input_stream.InputStream)
  45. self.mock_message = self.mox.CreateMock(message.Message)
  46. def testReadFieldNumberAndWireType(self):
  47. # Test field numbers that will require various varint sizes.
  48. for expected_field_number in (1, 15, 16, 2047, 2048):
  49. for expected_wire_type in range(6): # Highest-numbered wiretype is 5.
  50. e = encoder.Encoder()
  51. e._AppendTag(expected_field_number, expected_wire_type)
  52. s = e.ToString()
  53. d = decoder.Decoder(s)
  54. field_number, wire_type = d.ReadFieldNumberAndWireType()
  55. self.assertEqual(expected_field_number, field_number)
  56. self.assertEqual(expected_wire_type, wire_type)
  57. def ReadScalarTestHelper(self, test_name, decoder_method, expected_result,
  58. expected_stream_method_name,
  59. stream_method_return, *args):
  60. """Helper for testReadScalars below.
  61. Calls one of the Decoder.Read*() methods and ensures that the results are
  62. as expected.
  63. Args:
  64. test_name: Name of this test, used for logging only.
  65. decoder_method: Unbound decoder.Decoder method to call.
  66. expected_result: Value we expect returned from decoder_method().
  67. expected_stream_method_name: (string) Name of the InputStream
  68. method we expect Decoder to call to actually read the value
  69. on the wire.
  70. stream_method_return: Value our mocked-out stream method should
  71. return to the decoder.
  72. args: Additional arguments that we expect to be passed to the
  73. stream method.
  74. """
  75. logging.info('Testing %s scalar input.\n'
  76. 'Calling %r(), and expecting that to call the '
  77. 'stream method %s(%r), which will return %r. Finally, '
  78. 'expecting the Decoder method to return %r'% (
  79. test_name, decoder_method,
  80. expected_stream_method_name, args, stream_method_return,
  81. expected_result))
  82. d = decoder.Decoder('')
  83. d._stream = self.mock_stream
  84. if decoder_method in (decoder.Decoder.ReadString,
  85. decoder.Decoder.ReadBytes):
  86. self.mock_stream.ReadVarUInt32().AndReturn(len(stream_method_return))
  87. # We have to use names instead of methods to work around some
  88. # mox weirdness. (ResetAll() is overzealous).
  89. expected_stream_method = getattr(self.mock_stream,
  90. expected_stream_method_name)
  91. expected_stream_method(*args).AndReturn(stream_method_return)
  92. self.mox.ReplayAll()
  93. result = decoder_method(d)
  94. self.assertEqual(expected_result, result)
  95. self.assert_(isinstance(result, type(expected_result)))
  96. self.mox.VerifyAll()
  97. self.mox.ResetAll()
  98. def testReadScalars(self):
  99. test_string = 'I can feel myself getting sutpider.'
  100. scalar_tests = [
  101. ['int32', decoder.Decoder.ReadInt32, 0, 'ReadVarint32', 0],
  102. ['int64', decoder.Decoder.ReadInt64, 0, 'ReadVarint64', 0],
  103. ['uint32', decoder.Decoder.ReadUInt32, 0, 'ReadVarUInt32', 0],
  104. ['uint64', decoder.Decoder.ReadUInt64, 0, 'ReadVarUInt64', 0],
  105. ['fixed32', decoder.Decoder.ReadFixed32, 0xffffffff,
  106. 'ReadLittleEndian32', 0xffffffff],
  107. ['fixed64', decoder.Decoder.ReadFixed64, 0xffffffffffffffff,
  108. 'ReadLittleEndian64', 0xffffffffffffffff],
  109. ['sfixed32', decoder.Decoder.ReadSFixed32, long(-1),
  110. 'ReadLittleEndian32', 0xffffffff],
  111. ['sfixed64', decoder.Decoder.ReadSFixed64, long(-1),
  112. 'ReadLittleEndian64', 0xffffffffffffffff],
  113. ['float', decoder.Decoder.ReadFloat, 0.0,
  114. 'ReadBytes', struct.pack('f', 0.0), 4],
  115. ['double', decoder.Decoder.ReadDouble, 0.0,
  116. 'ReadBytes', struct.pack('d', 0.0), 8],
  117. ['bool', decoder.Decoder.ReadBool, True, 'ReadVarUInt32', 1],
  118. ['enum', decoder.Decoder.ReadEnum, 23, 'ReadVarUInt32', 23],
  119. ['string', decoder.Decoder.ReadString,
  120. unicode(test_string, 'utf-8'), 'ReadBytes', test_string,
  121. len(test_string)],
  122. ['utf8-string', decoder.Decoder.ReadString,
  123. unicode(test_string, 'utf-8'), 'ReadBytes', test_string,
  124. len(test_string)],
  125. ['bytes', decoder.Decoder.ReadBytes,
  126. test_string, 'ReadBytes', test_string, len(test_string)],
  127. # We test zigzag decoding routines more extensively below.
  128. ['sint32', decoder.Decoder.ReadSInt32, -1, 'ReadVarUInt32', 1],
  129. ['sint64', decoder.Decoder.ReadSInt64, -1, 'ReadVarUInt64', 1],
  130. ]
  131. # Ensure that we're testing different Decoder methods and using
  132. # different test names in all test cases above.
  133. self.assertEqual(len(scalar_tests), len(set(t[0] for t in scalar_tests)))
  134. self.assert_(len(scalar_tests) >= len(set(t[1] for t in scalar_tests)))
  135. for args in scalar_tests:
  136. self.ReadScalarTestHelper(*args)
  137. def testReadMessageInto(self):
  138. length = 23
  139. def Test(simulate_error):
  140. d = decoder.Decoder('')
  141. d._stream = self.mock_stream
  142. self.mock_stream.ReadVarUInt32().AndReturn(length)
  143. sub_buffer = object()
  144. self.mock_stream.GetSubBuffer(length).AndReturn(sub_buffer)
  145. if simulate_error:
  146. self.mock_message.MergeFromString(sub_buffer).AndReturn(length - 1)
  147. self.mox.ReplayAll()
  148. self.assertRaises(
  149. message.DecodeError, d.ReadMessageInto, self.mock_message)
  150. else:
  151. self.mock_message.MergeFromString(sub_buffer).AndReturn(length)
  152. self.mock_stream.SkipBytes(length)
  153. self.mox.ReplayAll()
  154. d.ReadMessageInto(self.mock_message)
  155. self.mox.VerifyAll()
  156. self.mox.ResetAll()
  157. Test(simulate_error=False)
  158. Test(simulate_error=True)
  159. def testReadGroupInto_Success(self):
  160. # Test both the empty and nonempty cases.
  161. for num_bytes in (5, 0):
  162. field_number = expected_field_number = 10
  163. d = decoder.Decoder('')
  164. d._stream = self.mock_stream
  165. sub_buffer = object()
  166. self.mock_stream.GetSubBuffer().AndReturn(sub_buffer)
  167. self.mock_message.MergeFromString(sub_buffer).AndReturn(num_bytes)
  168. self.mock_stream.SkipBytes(num_bytes)
  169. self.mock_stream.ReadVarUInt32().AndReturn(wire_format.PackTag(
  170. field_number, wire_format.WIRETYPE_END_GROUP))
  171. self.mox.ReplayAll()
  172. d.ReadGroupInto(expected_field_number, self.mock_message)
  173. self.mox.VerifyAll()
  174. self.mox.ResetAll()
  175. def ReadGroupInto_FailureTestHelper(self, bytes_read):
  176. d = decoder.Decoder('')
  177. d._stream = self.mock_stream
  178. sub_buffer = object()
  179. self.mock_stream.GetSubBuffer().AndReturn(sub_buffer)
  180. self.mock_message.MergeFromString(sub_buffer).AndReturn(bytes_read)
  181. return d
  182. def testReadGroupInto_NegativeBytesReported(self):
  183. expected_field_number = 10
  184. d = self.ReadGroupInto_FailureTestHelper(bytes_read=-1)
  185. self.mox.ReplayAll()
  186. self.assertRaises(message.DecodeError,
  187. d.ReadGroupInto, expected_field_number,
  188. self.mock_message)
  189. self.mox.VerifyAll()
  190. def testReadGroupInto_NoEndGroupTag(self):
  191. field_number = expected_field_number = 10
  192. num_bytes = 5
  193. d = self.ReadGroupInto_FailureTestHelper(bytes_read=num_bytes)
  194. self.mock_stream.SkipBytes(num_bytes)
  195. # Right field number, wrong wire type.
  196. self.mock_stream.ReadVarUInt32().AndReturn(wire_format.PackTag(
  197. field_number, wire_format.WIRETYPE_LENGTH_DELIMITED))
  198. self.mox.ReplayAll()
  199. self.assertRaises(message.DecodeError,
  200. d.ReadGroupInto, expected_field_number,
  201. self.mock_message)
  202. self.mox.VerifyAll()
  203. def testReadGroupInto_WrongFieldNumberInEndGroupTag(self):
  204. expected_field_number = 10
  205. field_number = expected_field_number + 1
  206. num_bytes = 5
  207. d = self.ReadGroupInto_FailureTestHelper(bytes_read=num_bytes)
  208. self.mock_stream.SkipBytes(num_bytes)
  209. # Wrong field number, right wire type.
  210. self.mock_stream.ReadVarUInt32().AndReturn(wire_format.PackTag(
  211. field_number, wire_format.WIRETYPE_END_GROUP))
  212. self.mox.ReplayAll()
  213. self.assertRaises(message.DecodeError,
  214. d.ReadGroupInto, expected_field_number,
  215. self.mock_message)
  216. self.mox.VerifyAll()
  217. def testSkipBytes(self):
  218. d = decoder.Decoder('')
  219. num_bytes = 1024
  220. self.mock_stream.SkipBytes(num_bytes)
  221. d._stream = self.mock_stream
  222. self.mox.ReplayAll()
  223. d.SkipBytes(num_bytes)
  224. self.mox.VerifyAll()
  225. if __name__ == '__main__':
  226. unittest.main()