blob: 68dd3eabe10a01f90c236c2dd9ede94d1c4b94fb [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
Victor Stinner8848c7a2011-01-04 02:07:36 +00006from test.support import precisionbigmemtest, _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
Antoine Pitrouf3d22752011-02-21 18:09:00 +000010try:
11 import mmap
12except ImportError:
13 mmap = None
14
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000015
Guido van Rossum7d9ea502003-02-03 20:45:52 +000016class ChecksumTestCase(unittest.TestCase):
17 # checksum test cases
18 def test_crc32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000019 self.assertEqual(zlib.crc32(b""), zlib.crc32(b"", 0))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000020 self.assertTrue(zlib.crc32(b"abc", 0xffffffff))
Andrew M. Kuchlingfcfc8d52001-08-10 15:50:11 +000021
Guido van Rossum7d9ea502003-02-03 20:45:52 +000022 def test_crc32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000023 self.assertEqual(zlib.crc32(b"", 0), 0)
24 self.assertEqual(zlib.crc32(b"", 1), 1)
25 self.assertEqual(zlib.crc32(b"", 432), 432)
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000026
Guido van Rossum7d9ea502003-02-03 20:45:52 +000027 def test_adler32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000028 self.assertEqual(zlib.adler32(b""), zlib.adler32(b"", 1))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000029 self.assertTrue(zlib.adler32(b"abc", 0xffffffff))
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000030
Guido van Rossum7d9ea502003-02-03 20:45:52 +000031 def test_adler32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000032 self.assertEqual(zlib.adler32(b"", 0), 0)
33 self.assertEqual(zlib.adler32(b"", 1), 1)
34 self.assertEqual(zlib.adler32(b"", 432), 432)
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000035
Guido van Rossum7d9ea502003-02-03 20:45:52 +000036 def assertEqual32(self, seen, expected):
37 # 32-bit values masked -- checksums on 32- vs 64- bit machines
38 # This is important if bit 31 (0x08000000L) is set.
Guido van Rossume2a383d2007-01-15 16:59:06 +000039 self.assertEqual(seen & 0x0FFFFFFFF, expected & 0x0FFFFFFFF)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000040
41 def test_penguins(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000042 self.assertEqual32(zlib.crc32(b"penguin", 0), 0x0e5c1a120)
43 self.assertEqual32(zlib.crc32(b"penguin", 1), 0x43b6aa94)
44 self.assertEqual32(zlib.adler32(b"penguin", 0), 0x0bcf02f6)
45 self.assertEqual32(zlib.adler32(b"penguin", 1), 0x0bd602f7)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000046
Guido van Rossum776152b2007-05-22 22:44:07 +000047 self.assertEqual(zlib.crc32(b"penguin"), zlib.crc32(b"penguin", 0))
48 self.assertEqual(zlib.adler32(b"penguin"),zlib.adler32(b"penguin",1))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000049
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000050 def test_crc32_adler32_unsigned(self):
Antoine Pitrou77b338b2009-12-14 18:00:06 +000051 foo = b'abcdefghijklmnop'
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000052 # explicitly test signed behavior
Gregory P. Smith27275032008-03-20 06:20:09 +000053 self.assertEqual(zlib.crc32(foo), 2486878355)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000054 self.assertEqual(zlib.crc32(b'spam'), 1138425661)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000055 self.assertEqual(zlib.adler32(foo+foo), 3573550353)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000056 self.assertEqual(zlib.adler32(b'spam'), 72286642)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000057
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000058 def test_same_as_binascii_crc32(self):
Martin v. Löwis15b16a32008-12-02 06:00:15 +000059 foo = b'abcdefghijklmnop'
Gregory P. Smith27275032008-03-20 06:20:09 +000060 crc = 2486878355
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000061 self.assertEqual(binascii.crc32(foo), crc)
62 self.assertEqual(zlib.crc32(foo), crc)
Martin v. Löwis15b16a32008-12-02 06:00:15 +000063 self.assertEqual(binascii.crc32(b'spam'), zlib.crc32(b'spam'))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000064
65
Antoine Pitrouf3d22752011-02-21 18:09:00 +000066# Issue #10276 - check that inputs >=4GB are handled correctly.
67class ChecksumBigBufferTestCase(unittest.TestCase):
68
69 def setUp(self):
70 with open(support.TESTFN, "wb+") as f:
71 f.seek(_4G)
72 f.write(b"asdf")
Victor Stinnera6cd0cf2011-05-02 01:05:37 +020073 f.flush()
Antoine Pitrouf3d22752011-02-21 18:09:00 +000074 self.mapping = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
75
76 def tearDown(self):
77 self.mapping.close()
78 support.unlink(support.TESTFN)
79
80 @unittest.skipUnless(mmap, "mmap() is not available.")
81 @unittest.skipUnless(sys.maxsize > _4G, "Can't run on a 32-bit system.")
82 @unittest.skipUnless(support.is_resource_enabled("largefile"),
83 "May use lots of disk space.")
84 def test_big_buffer(self):
85 self.assertEqual(zlib.crc32(self.mapping), 3058686908)
86 self.assertEqual(zlib.adler32(self.mapping), 82837919)
87
Christian Heimesb186d002008-03-18 15:15:01 +000088
Guido van Rossum7d9ea502003-02-03 20:45:52 +000089class ExceptionTestCase(unittest.TestCase):
90 # make sure we generate some expected errors
Guido van Rossum8ce8a782007-11-01 19:42:39 +000091 def test_badlevel(self):
92 # specifying compression level out of range causes an error
93 # (but -1 is Z_DEFAULT_COMPRESSION and apparently the zlib
94 # accepts 0 too)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000095 self.assertRaises(zlib.error, zlib.compress, b'ERROR', 10)
96
97 def test_badargs(self):
98 self.assertRaises(TypeError, zlib.adler32)
99 self.assertRaises(TypeError, zlib.crc32)
100 self.assertRaises(TypeError, zlib.compress)
101 self.assertRaises(TypeError, zlib.decompress)
102 for arg in (42, None, '', 'abc', (), []):
103 self.assertRaises(TypeError, zlib.adler32, arg)
104 self.assertRaises(TypeError, zlib.crc32, arg)
105 self.assertRaises(TypeError, zlib.compress, arg)
106 self.assertRaises(TypeError, zlib.decompress, arg)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000107
108 def test_badcompressobj(self):
109 # verify failure on building compress object with bad params
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000110 self.assertRaises(ValueError, zlib.compressobj, 1, zlib.DEFLATED, 0)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000111 # specifying total bits too large causes an error
112 self.assertRaises(ValueError,
113 zlib.compressobj, 1, zlib.DEFLATED, zlib.MAX_WBITS + 1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000114
115 def test_baddecompressobj(self):
116 # verify failure on building decompress object with bad params
Antoine Pitrou90ee4df2010-04-06 17:23:13 +0000117 self.assertRaises(ValueError, zlib.decompressobj, -1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000118
Christian Heimes5e696852008-04-09 08:37:03 +0000119 def test_decompressobj_badflush(self):
120 # verify failure on calling decompressobj.flush with bad params
121 self.assertRaises(ValueError, zlib.decompressobj().flush, 0)
122 self.assertRaises(ValueError, zlib.decompressobj().flush, -1)
123
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000124
Antoine Pitrou89562712010-05-07 17:04:02 +0000125class BaseCompressTestCase(object):
126 def check_big_compress_buffer(self, size, compress_func):
127 _1M = 1024 * 1024
128 fmt = "%%0%dx" % (2 * _1M)
129 # Generate 10MB worth of random, and expand it by repeating it.
130 # The assumption is that zlib's memory is not big enough to exploit
131 # such spread out redundancy.
132 data = b''.join([random.getrandbits(8 * _1M).to_bytes(_1M, 'little')
133 for i in range(10)])
134 data = data * (size // len(data) + 1)
135 try:
136 compress_func(data)
137 finally:
138 # Release memory
139 data = None
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000140
Antoine Pitrou89562712010-05-07 17:04:02 +0000141 def check_big_decompress_buffer(self, size, decompress_func):
142 data = b'x' * size
143 try:
144 compressed = zlib.compress(data, 1)
145 finally:
146 # Release memory
147 data = None
148 data = decompress_func(compressed)
149 # Sanity check
150 try:
151 self.assertEqual(len(data), size)
152 self.assertEqual(len(data.strip(b'x')), 0)
153 finally:
154 data = None
155
156
157class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000158 # Test compression in one go (whole message compression)
159 def test_speech(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000160 x = zlib.compress(HAMLET_SCENE)
161 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000162
163 def test_speech128(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000164 # compress more data
165 data = HAMLET_SCENE * 128
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000166 x = zlib.compress(data)
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000167 self.assertEqual(zlib.compress(bytearray(data)), x)
168 for ob in x, bytearray(x):
169 self.assertEqual(zlib.decompress(ob), data)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000170
Antoine Pitrou53b21662010-05-11 23:46:02 +0000171 def test_incomplete_stream(self):
172 # An useful error message is given
173 x = zlib.compress(HAMLET_SCENE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000174 self.assertRaisesRegex(zlib.error,
Antoine Pitrou53b21662010-05-11 23:46:02 +0000175 "Error -5 while decompressing data: incomplete or truncated stream",
176 zlib.decompress, x[:-1])
177
Antoine Pitrou89562712010-05-07 17:04:02 +0000178 # Memory use of the following functions takes into account overallocation
179
180 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=3)
181 def test_big_compress_buffer(self, size):
182 compress = lambda s: zlib.compress(s, 1)
183 self.check_big_compress_buffer(size, compress)
184
185 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=2)
186 def test_big_decompress_buffer(self, size):
187 self.check_big_decompress_buffer(size, zlib.decompress)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000188
Victor Stinner8848c7a2011-01-04 02:07:36 +0000189 @precisionbigmemtest(size=_4G + 100, memuse=1)
190 def test_length_overflow(self, size):
191 if size < _4G + 100:
192 self.skipTest("not enough free memory, need at least 4 GB")
193 data = b'x' * size
194 try:
195 self.assertRaises(OverflowError, zlib.compress, data, 1)
Nadeem Vawda154bdf92011-05-14 23:07:36 +0200196 self.assertRaises(OverflowError, zlib.decompress, data)
Victor Stinner8848c7a2011-01-04 02:07:36 +0000197 finally:
198 data = None
199
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000200
Antoine Pitrou89562712010-05-07 17:04:02 +0000201class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000202 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000203 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000204 # straightforward compress/decompress objects
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000205 datasrc = HAMLET_SCENE * 128
206 datazip = zlib.compress(datasrc)
207 # should compress both bytes and bytearray data
208 for data in (datasrc, bytearray(datasrc)):
209 co = zlib.compressobj()
210 x1 = co.compress(data)
211 x2 = co.flush()
212 self.assertRaises(zlib.error, co.flush) # second flush should not work
213 self.assertEqual(x1 + x2, datazip)
214 for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))):
215 dco = zlib.decompressobj()
216 y1 = dco.decompress(v1 + v2)
217 y2 = dco.flush()
218 self.assertEqual(data, y1 + y2)
219 self.assertIsInstance(dco.unconsumed_tail, bytes)
220 self.assertIsInstance(dco.unused_data, bytes)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000221
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000222 def test_compressoptions(self):
223 # specify lots of options to compressobj()
224 level = 2
225 method = zlib.DEFLATED
226 wbits = -12
227 memlevel = 9
228 strategy = zlib.Z_FILTERED
229 co = zlib.compressobj(level, method, wbits, memlevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000230 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000231 x2 = co.flush()
232 dco = zlib.decompressobj(wbits)
233 y1 = dco.decompress(x1 + x2)
234 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000235 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000236
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000237 def test_compressincremental(self):
238 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000239 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000240 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000241 bufs = []
242 for i in range(0, len(data), 256):
243 bufs.append(co.compress(data[i:i+256]))
244 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000245 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000246
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000247 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000248 y1 = dco.decompress(b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000249 y2 = dco.flush()
250 self.assertEqual(data, y1 + y2)
251
Neil Schemenauer6412b122004-06-05 19:34:28 +0000252 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000253 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000254 source = source or HAMLET_SCENE
255 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000256 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000257 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000258 for i in range(0, len(data), cx):
259 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000260 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000261 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000262
Gregory P. Smith693fc462008-09-06 20:13:06 +0000263 decombuf = zlib.decompress(combuf)
264 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000265 self.assertIsInstance(decombuf, bytes)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000266
267 self.assertEqual(data, decombuf)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000268
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000269 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000270 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000271 for i in range(0, len(combuf), dcx):
272 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000273 self.assertEqual(b'', dco.unconsumed_tail, ########
274 "(A) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000275 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000276 self.assertEqual(b'', dco.unused_data)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000277 if flush:
278 bufs.append(dco.flush())
279 else:
280 while True:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000281 chunk = dco.decompress(b'')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000282 if chunk:
283 bufs.append(chunk)
284 else:
285 break
Guido van Rossum776152b2007-05-22 22:44:07 +0000286 self.assertEqual(b'', dco.unconsumed_tail, ########
287 "(B) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000288 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000289 self.assertEqual(b'', dco.unused_data)
Guido van Rossum776152b2007-05-22 22:44:07 +0000290 self.assertEqual(data, b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000291 # Failure means: "decompressobj with init options failed"
292
Neil Schemenauer6412b122004-06-05 19:34:28 +0000293 def test_decompincflush(self):
294 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000295
Neil Schemenauer6412b122004-06-05 19:34:28 +0000296 def test_decompimax(self, source=None, cx=256, dcx=64):
297 # compress in steps, decompress in length-restricted steps
298 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000299 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000300 data = source * 128
301 co = zlib.compressobj()
302 bufs = []
303 for i in range(0, len(data), cx):
304 bufs.append(co.compress(data[i:i+cx]))
305 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000306 combuf = b''.join(bufs)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000307 self.assertEqual(data, zlib.decompress(combuf),
308 'compressed data failure')
309
310 dco = zlib.decompressobj()
311 bufs = []
312 cb = combuf
313 while cb:
314 #max_length = 1 + len(cb)//10
315 chunk = dco.decompress(cb, dcx)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000316 self.assertFalse(len(chunk) > dcx,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000317 'chunk too big (%d>%d)' % (len(chunk), dcx))
318 bufs.append(chunk)
319 cb = dco.unconsumed_tail
320 bufs.append(dco.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000321 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000322
323 def test_decompressmaxlen(self, flush=False):
324 # Check a decompression object with max_length specified
325 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000326 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000327 bufs = []
328 for i in range(0, len(data), 256):
329 bufs.append(co.compress(data[i:i+256]))
330 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000331 combuf = b''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000332 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000333 'compressed data failure')
334
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000335 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000336 bufs = []
337 cb = combuf
338 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000339 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000340 chunk = dco.decompress(cb, max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000341 self.assertFalse(len(chunk) > max_length,
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000342 'chunk too big (%d>%d)' % (len(chunk),max_length))
343 bufs.append(chunk)
344 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000345 if flush:
346 bufs.append(dco.flush())
347 else:
348 while chunk:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000349 chunk = dco.decompress(b'', max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000350 self.assertFalse(len(chunk) > max_length,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000351 'chunk too big (%d>%d)' % (len(chunk),max_length))
352 bufs.append(chunk)
Guido van Rossum776152b2007-05-22 22:44:07 +0000353 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000354
Neil Schemenauer6412b122004-06-05 19:34:28 +0000355 def test_decompressmaxlenflush(self):
356 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000357
358 def test_maxlenmisc(self):
359 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000360 dco = zlib.decompressobj()
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000361 self.assertRaises(ValueError, dco.decompress, b"", -1)
Guido van Rossum776152b2007-05-22 22:44:07 +0000362 self.assertEqual(b'', dco.unconsumed_tail)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000363
Nadeem Vawda7619e882011-05-14 14:05:20 +0200364 def test_clear_unconsumed_tail(self):
365 # Issue #12050: calling decompress() without providing max_length
366 # should clear the unconsumed_tail attribute.
367 cdata = b"x\x9cKLJ\x06\x00\x02M\x01" # "abc"
368 dco = zlib.decompressobj()
369 ddata = dco.decompress(cdata, 1)
370 ddata += dco.decompress(dco.unconsumed_tail)
371 self.assertEqual(dco.unconsumed_tail, b"")
372
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000373 def test_flushes(self):
374 # Test flush() with the various options, using all the
375 # different levels in order to provide more variations.
376 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH']
377 sync_opt = [getattr(zlib, opt) for opt in sync_opt
378 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000379 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000380
381 for sync in sync_opt:
382 for level in range(10):
383 obj = zlib.compressobj( level )
384 a = obj.compress( data[:3000] )
385 b = obj.flush( sync )
386 c = obj.compress( data[3000:] )
387 d = obj.flush()
Guido van Rossum776152b2007-05-22 22:44:07 +0000388 self.assertEqual(zlib.decompress(b''.join([a,b,c,d])),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000389 data, ("Decompress failed: flush "
390 "mode=%i, level=%i") % (sync, level))
391 del obj
392
393 def test_odd_flush(self):
394 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
395 import random
396
397 if hasattr(zlib, 'Z_SYNC_FLUSH'):
398 # Testing on 17K of "random" data
399
400 # Create compressor and decompressor objects
Neil Schemenauer6412b122004-06-05 19:34:28 +0000401 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000402 dco = zlib.decompressobj()
403
404 # Try 17K of data
405 # generate random data stream
406 try:
407 # In 2.3 and later, WichmannHill is the RNG of the bug report
408 gen = random.WichmannHill()
409 except AttributeError:
410 try:
411 # 2.2 called it Random
412 gen = random.Random()
413 except AttributeError:
414 # others might simply have a single RNG
415 gen = random
416 gen.seed(1)
417 data = genblock(1, 17 * 1024, generator=gen)
418
419 # compress, sync-flush, and decompress
420 first = co.compress(data)
421 second = co.flush(zlib.Z_SYNC_FLUSH)
422 expanded = dco.decompress(first + second)
423
424 # if decompressed data is different from the input data, choke.
425 self.assertEqual(expanded, data, "17K random source doesn't match")
426
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000427 def test_empty_flush(self):
428 # Test that calling .flush() on unused objects works.
429 # (Bug #1083110 -- calling .flush() on decompress objects
430 # caused a core dump.)
431
432 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000433 self.assertTrue(co.flush()) # Returns a zlib header
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000434 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000435 self.assertEqual(dco.flush(), b"") # Returns nothing
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000436
Antoine Pitrouc09c92f2010-05-11 23:36:40 +0000437 def test_decompress_incomplete_stream(self):
438 # This is 'foo', deflated
439 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
440 # For the record
441 self.assertEqual(zlib.decompress(x), b'foo')
442 self.assertRaises(zlib.error, zlib.decompress, x[:-5])
443 # Omitting the stream end works with decompressor objects
444 # (see issue #8672).
445 dco = zlib.decompressobj()
446 y = dco.decompress(x[:-5])
447 y += dco.flush()
448 self.assertEqual(y, b'foo')
449
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000450 if hasattr(zlib.compressobj(), "copy"):
451 def test_compresscopy(self):
452 # Test copying a compression object
453 data0 = HAMLET_SCENE
Guido van Rossum776152b2007-05-22 22:44:07 +0000454 data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000455 c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
456 bufs0 = []
457 bufs0.append(c0.compress(data0))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000458
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000459 c1 = c0.copy()
460 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000461
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000462 bufs0.append(c0.compress(data0))
463 bufs0.append(c0.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000464 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000465
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000466 bufs1.append(c1.compress(data1))
467 bufs1.append(c1.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000468 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000469
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000470 self.assertEqual(zlib.decompress(s0),data0+data0)
471 self.assertEqual(zlib.decompress(s1),data0+data1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000472
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000473 def test_badcompresscopy(self):
474 # Test copying a compression object in an inconsistent state
475 c = zlib.compressobj()
476 c.compress(HAMLET_SCENE)
477 c.flush()
478 self.assertRaises(ValueError, c.copy)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000479
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000480 if hasattr(zlib.decompressobj(), "copy"):
481 def test_decompresscopy(self):
482 # Test copying a decompression object
483 data = HAMLET_SCENE
484 comp = zlib.compress(data)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000485 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000486 self.assertIsInstance(comp, bytes)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000487
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000488 d0 = zlib.decompressobj()
489 bufs0 = []
490 bufs0.append(d0.decompress(comp[:32]))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000491
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000492 d1 = d0.copy()
493 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000494
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000495 bufs0.append(d0.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000496 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000497
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000498 bufs1.append(d1.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000499 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000500
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000501 self.assertEqual(s0,s1)
502 self.assertEqual(s0,data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000503
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000504 def test_baddecompresscopy(self):
505 # Test copying a compression object in an inconsistent state
506 data = zlib.compress(HAMLET_SCENE)
507 d = zlib.decompressobj()
508 d.decompress(data)
509 d.flush()
510 self.assertRaises(ValueError, d.copy)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000511
Antoine Pitrou89562712010-05-07 17:04:02 +0000512 # Memory use of the following functions takes into account overallocation
513
514 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=3)
515 def test_big_compress_buffer(self, size):
516 c = zlib.compressobj(1)
517 compress = lambda s: c.compress(s) + c.flush()
518 self.check_big_compress_buffer(size, compress)
519
520 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=2)
521 def test_big_decompress_buffer(self, size):
522 d = zlib.decompressobj()
523 decompress = lambda s: d.decompress(s) + d.flush()
524 self.check_big_decompress_buffer(size, decompress)
525
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200526 @precisionbigmemtest(size=_4G + 100, memuse=1)
527 def test_length_overflow(self, size):
528 if size < _4G + 100:
529 self.skipTest("not enough free memory, need at least 4 GB")
530 data = b'x' * size
Nadeem Vawda1161a9c2011-05-15 00:48:24 +0200531 c = zlib.compressobj(1)
532 d = zlib.decompressobj()
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200533 try:
Nadeem Vawda1161a9c2011-05-15 00:48:24 +0200534 self.assertRaises(OverflowError, c.compress, data)
535 self.assertRaises(OverflowError, d.decompress, data)
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200536 finally:
537 data = None
538
Antoine Pitrou89562712010-05-07 17:04:02 +0000539
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000540def genblock(seed, length, step=1024, generator=random):
541 """length-byte stream of random data from a seed (in step-byte blocks)."""
542 if seed is not None:
543 generator.seed(seed)
544 randint = generator.randint
545 if length < step or step < 2:
546 step = length
Guido van Rossum776152b2007-05-22 22:44:07 +0000547 blocks = bytes()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000548 for i in range(0, length, step):
Guido van Rossum776152b2007-05-22 22:44:07 +0000549 blocks += bytes(randint(0, 255) for x in range(step))
550 return blocks
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000551
552
553
554def choose_lines(source, number, seed=None, generator=random):
555 """Return a list of number lines randomly chosen from the source"""
556 if seed is not None:
557 generator.seed(seed)
558 sources = source.split('\n')
559 return [generator.choice(sources) for n in range(number)]
560
561
562
Guido van Rossum776152b2007-05-22 22:44:07 +0000563HAMLET_SCENE = b"""
Fred Drake004d5e62000-10-23 17:22:08 +0000564LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000565
566 O, fear me not.
567 I stay too long: but here my father comes.
568
569 Enter POLONIUS
570
571 A double blessing is a double grace,
572 Occasion smiles upon a second leave.
573
Fred Drake004d5e62000-10-23 17:22:08 +0000574LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000575
576 Yet here, Laertes! aboard, aboard, for shame!
577 The wind sits in the shoulder of your sail,
578 And you are stay'd for. There; my blessing with thee!
579 And these few precepts in thy memory
580 See thou character. Give thy thoughts no tongue,
581 Nor any unproportioned thought his act.
582 Be thou familiar, but by no means vulgar.
583 Those friends thou hast, and their adoption tried,
584 Grapple them to thy soul with hoops of steel;
585 But do not dull thy palm with entertainment
586 Of each new-hatch'd, unfledged comrade. Beware
587 Of entrance to a quarrel, but being in,
588 Bear't that the opposed may beware of thee.
589 Give every man thy ear, but few thy voice;
590 Take each man's censure, but reserve thy judgment.
591 Costly thy habit as thy purse can buy,
592 But not express'd in fancy; rich, not gaudy;
593 For the apparel oft proclaims the man,
594 And they in France of the best rank and station
595 Are of a most select and generous chief in that.
596 Neither a borrower nor a lender be;
597 For loan oft loses both itself and friend,
598 And borrowing dulls the edge of husbandry.
599 This above all: to thine ownself be true,
600 And it must follow, as the night the day,
601 Thou canst not then be false to any man.
602 Farewell: my blessing season this in thee!
603
Fred Drake004d5e62000-10-23 17:22:08 +0000604LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000605
606 Most humbly do I take my leave, my lord.
607
Fred Drake004d5e62000-10-23 17:22:08 +0000608LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000609
610 The time invites you; go; your servants tend.
611
Fred Drake004d5e62000-10-23 17:22:08 +0000612LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000613
614 Farewell, Ophelia; and remember well
615 What I have said to you.
616
Fred Drake004d5e62000-10-23 17:22:08 +0000617OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000618
619 'Tis in my memory lock'd,
620 And you yourself shall keep the key of it.
621
Fred Drake004d5e62000-10-23 17:22:08 +0000622LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000623
624 Farewell.
625"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000626
627
628def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000629 support.run_unittest(
Walter Dörwald21d3a322003-05-01 17:45:56 +0000630 ChecksumTestCase,
Antoine Pitrouf3d22752011-02-21 18:09:00 +0000631 ChecksumBigBufferTestCase,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000632 ExceptionTestCase,
633 CompressTestCase,
634 CompressObjectTestCase
635 )
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000636
637if __name__ == "__main__":
Guido van Rossum776152b2007-05-22 22:44:07 +0000638 unittest.main() # XXX
639 ###test_main()