blob: 5615c2d23967cf2e88b4e9c1a77e31b9a544f780 [file] [log] [blame]
Guido van Rossum7d9ea502003-02-03 20:45:52 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00003import binascii
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00004import random
Victor Stinner8848c7a2011-01-04 02:07:36 +00005from test.support import precisionbigmemtest, _1G, _4G
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00006
R. David Murraya21e4ca2009-03-31 23:16:50 +00007zlib = support.import_module('zlib')
8
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00009
Guido van Rossum7d9ea502003-02-03 20:45:52 +000010class ChecksumTestCase(unittest.TestCase):
11 # checksum test cases
12 def test_crc32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000013 self.assertEqual(zlib.crc32(b""), zlib.crc32(b"", 0))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000014 self.assertTrue(zlib.crc32(b"abc", 0xffffffff))
Andrew M. Kuchlingfcfc8d52001-08-10 15:50:11 +000015
Guido van Rossum7d9ea502003-02-03 20:45:52 +000016 def test_crc32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000017 self.assertEqual(zlib.crc32(b"", 0), 0)
18 self.assertEqual(zlib.crc32(b"", 1), 1)
19 self.assertEqual(zlib.crc32(b"", 432), 432)
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000020
Guido van Rossum7d9ea502003-02-03 20:45:52 +000021 def test_adler32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000022 self.assertEqual(zlib.adler32(b""), zlib.adler32(b"", 1))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000023 self.assertTrue(zlib.adler32(b"abc", 0xffffffff))
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000024
Guido van Rossum7d9ea502003-02-03 20:45:52 +000025 def test_adler32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000026 self.assertEqual(zlib.adler32(b"", 0), 0)
27 self.assertEqual(zlib.adler32(b"", 1), 1)
28 self.assertEqual(zlib.adler32(b"", 432), 432)
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000029
Guido van Rossum7d9ea502003-02-03 20:45:52 +000030 def assertEqual32(self, seen, expected):
31 # 32-bit values masked -- checksums on 32- vs 64- bit machines
32 # This is important if bit 31 (0x08000000L) is set.
Guido van Rossume2a383d2007-01-15 16:59:06 +000033 self.assertEqual(seen & 0x0FFFFFFFF, expected & 0x0FFFFFFFF)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000034
35 def test_penguins(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000036 self.assertEqual32(zlib.crc32(b"penguin", 0), 0x0e5c1a120)
37 self.assertEqual32(zlib.crc32(b"penguin", 1), 0x43b6aa94)
38 self.assertEqual32(zlib.adler32(b"penguin", 0), 0x0bcf02f6)
39 self.assertEqual32(zlib.adler32(b"penguin", 1), 0x0bd602f7)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000040
Guido van Rossum776152b2007-05-22 22:44:07 +000041 self.assertEqual(zlib.crc32(b"penguin"), zlib.crc32(b"penguin", 0))
42 self.assertEqual(zlib.adler32(b"penguin"),zlib.adler32(b"penguin",1))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000043
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000044 def test_crc32_adler32_unsigned(self):
Antoine Pitrou77b338b2009-12-14 18:00:06 +000045 foo = b'abcdefghijklmnop'
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000046 # explicitly test signed behavior
Gregory P. Smith27275032008-03-20 06:20:09 +000047 self.assertEqual(zlib.crc32(foo), 2486878355)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000048 self.assertEqual(zlib.crc32(b'spam'), 1138425661)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000049 self.assertEqual(zlib.adler32(foo+foo), 3573550353)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000050 self.assertEqual(zlib.adler32(b'spam'), 72286642)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000051
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000052 def test_same_as_binascii_crc32(self):
Martin v. Löwis15b16a32008-12-02 06:00:15 +000053 foo = b'abcdefghijklmnop'
Gregory P. Smith27275032008-03-20 06:20:09 +000054 crc = 2486878355
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000055 self.assertEqual(binascii.crc32(foo), crc)
56 self.assertEqual(zlib.crc32(foo), crc)
Martin v. Löwis15b16a32008-12-02 06:00:15 +000057 self.assertEqual(binascii.crc32(b'spam'), zlib.crc32(b'spam'))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000058
59
Christian Heimesb186d002008-03-18 15:15:01 +000060
Guido van Rossum7d9ea502003-02-03 20:45:52 +000061class ExceptionTestCase(unittest.TestCase):
62 # make sure we generate some expected errors
Guido van Rossum8ce8a782007-11-01 19:42:39 +000063 def test_badlevel(self):
64 # specifying compression level out of range causes an error
65 # (but -1 is Z_DEFAULT_COMPRESSION and apparently the zlib
66 # accepts 0 too)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000067 self.assertRaises(zlib.error, zlib.compress, b'ERROR', 10)
68
69 def test_badargs(self):
70 self.assertRaises(TypeError, zlib.adler32)
71 self.assertRaises(TypeError, zlib.crc32)
72 self.assertRaises(TypeError, zlib.compress)
73 self.assertRaises(TypeError, zlib.decompress)
74 for arg in (42, None, '', 'abc', (), []):
75 self.assertRaises(TypeError, zlib.adler32, arg)
76 self.assertRaises(TypeError, zlib.crc32, arg)
77 self.assertRaises(TypeError, zlib.compress, arg)
78 self.assertRaises(TypeError, zlib.decompress, arg)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000079
80 def test_badcompressobj(self):
81 # verify failure on building compress object with bad params
Neil Schemenauer94afd3e2004-06-05 19:02:52 +000082 self.assertRaises(ValueError, zlib.compressobj, 1, zlib.DEFLATED, 0)
Guido van Rossum8ce8a782007-11-01 19:42:39 +000083 # specifying total bits too large causes an error
84 self.assertRaises(ValueError,
85 zlib.compressobj, 1, zlib.DEFLATED, zlib.MAX_WBITS + 1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000086
87 def test_baddecompressobj(self):
88 # verify failure on building decompress object with bad params
Antoine Pitrou90ee4df2010-04-06 17:23:13 +000089 self.assertRaises(ValueError, zlib.decompressobj, -1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000090
Christian Heimes5e696852008-04-09 08:37:03 +000091 def test_decompressobj_badflush(self):
92 # verify failure on calling decompressobj.flush with bad params
93 self.assertRaises(ValueError, zlib.decompressobj().flush, 0)
94 self.assertRaises(ValueError, zlib.decompressobj().flush, -1)
95
Guido van Rossum7d9ea502003-02-03 20:45:52 +000096
Antoine Pitrou89562712010-05-07 17:04:02 +000097class BaseCompressTestCase(object):
98 def check_big_compress_buffer(self, size, compress_func):
99 _1M = 1024 * 1024
100 fmt = "%%0%dx" % (2 * _1M)
101 # Generate 10MB worth of random, and expand it by repeating it.
102 # The assumption is that zlib's memory is not big enough to exploit
103 # such spread out redundancy.
104 data = b''.join([random.getrandbits(8 * _1M).to_bytes(_1M, 'little')
105 for i in range(10)])
106 data = data * (size // len(data) + 1)
107 try:
108 compress_func(data)
109 finally:
110 # Release memory
111 data = None
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000112
Antoine Pitrou89562712010-05-07 17:04:02 +0000113 def check_big_decompress_buffer(self, size, decompress_func):
114 data = b'x' * size
115 try:
116 compressed = zlib.compress(data, 1)
117 finally:
118 # Release memory
119 data = None
120 data = decompress_func(compressed)
121 # Sanity check
122 try:
123 self.assertEqual(len(data), size)
124 self.assertEqual(len(data.strip(b'x')), 0)
125 finally:
126 data = None
127
128
129class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000130 # Test compression in one go (whole message compression)
131 def test_speech(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000132 x = zlib.compress(HAMLET_SCENE)
133 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000134
135 def test_speech128(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000136 # compress more data
137 data = HAMLET_SCENE * 128
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000138 x = zlib.compress(data)
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000139 self.assertEqual(zlib.compress(bytearray(data)), x)
140 for ob in x, bytearray(x):
141 self.assertEqual(zlib.decompress(ob), data)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000142
Antoine Pitrou53b21662010-05-11 23:46:02 +0000143 def test_incomplete_stream(self):
144 # An useful error message is given
145 x = zlib.compress(HAMLET_SCENE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000146 self.assertRaisesRegex(zlib.error,
Antoine Pitrou53b21662010-05-11 23:46:02 +0000147 "Error -5 while decompressing data: incomplete or truncated stream",
148 zlib.decompress, x[:-1])
149
Antoine Pitrou89562712010-05-07 17:04:02 +0000150 # Memory use of the following functions takes into account overallocation
151
152 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=3)
153 def test_big_compress_buffer(self, size):
154 compress = lambda s: zlib.compress(s, 1)
155 self.check_big_compress_buffer(size, compress)
156
157 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=2)
158 def test_big_decompress_buffer(self, size):
159 self.check_big_decompress_buffer(size, zlib.decompress)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000160
Victor Stinner8848c7a2011-01-04 02:07:36 +0000161 @precisionbigmemtest(size=_4G + 100, memuse=1)
162 def test_length_overflow(self, size):
163 if size < _4G + 100:
164 self.skipTest("not enough free memory, need at least 4 GB")
165 data = b'x' * size
166 try:
167 self.assertRaises(OverflowError, zlib.compress, data, 1)
168 finally:
169 data = None
170
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000171
Antoine Pitrou89562712010-05-07 17:04:02 +0000172class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000173 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000174 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000175 # straightforward compress/decompress objects
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000176 datasrc = HAMLET_SCENE * 128
177 datazip = zlib.compress(datasrc)
178 # should compress both bytes and bytearray data
179 for data in (datasrc, bytearray(datasrc)):
180 co = zlib.compressobj()
181 x1 = co.compress(data)
182 x2 = co.flush()
183 self.assertRaises(zlib.error, co.flush) # second flush should not work
184 self.assertEqual(x1 + x2, datazip)
185 for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))):
186 dco = zlib.decompressobj()
187 y1 = dco.decompress(v1 + v2)
188 y2 = dco.flush()
189 self.assertEqual(data, y1 + y2)
190 self.assertIsInstance(dco.unconsumed_tail, bytes)
191 self.assertIsInstance(dco.unused_data, bytes)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000192
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000193 def test_compressoptions(self):
194 # specify lots of options to compressobj()
195 level = 2
196 method = zlib.DEFLATED
197 wbits = -12
198 memlevel = 9
199 strategy = zlib.Z_FILTERED
200 co = zlib.compressobj(level, method, wbits, memlevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000201 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000202 x2 = co.flush()
203 dco = zlib.decompressobj(wbits)
204 y1 = dco.decompress(x1 + x2)
205 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000206 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000207
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000208 def test_compressincremental(self):
209 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000210 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000211 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000212 bufs = []
213 for i in range(0, len(data), 256):
214 bufs.append(co.compress(data[i:i+256]))
215 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000216 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000217
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000218 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000219 y1 = dco.decompress(b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000220 y2 = dco.flush()
221 self.assertEqual(data, y1 + y2)
222
Neil Schemenauer6412b122004-06-05 19:34:28 +0000223 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000224 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000225 source = source or HAMLET_SCENE
226 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000227 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000228 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000229 for i in range(0, len(data), cx):
230 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000231 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000232 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000233
Gregory P. Smith693fc462008-09-06 20:13:06 +0000234 decombuf = zlib.decompress(combuf)
235 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000236 self.assertIsInstance(decombuf, bytes)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000237
238 self.assertEqual(data, decombuf)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000239
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000240 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000241 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000242 for i in range(0, len(combuf), dcx):
243 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000244 self.assertEqual(b'', dco.unconsumed_tail, ########
245 "(A) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000246 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000247 self.assertEqual(b'', dco.unused_data)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000248 if flush:
249 bufs.append(dco.flush())
250 else:
251 while True:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000252 chunk = dco.decompress(b'')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000253 if chunk:
254 bufs.append(chunk)
255 else:
256 break
Guido van Rossum776152b2007-05-22 22:44:07 +0000257 self.assertEqual(b'', dco.unconsumed_tail, ########
258 "(B) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000259 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000260 self.assertEqual(b'', dco.unused_data)
Guido van Rossum776152b2007-05-22 22:44:07 +0000261 self.assertEqual(data, b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000262 # Failure means: "decompressobj with init options failed"
263
Neil Schemenauer6412b122004-06-05 19:34:28 +0000264 def test_decompincflush(self):
265 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000266
Neil Schemenauer6412b122004-06-05 19:34:28 +0000267 def test_decompimax(self, source=None, cx=256, dcx=64):
268 # compress in steps, decompress in length-restricted steps
269 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000270 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000271 data = source * 128
272 co = zlib.compressobj()
273 bufs = []
274 for i in range(0, len(data), cx):
275 bufs.append(co.compress(data[i:i+cx]))
276 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000277 combuf = b''.join(bufs)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000278 self.assertEqual(data, zlib.decompress(combuf),
279 'compressed data failure')
280
281 dco = zlib.decompressobj()
282 bufs = []
283 cb = combuf
284 while cb:
285 #max_length = 1 + len(cb)//10
286 chunk = dco.decompress(cb, dcx)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000287 self.assertFalse(len(chunk) > dcx,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000288 'chunk too big (%d>%d)' % (len(chunk), dcx))
289 bufs.append(chunk)
290 cb = dco.unconsumed_tail
291 bufs.append(dco.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000292 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000293
294 def test_decompressmaxlen(self, flush=False):
295 # Check a decompression object with max_length specified
296 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000297 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000298 bufs = []
299 for i in range(0, len(data), 256):
300 bufs.append(co.compress(data[i:i+256]))
301 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000302 combuf = b''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000303 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000304 'compressed data failure')
305
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000306 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000307 bufs = []
308 cb = combuf
309 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000310 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000311 chunk = dco.decompress(cb, max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000312 self.assertFalse(len(chunk) > max_length,
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000313 'chunk too big (%d>%d)' % (len(chunk),max_length))
314 bufs.append(chunk)
315 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000316 if flush:
317 bufs.append(dco.flush())
318 else:
319 while chunk:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000320 chunk = dco.decompress(b'', max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000321 self.assertFalse(len(chunk) > max_length,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000322 'chunk too big (%d>%d)' % (len(chunk),max_length))
323 bufs.append(chunk)
Guido van Rossum776152b2007-05-22 22:44:07 +0000324 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000325
Neil Schemenauer6412b122004-06-05 19:34:28 +0000326 def test_decompressmaxlenflush(self):
327 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000328
329 def test_maxlenmisc(self):
330 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000331 dco = zlib.decompressobj()
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000332 self.assertRaises(ValueError, dco.decompress, b"", -1)
Guido van Rossum776152b2007-05-22 22:44:07 +0000333 self.assertEqual(b'', dco.unconsumed_tail)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000334
335 def test_flushes(self):
336 # Test flush() with the various options, using all the
337 # different levels in order to provide more variations.
338 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH']
339 sync_opt = [getattr(zlib, opt) for opt in sync_opt
340 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000341 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000342
343 for sync in sync_opt:
344 for level in range(10):
345 obj = zlib.compressobj( level )
346 a = obj.compress( data[:3000] )
347 b = obj.flush( sync )
348 c = obj.compress( data[3000:] )
349 d = obj.flush()
Guido van Rossum776152b2007-05-22 22:44:07 +0000350 self.assertEqual(zlib.decompress(b''.join([a,b,c,d])),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000351 data, ("Decompress failed: flush "
352 "mode=%i, level=%i") % (sync, level))
353 del obj
354
355 def test_odd_flush(self):
356 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
357 import random
358
359 if hasattr(zlib, 'Z_SYNC_FLUSH'):
360 # Testing on 17K of "random" data
361
362 # Create compressor and decompressor objects
Neil Schemenauer6412b122004-06-05 19:34:28 +0000363 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000364 dco = zlib.decompressobj()
365
366 # Try 17K of data
367 # generate random data stream
368 try:
369 # In 2.3 and later, WichmannHill is the RNG of the bug report
370 gen = random.WichmannHill()
371 except AttributeError:
372 try:
373 # 2.2 called it Random
374 gen = random.Random()
375 except AttributeError:
376 # others might simply have a single RNG
377 gen = random
378 gen.seed(1)
379 data = genblock(1, 17 * 1024, generator=gen)
380
381 # compress, sync-flush, and decompress
382 first = co.compress(data)
383 second = co.flush(zlib.Z_SYNC_FLUSH)
384 expanded = dco.decompress(first + second)
385
386 # if decompressed data is different from the input data, choke.
387 self.assertEqual(expanded, data, "17K random source doesn't match")
388
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000389 def test_empty_flush(self):
390 # Test that calling .flush() on unused objects works.
391 # (Bug #1083110 -- calling .flush() on decompress objects
392 # caused a core dump.)
393
394 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000395 self.assertTrue(co.flush()) # Returns a zlib header
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000396 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000397 self.assertEqual(dco.flush(), b"") # Returns nothing
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000398
Antoine Pitrouc09c92f2010-05-11 23:36:40 +0000399 def test_decompress_incomplete_stream(self):
400 # This is 'foo', deflated
401 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
402 # For the record
403 self.assertEqual(zlib.decompress(x), b'foo')
404 self.assertRaises(zlib.error, zlib.decompress, x[:-5])
405 # Omitting the stream end works with decompressor objects
406 # (see issue #8672).
407 dco = zlib.decompressobj()
408 y = dco.decompress(x[:-5])
409 y += dco.flush()
410 self.assertEqual(y, b'foo')
411
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000412 if hasattr(zlib.compressobj(), "copy"):
413 def test_compresscopy(self):
414 # Test copying a compression object
415 data0 = HAMLET_SCENE
Guido van Rossum776152b2007-05-22 22:44:07 +0000416 data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000417 c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
418 bufs0 = []
419 bufs0.append(c0.compress(data0))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000420
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000421 c1 = c0.copy()
422 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000423
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000424 bufs0.append(c0.compress(data0))
425 bufs0.append(c0.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000426 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000427
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000428 bufs1.append(c1.compress(data1))
429 bufs1.append(c1.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000430 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000431
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000432 self.assertEqual(zlib.decompress(s0),data0+data0)
433 self.assertEqual(zlib.decompress(s1),data0+data1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000434
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000435 def test_badcompresscopy(self):
436 # Test copying a compression object in an inconsistent state
437 c = zlib.compressobj()
438 c.compress(HAMLET_SCENE)
439 c.flush()
440 self.assertRaises(ValueError, c.copy)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000441
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000442 if hasattr(zlib.decompressobj(), "copy"):
443 def test_decompresscopy(self):
444 # Test copying a decompression object
445 data = HAMLET_SCENE
446 comp = zlib.compress(data)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000447 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000448 self.assertIsInstance(comp, bytes)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000449
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000450 d0 = zlib.decompressobj()
451 bufs0 = []
452 bufs0.append(d0.decompress(comp[:32]))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000453
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000454 d1 = d0.copy()
455 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000456
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000457 bufs0.append(d0.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000458 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000459
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000460 bufs1.append(d1.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000461 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000462
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000463 self.assertEqual(s0,s1)
464 self.assertEqual(s0,data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000465
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000466 def test_baddecompresscopy(self):
467 # Test copying a compression object in an inconsistent state
468 data = zlib.compress(HAMLET_SCENE)
469 d = zlib.decompressobj()
470 d.decompress(data)
471 d.flush()
472 self.assertRaises(ValueError, d.copy)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000473
Antoine Pitrou89562712010-05-07 17:04:02 +0000474 # Memory use of the following functions takes into account overallocation
475
476 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=3)
477 def test_big_compress_buffer(self, size):
478 c = zlib.compressobj(1)
479 compress = lambda s: c.compress(s) + c.flush()
480 self.check_big_compress_buffer(size, compress)
481
482 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=2)
483 def test_big_decompress_buffer(self, size):
484 d = zlib.decompressobj()
485 decompress = lambda s: d.decompress(s) + d.flush()
486 self.check_big_decompress_buffer(size, decompress)
487
488
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000489def genblock(seed, length, step=1024, generator=random):
490 """length-byte stream of random data from a seed (in step-byte blocks)."""
491 if seed is not None:
492 generator.seed(seed)
493 randint = generator.randint
494 if length < step or step < 2:
495 step = length
Guido van Rossum776152b2007-05-22 22:44:07 +0000496 blocks = bytes()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000497 for i in range(0, length, step):
Guido van Rossum776152b2007-05-22 22:44:07 +0000498 blocks += bytes(randint(0, 255) for x in range(step))
499 return blocks
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000500
501
502
503def choose_lines(source, number, seed=None, generator=random):
504 """Return a list of number lines randomly chosen from the source"""
505 if seed is not None:
506 generator.seed(seed)
507 sources = source.split('\n')
508 return [generator.choice(sources) for n in range(number)]
509
510
511
Guido van Rossum776152b2007-05-22 22:44:07 +0000512HAMLET_SCENE = b"""
Fred Drake004d5e62000-10-23 17:22:08 +0000513LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000514
515 O, fear me not.
516 I stay too long: but here my father comes.
517
518 Enter POLONIUS
519
520 A double blessing is a double grace,
521 Occasion smiles upon a second leave.
522
Fred Drake004d5e62000-10-23 17:22:08 +0000523LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000524
525 Yet here, Laertes! aboard, aboard, for shame!
526 The wind sits in the shoulder of your sail,
527 And you are stay'd for. There; my blessing with thee!
528 And these few precepts in thy memory
529 See thou character. Give thy thoughts no tongue,
530 Nor any unproportioned thought his act.
531 Be thou familiar, but by no means vulgar.
532 Those friends thou hast, and their adoption tried,
533 Grapple them to thy soul with hoops of steel;
534 But do not dull thy palm with entertainment
535 Of each new-hatch'd, unfledged comrade. Beware
536 Of entrance to a quarrel, but being in,
537 Bear't that the opposed may beware of thee.
538 Give every man thy ear, but few thy voice;
539 Take each man's censure, but reserve thy judgment.
540 Costly thy habit as thy purse can buy,
541 But not express'd in fancy; rich, not gaudy;
542 For the apparel oft proclaims the man,
543 And they in France of the best rank and station
544 Are of a most select and generous chief in that.
545 Neither a borrower nor a lender be;
546 For loan oft loses both itself and friend,
547 And borrowing dulls the edge of husbandry.
548 This above all: to thine ownself be true,
549 And it must follow, as the night the day,
550 Thou canst not then be false to any man.
551 Farewell: my blessing season this in thee!
552
Fred Drake004d5e62000-10-23 17:22:08 +0000553LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000554
555 Most humbly do I take my leave, my lord.
556
Fred Drake004d5e62000-10-23 17:22:08 +0000557LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000558
559 The time invites you; go; your servants tend.
560
Fred Drake004d5e62000-10-23 17:22:08 +0000561LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000562
563 Farewell, Ophelia; and remember well
564 What I have said to you.
565
Fred Drake004d5e62000-10-23 17:22:08 +0000566OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000567
568 'Tis in my memory lock'd,
569 And you yourself shall keep the key of it.
570
Fred Drake004d5e62000-10-23 17:22:08 +0000571LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000572
573 Farewell.
574"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000575
576
577def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000578 support.run_unittest(
Walter Dörwald21d3a322003-05-01 17:45:56 +0000579 ChecksumTestCase,
580 ExceptionTestCase,
581 CompressTestCase,
582 CompressObjectTestCase
583 )
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000584
585if __name__ == "__main__":
Guido van Rossum776152b2007-05-22 22:44:07 +0000586 unittest.main() # XXX
587 ###test_main()