blob: 05adde46930ac44477a1565539fce53cf4b61ea2 [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 Pitrou89562712010-05-07 17:04:02 +00005from test.support import precisionbigmemtest, _1G
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00006
R. David Murraya21e4ca2009-03-31 23:16:50 +00007zlib = support.import_module('zlib')
8
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00009
Guido van Rossum7d9ea502003-02-03 20:45:52 +000010class ChecksumTestCase(unittest.TestCase):
11 # checksum test cases
12 def test_crc32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000013 self.assertEqual(zlib.crc32(b""), zlib.crc32(b"", 0))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000014 self.assertTrue(zlib.crc32(b"abc", 0xffffffff))
Andrew M. Kuchlingfcfc8d52001-08-10 15:50:11 +000015
Guido van Rossum7d9ea502003-02-03 20:45:52 +000016 def test_crc32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000017 self.assertEqual(zlib.crc32(b"", 0), 0)
18 self.assertEqual(zlib.crc32(b"", 1), 1)
19 self.assertEqual(zlib.crc32(b"", 432), 432)
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000020
Guido van Rossum7d9ea502003-02-03 20:45:52 +000021 def test_adler32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000022 self.assertEqual(zlib.adler32(b""), zlib.adler32(b"", 1))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000023 self.assertTrue(zlib.adler32(b"abc", 0xffffffff))
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000024
Guido van Rossum7d9ea502003-02-03 20:45:52 +000025 def test_adler32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000026 self.assertEqual(zlib.adler32(b"", 0), 0)
27 self.assertEqual(zlib.adler32(b"", 1), 1)
28 self.assertEqual(zlib.adler32(b"", 432), 432)
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000029
Guido van Rossum7d9ea502003-02-03 20:45:52 +000030 def assertEqual32(self, seen, expected):
31 # 32-bit values masked -- checksums on 32- vs 64- bit machines
32 # This is important if bit 31 (0x08000000L) is set.
Guido van Rossume2a383d2007-01-15 16:59:06 +000033 self.assertEqual(seen & 0x0FFFFFFFF, expected & 0x0FFFFFFFF)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000034
35 def test_penguins(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000036 self.assertEqual32(zlib.crc32(b"penguin", 0), 0x0e5c1a120)
37 self.assertEqual32(zlib.crc32(b"penguin", 1), 0x43b6aa94)
38 self.assertEqual32(zlib.adler32(b"penguin", 0), 0x0bcf02f6)
39 self.assertEqual32(zlib.adler32(b"penguin", 1), 0x0bd602f7)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000040
Guido van Rossum776152b2007-05-22 22:44:07 +000041 self.assertEqual(zlib.crc32(b"penguin"), zlib.crc32(b"penguin", 0))
42 self.assertEqual(zlib.adler32(b"penguin"),zlib.adler32(b"penguin",1))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000043
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000044 def test_crc32_adler32_unsigned(self):
Antoine Pitrou77b338b2009-12-14 18:00:06 +000045 foo = b'abcdefghijklmnop'
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000046 # explicitly test signed behavior
Gregory P. Smith27275032008-03-20 06:20:09 +000047 self.assertEqual(zlib.crc32(foo), 2486878355)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000048 self.assertEqual(zlib.crc32(b'spam'), 1138425661)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000049 self.assertEqual(zlib.adler32(foo+foo), 3573550353)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000050 self.assertEqual(zlib.adler32(b'spam'), 72286642)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000051
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000052 def test_same_as_binascii_crc32(self):
Martin v. Löwis15b16a32008-12-02 06:00:15 +000053 foo = b'abcdefghijklmnop'
Gregory P. Smith27275032008-03-20 06:20:09 +000054 crc = 2486878355
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000055 self.assertEqual(binascii.crc32(foo), crc)
56 self.assertEqual(zlib.crc32(foo), crc)
Martin v. Löwis15b16a32008-12-02 06:00:15 +000057 self.assertEqual(binascii.crc32(b'spam'), zlib.crc32(b'spam'))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000058
59
Christian Heimesb186d002008-03-18 15:15:01 +000060
Guido van Rossum7d9ea502003-02-03 20:45:52 +000061class ExceptionTestCase(unittest.TestCase):
62 # make sure we generate some expected errors
Guido van Rossum8ce8a782007-11-01 19:42:39 +000063 def test_badlevel(self):
64 # specifying compression level out of range causes an error
65 # (but -1 is Z_DEFAULT_COMPRESSION and apparently the zlib
66 # accepts 0 too)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000067 self.assertRaises(zlib.error, zlib.compress, b'ERROR', 10)
68
69 def test_badargs(self):
70 self.assertRaises(TypeError, zlib.adler32)
71 self.assertRaises(TypeError, zlib.crc32)
72 self.assertRaises(TypeError, zlib.compress)
73 self.assertRaises(TypeError, zlib.decompress)
74 for arg in (42, None, '', 'abc', (), []):
75 self.assertRaises(TypeError, zlib.adler32, arg)
76 self.assertRaises(TypeError, zlib.crc32, arg)
77 self.assertRaises(TypeError, zlib.compress, arg)
78 self.assertRaises(TypeError, zlib.decompress, arg)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000079
80 def test_badcompressobj(self):
81 # verify failure on building compress object with bad params
Neil Schemenauer94afd3e2004-06-05 19:02:52 +000082 self.assertRaises(ValueError, zlib.compressobj, 1, zlib.DEFLATED, 0)
Guido van Rossum8ce8a782007-11-01 19:42:39 +000083 # specifying total bits too large causes an error
84 self.assertRaises(ValueError,
85 zlib.compressobj, 1, zlib.DEFLATED, zlib.MAX_WBITS + 1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000086
87 def test_baddecompressobj(self):
88 # verify failure on building decompress object with bad params
Antoine Pitrou90ee4df2010-04-06 17:23:13 +000089 self.assertRaises(ValueError, zlib.decompressobj, -1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000090
Christian Heimes5e696852008-04-09 08:37:03 +000091 def test_decompressobj_badflush(self):
92 # verify failure on calling decompressobj.flush with bad params
93 self.assertRaises(ValueError, zlib.decompressobj().flush, 0)
94 self.assertRaises(ValueError, zlib.decompressobj().flush, -1)
95
Guido van Rossum7d9ea502003-02-03 20:45:52 +000096
Antoine Pitrou89562712010-05-07 17:04:02 +000097class BaseCompressTestCase(object):
98 def check_big_compress_buffer(self, size, compress_func):
99 _1M = 1024 * 1024
100 fmt = "%%0%dx" % (2 * _1M)
101 # Generate 10MB worth of random, and expand it by repeating it.
102 # The assumption is that zlib's memory is not big enough to exploit
103 # such spread out redundancy.
104 data = b''.join([random.getrandbits(8 * _1M).to_bytes(_1M, 'little')
105 for i in range(10)])
106 data = data * (size // len(data) + 1)
107 try:
108 compress_func(data)
109 finally:
110 # Release memory
111 data = None
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000112
Antoine Pitrou89562712010-05-07 17:04:02 +0000113 def check_big_decompress_buffer(self, size, decompress_func):
114 data = b'x' * size
115 try:
116 compressed = zlib.compress(data, 1)
117 finally:
118 # Release memory
119 data = None
120 data = decompress_func(compressed)
121 # Sanity check
122 try:
123 self.assertEqual(len(data), size)
124 self.assertEqual(len(data.strip(b'x')), 0)
125 finally:
126 data = None
127
128
129class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000130 # Test compression in one go (whole message compression)
131 def test_speech(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000132 x = zlib.compress(HAMLET_SCENE)
133 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000134
135 def test_speech128(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000136 # compress more data
137 data = HAMLET_SCENE * 128
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000138 x = zlib.compress(data)
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000139 self.assertEqual(zlib.compress(bytearray(data)), x)
140 for ob in x, bytearray(x):
141 self.assertEqual(zlib.decompress(ob), data)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000142
Antoine Pitrou53b21662010-05-11 23:46:02 +0000143 def test_incomplete_stream(self):
144 # An useful error message is given
145 x = zlib.compress(HAMLET_SCENE)
146 self.assertRaisesRegexp(zlib.error,
147 "Error -5 while decompressing data: incomplete or truncated stream",
148 zlib.decompress, x[:-1])
149
Antoine Pitrou89562712010-05-07 17:04:02 +0000150 # Memory use of the following functions takes into account overallocation
151
152 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=3)
153 def test_big_compress_buffer(self, size):
154 compress = lambda s: zlib.compress(s, 1)
155 self.check_big_compress_buffer(size, compress)
156
157 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=2)
158 def test_big_decompress_buffer(self, size):
159 self.check_big_decompress_buffer(size, zlib.decompress)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000160
161
Antoine Pitrou89562712010-05-07 17:04:02 +0000162class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000163 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000164 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000165 # straightforward compress/decompress objects
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000166 datasrc = HAMLET_SCENE * 128
167 datazip = zlib.compress(datasrc)
168 # should compress both bytes and bytearray data
169 for data in (datasrc, bytearray(datasrc)):
170 co = zlib.compressobj()
171 x1 = co.compress(data)
172 x2 = co.flush()
173 self.assertRaises(zlib.error, co.flush) # second flush should not work
174 self.assertEqual(x1 + x2, datazip)
175 for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))):
176 dco = zlib.decompressobj()
177 y1 = dco.decompress(v1 + v2)
178 y2 = dco.flush()
179 self.assertEqual(data, y1 + y2)
180 self.assertIsInstance(dco.unconsumed_tail, bytes)
181 self.assertIsInstance(dco.unused_data, bytes)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000182
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000183 def test_compressoptions(self):
184 # specify lots of options to compressobj()
185 level = 2
186 method = zlib.DEFLATED
187 wbits = -12
188 memlevel = 9
189 strategy = zlib.Z_FILTERED
190 co = zlib.compressobj(level, method, wbits, memlevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000191 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000192 x2 = co.flush()
193 dco = zlib.decompressobj(wbits)
194 y1 = dco.decompress(x1 + x2)
195 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000196 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000197
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000198 def test_compressincremental(self):
199 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000200 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000201 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000202 bufs = []
203 for i in range(0, len(data), 256):
204 bufs.append(co.compress(data[i:i+256]))
205 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000206 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000207
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000208 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000209 y1 = dco.decompress(b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000210 y2 = dco.flush()
211 self.assertEqual(data, y1 + y2)
212
Neil Schemenauer6412b122004-06-05 19:34:28 +0000213 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000214 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000215 source = source or HAMLET_SCENE
216 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000217 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000218 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000219 for i in range(0, len(data), cx):
220 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000221 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000222 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000223
Gregory P. Smith693fc462008-09-06 20:13:06 +0000224 decombuf = zlib.decompress(combuf)
225 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000226 self.assertIsInstance(decombuf, bytes)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000227
228 self.assertEqual(data, decombuf)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000229
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000230 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000231 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000232 for i in range(0, len(combuf), dcx):
233 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000234 self.assertEqual(b'', dco.unconsumed_tail, ########
235 "(A) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000236 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000237 self.assertEqual(b'', dco.unused_data)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000238 if flush:
239 bufs.append(dco.flush())
240 else:
241 while True:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000242 chunk = dco.decompress(b'')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000243 if chunk:
244 bufs.append(chunk)
245 else:
246 break
Guido van Rossum776152b2007-05-22 22:44:07 +0000247 self.assertEqual(b'', dco.unconsumed_tail, ########
248 "(B) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000249 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000250 self.assertEqual(b'', dco.unused_data)
Guido van Rossum776152b2007-05-22 22:44:07 +0000251 self.assertEqual(data, b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000252 # Failure means: "decompressobj with init options failed"
253
Neil Schemenauer6412b122004-06-05 19:34:28 +0000254 def test_decompincflush(self):
255 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000256
Neil Schemenauer6412b122004-06-05 19:34:28 +0000257 def test_decompimax(self, source=None, cx=256, dcx=64):
258 # compress in steps, decompress in length-restricted steps
259 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000260 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000261 data = source * 128
262 co = zlib.compressobj()
263 bufs = []
264 for i in range(0, len(data), cx):
265 bufs.append(co.compress(data[i:i+cx]))
266 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000267 combuf = b''.join(bufs)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000268 self.assertEqual(data, zlib.decompress(combuf),
269 'compressed data failure')
270
271 dco = zlib.decompressobj()
272 bufs = []
273 cb = combuf
274 while cb:
275 #max_length = 1 + len(cb)//10
276 chunk = dco.decompress(cb, dcx)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000277 self.assertFalse(len(chunk) > dcx,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000278 'chunk too big (%d>%d)' % (len(chunk), dcx))
279 bufs.append(chunk)
280 cb = dco.unconsumed_tail
281 bufs.append(dco.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000282 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000283
284 def test_decompressmaxlen(self, flush=False):
285 # Check a decompression object with max_length specified
286 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000287 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000288 bufs = []
289 for i in range(0, len(data), 256):
290 bufs.append(co.compress(data[i:i+256]))
291 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000292 combuf = b''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000293 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000294 'compressed data failure')
295
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000296 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000297 bufs = []
298 cb = combuf
299 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000300 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000301 chunk = dco.decompress(cb, max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000302 self.assertFalse(len(chunk) > max_length,
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000303 'chunk too big (%d>%d)' % (len(chunk),max_length))
304 bufs.append(chunk)
305 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000306 if flush:
307 bufs.append(dco.flush())
308 else:
309 while chunk:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000310 chunk = dco.decompress(b'', max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000311 self.assertFalse(len(chunk) > max_length,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000312 'chunk too big (%d>%d)' % (len(chunk),max_length))
313 bufs.append(chunk)
Guido van Rossum776152b2007-05-22 22:44:07 +0000314 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000315
Neil Schemenauer6412b122004-06-05 19:34:28 +0000316 def test_decompressmaxlenflush(self):
317 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000318
319 def test_maxlenmisc(self):
320 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000321 dco = zlib.decompressobj()
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000322 self.assertRaises(ValueError, dco.decompress, b"", -1)
Guido van Rossum776152b2007-05-22 22:44:07 +0000323 self.assertEqual(b'', dco.unconsumed_tail)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000324
325 def test_flushes(self):
326 # Test flush() with the various options, using all the
327 # different levels in order to provide more variations.
328 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH']
329 sync_opt = [getattr(zlib, opt) for opt in sync_opt
330 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000331 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000332
333 for sync in sync_opt:
334 for level in range(10):
335 obj = zlib.compressobj( level )
336 a = obj.compress( data[:3000] )
337 b = obj.flush( sync )
338 c = obj.compress( data[3000:] )
339 d = obj.flush()
Guido van Rossum776152b2007-05-22 22:44:07 +0000340 self.assertEqual(zlib.decompress(b''.join([a,b,c,d])),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000341 data, ("Decompress failed: flush "
342 "mode=%i, level=%i") % (sync, level))
343 del obj
344
345 def test_odd_flush(self):
346 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
347 import random
348
349 if hasattr(zlib, 'Z_SYNC_FLUSH'):
350 # Testing on 17K of "random" data
351
352 # Create compressor and decompressor objects
Neil Schemenauer6412b122004-06-05 19:34:28 +0000353 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000354 dco = zlib.decompressobj()
355
356 # Try 17K of data
357 # generate random data stream
358 try:
359 # In 2.3 and later, WichmannHill is the RNG of the bug report
360 gen = random.WichmannHill()
361 except AttributeError:
362 try:
363 # 2.2 called it Random
364 gen = random.Random()
365 except AttributeError:
366 # others might simply have a single RNG
367 gen = random
368 gen.seed(1)
369 data = genblock(1, 17 * 1024, generator=gen)
370
371 # compress, sync-flush, and decompress
372 first = co.compress(data)
373 second = co.flush(zlib.Z_SYNC_FLUSH)
374 expanded = dco.decompress(first + second)
375
376 # if decompressed data is different from the input data, choke.
377 self.assertEqual(expanded, data, "17K random source doesn't match")
378
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000379 def test_empty_flush(self):
380 # Test that calling .flush() on unused objects works.
381 # (Bug #1083110 -- calling .flush() on decompress objects
382 # caused a core dump.)
383
384 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000385 self.assertTrue(co.flush()) # Returns a zlib header
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000386 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000387 self.assertEqual(dco.flush(), b"") # Returns nothing
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000388
Antoine Pitrouc09c92f2010-05-11 23:36:40 +0000389 def test_decompress_incomplete_stream(self):
390 # This is 'foo', deflated
391 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
392 # For the record
393 self.assertEqual(zlib.decompress(x), b'foo')
394 self.assertRaises(zlib.error, zlib.decompress, x[:-5])
395 # Omitting the stream end works with decompressor objects
396 # (see issue #8672).
397 dco = zlib.decompressobj()
398 y = dco.decompress(x[:-5])
399 y += dco.flush()
400 self.assertEqual(y, b'foo')
401
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000402 if hasattr(zlib.compressobj(), "copy"):
403 def test_compresscopy(self):
404 # Test copying a compression object
405 data0 = HAMLET_SCENE
Guido van Rossum776152b2007-05-22 22:44:07 +0000406 data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000407 c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
408 bufs0 = []
409 bufs0.append(c0.compress(data0))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000410
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000411 c1 = c0.copy()
412 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000413
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000414 bufs0.append(c0.compress(data0))
415 bufs0.append(c0.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000416 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000417
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000418 bufs1.append(c1.compress(data1))
419 bufs1.append(c1.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000420 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000421
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000422 self.assertEqual(zlib.decompress(s0),data0+data0)
423 self.assertEqual(zlib.decompress(s1),data0+data1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000424
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000425 def test_badcompresscopy(self):
426 # Test copying a compression object in an inconsistent state
427 c = zlib.compressobj()
428 c.compress(HAMLET_SCENE)
429 c.flush()
430 self.assertRaises(ValueError, c.copy)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000431
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000432 if hasattr(zlib.decompressobj(), "copy"):
433 def test_decompresscopy(self):
434 # Test copying a decompression object
435 data = HAMLET_SCENE
436 comp = zlib.compress(data)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000437 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000438 self.assertIsInstance(comp, bytes)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000439
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000440 d0 = zlib.decompressobj()
441 bufs0 = []
442 bufs0.append(d0.decompress(comp[:32]))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000443
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000444 d1 = d0.copy()
445 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000446
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000447 bufs0.append(d0.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000448 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000449
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000450 bufs1.append(d1.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000451 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000452
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000453 self.assertEqual(s0,s1)
454 self.assertEqual(s0,data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000455
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000456 def test_baddecompresscopy(self):
457 # Test copying a compression object in an inconsistent state
458 data = zlib.compress(HAMLET_SCENE)
459 d = zlib.decompressobj()
460 d.decompress(data)
461 d.flush()
462 self.assertRaises(ValueError, d.copy)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000463
Antoine Pitrou89562712010-05-07 17:04:02 +0000464 # Memory use of the following functions takes into account overallocation
465
466 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=3)
467 def test_big_compress_buffer(self, size):
468 c = zlib.compressobj(1)
469 compress = lambda s: c.compress(s) + c.flush()
470 self.check_big_compress_buffer(size, compress)
471
472 @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=2)
473 def test_big_decompress_buffer(self, size):
474 d = zlib.decompressobj()
475 decompress = lambda s: d.decompress(s) + d.flush()
476 self.check_big_decompress_buffer(size, decompress)
477
478
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000479def genblock(seed, length, step=1024, generator=random):
480 """length-byte stream of random data from a seed (in step-byte blocks)."""
481 if seed is not None:
482 generator.seed(seed)
483 randint = generator.randint
484 if length < step or step < 2:
485 step = length
Guido van Rossum776152b2007-05-22 22:44:07 +0000486 blocks = bytes()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000487 for i in range(0, length, step):
Guido van Rossum776152b2007-05-22 22:44:07 +0000488 blocks += bytes(randint(0, 255) for x in range(step))
489 return blocks
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000490
491
492
493def choose_lines(source, number, seed=None, generator=random):
494 """Return a list of number lines randomly chosen from the source"""
495 if seed is not None:
496 generator.seed(seed)
497 sources = source.split('\n')
498 return [generator.choice(sources) for n in range(number)]
499
500
501
Guido van Rossum776152b2007-05-22 22:44:07 +0000502HAMLET_SCENE = b"""
Fred Drake004d5e62000-10-23 17:22:08 +0000503LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000504
505 O, fear me not.
506 I stay too long: but here my father comes.
507
508 Enter POLONIUS
509
510 A double blessing is a double grace,
511 Occasion smiles upon a second leave.
512
Fred Drake004d5e62000-10-23 17:22:08 +0000513LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000514
515 Yet here, Laertes! aboard, aboard, for shame!
516 The wind sits in the shoulder of your sail,
517 And you are stay'd for. There; my blessing with thee!
518 And these few precepts in thy memory
519 See thou character. Give thy thoughts no tongue,
520 Nor any unproportioned thought his act.
521 Be thou familiar, but by no means vulgar.
522 Those friends thou hast, and their adoption tried,
523 Grapple them to thy soul with hoops of steel;
524 But do not dull thy palm with entertainment
525 Of each new-hatch'd, unfledged comrade. Beware
526 Of entrance to a quarrel, but being in,
527 Bear't that the opposed may beware of thee.
528 Give every man thy ear, but few thy voice;
529 Take each man's censure, but reserve thy judgment.
530 Costly thy habit as thy purse can buy,
531 But not express'd in fancy; rich, not gaudy;
532 For the apparel oft proclaims the man,
533 And they in France of the best rank and station
534 Are of a most select and generous chief in that.
535 Neither a borrower nor a lender be;
536 For loan oft loses both itself and friend,
537 And borrowing dulls the edge of husbandry.
538 This above all: to thine ownself be true,
539 And it must follow, as the night the day,
540 Thou canst not then be false to any man.
541 Farewell: my blessing season this in thee!
542
Fred Drake004d5e62000-10-23 17:22:08 +0000543LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000544
545 Most humbly do I take my leave, my lord.
546
Fred Drake004d5e62000-10-23 17:22:08 +0000547LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000548
549 The time invites you; go; your servants tend.
550
Fred Drake004d5e62000-10-23 17:22:08 +0000551LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000552
553 Farewell, Ophelia; and remember well
554 What I have said to you.
555
Fred Drake004d5e62000-10-23 17:22:08 +0000556OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000557
558 'Tis in my memory lock'd,
559 And you yourself shall keep the key of it.
560
Fred Drake004d5e62000-10-23 17:22:08 +0000561LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000562
563 Farewell.
564"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000565
566
567def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000568 support.run_unittest(
Walter Dörwald21d3a322003-05-01 17:45:56 +0000569 ChecksumTestCase,
570 ExceptionTestCase,
571 CompressTestCase,
572 CompressObjectTestCase
573 )
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000574
575if __name__ == "__main__":
Guido van Rossum776152b2007-05-22 22:44:07 +0000576 unittest.main() # XXX
577 ###test_main()