blob: 68dc2b1afc15b3dc0f529f911e7839b5356f48d9 [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
Antoine Pitrouf3d22752011-02-21 18:09:00 +00005import sys
Antoine Pitrou94190bb2011-10-04 10:22:36 +02006from test.support import bigmemtest, _1G, _4G
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00007
R. David Murraya21e4ca2009-03-31 23:16:50 +00008zlib = support.import_module('zlib')
9
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000010
Nadeem Vawda64d25dd2011-09-12 00:04:13 +020011class VersionTestCase(unittest.TestCase):
12
13 def test_library_version(self):
Nadeem Vawda131c7072012-01-25 23:16:50 +020014 # Test that the major version of the actual library in use matches the
15 # major version that we were compiled against. We can't guarantee that
16 # the minor versions will match (even on the machine on which the module
17 # was compiled), and the API is stable between minor versions, so
Nadeem Vawdad770fe42012-01-28 17:32:47 +020018 # testing only the major versions avoids spurious failures.
Nadeem Vawda131c7072012-01-25 23:16:50 +020019 self.assertEqual(zlib.ZLIB_RUNTIME_VERSION[0], zlib.ZLIB_VERSION[0])
Nadeem Vawda64d25dd2011-09-12 00:04:13 +020020
21
Guido van Rossum7d9ea502003-02-03 20:45:52 +000022class ChecksumTestCase(unittest.TestCase):
23 # checksum test cases
24 def test_crc32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000025 self.assertEqual(zlib.crc32(b""), zlib.crc32(b"", 0))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000026 self.assertTrue(zlib.crc32(b"abc", 0xffffffff))
Andrew M. Kuchlingfcfc8d52001-08-10 15:50:11 +000027
Guido van Rossum7d9ea502003-02-03 20:45:52 +000028 def test_crc32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000029 self.assertEqual(zlib.crc32(b"", 0), 0)
30 self.assertEqual(zlib.crc32(b"", 1), 1)
31 self.assertEqual(zlib.crc32(b"", 432), 432)
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000032
Guido van Rossum7d9ea502003-02-03 20:45:52 +000033 def test_adler32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000034 self.assertEqual(zlib.adler32(b""), zlib.adler32(b"", 1))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000035 self.assertTrue(zlib.adler32(b"abc", 0xffffffff))
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000036
Guido van Rossum7d9ea502003-02-03 20:45:52 +000037 def test_adler32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000038 self.assertEqual(zlib.adler32(b"", 0), 0)
39 self.assertEqual(zlib.adler32(b"", 1), 1)
40 self.assertEqual(zlib.adler32(b"", 432), 432)
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000041
Guido van Rossum7d9ea502003-02-03 20:45:52 +000042 def assertEqual32(self, seen, expected):
43 # 32-bit values masked -- checksums on 32- vs 64- bit machines
44 # This is important if bit 31 (0x08000000L) is set.
Guido van Rossume2a383d2007-01-15 16:59:06 +000045 self.assertEqual(seen & 0x0FFFFFFFF, expected & 0x0FFFFFFFF)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000046
47 def test_penguins(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000048 self.assertEqual32(zlib.crc32(b"penguin", 0), 0x0e5c1a120)
49 self.assertEqual32(zlib.crc32(b"penguin", 1), 0x43b6aa94)
50 self.assertEqual32(zlib.adler32(b"penguin", 0), 0x0bcf02f6)
51 self.assertEqual32(zlib.adler32(b"penguin", 1), 0x0bd602f7)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000052
Guido van Rossum776152b2007-05-22 22:44:07 +000053 self.assertEqual(zlib.crc32(b"penguin"), zlib.crc32(b"penguin", 0))
54 self.assertEqual(zlib.adler32(b"penguin"),zlib.adler32(b"penguin",1))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000055
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000056 def test_crc32_adler32_unsigned(self):
Antoine Pitrou77b338b2009-12-14 18:00:06 +000057 foo = b'abcdefghijklmnop'
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000058 # explicitly test signed behavior
Gregory P. Smith27275032008-03-20 06:20:09 +000059 self.assertEqual(zlib.crc32(foo), 2486878355)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000060 self.assertEqual(zlib.crc32(b'spam'), 1138425661)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000061 self.assertEqual(zlib.adler32(foo+foo), 3573550353)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000062 self.assertEqual(zlib.adler32(b'spam'), 72286642)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000063
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000064 def test_same_as_binascii_crc32(self):
Martin v. Löwis15b16a32008-12-02 06:00:15 +000065 foo = b'abcdefghijklmnop'
Gregory P. Smith27275032008-03-20 06:20:09 +000066 crc = 2486878355
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000067 self.assertEqual(binascii.crc32(foo), crc)
68 self.assertEqual(zlib.crc32(foo), crc)
Martin v. Löwis15b16a32008-12-02 06:00:15 +000069 self.assertEqual(binascii.crc32(b'spam'), zlib.crc32(b'spam'))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000070
71
Antoine Pitrouf3d22752011-02-21 18:09:00 +000072# Issue #10276 - check that inputs >=4GB are handled correctly.
73class ChecksumBigBufferTestCase(unittest.TestCase):
74
Nadeem Vawdabc8c8172012-02-23 14:16:15 +020075 @bigmemtest(size=_4G + 4, memuse=1, dry_run=False)
76 def test_big_buffer(self, size):
Nadeem Vawdab063a482012-02-23 13:36:25 +020077 data = b"nyan" * (_1G + 1)
78 self.assertEqual(zlib.crc32(data), 1044521549)
79 self.assertEqual(zlib.adler32(data), 2256789997)
Antoine Pitrouf3d22752011-02-21 18:09:00 +000080
Christian Heimesb186d002008-03-18 15:15:01 +000081
Guido van Rossum7d9ea502003-02-03 20:45:52 +000082class ExceptionTestCase(unittest.TestCase):
83 # make sure we generate some expected errors
Guido van Rossum8ce8a782007-11-01 19:42:39 +000084 def test_badlevel(self):
85 # specifying compression level out of range causes an error
86 # (but -1 is Z_DEFAULT_COMPRESSION and apparently the zlib
87 # accepts 0 too)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000088 self.assertRaises(zlib.error, zlib.compress, b'ERROR', 10)
89
90 def test_badargs(self):
91 self.assertRaises(TypeError, zlib.adler32)
92 self.assertRaises(TypeError, zlib.crc32)
93 self.assertRaises(TypeError, zlib.compress)
94 self.assertRaises(TypeError, zlib.decompress)
95 for arg in (42, None, '', 'abc', (), []):
96 self.assertRaises(TypeError, zlib.adler32, arg)
97 self.assertRaises(TypeError, zlib.crc32, arg)
98 self.assertRaises(TypeError, zlib.compress, arg)
99 self.assertRaises(TypeError, zlib.decompress, arg)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000100
101 def test_badcompressobj(self):
102 # verify failure on building compress object with bad params
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000103 self.assertRaises(ValueError, zlib.compressobj, 1, zlib.DEFLATED, 0)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000104 # specifying total bits too large causes an error
105 self.assertRaises(ValueError,
106 zlib.compressobj, 1, zlib.DEFLATED, zlib.MAX_WBITS + 1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000107
108 def test_baddecompressobj(self):
109 # verify failure on building decompress object with bad params
Antoine Pitrou90ee4df2010-04-06 17:23:13 +0000110 self.assertRaises(ValueError, zlib.decompressobj, -1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000111
Christian Heimes5e696852008-04-09 08:37:03 +0000112 def test_decompressobj_badflush(self):
113 # verify failure on calling decompressobj.flush with bad params
114 self.assertRaises(ValueError, zlib.decompressobj().flush, 0)
115 self.assertRaises(ValueError, zlib.decompressobj().flush, -1)
116
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000117
Antoine Pitrou89562712010-05-07 17:04:02 +0000118class BaseCompressTestCase(object):
119 def check_big_compress_buffer(self, size, compress_func):
120 _1M = 1024 * 1024
121 fmt = "%%0%dx" % (2 * _1M)
122 # Generate 10MB worth of random, and expand it by repeating it.
123 # The assumption is that zlib's memory is not big enough to exploit
124 # such spread out redundancy.
125 data = b''.join([random.getrandbits(8 * _1M).to_bytes(_1M, 'little')
126 for i in range(10)])
127 data = data * (size // len(data) + 1)
128 try:
129 compress_func(data)
130 finally:
131 # Release memory
132 data = None
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000133
Antoine Pitrou89562712010-05-07 17:04:02 +0000134 def check_big_decompress_buffer(self, size, decompress_func):
135 data = b'x' * size
136 try:
137 compressed = zlib.compress(data, 1)
138 finally:
139 # Release memory
140 data = None
141 data = decompress_func(compressed)
142 # Sanity check
143 try:
144 self.assertEqual(len(data), size)
145 self.assertEqual(len(data.strip(b'x')), 0)
146 finally:
147 data = None
148
149
150class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000151 # Test compression in one go (whole message compression)
152 def test_speech(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000153 x = zlib.compress(HAMLET_SCENE)
154 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000155
156 def test_speech128(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000157 # compress more data
158 data = HAMLET_SCENE * 128
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000159 x = zlib.compress(data)
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000160 self.assertEqual(zlib.compress(bytearray(data)), x)
161 for ob in x, bytearray(x):
162 self.assertEqual(zlib.decompress(ob), data)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000163
Antoine Pitrou53b21662010-05-11 23:46:02 +0000164 def test_incomplete_stream(self):
165 # An useful error message is given
166 x = zlib.compress(HAMLET_SCENE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000167 self.assertRaisesRegex(zlib.error,
Antoine Pitrou53b21662010-05-11 23:46:02 +0000168 "Error -5 while decompressing data: incomplete or truncated stream",
169 zlib.decompress, x[:-1])
170
Antoine Pitrou89562712010-05-07 17:04:02 +0000171 # Memory use of the following functions takes into account overallocation
172
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200173 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000174 def test_big_compress_buffer(self, size):
175 compress = lambda s: zlib.compress(s, 1)
176 self.check_big_compress_buffer(size, compress)
177
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200178 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000179 def test_big_decompress_buffer(self, size):
180 self.check_big_decompress_buffer(size, zlib.decompress)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000181
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200182 @bigmemtest(size=_4G + 100, memuse=1)
Victor Stinner8848c7a2011-01-04 02:07:36 +0000183 def test_length_overflow(self, size):
184 if size < _4G + 100:
185 self.skipTest("not enough free memory, need at least 4 GB")
186 data = b'x' * size
187 try:
188 self.assertRaises(OverflowError, zlib.compress, data, 1)
Nadeem Vawda154bdf92011-05-14 23:07:36 +0200189 self.assertRaises(OverflowError, zlib.decompress, data)
Victor Stinner8848c7a2011-01-04 02:07:36 +0000190 finally:
191 data = None
192
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000193
Antoine Pitrou89562712010-05-07 17:04:02 +0000194class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000195 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000196 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000197 # straightforward compress/decompress objects
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000198 datasrc = HAMLET_SCENE * 128
199 datazip = zlib.compress(datasrc)
200 # should compress both bytes and bytearray data
201 for data in (datasrc, bytearray(datasrc)):
202 co = zlib.compressobj()
203 x1 = co.compress(data)
204 x2 = co.flush()
205 self.assertRaises(zlib.error, co.flush) # second flush should not work
206 self.assertEqual(x1 + x2, datazip)
207 for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))):
208 dco = zlib.decompressobj()
209 y1 = dco.decompress(v1 + v2)
210 y2 = dco.flush()
211 self.assertEqual(data, y1 + y2)
212 self.assertIsInstance(dco.unconsumed_tail, bytes)
213 self.assertIsInstance(dco.unused_data, bytes)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000214
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000215 def test_compressoptions(self):
216 # specify lots of options to compressobj()
217 level = 2
218 method = zlib.DEFLATED
219 wbits = -12
220 memlevel = 9
221 strategy = zlib.Z_FILTERED
222 co = zlib.compressobj(level, method, wbits, memlevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000223 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000224 x2 = co.flush()
225 dco = zlib.decompressobj(wbits)
226 y1 = dco.decompress(x1 + x2)
227 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000228 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000229
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000230 def test_compressincremental(self):
231 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000232 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000233 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000234 bufs = []
235 for i in range(0, len(data), 256):
236 bufs.append(co.compress(data[i:i+256]))
237 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000238 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000239
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000240 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000241 y1 = dco.decompress(b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000242 y2 = dco.flush()
243 self.assertEqual(data, y1 + y2)
244
Neil Schemenauer6412b122004-06-05 19:34:28 +0000245 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000246 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000247 source = source or HAMLET_SCENE
248 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000249 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000250 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000251 for i in range(0, len(data), cx):
252 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000253 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000254 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000255
Gregory P. Smith693fc462008-09-06 20:13:06 +0000256 decombuf = zlib.decompress(combuf)
257 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000258 self.assertIsInstance(decombuf, bytes)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000259
260 self.assertEqual(data, decombuf)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000261
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000262 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000263 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000264 for i in range(0, len(combuf), dcx):
265 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000266 self.assertEqual(b'', dco.unconsumed_tail, ########
267 "(A) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000268 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000269 self.assertEqual(b'', dco.unused_data)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000270 if flush:
271 bufs.append(dco.flush())
272 else:
273 while True:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000274 chunk = dco.decompress(b'')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000275 if chunk:
276 bufs.append(chunk)
277 else:
278 break
Guido van Rossum776152b2007-05-22 22:44:07 +0000279 self.assertEqual(b'', dco.unconsumed_tail, ########
280 "(B) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000281 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000282 self.assertEqual(b'', dco.unused_data)
Guido van Rossum776152b2007-05-22 22:44:07 +0000283 self.assertEqual(data, b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000284 # Failure means: "decompressobj with init options failed"
285
Neil Schemenauer6412b122004-06-05 19:34:28 +0000286 def test_decompincflush(self):
287 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000288
Neil Schemenauer6412b122004-06-05 19:34:28 +0000289 def test_decompimax(self, source=None, cx=256, dcx=64):
290 # compress in steps, decompress in length-restricted steps
291 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000292 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000293 data = source * 128
294 co = zlib.compressobj()
295 bufs = []
296 for i in range(0, len(data), cx):
297 bufs.append(co.compress(data[i:i+cx]))
298 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000299 combuf = b''.join(bufs)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000300 self.assertEqual(data, zlib.decompress(combuf),
301 'compressed data failure')
302
303 dco = zlib.decompressobj()
304 bufs = []
305 cb = combuf
306 while cb:
307 #max_length = 1 + len(cb)//10
308 chunk = dco.decompress(cb, dcx)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000309 self.assertFalse(len(chunk) > dcx,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000310 'chunk too big (%d>%d)' % (len(chunk), dcx))
311 bufs.append(chunk)
312 cb = dco.unconsumed_tail
313 bufs.append(dco.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000314 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000315
316 def test_decompressmaxlen(self, flush=False):
317 # Check a decompression object with max_length specified
318 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000319 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000320 bufs = []
321 for i in range(0, len(data), 256):
322 bufs.append(co.compress(data[i:i+256]))
323 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000324 combuf = b''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000325 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000326 'compressed data failure')
327
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000328 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000329 bufs = []
330 cb = combuf
331 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000332 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000333 chunk = dco.decompress(cb, max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000334 self.assertFalse(len(chunk) > max_length,
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000335 'chunk too big (%d>%d)' % (len(chunk),max_length))
336 bufs.append(chunk)
337 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000338 if flush:
339 bufs.append(dco.flush())
340 else:
341 while chunk:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000342 chunk = dco.decompress(b'', max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000343 self.assertFalse(len(chunk) > max_length,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000344 'chunk too big (%d>%d)' % (len(chunk),max_length))
345 bufs.append(chunk)
Guido van Rossum776152b2007-05-22 22:44:07 +0000346 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000347
Neil Schemenauer6412b122004-06-05 19:34:28 +0000348 def test_decompressmaxlenflush(self):
349 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000350
351 def test_maxlenmisc(self):
352 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000353 dco = zlib.decompressobj()
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000354 self.assertRaises(ValueError, dco.decompress, b"", -1)
Guido van Rossum776152b2007-05-22 22:44:07 +0000355 self.assertEqual(b'', dco.unconsumed_tail)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000356
Nadeem Vawda7619e882011-05-14 14:05:20 +0200357 def test_clear_unconsumed_tail(self):
358 # Issue #12050: calling decompress() without providing max_length
359 # should clear the unconsumed_tail attribute.
360 cdata = b"x\x9cKLJ\x06\x00\x02M\x01" # "abc"
361 dco = zlib.decompressobj()
362 ddata = dco.decompress(cdata, 1)
363 ddata += dco.decompress(dco.unconsumed_tail)
364 self.assertEqual(dco.unconsumed_tail, b"")
365
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000366 def test_flushes(self):
367 # Test flush() with the various options, using all the
368 # different levels in order to provide more variations.
369 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH']
370 sync_opt = [getattr(zlib, opt) for opt in sync_opt
371 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000372 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000373
374 for sync in sync_opt:
375 for level in range(10):
376 obj = zlib.compressobj( level )
377 a = obj.compress( data[:3000] )
378 b = obj.flush( sync )
379 c = obj.compress( data[3000:] )
380 d = obj.flush()
Guido van Rossum776152b2007-05-22 22:44:07 +0000381 self.assertEqual(zlib.decompress(b''.join([a,b,c,d])),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000382 data, ("Decompress failed: flush "
383 "mode=%i, level=%i") % (sync, level))
384 del obj
385
386 def test_odd_flush(self):
387 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
388 import random
389
390 if hasattr(zlib, 'Z_SYNC_FLUSH'):
391 # Testing on 17K of "random" data
392
393 # Create compressor and decompressor objects
Neil Schemenauer6412b122004-06-05 19:34:28 +0000394 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000395 dco = zlib.decompressobj()
396
397 # Try 17K of data
398 # generate random data stream
399 try:
400 # In 2.3 and later, WichmannHill is the RNG of the bug report
401 gen = random.WichmannHill()
402 except AttributeError:
403 try:
404 # 2.2 called it Random
405 gen = random.Random()
406 except AttributeError:
407 # others might simply have a single RNG
408 gen = random
409 gen.seed(1)
410 data = genblock(1, 17 * 1024, generator=gen)
411
412 # compress, sync-flush, and decompress
413 first = co.compress(data)
414 second = co.flush(zlib.Z_SYNC_FLUSH)
415 expanded = dco.decompress(first + second)
416
417 # if decompressed data is different from the input data, choke.
418 self.assertEqual(expanded, data, "17K random source doesn't match")
419
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000420 def test_empty_flush(self):
421 # Test that calling .flush() on unused objects works.
422 # (Bug #1083110 -- calling .flush() on decompress objects
423 # caused a core dump.)
424
425 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000426 self.assertTrue(co.flush()) # Returns a zlib header
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000427 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000428 self.assertEqual(dco.flush(), b"") # Returns nothing
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000429
Antoine Pitrouc09c92f2010-05-11 23:36:40 +0000430 def test_decompress_incomplete_stream(self):
431 # This is 'foo', deflated
432 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
433 # For the record
434 self.assertEqual(zlib.decompress(x), b'foo')
435 self.assertRaises(zlib.error, zlib.decompress, x[:-5])
436 # Omitting the stream end works with decompressor objects
437 # (see issue #8672).
438 dco = zlib.decompressobj()
439 y = dco.decompress(x[:-5])
440 y += dco.flush()
441 self.assertEqual(y, b'foo')
442
Nadeem Vawda1c385462011-08-13 15:22:40 +0200443 def test_decompress_eof(self):
444 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' # 'foo'
445 dco = zlib.decompressobj()
446 self.assertFalse(dco.eof)
447 dco.decompress(x[:-5])
448 self.assertFalse(dco.eof)
449 dco.decompress(x[-5:])
450 self.assertTrue(dco.eof)
451 dco.flush()
452 self.assertTrue(dco.eof)
453
454 def test_decompress_eof_incomplete_stream(self):
455 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' # 'foo'
456 dco = zlib.decompressobj()
457 self.assertFalse(dco.eof)
458 dco.decompress(x[:-5])
459 self.assertFalse(dco.eof)
460 dco.flush()
461 self.assertFalse(dco.eof)
462
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000463 if hasattr(zlib.compressobj(), "copy"):
464 def test_compresscopy(self):
465 # Test copying a compression object
466 data0 = HAMLET_SCENE
Guido van Rossum776152b2007-05-22 22:44:07 +0000467 data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000468 c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
469 bufs0 = []
470 bufs0.append(c0.compress(data0))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000471
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000472 c1 = c0.copy()
473 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000474
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000475 bufs0.append(c0.compress(data0))
476 bufs0.append(c0.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000477 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000478
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000479 bufs1.append(c1.compress(data1))
480 bufs1.append(c1.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000481 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000482
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000483 self.assertEqual(zlib.decompress(s0),data0+data0)
484 self.assertEqual(zlib.decompress(s1),data0+data1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000485
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000486 def test_badcompresscopy(self):
487 # Test copying a compression object in an inconsistent state
488 c = zlib.compressobj()
489 c.compress(HAMLET_SCENE)
490 c.flush()
491 self.assertRaises(ValueError, c.copy)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000492
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000493 if hasattr(zlib.decompressobj(), "copy"):
494 def test_decompresscopy(self):
495 # Test copying a decompression object
496 data = HAMLET_SCENE
497 comp = zlib.compress(data)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000498 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000499 self.assertIsInstance(comp, bytes)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000500
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000501 d0 = zlib.decompressobj()
502 bufs0 = []
503 bufs0.append(d0.decompress(comp[:32]))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000504
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000505 d1 = d0.copy()
506 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000507
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000508 bufs0.append(d0.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000509 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000510
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000511 bufs1.append(d1.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000512 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000513
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000514 self.assertEqual(s0,s1)
515 self.assertEqual(s0,data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000516
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000517 def test_baddecompresscopy(self):
518 # Test copying a compression object in an inconsistent state
519 data = zlib.compress(HAMLET_SCENE)
520 d = zlib.decompressobj()
521 d.decompress(data)
522 d.flush()
523 self.assertRaises(ValueError, d.copy)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000524
Antoine Pitrou89562712010-05-07 17:04:02 +0000525 # Memory use of the following functions takes into account overallocation
526
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200527 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000528 def test_big_compress_buffer(self, size):
529 c = zlib.compressobj(1)
530 compress = lambda s: c.compress(s) + c.flush()
531 self.check_big_compress_buffer(size, compress)
532
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200533 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000534 def test_big_decompress_buffer(self, size):
535 d = zlib.decompressobj()
536 decompress = lambda s: d.decompress(s) + d.flush()
537 self.check_big_decompress_buffer(size, decompress)
538
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200539 @bigmemtest(size=_4G + 100, memuse=1)
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200540 def test_length_overflow(self, size):
541 if size < _4G + 100:
542 self.skipTest("not enough free memory, need at least 4 GB")
543 data = b'x' * size
Nadeem Vawda1161a9c2011-05-15 00:48:24 +0200544 c = zlib.compressobj(1)
545 d = zlib.decompressobj()
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200546 try:
Nadeem Vawda1161a9c2011-05-15 00:48:24 +0200547 self.assertRaises(OverflowError, c.compress, data)
548 self.assertRaises(OverflowError, d.decompress, data)
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200549 finally:
550 data = None
551
Antoine Pitrou89562712010-05-07 17:04:02 +0000552
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000553def genblock(seed, length, step=1024, generator=random):
554 """length-byte stream of random data from a seed (in step-byte blocks)."""
555 if seed is not None:
556 generator.seed(seed)
557 randint = generator.randint
558 if length < step or step < 2:
559 step = length
Guido van Rossum776152b2007-05-22 22:44:07 +0000560 blocks = bytes()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000561 for i in range(0, length, step):
Guido van Rossum776152b2007-05-22 22:44:07 +0000562 blocks += bytes(randint(0, 255) for x in range(step))
563 return blocks
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000564
565
566
567def choose_lines(source, number, seed=None, generator=random):
568 """Return a list of number lines randomly chosen from the source"""
569 if seed is not None:
570 generator.seed(seed)
571 sources = source.split('\n')
572 return [generator.choice(sources) for n in range(number)]
573
574
575
Guido van Rossum776152b2007-05-22 22:44:07 +0000576HAMLET_SCENE = b"""
Fred Drake004d5e62000-10-23 17:22:08 +0000577LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000578
579 O, fear me not.
580 I stay too long: but here my father comes.
581
582 Enter POLONIUS
583
584 A double blessing is a double grace,
585 Occasion smiles upon a second leave.
586
Fred Drake004d5e62000-10-23 17:22:08 +0000587LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000588
589 Yet here, Laertes! aboard, aboard, for shame!
590 The wind sits in the shoulder of your sail,
591 And you are stay'd for. There; my blessing with thee!
592 And these few precepts in thy memory
593 See thou character. Give thy thoughts no tongue,
594 Nor any unproportioned thought his act.
595 Be thou familiar, but by no means vulgar.
596 Those friends thou hast, and their adoption tried,
597 Grapple them to thy soul with hoops of steel;
598 But do not dull thy palm with entertainment
599 Of each new-hatch'd, unfledged comrade. Beware
600 Of entrance to a quarrel, but being in,
601 Bear't that the opposed may beware of thee.
602 Give every man thy ear, but few thy voice;
603 Take each man's censure, but reserve thy judgment.
604 Costly thy habit as thy purse can buy,
605 But not express'd in fancy; rich, not gaudy;
606 For the apparel oft proclaims the man,
607 And they in France of the best rank and station
608 Are of a most select and generous chief in that.
609 Neither a borrower nor a lender be;
610 For loan oft loses both itself and friend,
611 And borrowing dulls the edge of husbandry.
612 This above all: to thine ownself be true,
613 And it must follow, as the night the day,
614 Thou canst not then be false to any man.
615 Farewell: my blessing season this in thee!
616
Fred Drake004d5e62000-10-23 17:22:08 +0000617LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000618
619 Most humbly do I take my leave, my lord.
620
Fred Drake004d5e62000-10-23 17:22:08 +0000621LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000622
623 The time invites you; go; your servants tend.
624
Fred Drake004d5e62000-10-23 17:22:08 +0000625LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000626
627 Farewell, Ophelia; and remember well
628 What I have said to you.
629
Fred Drake004d5e62000-10-23 17:22:08 +0000630OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000631
632 'Tis in my memory lock'd,
633 And you yourself shall keep the key of it.
634
Fred Drake004d5e62000-10-23 17:22:08 +0000635LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000636
637 Farewell.
638"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000639
640
641def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000642 support.run_unittest(
Nadeem Vawda64d25dd2011-09-12 00:04:13 +0200643 VersionTestCase,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000644 ChecksumTestCase,
Antoine Pitrouf3d22752011-02-21 18:09:00 +0000645 ChecksumBigBufferTestCase,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000646 ExceptionTestCase,
647 CompressTestCase,
648 CompressObjectTestCase
649 )
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000650
651if __name__ == "__main__":
Guido van Rossum776152b2007-05-22 22:44:07 +0000652 unittest.main() # XXX
653 ###test_main()