blob: 852857bb41c7ad34f6d9d7a7e73b98a6d13240fa [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)
196 finally:
197 data = None
198
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000199
Antoine Pitrou89562712010-05-07 17:04:02 +0000200class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000201 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000202 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000203 # straightforward compress/decompress objects
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000204 datasrc = HAMLET_SCENE * 128
205 datazip = zlib.compress(datasrc)
206 # should compress both bytes and bytearray data
207 for data in (datasrc, bytearray(datasrc)):
208 co = zlib.compressobj()
209 x1 = co.compress(data)
210 x2 = co.flush()
211 self.assertRaises(zlib.error, co.flush) # second flush should not work
212 self.assertEqual(x1 + x2, datazip)
213 for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))):
214 dco = zlib.decompressobj()
215 y1 = dco.decompress(v1 + v2)
216 y2 = dco.flush()
217 self.assertEqual(data, y1 + y2)
218 self.assertIsInstance(dco.unconsumed_tail, bytes)
219 self.assertIsInstance(dco.unused_data, bytes)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000220
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000221 def test_compressoptions(self):
222 # specify lots of options to compressobj()
223 level = 2
224 method = zlib.DEFLATED
225 wbits = -12
226 memlevel = 9
227 strategy = zlib.Z_FILTERED
228 co = zlib.compressobj(level, method, wbits, memlevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000229 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000230 x2 = co.flush()
231 dco = zlib.decompressobj(wbits)
232 y1 = dco.decompress(x1 + x2)
233 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000234 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000235
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000236 def test_compressincremental(self):
237 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000238 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000239 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000240 bufs = []
241 for i in range(0, len(data), 256):
242 bufs.append(co.compress(data[i:i+256]))
243 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000244 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000245
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000246 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000247 y1 = dco.decompress(b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000248 y2 = dco.flush()
249 self.assertEqual(data, y1 + y2)
250
Neil Schemenauer6412b122004-06-05 19:34:28 +0000251 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000252 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000253 source = source or HAMLET_SCENE
254 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000255 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000256 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000257 for i in range(0, len(data), cx):
258 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000259 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000260 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000261
Gregory P. Smith693fc462008-09-06 20:13:06 +0000262 decombuf = zlib.decompress(combuf)
263 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000264 self.assertIsInstance(decombuf, bytes)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000265
266 self.assertEqual(data, decombuf)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000267
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000268 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000269 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000270 for i in range(0, len(combuf), dcx):
271 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000272 self.assertEqual(b'', dco.unconsumed_tail, ########
273 "(A) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000274 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000275 self.assertEqual(b'', dco.unused_data)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000276 if flush:
277 bufs.append(dco.flush())
278 else:
279 while True:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000280 chunk = dco.decompress(b'')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000281 if chunk:
282 bufs.append(chunk)
283 else:
284 break
Guido van Rossum776152b2007-05-22 22:44:07 +0000285 self.assertEqual(b'', dco.unconsumed_tail, ########
286 "(B) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000287 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000288 self.assertEqual(b'', dco.unused_data)
Guido van Rossum776152b2007-05-22 22:44:07 +0000289 self.assertEqual(data, b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000290 # Failure means: "decompressobj with init options failed"
291
Neil Schemenauer6412b122004-06-05 19:34:28 +0000292 def test_decompincflush(self):
293 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000294
Neil Schemenauer6412b122004-06-05 19:34:28 +0000295 def test_decompimax(self, source=None, cx=256, dcx=64):
296 # compress in steps, decompress in length-restricted steps
297 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000298 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000299 data = source * 128
300 co = zlib.compressobj()
301 bufs = []
302 for i in range(0, len(data), cx):
303 bufs.append(co.compress(data[i:i+cx]))
304 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000305 combuf = b''.join(bufs)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000306 self.assertEqual(data, zlib.decompress(combuf),
307 'compressed data failure')
308
309 dco = zlib.decompressobj()
310 bufs = []
311 cb = combuf
312 while cb:
313 #max_length = 1 + len(cb)//10
314 chunk = dco.decompress(cb, dcx)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000315 self.assertFalse(len(chunk) > dcx,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000316 'chunk too big (%d>%d)' % (len(chunk), dcx))
317 bufs.append(chunk)
318 cb = dco.unconsumed_tail
319 bufs.append(dco.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000320 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000321
322 def test_decompressmaxlen(self, flush=False):
323 # Check a decompression object with max_length specified
324 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000325 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000326 bufs = []
327 for i in range(0, len(data), 256):
328 bufs.append(co.compress(data[i:i+256]))
329 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000330 combuf = b''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000331 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000332 'compressed data failure')
333
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000334 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000335 bufs = []
336 cb = combuf
337 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000338 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000339 chunk = dco.decompress(cb, max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000340 self.assertFalse(len(chunk) > max_length,
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000341 'chunk too big (%d>%d)' % (len(chunk),max_length))
342 bufs.append(chunk)
343 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000344 if flush:
345 bufs.append(dco.flush())
346 else:
347 while chunk:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000348 chunk = dco.decompress(b'', max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000349 self.assertFalse(len(chunk) > max_length,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000350 'chunk too big (%d>%d)' % (len(chunk),max_length))
351 bufs.append(chunk)
Guido van Rossum776152b2007-05-22 22:44:07 +0000352 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000353
Neil Schemenauer6412b122004-06-05 19:34:28 +0000354 def test_decompressmaxlenflush(self):
355 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000356
357 def test_maxlenmisc(self):
358 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000359 dco = zlib.decompressobj()
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000360 self.assertRaises(ValueError, dco.decompress, b"", -1)
Guido van Rossum776152b2007-05-22 22:44:07 +0000361 self.assertEqual(b'', dco.unconsumed_tail)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000362
Nadeem Vawda7619e882011-05-14 14:05:20 +0200363 def test_clear_unconsumed_tail(self):
364 # Issue #12050: calling decompress() without providing max_length
365 # should clear the unconsumed_tail attribute.
366 cdata = b"x\x9cKLJ\x06\x00\x02M\x01" # "abc"
367 dco = zlib.decompressobj()
368 ddata = dco.decompress(cdata, 1)
369 ddata += dco.decompress(dco.unconsumed_tail)
370 self.assertEqual(dco.unconsumed_tail, b"")
371
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000372 def test_flushes(self):
373 # Test flush() with the various options, using all the
374 # different levels in order to provide more variations.
375 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH']
376 sync_opt = [getattr(zlib, opt) for opt in sync_opt
377 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000378 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000379
380 for sync in sync_opt:
381 for level in range(10):
382 obj = zlib.compressobj( level )
383 a = obj.compress( data[:3000] )
384 b = obj.flush( sync )
385 c = obj.compress( data[3000:] )
386 d = obj.flush()
Guido van Rossum776152b2007-05-22 22:44:07 +0000387 self.assertEqual(zlib.decompress(b''.join([a,b,c,d])),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000388 data, ("Decompress failed: flush "
389 "mode=%i, level=%i") % (sync, level))
390 del obj
391
392 def test_odd_flush(self):
393 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
394 import random
395
396 if hasattr(zlib, 'Z_SYNC_FLUSH'):
397 # Testing on 17K of "random" data
398
399 # Create compressor and decompressor objects
Neil Schemenauer6412b122004-06-05 19:34:28 +0000400 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000401 dco = zlib.decompressobj()
402
403 # Try 17K of data
404 # generate random data stream
405 try:
406 # In 2.3 and later, WichmannHill is the RNG of the bug report
407 gen = random.WichmannHill()
408 except AttributeError:
409 try:
410 # 2.2 called it Random
411 gen = random.Random()
412 except AttributeError:
413 # others might simply have a single RNG
414 gen = random
415 gen.seed(1)
416 data = genblock(1, 17 * 1024, generator=gen)
417
418 # compress, sync-flush, and decompress
419 first = co.compress(data)
420 second = co.flush(zlib.Z_SYNC_FLUSH)
421 expanded = dco.decompress(first + second)
422
423 # if decompressed data is different from the input data, choke.
424 self.assertEqual(expanded, data, "17K random source doesn't match")
425
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000426 def test_empty_flush(self):
427 # Test that calling .flush() on unused objects works.
428 # (Bug #1083110 -- calling .flush() on decompress objects
429 # caused a core dump.)
430
431 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000432 self.assertTrue(co.flush()) # Returns a zlib header
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000433 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000434 self.assertEqual(dco.flush(), b"") # Returns nothing
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000435
Antoine Pitrouc09c92f2010-05-11 23:36:40 +0000436 def test_decompress_incomplete_stream(self):
437 # This is 'foo', deflated
438 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
439 # For the record
440 self.assertEqual(zlib.decompress(x), b'foo')
441 self.assertRaises(zlib.error, zlib.decompress, x[:-5])
442 # Omitting the stream end works with decompressor objects
443 # (see issue #8672).
444 dco = zlib.decompressobj()
445 y = dco.decompress(x[:-5])
446 y += dco.flush()
447 self.assertEqual(y, b'foo')
448
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000449 if hasattr(zlib.compressobj(), "copy"):
450 def test_compresscopy(self):
451 # Test copying a compression object
452 data0 = HAMLET_SCENE
Guido van Rossum776152b2007-05-22 22:44:07 +0000453 data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000454 c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
455 bufs0 = []
456 bufs0.append(c0.compress(data0))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000457
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000458 c1 = c0.copy()
459 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000460
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000461 bufs0.append(c0.compress(data0))
462 bufs0.append(c0.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000463 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000464
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000465 bufs1.append(c1.compress(data1))
466 bufs1.append(c1.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000467 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000468
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000469 self.assertEqual(zlib.decompress(s0),data0+data0)
470 self.assertEqual(zlib.decompress(s1),data0+data1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000471
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000472 def test_badcompresscopy(self):
473 # Test copying a compression object in an inconsistent state
474 c = zlib.compressobj()
475 c.compress(HAMLET_SCENE)
476 c.flush()
477 self.assertRaises(ValueError, c.copy)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000478
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000479 if hasattr(zlib.decompressobj(), "copy"):
480 def test_decompresscopy(self):
481 # Test copying a decompression object
482 data = HAMLET_SCENE
483 comp = zlib.compress(data)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000484 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000485 self.assertIsInstance(comp, bytes)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000486
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000487 d0 = zlib.decompressobj()
488 bufs0 = []
489 bufs0.append(d0.decompress(comp[:32]))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000490
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000491 d1 = d0.copy()
492 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000493
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000494 bufs0.append(d0.decompress(comp[32:]))
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(d1.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000498 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000499
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000500 self.assertEqual(s0,s1)
501 self.assertEqual(s0,data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000502
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000503 def test_baddecompresscopy(self):
504 # Test copying a compression object in an inconsistent state
505 data = zlib.compress(HAMLET_SCENE)
506 d = zlib.decompressobj()
507 d.decompress(data)
508 d.flush()
509 self.assertRaises(ValueError, d.copy)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000510
Antoine Pitrou89562712010-05-07 17:04:02 +0000511 # Memory use of the following functions takes into account overallocation
512
513 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=3)
514 def test_big_compress_buffer(self, size):
515 c = zlib.compressobj(1)
516 compress = lambda s: c.compress(s) + c.flush()
517 self.check_big_compress_buffer(size, compress)
518
519 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=2)
520 def test_big_decompress_buffer(self, size):
521 d = zlib.decompressobj()
522 decompress = lambda s: d.decompress(s) + d.flush()
523 self.check_big_decompress_buffer(size, decompress)
524
525
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000526def genblock(seed, length, step=1024, generator=random):
527 """length-byte stream of random data from a seed (in step-byte blocks)."""
528 if seed is not None:
529 generator.seed(seed)
530 randint = generator.randint
531 if length < step or step < 2:
532 step = length
Guido van Rossum776152b2007-05-22 22:44:07 +0000533 blocks = bytes()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000534 for i in range(0, length, step):
Guido van Rossum776152b2007-05-22 22:44:07 +0000535 blocks += bytes(randint(0, 255) for x in range(step))
536 return blocks
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000537
538
539
540def choose_lines(source, number, seed=None, generator=random):
541 """Return a list of number lines randomly chosen from the source"""
542 if seed is not None:
543 generator.seed(seed)
544 sources = source.split('\n')
545 return [generator.choice(sources) for n in range(number)]
546
547
548
Guido van Rossum776152b2007-05-22 22:44:07 +0000549HAMLET_SCENE = b"""
Fred Drake004d5e62000-10-23 17:22:08 +0000550LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000551
552 O, fear me not.
553 I stay too long: but here my father comes.
554
555 Enter POLONIUS
556
557 A double blessing is a double grace,
558 Occasion smiles upon a second leave.
559
Fred Drake004d5e62000-10-23 17:22:08 +0000560LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000561
562 Yet here, Laertes! aboard, aboard, for shame!
563 The wind sits in the shoulder of your sail,
564 And you are stay'd for. There; my blessing with thee!
565 And these few precepts in thy memory
566 See thou character. Give thy thoughts no tongue,
567 Nor any unproportioned thought his act.
568 Be thou familiar, but by no means vulgar.
569 Those friends thou hast, and their adoption tried,
570 Grapple them to thy soul with hoops of steel;
571 But do not dull thy palm with entertainment
572 Of each new-hatch'd, unfledged comrade. Beware
573 Of entrance to a quarrel, but being in,
574 Bear't that the opposed may beware of thee.
575 Give every man thy ear, but few thy voice;
576 Take each man's censure, but reserve thy judgment.
577 Costly thy habit as thy purse can buy,
578 But not express'd in fancy; rich, not gaudy;
579 For the apparel oft proclaims the man,
580 And they in France of the best rank and station
581 Are of a most select and generous chief in that.
582 Neither a borrower nor a lender be;
583 For loan oft loses both itself and friend,
584 And borrowing dulls the edge of husbandry.
585 This above all: to thine ownself be true,
586 And it must follow, as the night the day,
587 Thou canst not then be false to any man.
588 Farewell: my blessing season this in thee!
589
Fred Drake004d5e62000-10-23 17:22:08 +0000590LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000591
592 Most humbly do I take my leave, my lord.
593
Fred Drake004d5e62000-10-23 17:22:08 +0000594LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000595
596 The time invites you; go; your servants tend.
597
Fred Drake004d5e62000-10-23 17:22:08 +0000598LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000599
600 Farewell, Ophelia; and remember well
601 What I have said to you.
602
Fred Drake004d5e62000-10-23 17:22:08 +0000603OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000604
605 'Tis in my memory lock'd,
606 And you yourself shall keep the key of it.
607
Fred Drake004d5e62000-10-23 17:22:08 +0000608LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000609
610 Farewell.
611"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000612
613
614def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000615 support.run_unittest(
Walter Dörwald21d3a322003-05-01 17:45:56 +0000616 ChecksumTestCase,
Antoine Pitrouf3d22752011-02-21 18:09:00 +0000617 ChecksumBigBufferTestCase,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000618 ExceptionTestCase,
619 CompressTestCase,
620 CompressObjectTestCase
621 )
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000622
623if __name__ == "__main__":
Guido van Rossum776152b2007-05-22 22:44:07 +0000624 unittest.main() # XXX
625 ###test_main()