blob: fb62081f1db914287b6e5da10d2bdc385726cbf7 [file] [log] [blame]
Guido van Rossum7d9ea502003-02-03 20:45:52 +00001import unittest
Victor Stinnerf9fb4342011-05-03 15:19:23 +02002from test.test_support import TESTFN, run_unittest, import_module, unlink, requires
Gregory P. Smithc856fa82008-03-18 22:27:41 +00003import binascii
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00004import random
Victor Stinner7fd90c42011-05-04 21:27:39 +02005from test.test_support import precisionbigmemtest, _1G, _4G
Victor Stinnerf9fb4342011-05-03 15:19:23 +02006import sys
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00007
Victor Stinnerf9fb4342011-05-03 15:19:23 +02008try:
9 import mmap
10except ImportError:
11 mmap = None
12
13zlib = import_module('zlib')
R. David Murray3db8a342009-03-30 23:05:48 +000014
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020015requires_Compress_copy = unittest.skipUnless(
16 hasattr(zlib.compressobj(), "copy"),
17 'requires Compress.copy()')
18requires_Decompress_copy = unittest.skipUnless(
19 hasattr(zlib.decompressobj(), "copy"),
20 'requires Decompress.copy()')
21
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000022
Guido van Rossum7d9ea502003-02-03 20:45:52 +000023class ChecksumTestCase(unittest.TestCase):
24 # checksum test cases
25 def test_crc32start(self):
26 self.assertEqual(zlib.crc32(""), zlib.crc32("", 0))
Benjamin Peterson5c8da862009-06-30 22:57:08 +000027 self.assertTrue(zlib.crc32("abc", 0xffffffff))
Andrew M. Kuchlingfcfc8d52001-08-10 15:50:11 +000028
Guido van Rossum7d9ea502003-02-03 20:45:52 +000029 def test_crc32empty(self):
30 self.assertEqual(zlib.crc32("", 0), 0)
31 self.assertEqual(zlib.crc32("", 1), 1)
32 self.assertEqual(zlib.crc32("", 432), 432)
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000033
Guido van Rossum7d9ea502003-02-03 20:45:52 +000034 def test_adler32start(self):
35 self.assertEqual(zlib.adler32(""), zlib.adler32("", 1))
Benjamin Peterson5c8da862009-06-30 22:57:08 +000036 self.assertTrue(zlib.adler32("abc", 0xffffffff))
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000037
Guido van Rossum7d9ea502003-02-03 20:45:52 +000038 def test_adler32empty(self):
39 self.assertEqual(zlib.adler32("", 0), 0)
40 self.assertEqual(zlib.adler32("", 1), 1)
41 self.assertEqual(zlib.adler32("", 432), 432)
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000042
Guido van Rossum7d9ea502003-02-03 20:45:52 +000043 def assertEqual32(self, seen, expected):
44 # 32-bit values masked -- checksums on 32- vs 64- bit machines
45 # This is important if bit 31 (0x08000000L) is set.
46 self.assertEqual(seen & 0x0FFFFFFFFL, expected & 0x0FFFFFFFFL)
47
48 def test_penguins(self):
49 self.assertEqual32(zlib.crc32("penguin", 0), 0x0e5c1a120L)
50 self.assertEqual32(zlib.crc32("penguin", 1), 0x43b6aa94)
51 self.assertEqual32(zlib.adler32("penguin", 0), 0x0bcf02f6)
52 self.assertEqual32(zlib.adler32("penguin", 1), 0x0bd602f7)
53
54 self.assertEqual(zlib.crc32("penguin"), zlib.crc32("penguin", 0))
55 self.assertEqual(zlib.adler32("penguin"),zlib.adler32("penguin",1))
56
Gregory P. Smithf48f9d32008-03-17 18:48:05 +000057 def test_abcdefghijklmnop(self):
58 """test issue1202 compliance: signed crc32, adler32 in 2.x"""
59 foo = 'abcdefghijklmnop'
60 # explicitly test signed behavior
61 self.assertEqual(zlib.crc32(foo), -1808088941)
62 self.assertEqual(zlib.crc32('spam'), 1138425661)
63 self.assertEqual(zlib.adler32(foo+foo), -721416943)
64 self.assertEqual(zlib.adler32('spam'), 72286642)
65
Gregory P. Smithc856fa82008-03-18 22:27:41 +000066 def test_same_as_binascii_crc32(self):
67 foo = 'abcdefghijklmnop'
68 self.assertEqual(binascii.crc32(foo), zlib.crc32(foo))
69 self.assertEqual(binascii.crc32('spam'), zlib.crc32('spam'))
70
Gregory P. Smith88440962008-03-25 06:12:45 +000071 def test_negative_crc_iv_input(self):
72 # The range of valid input values for the crc state should be
73 # -2**31 through 2**32-1 to allow inputs artifically constrained
74 # to a signed 32-bit integer.
75 self.assertEqual(zlib.crc32('ham', -1), zlib.crc32('ham', 0xffffffffL))
76 self.assertEqual(zlib.crc32('spam', -3141593),
77 zlib.crc32('spam', 0xffd01027L))
78 self.assertEqual(zlib.crc32('spam', -(2**31)),
79 zlib.crc32('spam', (2**31)))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000080
81
82class ExceptionTestCase(unittest.TestCase):
83 # make sure we generate some expected errors
Armin Rigoec560192007-10-15 07:48:35 +000084 def test_badlevel(self):
85 # specifying compression level out of range causes an error
86 # (but -1 is Z_DEFAULT_COMPRESSION and apparently the zlib
87 # accepts 0 too)
88 self.assertRaises(zlib.error, zlib.compress, 'ERROR', 10)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000089
90 def test_badcompressobj(self):
91 # verify failure on building compress object with bad params
Neil Schemenauer94afd3e2004-06-05 19:02:52 +000092 self.assertRaises(ValueError, zlib.compressobj, 1, zlib.DEFLATED, 0)
Armin Rigoec560192007-10-15 07:48:35 +000093 # specifying total bits too large causes an error
94 self.assertRaises(ValueError,
95 zlib.compressobj, 1, zlib.DEFLATED, zlib.MAX_WBITS + 1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000096
97 def test_baddecompressobj(self):
98 # verify failure on building decompress object with bad params
Antoine Pitrou3b4c9892010-04-06 17:21:09 +000099 self.assertRaises(ValueError, zlib.decompressobj, -1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000100
Gregory P. Smith79e42a02008-04-09 00:25:17 +0000101 def test_decompressobj_badflush(self):
102 # verify failure on calling decompressobj.flush with bad params
103 self.assertRaises(ValueError, zlib.decompressobj().flush, 0)
104 self.assertRaises(ValueError, zlib.decompressobj().flush, -1)
105
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000106
Antoine Pitrou3843cd82010-05-07 16:50:34 +0000107class BaseCompressTestCase(object):
108 def check_big_compress_buffer(self, size, compress_func):
109 _1M = 1024 * 1024
110 fmt = "%%0%dx" % (2 * _1M)
111 # Generate 10MB worth of random, and expand it by repeating it.
112 # The assumption is that zlib's memory is not big enough to exploit
113 # such spread out redundancy.
114 data = ''.join([binascii.a2b_hex(fmt % random.getrandbits(8 * _1M))
115 for i in range(10)])
116 data = data * (size // len(data) + 1)
117 try:
118 compress_func(data)
119 finally:
120 # Release memory
121 data = None
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000122
Antoine Pitrou3843cd82010-05-07 16:50:34 +0000123 def check_big_decompress_buffer(self, size, decompress_func):
124 data = 'x' * size
125 try:
126 compressed = zlib.compress(data, 1)
127 finally:
128 # Release memory
129 data = None
130 data = decompress_func(compressed)
131 # Sanity check
132 try:
133 self.assertEqual(len(data), size)
134 self.assertEqual(len(data.strip('x')), 0)
135 finally:
136 data = None
137
138
139class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000140 # Test compression in one go (whole message compression)
141 def test_speech(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000142 x = zlib.compress(HAMLET_SCENE)
143 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000144
145 def test_speech128(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000146 # compress more data
147 data = HAMLET_SCENE * 128
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000148 x = zlib.compress(data)
149 self.assertEqual(zlib.decompress(x), data)
150
Antoine Pitroufc3bfad2010-05-11 23:42:28 +0000151 def test_incomplete_stream(self):
152 # An useful error message is given
153 x = zlib.compress(HAMLET_SCENE)
154 self.assertRaisesRegexp(zlib.error,
155 "Error -5 while decompressing data: incomplete or truncated stream",
156 zlib.decompress, x[:-1])
157
Antoine Pitrou3843cd82010-05-07 16:50:34 +0000158 # Memory use of the following functions takes into account overallocation
159
160 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=3)
161 def test_big_compress_buffer(self, size):
162 compress = lambda s: zlib.compress(s, 1)
163 self.check_big_compress_buffer(size, compress)
164
165 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=2)
166 def test_big_decompress_buffer(self, size):
167 self.check_big_decompress_buffer(size, zlib.decompress)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000168
169
Antoine Pitrou3843cd82010-05-07 16:50:34 +0000170class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000171 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000172 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000173 # straightforward compress/decompress objects
174 data = HAMLET_SCENE * 128
175 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000176 x1 = co.compress(data)
177 x2 = co.flush()
178 self.assertRaises(zlib.error, co.flush) # second flush should not work
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000179 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000180 y1 = dco.decompress(x1 + x2)
181 y2 = dco.flush()
182 self.assertEqual(data, y1 + y2)
183
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000184 def test_compressoptions(self):
185 # specify lots of options to compressobj()
186 level = 2
187 method = zlib.DEFLATED
188 wbits = -12
189 memlevel = 9
190 strategy = zlib.Z_FILTERED
191 co = zlib.compressobj(level, method, wbits, memlevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000192 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000193 x2 = co.flush()
194 dco = zlib.decompressobj(wbits)
195 y1 = dco.decompress(x1 + x2)
196 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000197 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000198
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000199 def test_compressincremental(self):
200 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000201 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000202 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000203 bufs = []
204 for i in range(0, len(data), 256):
205 bufs.append(co.compress(data[i:i+256]))
206 bufs.append(co.flush())
207 combuf = ''.join(bufs)
208
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000209 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000210 y1 = dco.decompress(''.join(bufs))
211 y2 = dco.flush()
212 self.assertEqual(data, y1 + y2)
213
Neil Schemenauer6412b122004-06-05 19:34:28 +0000214 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000215 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000216 source = source or HAMLET_SCENE
217 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000218 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000219 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000220 for i in range(0, len(data), cx):
221 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000222 bufs.append(co.flush())
223 combuf = ''.join(bufs)
224
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000225 self.assertEqual(data, zlib.decompress(combuf))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000226
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000227 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000228 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000229 for i in range(0, len(combuf), dcx):
230 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000231 self.assertEqual('', dco.unconsumed_tail, ########
232 "(A) uct should be '': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000233 len(dco.unconsumed_tail))
234 if flush:
235 bufs.append(dco.flush())
236 else:
237 while True:
238 chunk = dco.decompress('')
239 if chunk:
240 bufs.append(chunk)
241 else:
242 break
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000243 self.assertEqual('', dco.unconsumed_tail, ########
Neil Schemenauer6412b122004-06-05 19:34:28 +0000244 "(B) uct should be '': not %d long" %
245 len(dco.unconsumed_tail))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000246 self.assertEqual(data, ''.join(bufs))
247 # Failure means: "decompressobj with init options failed"
248
Neil Schemenauer6412b122004-06-05 19:34:28 +0000249 def test_decompincflush(self):
250 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000251
Neil Schemenauer6412b122004-06-05 19:34:28 +0000252 def test_decompimax(self, source=None, cx=256, dcx=64):
253 # compress in steps, decompress in length-restricted steps
254 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000255 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000256 data = source * 128
257 co = zlib.compressobj()
258 bufs = []
259 for i in range(0, len(data), cx):
260 bufs.append(co.compress(data[i:i+cx]))
261 bufs.append(co.flush())
262 combuf = ''.join(bufs)
263 self.assertEqual(data, zlib.decompress(combuf),
264 'compressed data failure')
265
266 dco = zlib.decompressobj()
267 bufs = []
268 cb = combuf
269 while cb:
270 #max_length = 1 + len(cb)//10
271 chunk = dco.decompress(cb, dcx)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000272 self.assertFalse(len(chunk) > dcx,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000273 'chunk too big (%d>%d)' % (len(chunk), dcx))
274 bufs.append(chunk)
275 cb = dco.unconsumed_tail
276 bufs.append(dco.flush())
277 self.assertEqual(data, ''.join(bufs), 'Wrong data retrieved')
278
279 def test_decompressmaxlen(self, flush=False):
280 # Check a decompression object with max_length specified
281 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000282 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000283 bufs = []
284 for i in range(0, len(data), 256):
285 bufs.append(co.compress(data[i:i+256]))
286 bufs.append(co.flush())
287 combuf = ''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000288 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000289 'compressed data failure')
290
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000291 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000292 bufs = []
293 cb = combuf
294 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000295 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000296 chunk = dco.decompress(cb, max_length)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000297 self.assertFalse(len(chunk) > max_length,
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000298 'chunk too big (%d>%d)' % (len(chunk),max_length))
299 bufs.append(chunk)
300 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000301 if flush:
302 bufs.append(dco.flush())
303 else:
304 while chunk:
305 chunk = dco.decompress('', max_length)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000306 self.assertFalse(len(chunk) > max_length,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000307 'chunk too big (%d>%d)' % (len(chunk),max_length))
308 bufs.append(chunk)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000309 self.assertEqual(data, ''.join(bufs), 'Wrong data retrieved')
310
Neil Schemenauer6412b122004-06-05 19:34:28 +0000311 def test_decompressmaxlenflush(self):
312 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000313
314 def test_maxlenmisc(self):
315 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000316 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000317 self.assertRaises(ValueError, dco.decompress, "", -1)
318 self.assertEqual('', dco.unconsumed_tail)
319
Nadeem Vawda0cc4fd92011-05-14 14:29:07 +0200320 def test_clear_unconsumed_tail(self):
321 # Issue #12050: calling decompress() without providing max_length
322 # should clear the unconsumed_tail attribute.
323 cdata = "x\x9cKLJ\x06\x00\x02M\x01" # "abc"
324 dco = zlib.decompressobj()
325 ddata = dco.decompress(cdata, 1)
326 ddata += dco.decompress(dco.unconsumed_tail)
327 self.assertEqual(dco.unconsumed_tail, "")
328
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000329 def test_flushes(self):
330 # Test flush() with the various options, using all the
331 # different levels in order to provide more variations.
332 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH']
333 sync_opt = [getattr(zlib, opt) for opt in sync_opt
334 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000335 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000336
337 for sync in sync_opt:
338 for level in range(10):
339 obj = zlib.compressobj( level )
340 a = obj.compress( data[:3000] )
341 b = obj.flush( sync )
342 c = obj.compress( data[3000:] )
343 d = obj.flush()
344 self.assertEqual(zlib.decompress(''.join([a,b,c,d])),
345 data, ("Decompress failed: flush "
346 "mode=%i, level=%i") % (sync, level))
347 del obj
348
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200349 @unittest.skipUnless(hasattr(zlib, 'Z_SYNC_FLUSH'),
350 'requires zlib.Z_SYNC_FLUSH')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000351 def test_odd_flush(self):
352 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
353 import random
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200354 # Testing on 17K of "random" data
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000355
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200356 # Create compressor and decompressor objects
357 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
358 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000359
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200360 # Try 17K of data
361 # generate random data stream
362 try:
363 # In 2.3 and later, WichmannHill is the RNG of the bug report
364 gen = random.WichmannHill()
365 except AttributeError:
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000366 try:
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200367 # 2.2 called it Random
368 gen = random.Random()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000369 except AttributeError:
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200370 # others might simply have a single RNG
371 gen = random
372 gen.seed(1)
373 data = genblock(1, 17 * 1024, generator=gen)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000374
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200375 # compress, sync-flush, and decompress
376 first = co.compress(data)
377 second = co.flush(zlib.Z_SYNC_FLUSH)
378 expanded = dco.decompress(first + second)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000379
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200380 # if decompressed data is different from the input data, choke.
381 self.assertEqual(expanded, data, "17K random source doesn't match")
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000382
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000383 def test_empty_flush(self):
384 # Test that calling .flush() on unused objects works.
385 # (Bug #1083110 -- calling .flush() on decompress objects
386 # caused a core dump.)
387
388 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000389 self.assertTrue(co.flush()) # Returns a zlib header
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000390 dco = zlib.decompressobj()
391 self.assertEqual(dco.flush(), "") # Returns nothing
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000392
Antoine Pitrou37ffc3e2010-05-11 23:32:31 +0000393 def test_decompress_incomplete_stream(self):
394 # This is 'foo', deflated
395 x = 'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
396 # For the record
397 self.assertEqual(zlib.decompress(x), 'foo')
398 self.assertRaises(zlib.error, zlib.decompress, x[:-5])
399 # Omitting the stream end works with decompressor objects
400 # (see issue #8672).
401 dco = zlib.decompressobj()
402 y = dco.decompress(x[:-5])
403 y += dco.flush()
404 self.assertEqual(y, 'foo')
405
Nadeem Vawda3c309702012-11-11 03:14:56 +0100406 def test_flush_with_freed_input(self):
407 # Issue #16411: decompressor accesses input to last decompress() call
408 # in flush(), even if this object has been freed in the meanwhile.
409 input1 = 'abcdefghijklmnopqrstuvwxyz'
410 input2 = 'QWERTYUIOPASDFGHJKLZXCVBNM'
411 data = zlib.compress(input1)
412 dco = zlib.decompressobj()
413 dco.decompress(data, 1)
414 del data
415 data = zlib.compress(input2)
416 self.assertEqual(dco.flush(), input1[1:])
417
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200418 @requires_Compress_copy
419 def test_compresscopy(self):
420 # Test copying a compression object
421 data0 = HAMLET_SCENE
422 data1 = HAMLET_SCENE.swapcase()
423 c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
424 bufs0 = []
425 bufs0.append(c0.compress(data0))
Georg Brandl8d3342b2006-05-16 07:38:27 +0000426
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200427 c1 = c0.copy()
428 bufs1 = bufs0[:]
Georg Brandl8d3342b2006-05-16 07:38:27 +0000429
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200430 bufs0.append(c0.compress(data0))
431 bufs0.append(c0.flush())
432 s0 = ''.join(bufs0)
Georg Brandl8d3342b2006-05-16 07:38:27 +0000433
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200434 bufs1.append(c1.compress(data1))
435 bufs1.append(c1.flush())
436 s1 = ''.join(bufs1)
Georg Brandl8d3342b2006-05-16 07:38:27 +0000437
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200438 self.assertEqual(zlib.decompress(s0),data0+data0)
439 self.assertEqual(zlib.decompress(s1),data0+data1)
Georg Brandl8d3342b2006-05-16 07:38:27 +0000440
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200441 @requires_Compress_copy
442 def test_badcompresscopy(self):
443 # Test copying a compression object in an inconsistent state
444 c = zlib.compressobj()
445 c.compress(HAMLET_SCENE)
446 c.flush()
447 self.assertRaises(ValueError, c.copy)
Georg Brandl8d3342b2006-05-16 07:38:27 +0000448
Nadeem Vawda6cad3712012-11-05 00:55:06 +0100449 def test_decompress_unused_data(self):
450 # Repeated calls to decompress() after EOF should accumulate data in
451 # dco.unused_data, instead of just storing the arg to the last call.
Nadeem Vawda252f4dc2012-11-11 02:14:15 +0100452 source = b'abcdefghijklmnopqrstuvwxyz'
453 remainder = b'0123456789'
454 y = zlib.compress(source)
455 x = y + remainder
456 for maxlen in 0, 1000:
457 for step in 1, 2, len(y), len(x):
458 dco = zlib.decompressobj()
459 data = b''
460 for i in range(0, len(x), step):
461 if i < len(y):
462 self.assertEqual(dco.unused_data, b'')
463 if maxlen == 0:
464 data += dco.decompress(x[i : i + step])
465 self.assertEqual(dco.unconsumed_tail, b'')
466 else:
467 data += dco.decompress(
468 dco.unconsumed_tail + x[i : i + step], maxlen)
469 data += dco.flush()
470 self.assertEqual(data, source)
471 self.assertEqual(dco.unconsumed_tail, b'')
472 self.assertEqual(dco.unused_data, remainder)
Nadeem Vawda6cad3712012-11-05 00:55:06 +0100473
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200474 @requires_Decompress_copy
475 def test_decompresscopy(self):
476 # Test copying a decompression object
477 data = HAMLET_SCENE
478 comp = zlib.compress(data)
Georg Brandl8d3342b2006-05-16 07:38:27 +0000479
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200480 d0 = zlib.decompressobj()
481 bufs0 = []
482 bufs0.append(d0.decompress(comp[:32]))
Georg Brandl8d3342b2006-05-16 07:38:27 +0000483
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200484 d1 = d0.copy()
485 bufs1 = bufs0[:]
Georg Brandl8d3342b2006-05-16 07:38:27 +0000486
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200487 bufs0.append(d0.decompress(comp[32:]))
488 s0 = ''.join(bufs0)
Georg Brandl8d3342b2006-05-16 07:38:27 +0000489
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200490 bufs1.append(d1.decompress(comp[32:]))
491 s1 = ''.join(bufs1)
Georg Brandl8d3342b2006-05-16 07:38:27 +0000492
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200493 self.assertEqual(s0,s1)
494 self.assertEqual(s0,data)
Georg Brandl8d3342b2006-05-16 07:38:27 +0000495
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200496 @requires_Decompress_copy
497 def test_baddecompresscopy(self):
498 # Test copying a compression object in an inconsistent state
499 data = zlib.compress(HAMLET_SCENE)
500 d = zlib.decompressobj()
501 d.decompress(data)
502 d.flush()
503 self.assertRaises(ValueError, d.copy)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000504
Antoine Pitrou3843cd82010-05-07 16:50:34 +0000505 # Memory use of the following functions takes into account overallocation
506
507 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=3)
508 def test_big_compress_buffer(self, size):
509 c = zlib.compressobj(1)
510 compress = lambda s: c.compress(s) + c.flush()
511 self.check_big_compress_buffer(size, compress)
512
513 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=2)
514 def test_big_decompress_buffer(self, size):
515 d = zlib.decompressobj()
516 decompress = lambda s: d.decompress(s) + d.flush()
517 self.check_big_decompress_buffer(size, decompress)
518
519
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000520def genblock(seed, length, step=1024, generator=random):
521 """length-byte stream of random data from a seed (in step-byte blocks)."""
522 if seed is not None:
523 generator.seed(seed)
524 randint = generator.randint
525 if length < step or step < 2:
526 step = length
527 blocks = []
528 for i in range(0, length, step):
529 blocks.append(''.join([chr(randint(0,255))
530 for x in range(step)]))
531 return ''.join(blocks)[:length]
532
533
534
535def choose_lines(source, number, seed=None, generator=random):
536 """Return a list of number lines randomly chosen from the source"""
537 if seed is not None:
538 generator.seed(seed)
539 sources = source.split('\n')
540 return [generator.choice(sources) for n in range(number)]
541
542
543
Neil Schemenauer6412b122004-06-05 19:34:28 +0000544HAMLET_SCENE = """
Fred Drake004d5e62000-10-23 17:22:08 +0000545LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000546
547 O, fear me not.
548 I stay too long: but here my father comes.
549
550 Enter POLONIUS
551
552 A double blessing is a double grace,
553 Occasion smiles upon a second leave.
554
Fred Drake004d5e62000-10-23 17:22:08 +0000555LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000556
557 Yet here, Laertes! aboard, aboard, for shame!
558 The wind sits in the shoulder of your sail,
559 And you are stay'd for. There; my blessing with thee!
560 And these few precepts in thy memory
561 See thou character. Give thy thoughts no tongue,
562 Nor any unproportioned thought his act.
563 Be thou familiar, but by no means vulgar.
564 Those friends thou hast, and their adoption tried,
565 Grapple them to thy soul with hoops of steel;
566 But do not dull thy palm with entertainment
567 Of each new-hatch'd, unfledged comrade. Beware
568 Of entrance to a quarrel, but being in,
569 Bear't that the opposed may beware of thee.
570 Give every man thy ear, but few thy voice;
571 Take each man's censure, but reserve thy judgment.
572 Costly thy habit as thy purse can buy,
573 But not express'd in fancy; rich, not gaudy;
574 For the apparel oft proclaims the man,
575 And they in France of the best rank and station
576 Are of a most select and generous chief in that.
577 Neither a borrower nor a lender be;
578 For loan oft loses both itself and friend,
579 And borrowing dulls the edge of husbandry.
580 This above all: to thine ownself be true,
581 And it must follow, as the night the day,
582 Thou canst not then be false to any man.
583 Farewell: my blessing season this in thee!
584
Fred Drake004d5e62000-10-23 17:22:08 +0000585LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000586
587 Most humbly do I take my leave, my lord.
588
Fred Drake004d5e62000-10-23 17:22:08 +0000589LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000590
591 The time invites you; go; your servants tend.
592
Fred Drake004d5e62000-10-23 17:22:08 +0000593LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000594
595 Farewell, Ophelia; and remember well
596 What I have said to you.
597
Fred Drake004d5e62000-10-23 17:22:08 +0000598OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000599
600 'Tis in my memory lock'd,
601 And you yourself shall keep the key of it.
602
Fred Drake004d5e62000-10-23 17:22:08 +0000603LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000604
605 Farewell.
606"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000607
608
609def test_main():
Victor Stinnerf9fb4342011-05-03 15:19:23 +0200610 run_unittest(
Walter Dörwald21d3a322003-05-01 17:45:56 +0000611 ChecksumTestCase,
612 ExceptionTestCase,
613 CompressTestCase,
614 CompressObjectTestCase
615 )
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000616
617if __name__ == "__main__":
618 test_main()