blob: 8683879f192cedcc605c0a500f66f60c312b91be [file] [log] [blame]
Guido van Rossum7d9ea502003-02-03 20:45:52 +00001import unittest
2from test import test_support
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +00003import zlib
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00004import random
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00005
Guido van Rossum7d9ea502003-02-03 20:45:52 +00006# print test_support.TESTFN
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00007
Guido van Rossum7d9ea502003-02-03 20:45:52 +00008def getbuf():
9 # This was in the original. Avoid non-repeatable sources.
10 # Left here (unused) in case something wants to be done with it.
11 import imp
12 try:
13 t = imp.find_module('test_zlib')
14 file = t[0]
15 except ImportError:
16 file = open(__file__)
17 buf = file.read() * 8
18 file.close()
19 return buf
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000020
Tim Peters0009c4e2001-02-21 07:29:48 +000021
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))
Andrew M. Kuchlingfcfc8d52001-08-10 15:50:11 +000027
Guido van Rossum7d9ea502003-02-03 20:45:52 +000028 def test_crc32empty(self):
29 self.assertEqual(zlib.crc32("", 0), 0)
30 self.assertEqual(zlib.crc32("", 1), 1)
31 self.assertEqual(zlib.crc32("", 432), 432)
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000032
Guido van Rossum7d9ea502003-02-03 20:45:52 +000033 def test_adler32start(self):
34 self.assertEqual(zlib.adler32(""), zlib.adler32("", 1))
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000035
Guido van Rossum7d9ea502003-02-03 20:45:52 +000036 def test_adler32empty(self):
37 self.assertEqual(zlib.adler32("", 0), 0)
38 self.assertEqual(zlib.adler32("", 1), 1)
39 self.assertEqual(zlib.adler32("", 432), 432)
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000040
Guido van Rossum7d9ea502003-02-03 20:45:52 +000041 def assertEqual32(self, seen, expected):
42 # 32-bit values masked -- checksums on 32- vs 64- bit machines
43 # This is important if bit 31 (0x08000000L) is set.
44 self.assertEqual(seen & 0x0FFFFFFFFL, expected & 0x0FFFFFFFFL)
45
46 def test_penguins(self):
47 self.assertEqual32(zlib.crc32("penguin", 0), 0x0e5c1a120L)
48 self.assertEqual32(zlib.crc32("penguin", 1), 0x43b6aa94)
49 self.assertEqual32(zlib.adler32("penguin", 0), 0x0bcf02f6)
50 self.assertEqual32(zlib.adler32("penguin", 1), 0x0bd602f7)
51
52 self.assertEqual(zlib.crc32("penguin"), zlib.crc32("penguin", 0))
53 self.assertEqual(zlib.adler32("penguin"),zlib.adler32("penguin",1))
54
55
56
57class ExceptionTestCase(unittest.TestCase):
58 # make sure we generate some expected errors
59 def test_bigbits(self):
60 # specifying total bits too large causes an error
61 self.assertRaises(zlib.error,
62 zlib.compress, 'ERROR', zlib.MAX_WBITS + 1)
63
64 def test_badcompressobj(self):
65 # verify failure on building compress object with bad params
Neil Schemenauer94afd3e2004-06-05 19:02:52 +000066 self.assertRaises(ValueError, zlib.compressobj, 1, zlib.DEFLATED, 0)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000067
68 def test_baddecompressobj(self):
69 # verify failure on building decompress object with bad params
70 self.assertRaises(ValueError, zlib.decompressobj, 0)
71
72
73
74class CompressTestCase(unittest.TestCase):
75 # Test compression in one go (whole message compression)
76 def test_speech(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +000077 x = zlib.compress(HAMLET_SCENE)
78 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000079
80 def test_speech128(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +000081 # compress more data
82 data = HAMLET_SCENE * 128
Guido van Rossum7d9ea502003-02-03 20:45:52 +000083 x = zlib.compress(data)
84 self.assertEqual(zlib.decompress(x), data)
85
Guido van Rossum7d9ea502003-02-03 20:45:52 +000086
87
88
89class CompressObjectTestCase(unittest.TestCase):
90 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +000091 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +000092 # straightforward compress/decompress objects
93 data = HAMLET_SCENE * 128
94 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +000095 x1 = co.compress(data)
96 x2 = co.flush()
97 self.assertRaises(zlib.error, co.flush) # second flush should not work
Neil Schemenauer94afd3e2004-06-05 19:02:52 +000098 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +000099 y1 = dco.decompress(x1 + x2)
100 y2 = dco.flush()
101 self.assertEqual(data, y1 + y2)
102
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000103 def test_compressoptions(self):
104 # specify lots of options to compressobj()
105 level = 2
106 method = zlib.DEFLATED
107 wbits = -12
108 memlevel = 9
109 strategy = zlib.Z_FILTERED
110 co = zlib.compressobj(level, method, wbits, memlevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000111 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000112 x2 = co.flush()
113 dco = zlib.decompressobj(wbits)
114 y1 = dco.decompress(x1 + x2)
115 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000116 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000117
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000118 def test_compressincremental(self):
119 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000120 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000121 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000122 bufs = []
123 for i in range(0, len(data), 256):
124 bufs.append(co.compress(data[i:i+256]))
125 bufs.append(co.flush())
126 combuf = ''.join(bufs)
127
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000128 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000129 y1 = dco.decompress(''.join(bufs))
130 y2 = dco.flush()
131 self.assertEqual(data, y1 + y2)
132
Neil Schemenauer6412b122004-06-05 19:34:28 +0000133 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000134 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000135 source = source or HAMLET_SCENE
136 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000137 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000138 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000139 for i in range(0, len(data), cx):
140 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000141 bufs.append(co.flush())
142 combuf = ''.join(bufs)
143
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000144 self.assertEqual(data, zlib.decompress(combuf))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000145
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000146 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000147 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000148 for i in range(0, len(combuf), dcx):
149 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000150 self.assertEqual('', dco.unconsumed_tail, ########
151 "(A) uct should be '': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000152 len(dco.unconsumed_tail))
153 if flush:
154 bufs.append(dco.flush())
155 else:
156 while True:
157 chunk = dco.decompress('')
158 if chunk:
159 bufs.append(chunk)
160 else:
161 break
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000162 self.assertEqual('', dco.unconsumed_tail, ########
Neil Schemenauer6412b122004-06-05 19:34:28 +0000163 "(B) uct should be '': not %d long" %
164 len(dco.unconsumed_tail))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000165 self.assertEqual(data, ''.join(bufs))
166 # Failure means: "decompressobj with init options failed"
167
Neil Schemenauer6412b122004-06-05 19:34:28 +0000168 def test_decompincflush(self):
169 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000170
Neil Schemenauer6412b122004-06-05 19:34:28 +0000171 def test_decompimax(self, source=None, cx=256, dcx=64):
172 # compress in steps, decompress in length-restricted steps
173 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000174 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000175 data = source * 128
176 co = zlib.compressobj()
177 bufs = []
178 for i in range(0, len(data), cx):
179 bufs.append(co.compress(data[i:i+cx]))
180 bufs.append(co.flush())
181 combuf = ''.join(bufs)
182 self.assertEqual(data, zlib.decompress(combuf),
183 'compressed data failure')
184
185 dco = zlib.decompressobj()
186 bufs = []
187 cb = combuf
188 while cb:
189 #max_length = 1 + len(cb)//10
190 chunk = dco.decompress(cb, dcx)
191 self.failIf(len(chunk) > dcx,
192 'chunk too big (%d>%d)' % (len(chunk), dcx))
193 bufs.append(chunk)
194 cb = dco.unconsumed_tail
195 bufs.append(dco.flush())
196 self.assertEqual(data, ''.join(bufs), 'Wrong data retrieved')
197
198 def test_decompressmaxlen(self, flush=False):
199 # Check a decompression object with max_length specified
200 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())
206 combuf = ''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000207 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000208 'compressed data failure')
209
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000210 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000211 bufs = []
212 cb = combuf
213 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000214 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000215 chunk = dco.decompress(cb, max_length)
216 self.failIf(len(chunk) > max_length,
217 'chunk too big (%d>%d)' % (len(chunk),max_length))
218 bufs.append(chunk)
219 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000220 if flush:
221 bufs.append(dco.flush())
222 else:
223 while chunk:
224 chunk = dco.decompress('', max_length)
225 self.failIf(len(chunk) > max_length,
226 'chunk too big (%d>%d)' % (len(chunk),max_length))
227 bufs.append(chunk)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000228 self.assertEqual(data, ''.join(bufs), 'Wrong data retrieved')
229
Neil Schemenauer6412b122004-06-05 19:34:28 +0000230 def test_decompressmaxlenflush(self):
231 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000232
233 def test_maxlenmisc(self):
234 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000235 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000236 self.assertRaises(ValueError, dco.decompress, "", -1)
237 self.assertEqual('', dco.unconsumed_tail)
238
239 def test_flushes(self):
240 # Test flush() with the various options, using all the
241 # different levels in order to provide more variations.
242 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH']
243 sync_opt = [getattr(zlib, opt) for opt in sync_opt
244 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000245 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000246
247 for sync in sync_opt:
248 for level in range(10):
249 obj = zlib.compressobj( level )
250 a = obj.compress( data[:3000] )
251 b = obj.flush( sync )
252 c = obj.compress( data[3000:] )
253 d = obj.flush()
254 self.assertEqual(zlib.decompress(''.join([a,b,c,d])),
255 data, ("Decompress failed: flush "
256 "mode=%i, level=%i") % (sync, level))
257 del obj
258
259 def test_odd_flush(self):
260 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
261 import random
262
263 if hasattr(zlib, 'Z_SYNC_FLUSH'):
264 # Testing on 17K of "random" data
265
266 # Create compressor and decompressor objects
Neil Schemenauer6412b122004-06-05 19:34:28 +0000267 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000268 dco = zlib.decompressobj()
269
270 # Try 17K of data
271 # generate random data stream
272 try:
273 # In 2.3 and later, WichmannHill is the RNG of the bug report
274 gen = random.WichmannHill()
275 except AttributeError:
276 try:
277 # 2.2 called it Random
278 gen = random.Random()
279 except AttributeError:
280 # others might simply have a single RNG
281 gen = random
282 gen.seed(1)
283 data = genblock(1, 17 * 1024, generator=gen)
284
285 # compress, sync-flush, and decompress
286 first = co.compress(data)
287 second = co.flush(zlib.Z_SYNC_FLUSH)
288 expanded = dco.decompress(first + second)
289
290 # if decompressed data is different from the input data, choke.
291 self.assertEqual(expanded, data, "17K random source doesn't match")
292
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000293
294def genblock(seed, length, step=1024, generator=random):
295 """length-byte stream of random data from a seed (in step-byte blocks)."""
296 if seed is not None:
297 generator.seed(seed)
298 randint = generator.randint
299 if length < step or step < 2:
300 step = length
301 blocks = []
302 for i in range(0, length, step):
303 blocks.append(''.join([chr(randint(0,255))
304 for x in range(step)]))
305 return ''.join(blocks)[:length]
306
307
308
309def choose_lines(source, number, seed=None, generator=random):
310 """Return a list of number lines randomly chosen from the source"""
311 if seed is not None:
312 generator.seed(seed)
313 sources = source.split('\n')
314 return [generator.choice(sources) for n in range(number)]
315
316
317
Neil Schemenauer6412b122004-06-05 19:34:28 +0000318HAMLET_SCENE = """
Fred Drake004d5e62000-10-23 17:22:08 +0000319LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000320
321 O, fear me not.
322 I stay too long: but here my father comes.
323
324 Enter POLONIUS
325
326 A double blessing is a double grace,
327 Occasion smiles upon a second leave.
328
Fred Drake004d5e62000-10-23 17:22:08 +0000329LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000330
331 Yet here, Laertes! aboard, aboard, for shame!
332 The wind sits in the shoulder of your sail,
333 And you are stay'd for. There; my blessing with thee!
334 And these few precepts in thy memory
335 See thou character. Give thy thoughts no tongue,
336 Nor any unproportioned thought his act.
337 Be thou familiar, but by no means vulgar.
338 Those friends thou hast, and their adoption tried,
339 Grapple them to thy soul with hoops of steel;
340 But do not dull thy palm with entertainment
341 Of each new-hatch'd, unfledged comrade. Beware
342 Of entrance to a quarrel, but being in,
343 Bear't that the opposed may beware of thee.
344 Give every man thy ear, but few thy voice;
345 Take each man's censure, but reserve thy judgment.
346 Costly thy habit as thy purse can buy,
347 But not express'd in fancy; rich, not gaudy;
348 For the apparel oft proclaims the man,
349 And they in France of the best rank and station
350 Are of a most select and generous chief in that.
351 Neither a borrower nor a lender be;
352 For loan oft loses both itself and friend,
353 And borrowing dulls the edge of husbandry.
354 This above all: to thine ownself be true,
355 And it must follow, as the night the day,
356 Thou canst not then be false to any man.
357 Farewell: my blessing season this in thee!
358
Fred Drake004d5e62000-10-23 17:22:08 +0000359LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000360
361 Most humbly do I take my leave, my lord.
362
Fred Drake004d5e62000-10-23 17:22:08 +0000363LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000364
365 The time invites you; go; your servants tend.
366
Fred Drake004d5e62000-10-23 17:22:08 +0000367LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000368
369 Farewell, Ophelia; and remember well
370 What I have said to you.
371
Fred Drake004d5e62000-10-23 17:22:08 +0000372OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000373
374 'Tis in my memory lock'd,
375 And you yourself shall keep the key of it.
376
Fred Drake004d5e62000-10-23 17:22:08 +0000377LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000378
379 Farewell.
380"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000381
382
383def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000384 test_support.run_unittest(
385 ChecksumTestCase,
386 ExceptionTestCase,
387 CompressTestCase,
388 CompressObjectTestCase
389 )
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000390
391if __name__ == "__main__":
392 test_main()
393
394def test(tests=''):
395 if not tests: tests = 'o'
Walter Dörwald21d3a322003-05-01 17:45:56 +0000396 testcases = []
397 if 'k' in tests: testcases.append(ChecksumTestCase)
398 if 'x' in tests: testcases.append(ExceptionTestCase)
399 if 'c' in tests: testcases.append(CompressTestCase)
400 if 'o' in tests: testcases.append(CompressObjectTestCase)
401 test_support.run_unittest(*testcases)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000402
403if False:
404 import sys
405 sys.path.insert(1, '/Py23Src/python/dist/src/Lib/test')
406 import test_zlib as tz
407 ts, ut = tz.test_support, tz.unittest
408 su = ut.TestSuite()
409 su.addTest(ut.makeSuite(tz.CompressTestCase))
410 ts.run_suite(su)