PageRenderTime 98ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

/python/google/protobuf/internal/input_stream_test.py

https://bitbucket.org/Abd4llA/test
Python | 293 lines | 243 code | 11 blank | 39 comment | 1 complexity | b4afe9e742700a51742b4fb2d367ce9f 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.input_stream."""
  31. __author__ = 'robinson@google.com (Will Robinson)'
  32. import unittest
  33. from google.protobuf import message
  34. from google.protobuf.internal import wire_format
  35. from google.protobuf.internal import input_stream
  36. class InputStreamTest(unittest.TestCase):
  37. def testEndOfStream(self):
  38. stream = input_stream.InputStream('abcd')
  39. self.assertFalse(stream.EndOfStream())
  40. self.assertEqual('abcd', stream.ReadBytes(10))
  41. self.assertTrue(stream.EndOfStream())
  42. def testPosition(self):
  43. stream = input_stream.InputStream('abcd')
  44. self.assertEqual(0, stream.Position())
  45. self.assertEqual(0, stream.Position()) # No side-effects.
  46. stream.ReadBytes(1)
  47. self.assertEqual(1, stream.Position())
  48. stream.ReadBytes(1)
  49. self.assertEqual(2, stream.Position())
  50. stream.ReadBytes(10)
  51. self.assertEqual(4, stream.Position()) # Can't go past end of stream.
  52. def testGetSubBuffer(self):
  53. stream = input_stream.InputStream('abcd')
  54. # Try leaving out the size.
  55. self.assertEqual('abcd', str(stream.GetSubBuffer()))
  56. stream.SkipBytes(1)
  57. # GetSubBuffer() always starts at current size.
  58. self.assertEqual('bcd', str(stream.GetSubBuffer()))
  59. # Try 0-size.
  60. self.assertEqual('', str(stream.GetSubBuffer(0)))
  61. # Negative sizes should raise an error.
  62. self.assertRaises(message.DecodeError, stream.GetSubBuffer, -1)
  63. # Positive sizes should work as expected.
  64. self.assertEqual('b', str(stream.GetSubBuffer(1)))
  65. self.assertEqual('bc', str(stream.GetSubBuffer(2)))
  66. # Sizes longer than remaining bytes in the buffer should
  67. # return the whole remaining buffer.
  68. self.assertEqual('bcd', str(stream.GetSubBuffer(1000)))
  69. def testSkipBytes(self):
  70. stream = input_stream.InputStream('')
  71. # Skipping bytes when at the end of stream
  72. # should have no effect.
  73. stream.SkipBytes(0)
  74. stream.SkipBytes(1)
  75. stream.SkipBytes(2)
  76. self.assertTrue(stream.EndOfStream())
  77. self.assertEqual(0, stream.Position())
  78. # Try skipping within a stream.
  79. stream = input_stream.InputStream('abcd')
  80. self.assertEqual(0, stream.Position())
  81. stream.SkipBytes(1)
  82. self.assertEqual(1, stream.Position())
  83. stream.SkipBytes(10) # Can't skip past the end.
  84. self.assertEqual(4, stream.Position())
  85. # Ensure that a negative skip raises an exception.
  86. stream = input_stream.InputStream('abcd')
  87. stream.SkipBytes(1)
  88. self.assertRaises(message.DecodeError, stream.SkipBytes, -1)
  89. def testReadBytes(self):
  90. s = 'abcd'
  91. # Also test going past the total stream length.
  92. for i in range(len(s) + 10):
  93. stream = input_stream.InputStream(s)
  94. self.assertEqual(s[:i], stream.ReadBytes(i))
  95. self.assertEqual(min(i, len(s)), stream.Position())
  96. stream = input_stream.InputStream(s)
  97. self.assertRaises(message.DecodeError, stream.ReadBytes, -1)
  98. def EnsureFailureOnEmptyStream(self, input_stream_method):
  99. """Helper for integer-parsing tests below.
  100. Ensures that the given InputStream method raises a DecodeError
  101. if called on a stream with no bytes remaining.
  102. """
  103. stream = input_stream.InputStream('')
  104. self.assertRaises(message.DecodeError, input_stream_method, stream)
  105. def testReadLittleEndian32(self):
  106. self.EnsureFailureOnEmptyStream(input_stream.InputStream.ReadLittleEndian32)
  107. s = ''
  108. # Read 0.
  109. s += '\x00\x00\x00\x00'
  110. # Read 1.
  111. s += '\x01\x00\x00\x00'
  112. # Read a bunch of different bytes.
  113. s += '\x01\x02\x03\x04'
  114. # Read max unsigned 32-bit int.
  115. s += '\xff\xff\xff\xff'
  116. # Try a read with fewer than 4 bytes left in the stream.
  117. s += '\x00\x00\x00'
  118. stream = input_stream.InputStream(s)
  119. self.assertEqual(0, stream.ReadLittleEndian32())
  120. self.assertEqual(4, stream.Position())
  121. self.assertEqual(1, stream.ReadLittleEndian32())
  122. self.assertEqual(8, stream.Position())
  123. self.assertEqual(0x04030201, stream.ReadLittleEndian32())
  124. self.assertEqual(12, stream.Position())
  125. self.assertEqual(wire_format.UINT32_MAX, stream.ReadLittleEndian32())
  126. self.assertEqual(16, stream.Position())
  127. self.assertRaises(message.DecodeError, stream.ReadLittleEndian32)
  128. def testReadLittleEndian64(self):
  129. self.EnsureFailureOnEmptyStream(input_stream.InputStream.ReadLittleEndian64)
  130. s = ''
  131. # Read 0.
  132. s += '\x00\x00\x00\x00\x00\x00\x00\x00'
  133. # Read 1.
  134. s += '\x01\x00\x00\x00\x00\x00\x00\x00'
  135. # Read a bunch of different bytes.
  136. s += '\x01\x02\x03\x04\x05\x06\x07\x08'
  137. # Read max unsigned 64-bit int.
  138. s += '\xff\xff\xff\xff\xff\xff\xff\xff'
  139. # Try a read with fewer than 8 bytes left in the stream.
  140. s += '\x00\x00\x00'
  141. stream = input_stream.InputStream(s)
  142. self.assertEqual(0, stream.ReadLittleEndian64())
  143. self.assertEqual(8, stream.Position())
  144. self.assertEqual(1, stream.ReadLittleEndian64())
  145. self.assertEqual(16, stream.Position())
  146. self.assertEqual(0x0807060504030201, stream.ReadLittleEndian64())
  147. self.assertEqual(24, stream.Position())
  148. self.assertEqual(wire_format.UINT64_MAX, stream.ReadLittleEndian64())
  149. self.assertEqual(32, stream.Position())
  150. self.assertRaises(message.DecodeError, stream.ReadLittleEndian64)
  151. def ReadVarintSuccessTestHelper(self, varints_and_ints, read_method):
  152. """Helper for tests below that test successful reads of various varints.
  153. Args:
  154. varints_and_ints: Iterable of (str, integer) pairs, where the string
  155. gives the wire encoding and the integer gives the value we expect
  156. to be returned by the read_method upon encountering this string.
  157. read_method: Unbound InputStream method that is capable of reading
  158. the encoded strings provided in the first elements of varints_and_ints.
  159. """
  160. s = ''.join(s for s, i in varints_and_ints)
  161. stream = input_stream.InputStream(s)
  162. expected_pos = 0
  163. self.assertEqual(expected_pos, stream.Position())
  164. for s, expected_int in varints_and_ints:
  165. self.assertEqual(expected_int, read_method(stream))
  166. expected_pos += len(s)
  167. self.assertEqual(expected_pos, stream.Position())
  168. def testReadVarint32Success(self):
  169. varints_and_ints = [
  170. ('\x00', 0),
  171. ('\x01', 1),
  172. ('\x7f', 127),
  173. ('\x80\x01', 128),
  174. ('\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01', -1),
  175. ('\xff\xff\xff\xff\x07', wire_format.INT32_MAX),
  176. ('\x80\x80\x80\x80\xf8\xff\xff\xff\xff\x01', wire_format.INT32_MIN),
  177. ]
  178. self.ReadVarintSuccessTestHelper(varints_and_ints,
  179. input_stream.InputStream.ReadVarint32)
  180. def testReadVarint32Failure(self):
  181. self.EnsureFailureOnEmptyStream(input_stream.InputStream.ReadVarint32)
  182. # Try and fail to read INT32_MAX + 1.
  183. s = '\x80\x80\x80\x80\x08'
  184. stream = input_stream.InputStream(s)
  185. self.assertRaises(message.DecodeError, stream.ReadVarint32)
  186. # Try and fail to read INT32_MIN - 1.
  187. s = '\xfe\xff\xff\xff\xf7\xff\xff\xff\xff\x01'
  188. stream = input_stream.InputStream(s)
  189. self.assertRaises(message.DecodeError, stream.ReadVarint32)
  190. # Try and fail to read something that looks like
  191. # a varint with more than 10 bytes.
  192. s = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00'
  193. stream = input_stream.InputStream(s)
  194. self.assertRaises(message.DecodeError, stream.ReadVarint32)
  195. def testReadVarUInt32Success(self):
  196. varints_and_ints = [
  197. ('\x00', 0),
  198. ('\x01', 1),
  199. ('\x7f', 127),
  200. ('\x80\x01', 128),
  201. ('\xff\xff\xff\xff\x0f', wire_format.UINT32_MAX),
  202. ]
  203. self.ReadVarintSuccessTestHelper(varints_and_ints,
  204. input_stream.InputStream.ReadVarUInt32)
  205. def testReadVarUInt32Failure(self):
  206. self.EnsureFailureOnEmptyStream(input_stream.InputStream.ReadVarUInt32)
  207. # Try and fail to read UINT32_MAX + 1
  208. s = '\x80\x80\x80\x80\x10'
  209. stream = input_stream.InputStream(s)
  210. self.assertRaises(message.DecodeError, stream.ReadVarUInt32)
  211. # Try and fail to read something that looks like
  212. # a varint with more than 10 bytes.
  213. s = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00'
  214. stream = input_stream.InputStream(s)
  215. self.assertRaises(message.DecodeError, stream.ReadVarUInt32)
  216. def testReadVarint64Success(self):
  217. varints_and_ints = [
  218. ('\x00', 0),
  219. ('\x01', 1),
  220. ('\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01', -1),
  221. ('\x7f', 127),
  222. ('\x80\x01', 128),
  223. ('\xff\xff\xff\xff\xff\xff\xff\xff\x7f', wire_format.INT64_MAX),
  224. ('\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01', wire_format.INT64_MIN),
  225. ]
  226. self.ReadVarintSuccessTestHelper(varints_and_ints,
  227. input_stream.InputStream.ReadVarint64)
  228. def testReadVarint64Failure(self):
  229. self.EnsureFailureOnEmptyStream(input_stream.InputStream.ReadVarint64)
  230. # Try and fail to read something with the mythical 64th bit set.
  231. s = '\x80\x80\x80\x80\x80\x80\x80\x80\x80\x02'
  232. stream = input_stream.InputStream(s)
  233. self.assertRaises(message.DecodeError, stream.ReadVarint64)
  234. # Try and fail to read something that looks like
  235. # a varint with more than 10 bytes.
  236. s = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00'
  237. stream = input_stream.InputStream(s)
  238. self.assertRaises(message.DecodeError, stream.ReadVarint64)
  239. def testReadVarUInt64Success(self):
  240. varints_and_ints = [
  241. ('\x00', 0),
  242. ('\x01', 1),
  243. ('\x7f', 127),
  244. ('\x80\x01', 128),
  245. ('\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01', 1 << 63),
  246. ]
  247. self.ReadVarintSuccessTestHelper(varints_and_ints,
  248. input_stream.InputStream.ReadVarUInt64)
  249. def testReadVarUInt64Failure(self):
  250. self.EnsureFailureOnEmptyStream(input_stream.InputStream.ReadVarUInt64)
  251. # Try and fail to read something with the mythical 64th bit set.
  252. s = '\x80\x80\x80\x80\x80\x80\x80\x80\x80\x02'
  253. stream = input_stream.InputStream(s)
  254. self.assertRaises(message.DecodeError, stream.ReadVarUInt64)
  255. # Try and fail to read something that looks like
  256. # a varint with more than 10 bytes.
  257. s = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00'
  258. stream = input_stream.InputStream(s)
  259. self.assertRaises(message.DecodeError, stream.ReadVarUInt64)
  260. if __name__ == '__main__':
  261. unittest.main()