Coverage for /home/runner/work/zserio/zserio/compiler/extensions/python/runtime/tests/test_bitreader.py: 100%

188 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2024-04-30 09:38 +0000

1import unittest 

2 

3from zserio.bitbuffer import BitBuffer 

4from zserio.bitreader import BitStreamReader 

5from zserio.bitsizeof import INT64_MIN 

6from zserio.exception import PythonRuntimeException 

7 

8 

9class BitStreamReaderTest(unittest.TestCase): 

10 

11 def test_constructor(self): 

12 reader = BitStreamReader(bytes([0xAE, 0xEA, 0x80]), 17) 

13 self.assertEqual(0xAE, reader.read_bits(8)) 

14 self.assertEqual(0xEA, reader.read_bits(8)) 

15 self.assertEqual(0x01, reader.read_bits(1)) 

16 with self.assertRaises(PythonRuntimeException): 

17 reader.read_bits(1) # no more bits available 

18 

19 def test_constructor_wrong_bitsize(self): 

20 with self.assertRaises(PythonRuntimeException): 

21 BitStreamReader(bytes([0xAE]), 9) 

22 

23 def test_from_bitbuffer(self): 

24 bitbuffer = BitBuffer(bytes([0xAE, 0xEA, 0x80]), 17) 

25 reader = BitStreamReader.from_bitbuffer(bitbuffer) 

26 self.assertEqual(bitbuffer.bitsize, reader.buffer_bitsize) 

27 self.assertEqual(0xAEE, reader.read_bits(12)) 

28 self.assertEqual(0x0A, reader.read_bits(4)) 

29 self.assertEqual(0x01, reader.read_bits(1)) 

30 with self.assertRaises(PythonRuntimeException): 

31 reader.read_bits(1) 

32 

33 def test_from_bitbuffer_overflow(self): 

34 bitbuffer = BitBuffer(bytes([0xFF, 0xFF, 0xF0]), 19) 

35 reader = BitStreamReader.from_bitbuffer(bitbuffer) 

36 self.assertEqual(bitbuffer.bitsize, reader.buffer_bitsize) 

37 with self.assertRaises(PythonRuntimeException): 

38 reader.read_bits(20) 

39 

40 def test_read_unaligned_data(self): 

41 # number expected to read at offset 

42 test_value = 123 

43 

44 for offset in range(65): 

