blob: 851fbf7cf71ff08c126b55f882f8a1d7c57d1858 [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
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
Nadeem Vawda64d25dd2011-09-12 00:04:13 +020016class VersionTestCase(unittest.TestCase):
17
18 def test_library_version(self):
Nadeem Vawda131c7072012-01-25 23:16:50 +020019 # Test that the major version of the actual library in use matches the
20 # major version that we were compiled against. We can't guarantee that
21 # the minor versions will match (even on the machine on which the module
22 # was compiled), and the API is stable between minor versions, so
23 # testing only the major verions avoids spurious failures.
24 self.assertEqual(zlib.ZLIB_RUNTIME_VERSION[0], zlib.ZLIB_VERSION[0])
Nadeem Vawda64d25dd2011-09-12 00:04:13 +020025
26
Guido van Rossum7d9ea502003-02-03 20:45:52 +000027class ChecksumTestCase(unittest.TestCase):
28 # checksum test cases
29 def test_crc32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000030 self.assertEqual(zlib.crc32(b""), zlib.crc32(b"", 0))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000031 self.assertTrue(zlib.crc32(b"abc", 0xffffffff))
Andrew M. Kuchlingfcfc8d52001-08-10 15:50:11 +000032
Guido van Rossum7d9ea502003-02-03 20:45:52 +000033 def test_crc32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000034 self.assertEqual(zlib.crc32(b"", 0), 0)
35 self.assertEqual(zlib.crc32(b"", 1), 1)
36 self.assertEqual(zlib.crc32(b"", 432), 432)
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000037
Guido van Rossum7d9ea502003-02-03 20:45:52 +000038 def test_adler32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000039 self.assertEqual(zlib.adler32(b""), zlib.adler32(b"", 1))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000040 self.assertTrue(zlib.adler32(b"abc", 0xffffffff))
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000041
Guido van Rossum7d9ea502003-02-03 20:45:52 +000042 def test_adler32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000043 self.assertEqual(zlib.adler32(b"", 0), 0)
44 self.assertEqual(zlib.adler32(b"", 1), 1)
45 self.assertEqual(zlib.adler32(b"", 432), 432)
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000046
Guido van Rossum7d9ea502003-02-03 20:45:52 +000047 def assertEqual32(self, seen, expected):
48 # 32-bit values masked -- checksums on 32- vs 64- bit machines
49 # This is important if bit 31 (0x08000000L) is set.
Guido van Rossume2a383d2007-01-15 16:59:06 +000050 self.assertEqual(seen & 0x0FFFFFFFF, expected & 0x0FFFFFFFF)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000051
52 def test_penguins(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000053 self.assertEqual32(zlib.crc32(b"penguin", 0), 0x0e5c1a120)
54 self.assertEqual32(zlib.crc32(b"penguin", 1), 0x43b6aa94)
55 self.assertEqual32(zlib.adler32(b"penguin", 0), 0x0bcf02f6)
56 self.assertEqual32(zlib.adler32(b"penguin", 1), 0x0bd602f7)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000057
Guido van Rossum776152b2007-05-22 22:44:07 +000058 self.assertEqual(zlib.crc32(b"penguin"), zlib.crc32(b"penguin", 0))
59 self.assertEqual(zlib.adler32(b"penguin"),zlib.adler32(b"penguin",1))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000060
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000061 def test_crc32_adler32_unsigned(self):
Antoine Pitrou77b338b2009-12-14 18:00:06 +000062 foo = b'abcdefghijklmnop'
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000063 # explicitly test signed behavior
Gregory P. Smith27275032008-03-20 06:20:09 +000064 self.assertEqual(zlib.crc32(foo), 2486878355)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000065 self.assertEqual(zlib.crc32(b'spam'), 1138425661)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000066 self.assertEqual(zlib.adler32(foo+foo), 3573550353)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000067 self.assertEqual(zlib.adler32(b'spam'), 72286642)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000068
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000069 def test_same_as_binascii_crc32(self):
Martin v. Löwis15b16a32008-12-02 06:00:15 +000070 foo = b'abcdefghijklmnop'
Gregory P. Smith27275032008-03-20 06:20:09 +000071 crc = 2486878355
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000072 self.assertEqual(binascii.crc32(foo), crc)
73 self.assertEqual(zlib.crc32(foo), crc)
Martin v. Löwis15b16a32008-12-02 06:00:15 +000074 self.assertEqual(binascii.crc32(b'spam'), zlib.crc32(b'spam'))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000075
76
Antoine Pitrouf3d22752011-02-21 18:09:00 +000077# Issue #10276 - check that inputs >=4GB are handled correctly.
78class ChecksumBigBufferTestCase(unittest.TestCase):
79
80 def setUp(self):
81 with open(support.TESTFN, "wb+") as f:
82 f.seek(_4G)
83 f.write(b"asdf")
Victor Stinnera6cd0cf2011-05-02 01:05:37 +020084 f.flush()
Antoine Pitrouf3d22752011-02-21 18:09:00 +000085 self.mapping = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
86
87 def tearDown(self):
88 self.mapping.close()
89 support.unlink(support.TESTFN)
90
91 @unittest.skipUnless(mmap, "mmap() is not available.")
92 @unittest.skipUnless(sys.maxsize > _4G, "Can't run on a 32-bit system.")
93 @unittest.skipUnless(support.is_resource_enabled("largefile"),
94 "May use lots of disk space.")
95 def test_big_buffer(self):
96 self.assertEqual(zlib.crc32(self.mapping), 3058686908)
97 self.assertEqual(zlib.adler32(self.mapping), 82837919)
98
Christian Heimesb186d002008-03-18 15:15:01 +000099
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000100class ExceptionTestCase(unittest.TestCase):
101 # make sure we generate some expected errors
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000102 def test_badlevel(self):
103 # specifying compression level out of range causes an error
104 # (but -1 is Z_DEFAULT_COMPRESSION and apparently the zlib
105 # accepts 0 too)
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000106 self.assertRaises(zlib.error, zlib.compress, b'ERROR', 10)
107
108 def test_badargs(self):
109 self.assertRaises(TypeError, zlib.adler32)
110 self.assertRaises(TypeError, zlib.crc32)
111 self.assertRaises(TypeError, zlib.compress)
112 self.assertRaises(TypeError, zlib.decompress)
113 for arg in (42, None, '', 'abc', (), []):
114 self.assertRaises(TypeError, zlib.adler32, arg)
115 self.assertRaises(TypeError, zlib.crc32, arg)
116 self.assertRaises(TypeError, zlib.compress, arg)
117 self.assertRaises(TypeError, zlib.decompress, arg)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000118
119 def test_badcompressobj(self):
120 # verify failure on building compress object with bad params
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000121 self.assertRaises(ValueError, zlib.compressobj, 1, zlib.DEFLATED, 0)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000122 # specifying total bits too large causes an error
123 self.assertRaises(ValueError,
124 zlib.compressobj, 1, zlib.DEFLATED, zlib.MAX_WBITS + 1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000125
126 def test_baddecompressobj(self):
127 # verify failure on building decompress object with bad params
Antoine Pitrou90ee4df2010-04-06 17:23:13 +0000128 self.assertRaises(ValueError, zlib.decompressobj, -1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000129
Christian Heimes5e696852008-04-09 08:37:03 +0000130 def test_decompressobj_badflush(self):
131 # verify failure on calling decompressobj.flush with bad params
132 self.assertRaises(ValueError, zlib.decompressobj().flush, 0)
133 self.assertRaises(ValueError, zlib.decompressobj().flush, -1)
134
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000135
Antoine Pitrou89562712010-05-07 17:04:02 +0000136class BaseCompressTestCase(object):
137 def check_big_compress_buffer(self, size, compress_func):
138 _1M = 1024 * 1024
139 fmt = "%%0%dx" % (2 * _1M)
140 # Generate 10MB worth of random, and expand it by repeating it.
141 # The assumption is that zlib's memory is not big enough to exploit
142 # such spread out redundancy.
143 data = b''.join([random.getrandbits(8 * _1M).to_bytes(_1M, 'little')
144 for i in range(10)])
145 data = data * (size // len(data) + 1)
146 try:
147 compress_func(data)
148 finally:
149 # Release memory
150 data = None
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000151
Antoine Pitrou89562712010-05-07 17:04:02 +0000152 def check_big_decompress_buffer(self, size, decompress_func):
153 data = b'x' * size
154 try:
155 compressed = zlib.compress(data, 1)
156 finally:
157 # Release memory
158 data = None
159 data = decompress_func(compressed)
160 # Sanity check
161 try:
162 self.assertEqual(len(data), size)
163 self.assertEqual(len(data.strip(b'x')), 0)
164 finally:
165 data = None
166
167
168class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000169 # Test compression in one go (whole message compression)
170 def test_speech(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000171 x = zlib.compress(HAMLET_SCENE)
172 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000173
174 def test_speech128(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000175 # compress more data
176 data = HAMLET_SCENE * 128
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000177 x = zlib.compress(data)
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000178 self.assertEqual(zlib.compress(bytearray(data)), x)
179 for ob in x, bytearray(x):
180 self.assertEqual(zlib.decompress(ob), data)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000181
Antoine Pitrou53b21662010-05-11 23:46:02 +0000182 def test_incomplete_stream(self):
183 # An useful error message is given
184 x = zlib.compress(HAMLET_SCENE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000185 self.assertRaisesRegex(zlib.error,
Antoine Pitrou53b21662010-05-11 23:46:02 +0000186 "Error -5 while decompressing data: incomplete or truncated stream",
187 zlib.decompress, x[:-1])
188
Antoine Pitrou89562712010-05-07 17:04:02 +0000189 # Memory use of the following functions takes into account overallocation
190
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200191 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000192 def test_big_compress_buffer(self, size):
193 compress = lambda s: zlib.compress(s, 1)
194 self.check_big_compress_buffer(size, compress)
195
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200196 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000197 def test_big_decompress_buffer(self, size):
198 self.check_big_decompress_buffer(size, zlib.decompress)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000199
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200200 @bigmemtest(size=_4G + 100, memuse=1)
Victor Stinner8848c7a2011-01-04 02:07:36 +0000201 def test_length_overflow(self, size):
202 if size < _4G + 100:
203 self.skipTest("not enough free memory, need at least 4 GB")
204 data = b'x' * size
205 try:
206 self.assertRaises(OverflowError, zlib.compress, data, 1)
Nadeem Vawda154bdf92011-05-14 23:07:36 +0200207 self.assertRaises(OverflowError, zlib.decompress, data)
Victor Stinner8848c7a2011-01-04 02:07:36 +0000208 finally:
209 data = None
210
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000211
Antoine Pitrou89562712010-05-07 17:04:02 +0000212class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000213 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000214 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000215 # straightforward compress/decompress objects
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000216 datasrc = HAMLET_SCENE * 128
217 datazip = zlib.compress(datasrc)
218 # should compress both bytes and bytearray data
219 for data in (datasrc, bytearray(datasrc)):
220 co = zlib.compressobj()
221 x1 = co.compress(data)
222 x2 = co.flush()
223 self.assertRaises(zlib.error, co.flush) # second flush should not work
224 self.assertEqual(x1 + x2, datazip)
225 for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))):
226 dco = zlib.decompressobj()
227 y1 = dco.decompress(v1 + v2)
228 y2 = dco.flush()
229 self.assertEqual(data, y1 + y2)
230 self.assertIsInstance(dco.unconsumed_tail, bytes)
231 self.assertIsInstance(dco.unused_data, bytes)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000232
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000233 def test_compressoptions(self):
234 # specify lots of options to compressobj()
235 level = 2
236 method = zlib.DEFLATED
237 wbits = -12
238 memlevel = 9
239 strategy = zlib.Z_FILTERED
240 co = zlib.compressobj(level, method, wbits, memlevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000241 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000242 x2 = co.flush()
243 dco = zlib.decompressobj(wbits)
244 y1 = dco.decompress(x1 + x2)
245 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000246 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000247
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000248 def test_compressincremental(self):
249 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000250 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000251 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000252 bufs = []
253 for i in range(0, len(data), 256):
254 bufs.append(co.compress(data[i:i+256]))
255 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000256 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000257
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000258 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000259 y1 = dco.decompress(b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000260 y2 = dco.flush()
261 self.assertEqual(data, y1 + y2)
262
Neil Schemenauer6412b122004-06-05 19:34:28 +0000263 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000264 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000265 source = source or HAMLET_SCENE
266 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000267 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000268 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000269 for i in range(0, len(data), cx):
270 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000271 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000272 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000273
Gregory P. Smith693fc462008-09-06 20:13:06 +0000274 decombuf = zlib.decompress(combuf)
275 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000276 self.assertIsInstance(decombuf, bytes)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000277
278 self.assertEqual(data, decombuf)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000279
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000280 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000281 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000282 for i in range(0, len(combuf), dcx):
283 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000284 self.assertEqual(b'', dco.unconsumed_tail, ########
285 "(A) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000286 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000287 self.assertEqual(b'', dco.unused_data)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000288 if flush:
289 bufs.append(dco.flush())
290 else:
291 while True:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000292 chunk = dco.decompress(b'')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000293 if chunk:
294 bufs.append(chunk)
295 else:
296 break
Guido van Rossum776152b2007-05-22 22:44:07 +0000297 self.assertEqual(b'', dco.unconsumed_tail, ########
298 "(B) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000299 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000300 self.assertEqual(b'', dco.unused_data)
Guido van Rossum776152b2007-05-22 22:44:07 +0000301 self.assertEqual(data, b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000302 # Failure means: "decompressobj with init options failed"
303
Neil Schemenauer6412b122004-06-05 19:34:28 +0000304 def test_decompincflush(self):
305 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000306
Neil Schemenauer6412b122004-06-05 19:34:28 +0000307 def test_decompimax(self, source=None, cx=256, dcx=64):
308 # compress in steps, decompress in length-restricted steps
309 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000310 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000311 data = source * 128
312 co = zlib.compressobj()
313 bufs = []
314 for i in range(0, len(data), cx):
315 bufs.append(co.compress(data[i:i+cx]))
316 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000317 combuf = b''.join(bufs)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000318 self.assertEqual(data, zlib.decompress(combuf),
319 'compressed data failure')
320
321 dco = zlib.decompressobj()
322 bufs = []
323 cb = combuf
324 while cb:
325 #max_length = 1 + len(cb)//10
326 chunk = dco.decompress(cb, dcx)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000327 self.assertFalse(len(chunk) > dcx,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000328 'chunk too big (%d>%d)' % (len(chunk), dcx))
329 bufs.append(chunk)
330 cb = dco.unconsumed_tail
331 bufs.append(dco.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000332 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000333
334 def test_decompressmaxlen(self, flush=False):
335 # Check a decompression object with max_length specified
336 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000337 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000338 bufs = []
339 for i in range(0, len(data), 256):
340 bufs.append(co.compress(data[i:i+256]))
341 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000342 combuf = b''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000343 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000344 'compressed data failure')
345
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000346 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000347 bufs = []
348 cb = combuf
349 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000350 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000351 chunk = dco.decompress(cb, max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000352 self.assertFalse(len(chunk) > max_length,
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000353 'chunk too big (%d>%d)' % (len(chunk),max_length))
354 bufs.append(chunk)
355 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000356 if flush:
357 bufs.append(dco.flush())
358 else:
359 while chunk:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000360 chunk = dco.decompress(b'', max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000361 self.assertFalse(len(chunk) > max_length,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000362 'chunk too big (%d>%d)' % (len(chunk),max_length))
363 bufs.append(chunk)
Guido van Rossum776152b2007-05-22 22:44:07 +0000364 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000365
Neil Schemenauer6412b122004-06-05 19:34:28 +0000366 def test_decompressmaxlenflush(self):
367 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000368
369 def test_maxlenmisc(self):
370 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000371 dco = zlib.decompressobj()
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000372 self.assertRaises(ValueError, dco.decompress, b"", -1)
Guido van Rossum776152b2007-05-22 22:44:07 +0000373 self.assertEqual(b'', dco.unconsumed_tail)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000374
Nadeem Vawda7619e882011-05-14 14:05:20 +0200375 def test_clear_unconsumed_tail(self):
376 # Issue #12050: calling decompress() without providing max_length
377 # should clear the unconsumed_tail attribute.
378 cdata = b"x\x9cKLJ\x06\x00\x02M\x01" # "abc"
379 dco = zlib.decompressobj()
380 ddata = dco.decompress(cdata, 1)
381 ddata += dco.decompress(dco.unconsumed_tail)
382 self.assertEqual(dco.unconsumed_tail, b"")
383
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000384 def test_flushes(self):
385 # Test flush() with the various options, using all the
386 # different levels in order to provide more variations.
387 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH']
388 sync_opt = [getattr(zlib, opt) for opt in sync_opt
389 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000390 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000391
392 for sync in sync_opt:
393 for level in range(10):
394 obj = zlib.compressobj( level )
395 a = obj.compress( data[:3000] )
396 b = obj.flush( sync )
397 c = obj.compress( data[3000:] )
398 d = obj.flush()
Guido van Rossum776152b2007-05-22 22:44:07 +0000399 self.assertEqual(zlib.decompress(b''.join([a,b,c,d])),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000400 data, ("Decompress failed: flush "
401 "mode=%i, level=%i") % (sync, level))
402 del obj
403
404 def test_odd_flush(self):
405 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
406 import random
407
408 if hasattr(zlib, 'Z_SYNC_FLUSH'):
409 # Testing on 17K of "random" data
410
411 # Create compressor and decompressor objects
Neil Schemenauer6412b122004-06-05 19:34:28 +0000412 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000413 dco = zlib.decompressobj()
414
415 # Try 17K of data
416 # generate random data stream
417 try:
418 # In 2.3 and later, WichmannHill is the RNG of the bug report
419 gen = random.WichmannHill()
420 except AttributeError:
421 try:
422 # 2.2 called it Random
423 gen = random.Random()
424 except AttributeError:
425 # others might simply have a single RNG
426 gen = random
427 gen.seed(1)
428 data = genblock(1, 17 * 1024, generator=gen)
429
430 # compress, sync-flush, and decompress
431 first = co.compress(data)
432 second = co.flush(zlib.Z_SYNC_FLUSH)
433 expanded = dco.decompress(first + second)
434
435 # if decompressed data is different from the input data, choke.
436 self.assertEqual(expanded, data, "17K random source doesn't match")
437
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000438 def test_empty_flush(self):
439 # Test that calling .flush() on unused objects works.
440 # (Bug #1083110 -- calling .flush() on decompress objects
441 # caused a core dump.)
442
443 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000444 self.assertTrue(co.flush()) # Returns a zlib header
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000445 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000446 self.assertEqual(dco.flush(), b"") # Returns nothing
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000447
Antoine Pitrouc09c92f2010-05-11 23:36:40 +0000448 def test_decompress_incomplete_stream(self):
449 # This is 'foo', deflated
450 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
451 # For the record
452 self.assertEqual(zlib.decompress(x), b'foo')
453 self.assertRaises(zlib.error, zlib.decompress, x[:-5])
454 # Omitting the stream end works with decompressor objects
455 # (see issue #8672).
456 dco = zlib.decompressobj()
457 y = dco.decompress(x[:-5])
458 y += dco.flush()
459 self.assertEqual(y, b'foo')
460
Nadeem Vawda1c385462011-08-13 15:22:40 +0200461 def test_decompress_eof(self):
462 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' # 'foo'
463 dco = zlib.decompressobj()
464 self.assertFalse(dco.eof)
465 dco.decompress(x[:-5])
466 self.assertFalse(dco.eof)
467 dco.decompress(x[-5:])
468 self.assertTrue(dco.eof)
469 dco.flush()
470 self.assertTrue(dco.eof)
471
472 def test_decompress_eof_incomplete_stream(self):
473 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' # 'foo'
474 dco = zlib.decompressobj()
475 self.assertFalse(dco.eof)
476 dco.decompress(x[:-5])
477 self.assertFalse(dco.eof)
478 dco.flush()
479 self.assertFalse(dco.eof)
480
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000481 if hasattr(zlib.compressobj(), "copy"):
482 def test_compresscopy(self):
483 # Test copying a compression object
484 data0 = HAMLET_SCENE
Guido van Rossum776152b2007-05-22 22:44:07 +0000485 data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000486 c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
487 bufs0 = []
488 bufs0.append(c0.compress(data0))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000489
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000490 c1 = c0.copy()
491 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000492
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000493 bufs0.append(c0.compress(data0))
494 bufs0.append(c0.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000495 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000496
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000497 bufs1.append(c1.compress(data1))
498 bufs1.append(c1.flush())
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(zlib.decompress(s0),data0+data0)
502 self.assertEqual(zlib.decompress(s1),data0+data1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000503
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000504 def test_badcompresscopy(self):
505 # Test copying a compression object in an inconsistent state
506 c = zlib.compressobj()
507 c.compress(HAMLET_SCENE)
508 c.flush()
509 self.assertRaises(ValueError, c.copy)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000510
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000511 if hasattr(zlib.decompressobj(), "copy"):
512 def test_decompresscopy(self):
513 # Test copying a decompression object
514 data = HAMLET_SCENE
515 comp = zlib.compress(data)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000516 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000517 self.assertIsInstance(comp, bytes)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000518
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000519 d0 = zlib.decompressobj()
520 bufs0 = []
521 bufs0.append(d0.decompress(comp[:32]))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000522
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000523 d1 = d0.copy()
524 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000525
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000526 bufs0.append(d0.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000527 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000528
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000529 bufs1.append(d1.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000530 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000531
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000532 self.assertEqual(s0,s1)
533 self.assertEqual(s0,data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000534
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000535 def test_baddecompresscopy(self):
536 # Test copying a compression object in an inconsistent state
537 data = zlib.compress(HAMLET_SCENE)
538 d = zlib.decompressobj()
539 d.decompress(data)
540 d.flush()
541 self.assertRaises(ValueError, d.copy)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000542
Antoine Pitrou89562712010-05-07 17:04:02 +0000543 # Memory use of the following functions takes into account overallocation
544
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200545 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000546 def test_big_compress_buffer(self, size):
547 c = zlib.compressobj(1)
548 compress = lambda s: c.compress(s) + c.flush()
549 self.check_big_compress_buffer(size, compress)
550
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200551 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000552 def test_big_decompress_buffer(self, size):
553 d = zlib.decompressobj()
554 decompress = lambda s: d.decompress(s) + d.flush()
555 self.check_big_decompress_buffer(size, decompress)
556
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200557 @bigmemtest(size=_4G + 100, memuse=1)
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200558 def test_length_overflow(self, size):
559 if size < _4G + 100:
560 self.skipTest("not enough free memory, need at least 4 GB")
561 data = b'x' * size
Nadeem Vawda1161a9c2011-05-15 00:48:24 +0200562 c = zlib.compressobj(1)
563 d = zlib.decompressobj()
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200564 try:
Nadeem Vawda1161a9c2011-05-15 00:48:24 +0200565 self.assertRaises(OverflowError, c.compress, data)
566 self.assertRaises(OverflowError, d.decompress, data)
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200567 finally:
568 data = None
569
Antoine Pitrou89562712010-05-07 17:04:02 +0000570
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000571def genblock(seed, length, step=1024, generator=random):
572 """length-byte stream of random data from a seed (in step-byte blocks)."""
573 if seed is not None:
574 generator.seed(seed)
575 randint = generator.randint
576 if length < step or step < 2:
577 step = length
Guido van Rossum776152b2007-05-22 22:44:07 +0000578 blocks = bytes()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000579 for i in range(0, length, step):
Guido van Rossum776152b2007-05-22 22:44:07 +0000580 blocks += bytes(randint(0, 255) for x in range(step))
581 return blocks
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000582
583
584
585def choose_lines(source, number, seed=None, generator=random):
586 """Return a list of number lines randomly chosen from the source"""
587 if seed is not None:
588 generator.seed(seed)
589 sources = source.split('\n')
590 return [generator.choice(sources) for n in range(number)]
591
592
593
Guido van Rossum776152b2007-05-22 22:44:07 +0000594HAMLET_SCENE = b"""
Fred Drake004d5e62000-10-23 17:22:08 +0000595LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000596
597 O, fear me not.
598 I stay too long: but here my father comes.
599
600 Enter POLONIUS
601
602 A double blessing is a double grace,
603 Occasion smiles upon a second leave.
604
Fred Drake004d5e62000-10-23 17:22:08 +0000605LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000606
607 Yet here, Laertes! aboard, aboard, for shame!
608 The wind sits in the shoulder of your sail,
609 And you are stay'd for. There; my blessing with thee!
610 And these few precepts in thy memory
611 See thou character. Give thy thoughts no tongue,
612 Nor any unproportioned thought his act.
613 Be thou familiar, but by no means vulgar.
614 Those friends thou hast, and their adoption tried,
615 Grapple them to thy soul with hoops of steel;
616 But do not dull thy palm with entertainment
617 Of each new-hatch'd, unfledged comrade. Beware
618 Of entrance to a quarrel, but being in,
619 Bear't that the opposed may beware of thee.
620 Give every man thy ear, but few thy voice;
621 Take each man's censure, but reserve thy judgment.
622 Costly thy habit as thy purse can buy,
623 But not express'd in fancy; rich, not gaudy;
624 For the apparel oft proclaims the man,
625 And they in France of the best rank and station
626 Are of a most select and generous chief in that.
627 Neither a borrower nor a lender be;
628 For loan oft loses both itself and friend,
629 And borrowing dulls the edge of husbandry.
630 This above all: to thine ownself be true,
631 And it must follow, as the night the day,
632 Thou canst not then be false to any man.
633 Farewell: my blessing season this in thee!
634
Fred Drake004d5e62000-10-23 17:22:08 +0000635LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000636
637 Most humbly do I take my leave, my lord.
638
Fred Drake004d5e62000-10-23 17:22:08 +0000639LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000640
641 The time invites you; go; your servants tend.
642
Fred Drake004d5e62000-10-23 17:22:08 +0000643LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000644
645 Farewell, Ophelia; and remember well
646 What I have said to you.
647
Fred Drake004d5e62000-10-23 17:22:08 +0000648OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000649
650 'Tis in my memory lock'd,
651 And you yourself shall keep the key of it.
652
Fred Drake004d5e62000-10-23 17:22:08 +0000653LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000654
655 Farewell.
656"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000657
658
659def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000660 support.run_unittest(
Nadeem Vawda64d25dd2011-09-12 00:04:13 +0200661 VersionTestCase,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000662 ChecksumTestCase,
Antoine Pitrouf3d22752011-02-21 18:09:00 +0000663 ChecksumBigBufferTestCase,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000664 ExceptionTestCase,
665 CompressTestCase,
666 CompressObjectTestCase
667 )
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000668
669if __name__ == "__main__":
Guido van Rossum776152b2007-05-22 22:44:07 +0000670 unittest.main() # XXX
671 ###test_main()