45 buffer = bytearray((8 + offset + 7) // 8) 

46 

47 # write test value at offset to data buffer 

48 buffer[offset // 8] = test_value >> (offset % 8) 

49 if offset % 8 != 0: # don't write behind the buffer 

50 buffer[offset // 8 + 1] = 0xFF & test_value << (8 - offset % 8) 

51 

52 bitbuffer = BitBuffer(buffer, 8 + offset) 

53 reader = BitStreamReader.from_bitbuffer(bitbuffer) 

54 

55 # read offset bits 

56 self.assertEqual(0, reader.read_bits(offset)) 

57 

58 # read magic number 

59 self.assertEqual(test_value, reader.read_bits(8), msg="Offset: " + str(offset)) 

60 

61 # check eof 

62 with self.assertRaises(PythonRuntimeException): 

63 reader.read_bits(1) 

64 

65 def test_read_bits(self): 

66 data = [0, 1, 255, 128, 127] 

67 reader = BitStreamReader(bytes(data)) 

68 for byte in data: 

69 self.assertEqual(byte, reader.read_bits(8)) 

70 

71 with self.assertRaises(PythonRuntimeException): 

72 reader.read_bits(-1) 

73 

74 self.assertEqual(0, reader.read_bits(0)) # read 0 bits 

75 

76 with self.assertRaises(PythonRuntimeException): 

77 reader.read_bits(1) # no more bits available 

78 

79 def test_read_signed_bits(self): 

80 data = [0, 0xFF, 1, 127, 0x80] 

81 reader = BitStreamReader(bytes(data)) 

82 self.assertEqual(0, reader.read_signed_bits(8)) 

83 self.assertEqual(-1, reader.read_signed_bits(8)) # 0xff == -1 

84 self.assertEqual(1, reader.read_signed_bits(8)) 

85 self.assertEqual(127, reader.read_signed_bits(8)) 

86 self.assertEqual(-128, reader.read_signed_bits(8)) # 0x80 == -128 

87 

88 self.assertEqual(0, reader.read_signed_bits(0)) # read 0 bits 

89 

90 with self.assertRaises(PythonRuntimeException): 

91 reader.read_signed_bits(1) # no more bits available 

92 

93 with self.assertRaises(PythonRuntimeException): 

94 reader.read_signed_bits(-1) 

95 

96 def test_read_varint16(self): 

97 reader = BitStreamReader(bytes(1)) 

98 self.assertEqual(0, reader.read_varint16()) 

99 self.assertEqual(8, reader.bitposition) 

100 with self.assertRaises(PythonRuntimeException): 

101 reader.read_varint16() 

102 

103 def test_read_varint32(self): 

104 reader = BitStreamReader(bytes(1)) 

105 self.assertEqual(0, reader.read_varint32()) 

106 self.assertEqual(8, reader.bitposition) 

107 with self.assertRaises(PythonRuntimeException): 

108 reader.read_varint32() 

109 

110 def test_read_varint64(self): 

111 reader = BitStreamReader(bytes(1)) 

112 self.assertEqual(0, reader.read_varint64()) 

113 self.assertEqual(8, reader.bitposition) 

114 with self.assertRaises(PythonRuntimeException): 

115 reader.read_varint64() 

116 

117 def test_read_varint(self): 

118 reader = BitStreamReader(b"\x00\x80") 

119 self.assertEqual(0, reader.read_varint()) 

120 self.assertEqual(8, reader.bitposition) 

121 self.assertEqual(INT64_MIN, reader.read_varint()) 

122 self.assertEqual(16, reader.bitposition) 

123 with self.assertRaises(PythonRuntimeException): 

124 reader.read_varint() 

125 

126 def test_read_varuint16(self): 

127 reader = BitStreamReader(bytes(1)) 

128 self.assertEqual(0, reader.read_varuint16()) 

129 self.assertEqual(8, reader.bitposition) 

130 with self.assertRaises(PythonRuntimeException): 

131 reader.read_varuint16() 

132 

133 def test_read_varuint32(self): 

134 reader = BitStreamReader(bytes(1)) 

135 self.assertEqual(0, reader.read_varuint32()) 

136 self.assertEqual(8, reader.bitposition) 

137 with self.assertRaises(PythonRuntimeException): 

138 reader.read_varuint32() 

139 

140 def test_read_varuint64(self): 

141 reader = BitStreamReader(bytes(1)) 

142 self.assertEqual(0, reader.read_varuint64()) 

143 self.assertEqual(8, reader.bitposition) 

144 with self.assertRaises(PythonRuntimeException): 

145 reader.read_varuint64() 

146 

147 def test_read_varuint(self): 

148 reader = BitStreamReader(bytes(1)) 

149 self.assertEqual(0, reader.read_varuint()) 

150 self.assertEqual(8, reader.bitposition) 

151 with self.assertRaises(PythonRuntimeException): 

152 reader.read_varuint() 

153 

154 def test_read_varsize(self): 

155 # overflow, 2^32 - 1 is too much (b'\x83\xFF\xFF\xFF\xFF') is the maximum) 

156 reader = BitStreamReader(b"\x87\xFF\xFF\xFF\xFF") 

157 with self.assertRaises(PythonRuntimeException): 

158 reader.read_varsize() 

159 

160 # overflow, 2^36 - 1 is too much (b'\x83\xFF\xFF\xFF\xFF') is the maximum) 

161 reader = BitStreamReader(b"\xFF\xFF\xFF\xFF\xFF") 

162 with self.assertRaises(PythonRuntimeException): 

163 reader.read_varsize() 

164 

165 def test_read_float16(self): 

166 reader = BitStreamReader(bytes(2)) 

167 self.assertEqual(0.0, reader.read_float16()) 

168 self.assertEqual(16, reader.bitposition) 

169 with self.assertRaises(PythonRuntimeException): 

170 reader.read_float16() 

171 

172 def test_read_float32(self): 

173 reader = BitStreamReader(bytes(4)) 

174 self.assertEqual(0.0, reader.read_float32()) 

175 self.assertEqual(32, reader.bitposition) 

176 with self.assertRaises(PythonRuntimeException): 

177 reader.read_float32() 

178 

179 def test_read_float64(self): 

180 reader = BitStreamReader(bytes(8)) 

181 self.assertEqual(0.0, reader.read_float64()) 

182 self.assertEqual(64, reader.bitposition) 

183 with self.assertRaises(PythonRuntimeException): 

184 reader.read_float64() 

185 

186 def test_read_string(self): 

187 reader = BitStreamReader(bytes(b"\x01\x41")) 

188 self.assertEqual("A", reader.read_string()) 

189 self.assertEqual(16, reader.bitposition) 

190 with self.assertRaises(PythonRuntimeException): 

191 reader.read_string() 

192 

193 def test_read_bool(self): 

194 reader = BitStreamReader(bytes(b"\xA8")) 

195 self.assertEqual(True, reader.read_bool()) 

196 self.assertEqual(False, reader.read_bool()) 

197 self.assertEqual(True, reader.read_bool()) 

198 self.assertEqual(False, reader.read_bool()) 

199 self.assertEqual(True, reader.read_bool()) 

200 self.assertEqual(False, reader.read_bool()) 

201 self.assertEqual(False, reader.read_bool()) 

202 self.assertEqual(False, reader.read_bool()) 

203 with self.assertRaises(PythonRuntimeException): 

204 reader.read_bool() 

205 

206 def test_read_bitbuffer(self): 

207 reader = BitStreamReader(bytes(b"\x0B\xAB\xE1\xE0\x1F\xC0")) 

208 self.assertEqual(BitBuffer(bytes([0xAB, 0xE0]), 11), reader.read_bitbuffer()) 

209 self.assertEqual(BitBuffer(bytes([0x00, 0xFE]), 15), reader.read_bitbuffer()) 

210 with self.assertRaises(PythonRuntimeException): 

211 reader.read_bitbuffer() 

212 

213 def test_bitposition(self): 

214 reader = BitStreamReader(bytes(1), 7) 

215 reader.bitposition = 0 

216 self.assertEqual(0, reader.bitposition) 

217 reader.bitposition = 7 

218 self.assertEqual(7, reader.bitposition) 

219 

220 with self.assertRaises(PythonRuntimeException): 

221 reader.bitposition = 8 

222 with self.assertRaises(PythonRuntimeException): 

223 reader.bitposition = -1 

224 

225 reader.bitposition = 0 

226 self.assertEqual(0, reader.bitposition) 

227 

228 def test_alignto(self): 

229 reader = BitStreamReader(bytes(1)) 

230 reader.alignto(1) 

231 self.assertEqual(0, reader.bitposition) 

232 reader.read_bits(1) 

233 self.assertEqual(1, reader.bitposition) 

234 reader.alignto(1) 

235 self.assertEqual(1, reader.bitposition) 

236 reader.alignto(4) 

237 self.assertEqual(4, reader.bitposition)