blob: 7957babaf01eb1d11e4b0bd18fdb81b903a920a9 [file] [log] [blame]
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +00001# We can test part of the module without zlib.
Guido van Rossum368f04a2000-04-10 13:23:04 +00002try:
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +00003 import zlib
4except ImportError:
5 zlib = None
Tim Petersa45cacf2004-08-20 03:47:14 +00006
Martin v. Löwis3eb76482007-03-06 10:41:24 +00007import zipfile, os, unittest, sys, shutil, struct
Tim Petersa19a1682001-03-29 04:36:09 +00008
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +00009from StringIO import StringIO
10from tempfile import TemporaryFile
Martin v. Löwis3eb76482007-03-06 10:41:24 +000011from random import randint, random
Tim Petersa19a1682001-03-29 04:36:09 +000012
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000013from test.test_support import TESTFN, run_unittest
Guido van Rossum368f04a2000-04-10 13:23:04 +000014
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000015TESTFN2 = TESTFN + "2"
Martin v. Löwis3eb76482007-03-06 10:41:24 +000016FIXEDTEST_SIZE = 10
Guido van Rossum368f04a2000-04-10 13:23:04 +000017
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000018class TestsWithSourceFile(unittest.TestCase):
19 def setUp(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +000020 self.line_gen = ("Zipfile test line %d. random float: %f" % (i, random())
21 for i in xrange(FIXEDTEST_SIZE))
22 self.data = '\n'.join(self.line_gen) + '\n'
Fred Drake6e7e4852001-02-28 05:34:16 +000023
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000024 # Make a source file with some lines
25 fp = open(TESTFN, "wb")
26 fp.write(self.data)
27 fp.close()
Tim Peters7d3bad62001-04-04 18:56:49 +000028
Martin v. Löwis3eb76482007-03-06 10:41:24 +000029 def makeTestArchive(self, f, compression):
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000030 # Create the ZIP archive
31 zipfp = zipfile.ZipFile(f, "w", compression)
32 zipfp.write(TESTFN, "another"+os.extsep+"name")
33 zipfp.write(TESTFN, TESTFN)
Ronald Oussoren143cefb2006-06-15 08:14:18 +000034 zipfp.writestr("strfile", self.data)
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000035 zipfp.close()
Tim Peters7d3bad62001-04-04 18:56:49 +000036
Martin v. Löwis3eb76482007-03-06 10:41:24 +000037 def zipTest(self, f, compression):
38 self.makeTestArchive(f, compression)
39
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000040 # Read the ZIP archive
41 zipfp = zipfile.ZipFile(f, "r", compression)
42 self.assertEqual(zipfp.read(TESTFN), self.data)
43 self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data)
Ronald Oussoren143cefb2006-06-15 08:14:18 +000044 self.assertEqual(zipfp.read("strfile"), self.data)
45
46 # Print the ZIP directory
47 fp = StringIO()
48 stdout = sys.stdout
49 try:
50 sys.stdout = fp
51
52 zipfp.printdir()
53 finally:
54 sys.stdout = stdout
Tim Petersa608bb22006-06-15 18:06:29 +000055
Ronald Oussoren143cefb2006-06-15 08:14:18 +000056 directory = fp.getvalue()
57 lines = directory.splitlines()
58 self.assertEquals(len(lines), 4) # Number of files + header
59
60 self.assert_('File Name' in lines[0])
61 self.assert_('Modified' in lines[0])
62 self.assert_('Size' in lines[0])
63
64 fn, date, time, size = lines[1].split()
65 self.assertEquals(fn, 'another.name')
66 # XXX: timestamp is not tested
67 self.assertEquals(size, str(len(self.data)))
68
69 # Check the namelist
70 names = zipfp.namelist()
71 self.assertEquals(len(names), 3)
72 self.assert_(TESTFN in names)
73 self.assert_("another"+os.extsep+"name" in names)
74 self.assert_("strfile" in names)
75
76 # Check infolist
77 infos = zipfp.infolist()
78 names = [ i.filename for i in infos ]
79 self.assertEquals(len(names), 3)
80 self.assert_(TESTFN in names)
81 self.assert_("another"+os.extsep+"name" in names)
82 self.assert_("strfile" in names)
83 for i in infos:
84 self.assertEquals(i.file_size, len(self.data))
85
86 # check getinfo
87 for nm in (TESTFN, "another"+os.extsep+"name", "strfile"):
88 info = zipfp.getinfo(nm)
89 self.assertEquals(info.filename, nm)
90 self.assertEquals(info.file_size, len(self.data))
91
92 # Check that testzip doesn't raise an exception
93 zipfp.testzip()
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000094 zipfp.close()
Tim Peters7d3bad62001-04-04 18:56:49 +000095
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000096 def testStored(self):
97 for f in (TESTFN2, TemporaryFile(), StringIO()):
98 self.zipTest(f, zipfile.ZIP_STORED)
Raymond Hettingerc0fac962003-06-27 22:25:03 +000099
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000100 def zipOpenTest(self, f, compression):
101 self.makeTestArchive(f, compression)
102
103 # Read the ZIP archive
104 zipfp = zipfile.ZipFile(f, "r", compression)
105 zipdata1 = []
106 zipopen1 = zipfp.open(TESTFN)
107 while 1:
108 read_data = zipopen1.read(256)
109 if not read_data:
110 break
111 zipdata1.append(read_data)
112
113 zipdata2 = []
114 zipopen2 = zipfp.open("another"+os.extsep+"name")
115 while 1:
116 read_data = zipopen2.read(256)
117 if not read_data:
118 break
119 zipdata2.append(read_data)
Tim Petersea5962f2007-03-12 18:07:52 +0000120
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000121 self.assertEqual(''.join(zipdata1), self.data)
122 self.assertEqual(''.join(zipdata2), self.data)
123 zipfp.close()
Tim Petersea5962f2007-03-12 18:07:52 +0000124
125 def testOpenStored(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000126 for f in (TESTFN2, TemporaryFile(), StringIO()):
127 self.zipOpenTest(f, zipfile.ZIP_STORED)
128
129 def zipRandomOpenTest(self, f, compression):
130 self.makeTestArchive(f, compression)
131
132 # Read the ZIP archive
133 zipfp = zipfile.ZipFile(f, "r", compression)
134 zipdata1 = []
135 zipopen1 = zipfp.open(TESTFN)
136 while 1:
137 read_data = zipopen1.read(randint(1, 1024))
138 if not read_data:
139 break
140 zipdata1.append(read_data)
141
142 self.assertEqual(''.join(zipdata1), self.data)
143 zipfp.close()
Tim Petersea5962f2007-03-12 18:07:52 +0000144
145 def testRandomOpenStored(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000146 for f in (TESTFN2, TemporaryFile(), StringIO()):
147 self.zipRandomOpenTest(f, zipfile.ZIP_STORED)
Tim Petersea5962f2007-03-12 18:07:52 +0000148
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000149 def zipReadlineTest(self, f, compression):
150 self.makeTestArchive(f, compression)
151
152 # Read the ZIP archive
153 zipfp = zipfile.ZipFile(f, "r")
154 zipopen = zipfp.open(TESTFN)
155 for line in self.line_gen:
156 linedata = zipopen.readline()
157 self.assertEqual(linedata, line + '\n')
158
159 zipfp.close()
160
161 def zipReadlinesTest(self, f, compression):
162 self.makeTestArchive(f, compression)
163
164 # Read the ZIP archive
165 zipfp = zipfile.ZipFile(f, "r")
166 ziplines = zipfp.open(TESTFN).readlines()
167 for line, zipline in zip(self.line_gen, ziplines):
168 self.assertEqual(zipline, line + '\n')
169
170 zipfp.close()
171
172 def zipIterlinesTest(self, f, compression):
173 self.makeTestArchive(f, compression)
174
175 # Read the ZIP archive
176 zipfp = zipfile.ZipFile(f, "r")
177 for line, zipline in zip(self.line_gen, zipfp.open(TESTFN)):
178 self.assertEqual(zipline, line + '\n')
179
180 zipfp.close()
Tim Petersea5962f2007-03-12 18:07:52 +0000181
182 def testReadlineStored(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000183 for f in (TESTFN2, TemporaryFile(), StringIO()):
184 self.zipReadlineTest(f, zipfile.ZIP_STORED)
185
Tim Petersea5962f2007-03-12 18:07:52 +0000186 def testReadlinesStored(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000187 for f in (TESTFN2, TemporaryFile(), StringIO()):
188 self.zipReadlinesTest(f, zipfile.ZIP_STORED)
189
Tim Petersea5962f2007-03-12 18:07:52 +0000190 def testIterlinesStored(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000191 for f in (TESTFN2, TemporaryFile(), StringIO()):
192 self.zipIterlinesTest(f, zipfile.ZIP_STORED)
193
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000194 if zlib:
195 def testDeflated(self):
196 for f in (TESTFN2, TemporaryFile(), StringIO()):
197 self.zipTest(f, zipfile.ZIP_DEFLATED)
Raymond Hettingerc0fac962003-06-27 22:25:03 +0000198
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000199 def testOpenDeflated(self):
200 for f in (TESTFN2, TemporaryFile(), StringIO()):
201 self.zipOpenTest(f, zipfile.ZIP_DEFLATED)
202
203 def testRandomOpenDeflated(self):
204 for f in (TESTFN2, TemporaryFile(), StringIO()):
205 self.zipRandomOpenTest(f, zipfile.ZIP_DEFLATED)
206
Tim Petersea5962f2007-03-12 18:07:52 +0000207 def testReadlineDeflated(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000208 for f in (TESTFN2, TemporaryFile(), StringIO()):
209 self.zipReadlineTest(f, zipfile.ZIP_DEFLATED)
210
Tim Petersea5962f2007-03-12 18:07:52 +0000211 def testReadlinesDeflated(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000212 for f in (TESTFN2, TemporaryFile(), StringIO()):
213 self.zipReadlinesTest(f, zipfile.ZIP_DEFLATED)
214
Tim Petersea5962f2007-03-12 18:07:52 +0000215 def testIterlinesDeflated(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000216 for f in (TESTFN2, TemporaryFile(), StringIO()):
217 self.zipIterlinesTest(f, zipfile.ZIP_DEFLATED)
Tim Petersea5962f2007-03-12 18:07:52 +0000218
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000219 def testLowCompression(self):
220 # Checks for cases where compressed data is larger than original
221 # Create the ZIP archive
222 zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED)
223 zipfp.writestr("strfile", '12')
224 zipfp.close()
225
226 # Get an open object for strfile
227 zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_DEFLATED)
228 openobj = zipfp.open("strfile")
229 self.assertEqual(openobj.read(1), '1')
230 self.assertEqual(openobj.read(1), '2')
231
Georg Brandl8f7c54e2006-02-20 08:40:38 +0000232 def testAbsoluteArcnames(self):
233 zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED)
234 zipfp.write(TESTFN, "/absolute")
235 zipfp.close()
236
237 zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED)
238 self.assertEqual(zipfp.namelist(), ["absolute"])
239 zipfp.close()
Tim Peters32cbc962006-02-20 21:42:18 +0000240
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000241 def tearDown(self):
242 os.remove(TESTFN)
243 os.remove(TESTFN2)
244
Ronald Oussoren143cefb2006-06-15 08:14:18 +0000245class TestZip64InSmallFiles(unittest.TestCase):
246 # These tests test the ZIP64 functionality without using large files,
247 # see test_zipfile64 for proper tests.
248
249 def setUp(self):
250 self._limit = zipfile.ZIP64_LIMIT
251 zipfile.ZIP64_LIMIT = 5
252
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000253 line_gen = ("Test of zipfile line %d." % i for i in range(0, FIXEDTEST_SIZE))
Ronald Oussoren143cefb2006-06-15 08:14:18 +0000254 self.data = '\n'.join(line_gen)
255
256 # Make a source file with some lines
257 fp = open(TESTFN, "wb")
258 fp.write(self.data)
259 fp.close()
260
261 def largeFileExceptionTest(self, f, compression):
262 zipfp = zipfile.ZipFile(f, "w", compression)
Tim Petersa608bb22006-06-15 18:06:29 +0000263 self.assertRaises(zipfile.LargeZipFile,
Ronald Oussoren143cefb2006-06-15 08:14:18 +0000264 zipfp.write, TESTFN, "another"+os.extsep+"name")
265 zipfp.close()
266
267 def largeFileExceptionTest2(self, f, compression):
268 zipfp = zipfile.ZipFile(f, "w", compression)
Tim Petersa608bb22006-06-15 18:06:29 +0000269 self.assertRaises(zipfile.LargeZipFile,
Ronald Oussoren143cefb2006-06-15 08:14:18 +0000270 zipfp.writestr, "another"+os.extsep+"name", self.data)
271 zipfp.close()
272
273 def testLargeFileException(self):
274 for f in (TESTFN2, TemporaryFile(), StringIO()):
275 self.largeFileExceptionTest(f, zipfile.ZIP_STORED)
276 self.largeFileExceptionTest2(f, zipfile.ZIP_STORED)
277
278 def zipTest(self, f, compression):
279 # Create the ZIP archive
280 zipfp = zipfile.ZipFile(f, "w", compression, allowZip64=True)
281 zipfp.write(TESTFN, "another"+os.extsep+"name")
282 zipfp.write(TESTFN, TESTFN)
283 zipfp.writestr("strfile", self.data)
284 zipfp.close()
285
286 # Read the ZIP archive
287 zipfp = zipfile.ZipFile(f, "r", compression)
288 self.assertEqual(zipfp.read(TESTFN), self.data)
289 self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data)
290 self.assertEqual(zipfp.read("strfile"), self.data)
291
292 # Print the ZIP directory
293 fp = StringIO()
294 stdout = sys.stdout
295 try:
296 sys.stdout = fp
297
298 zipfp.printdir()
299 finally:
300 sys.stdout = stdout
Tim Petersa608bb22006-06-15 18:06:29 +0000301
Ronald Oussoren143cefb2006-06-15 08:14:18 +0000302 directory = fp.getvalue()
303 lines = directory.splitlines()
304 self.assertEquals(len(lines), 4) # Number of files + header
305
306 self.assert_('File Name' in lines[0])
307 self.assert_('Modified' in lines[0])
308 self.assert_('Size' in lines[0])
309
310 fn, date, time, size = lines[1].split()
311 self.assertEquals(fn, 'another.name')
312 # XXX: timestamp is not tested
313 self.assertEquals(size, str(len(self.data)))
314
315 # Check the namelist
316 names = zipfp.namelist()
317 self.assertEquals(len(names), 3)
318 self.assert_(TESTFN in names)
319 self.assert_("another"+os.extsep+"name" in names)
320 self.assert_("strfile" in names)
321
322 # Check infolist
323 infos = zipfp.infolist()
324 names = [ i.filename for i in infos ]
325 self.assertEquals(len(names), 3)
326 self.assert_(TESTFN in names)
327 self.assert_("another"+os.extsep+"name" in names)
328 self.assert_("strfile" in names)
329 for i in infos:
330 self.assertEquals(i.file_size, len(self.data))
331
332 # check getinfo
333 for nm in (TESTFN, "another"+os.extsep+"name", "strfile"):
334 info = zipfp.getinfo(nm)
335 self.assertEquals(info.filename, nm)
336 self.assertEquals(info.file_size, len(self.data))
337
338 # Check that testzip doesn't raise an exception
339 zipfp.testzip()
340
341
342 zipfp.close()
343
344 def testStored(self):
345 for f in (TESTFN2, TemporaryFile(), StringIO()):
346 self.zipTest(f, zipfile.ZIP_STORED)
347
348
349 if zlib:
350 def testDeflated(self):
351 for f in (TESTFN2, TemporaryFile(), StringIO()):
352 self.zipTest(f, zipfile.ZIP_DEFLATED)
353
354 def testAbsoluteArcnames(self):
355 zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED, allowZip64=True)
356 zipfp.write(TESTFN, "/absolute")
357 zipfp.close()
358
359 zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED)
360 self.assertEqual(zipfp.namelist(), ["absolute"])
361 zipfp.close()
362
363
364 def tearDown(self):
365 zipfile.ZIP64_LIMIT = self._limit
366 os.remove(TESTFN)
367 os.remove(TESTFN2)
368
369class PyZipFileTests(unittest.TestCase):
370 def testWritePyfile(self):
371 zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
372 fn = __file__
373 if fn.endswith('.pyc') or fn.endswith('.pyo'):
374 fn = fn[:-1]
375
376 zipfp.writepy(fn)
377
378 bn = os.path.basename(fn)
379 self.assert_(bn not in zipfp.namelist())
380 self.assert_(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist())
381 zipfp.close()
382
383
384 zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
385 fn = __file__
386 if fn.endswith('.pyc') or fn.endswith('.pyo'):
387 fn = fn[:-1]
388
389 zipfp.writepy(fn, "testpackage")
390
391 bn = "%s/%s"%("testpackage", os.path.basename(fn))
392 self.assert_(bn not in zipfp.namelist())
393 self.assert_(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist())
394 zipfp.close()
395
396 def testWritePythonPackage(self):
397 import email
398 packagedir = os.path.dirname(email.__file__)
399
400 zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
401 zipfp.writepy(packagedir)
402
403 # Check for a couple of modules at different levels of the hieararchy
404 names = zipfp.namelist()
405 self.assert_('email/__init__.pyo' in names or 'email/__init__.pyc' in names)
406 self.assert_('email/mime/text.pyo' in names or 'email/mime/text.pyc' in names)
407
408 def testWritePythonDirectory(self):
409 os.mkdir(TESTFN2)
410 try:
411 fp = open(os.path.join(TESTFN2, "mod1.py"), "w")
412 fp.write("print 42\n")
413 fp.close()
414
415 fp = open(os.path.join(TESTFN2, "mod2.py"), "w")
416 fp.write("print 42 * 42\n")
417 fp.close()
418
419 fp = open(os.path.join(TESTFN2, "mod2.txt"), "w")
420 fp.write("bla bla bla\n")
421 fp.close()
422
423 zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
424 zipfp.writepy(TESTFN2)
425
426 names = zipfp.namelist()
427 self.assert_('mod1.pyc' in names or 'mod1.pyo' in names)
428 self.assert_('mod2.pyc' in names or 'mod2.pyo' in names)
429 self.assert_('mod2.txt' not in names)
430
431 finally:
432 shutil.rmtree(TESTFN2)
433
434
435
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000436class OtherTests(unittest.TestCase):
Martin v. Löwis84f6de92007-02-13 10:10:39 +0000437 def testCreateNonExistentFileForAppend(self):
438 if os.path.exists(TESTFN):
439 os.unlink(TESTFN)
Tim Petersea5962f2007-03-12 18:07:52 +0000440
Martin v. Löwis84f6de92007-02-13 10:10:39 +0000441 filename = 'testfile.txt'
442 content = 'hello, world. this is some content.'
Tim Petersea5962f2007-03-12 18:07:52 +0000443
Martin v. Löwis84f6de92007-02-13 10:10:39 +0000444 try:
445 zf = zipfile.ZipFile(TESTFN, 'a')
446 zf.writestr(filename, content)
447 zf.close()
448 except IOError, (errno, errmsg):
449 self.fail('Could not append data to a non-existent zip file.')
450
451 self.assert_(os.path.exists(TESTFN))
452
453 zf = zipfile.ZipFile(TESTFN, 'r')
454 self.assertEqual(zf.read(filename), content)
455 zf.close()
Tim Petersea5962f2007-03-12 18:07:52 +0000456
Martin v. Löwis84f6de92007-02-13 10:10:39 +0000457 os.unlink(TESTFN)
Tim Petersea5962f2007-03-12 18:07:52 +0000458
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000459 def testCloseErroneousFile(self):
460 # This test checks that the ZipFile constructor closes the file object
461 # it opens if there's an error in the file. If it doesn't, the traceback
462 # holds a reference to the ZipFile object and, indirectly, the file object.
463 # On Windows, this causes the os.unlink() call to fail because the
464 # underlying file is still open. This is SF bug #412214.
465 #
466 fp = open(TESTFN, "w")
467 fp.write("this is not a legal zip file\n")
468 fp.close()
469 try:
470 zf = zipfile.ZipFile(TESTFN)
471 except zipfile.BadZipfile:
472 os.unlink(TESTFN)
473
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000474 def testIsZipErroneousFile(self):
Tim Petersea5962f2007-03-12 18:07:52 +0000475 # This test checks that the is_zipfile function correctly identifies
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000476 # a file that is not a zip file
477 fp = open(TESTFN, "w")
478 fp.write("this is not a legal zip file\n")
479 fp.close()
Tim Petersea5962f2007-03-12 18:07:52 +0000480 chk = zipfile.is_zipfile(TESTFN)
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000481 os.unlink(TESTFN)
Tim Petersea5962f2007-03-12 18:07:52 +0000482 self.assert_(chk is False)
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000483
484 def testIsZipValidFile(self):
Tim Petersea5962f2007-03-12 18:07:52 +0000485 # This test checks that the is_zipfile function correctly identifies
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000486 # a file that is a zip file
487 zipf = zipfile.ZipFile(TESTFN, mode="w")
488 zipf.writestr("foo.txt", "O, for a Muse of Fire!")
489 zipf.close()
Tim Petersea5962f2007-03-12 18:07:52 +0000490 chk = zipfile.is_zipfile(TESTFN)
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000491 os.unlink(TESTFN)
Tim Petersea5962f2007-03-12 18:07:52 +0000492 self.assert_(chk is True)
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000493
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000494 def testNonExistentFileRaisesIOError(self):
495 # make sure we don't raise an AttributeError when a partially-constructed
496 # ZipFile instance is finalized; this tests for regression on SF tracker
497 # bug #403871.
498
499 # The bug we're testing for caused an AttributeError to be raised
500 # when a ZipFile instance was created for a file that did not
501 # exist; the .fp member was not initialized but was needed by the
502 # __del__() method. Since the AttributeError is in the __del__(),
503 # it is ignored, but the user should be sufficiently annoyed by
504 # the message on the output that regression will be noticed
505 # quickly.
506 self.assertRaises(IOError, zipfile.ZipFile, TESTFN)
507
508 def testClosedZipRaisesRuntimeError(self):
509 # Verify that testzip() doesn't swallow inappropriate exceptions.
510 data = StringIO()
511 zipf = zipfile.ZipFile(data, mode="w")
512 zipf.writestr("foo.txt", "O, for a Muse of Fire!")
513 zipf.close()
514
515 # This is correct; calling .read on a closed ZipFile should throw
516 # a RuntimeError, and so should calling .testzip. An earlier
517 # version of .testzip would swallow this exception (and any other)
518 # and report that the first file in the archive was corrupt.
519 self.assertRaises(RuntimeError, zipf.testzip)
520
Martin v. Löwisc6d626e2007-02-13 09:49:38 +0000521class DecryptionTests(unittest.TestCase):
522 # This test checks that ZIP decryption works. Since the library does not
523 # support encryption at the moment, we use a pre-generated encrypted
524 # ZIP file
525
526 data = (
527 'PK\x03\x04\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00\x1a\x00'
528 '\x00\x00\x08\x00\x00\x00test.txt\xfa\x10\xa0gly|\xfa-\xc5\xc0=\xf9y'
529 '\x18\xe0\xa8r\xb3Z}Lg\xbc\xae\xf9|\x9b\x19\xe4\x8b\xba\xbb)\x8c\xb0\xdbl'
530 'PK\x01\x02\x14\x00\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00'
531 '\x1a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00 \x00\xb6\x81'
532 '\x00\x00\x00\x00test.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00'
533 '\x00\x00L\x00\x00\x00\x00\x00' )
534
535 plain = 'zipfile.py encryption test'
536
537 def setUp(self):
538 fp = open(TESTFN, "wb")
539 fp.write(self.data)
540 fp.close()
541 self.zip = zipfile.ZipFile(TESTFN, "r")
542
543 def tearDown(self):
544 self.zip.close()
545 os.unlink(TESTFN)
546
547 def testNoPassword(self):
548 # Reading the encrypted file without password
549 # must generate a RunTime exception
550 self.assertRaises(RuntimeError, self.zip.read, "test.txt")
551
552 def testBadPassword(self):
553 self.zip.setpassword("perl")
554 self.assertRaises(RuntimeError, self.zip.read, "test.txt")
Tim Petersea5962f2007-03-12 18:07:52 +0000555
Martin v. Löwisc6d626e2007-02-13 09:49:38 +0000556 def testGoodPassword(self):
557 self.zip.setpassword("python")
558 self.assertEquals(self.zip.read("test.txt"), self.plain)
559
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000560
561class TestsWithRandomBinaryFiles(unittest.TestCase):
562 def setUp(self):
563 datacount = randint(16, 64)*1024 + randint(1, 1024)
564 self.data = ''.join((struct.pack('<f', random()*randint(-1000, 1000)) for i in xrange(datacount)))
565
566 # Make a source file with some lines
567 fp = open(TESTFN, "wb")
568 fp.write(self.data)
569 fp.close()
570
571 def makeTestArchive(self, f, compression):
572 # Create the ZIP archive
573 zipfp = zipfile.ZipFile(f, "w", compression)
574 zipfp.write(TESTFN, "another"+os.extsep+"name")
575 zipfp.write(TESTFN, TESTFN)
576 zipfp.close()
577
578 def zipTest(self, f, compression):
579 self.makeTestArchive(f, compression)
580
581 # Read the ZIP archive
582 zipfp = zipfile.ZipFile(f, "r", compression)
583 testdata = zipfp.read(TESTFN)
584 self.assertEqual(len(testdata), len(self.data))
585 self.assertEqual(testdata, self.data)
586 self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data)
587 zipfp.close()
588
589 def testStored(self):
590 for f in (TESTFN2, TemporaryFile(), StringIO()):
591 self.zipTest(f, zipfile.ZIP_STORED)
Tim Petersea5962f2007-03-12 18:07:52 +0000592
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000593 def zipOpenTest(self, f, compression):
594 self.makeTestArchive(f, compression)
595
596 # Read the ZIP archive
597 zipfp = zipfile.ZipFile(f, "r", compression)
598 zipdata1 = []
599 zipopen1 = zipfp.open(TESTFN)
600 while 1:
601 read_data = zipopen1.read(256)
602 if not read_data:
603 break
604 zipdata1.append(read_data)
605
606 zipdata2 = []
607 zipopen2 = zipfp.open("another"+os.extsep+"name")
608 while 1:
609 read_data = zipopen2.read(256)
610 if not read_data:
611 break
612 zipdata2.append(read_data)
Tim Petersea5962f2007-03-12 18:07:52 +0000613
614 testdata1 = ''.join(zipdata1)
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000615 self.assertEqual(len(testdata1), len(self.data))
616 self.assertEqual(testdata1, self.data)
617
Tim Petersea5962f2007-03-12 18:07:52 +0000618 testdata2 = ''.join(zipdata2)
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000619 self.assertEqual(len(testdata1), len(self.data))
620 self.assertEqual(testdata1, self.data)
621 zipfp.close()
Tim Petersea5962f2007-03-12 18:07:52 +0000622
623 def testOpenStored(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000624 for f in (TESTFN2, TemporaryFile(), StringIO()):
625 self.zipOpenTest(f, zipfile.ZIP_STORED)
626
627 def zipRandomOpenTest(self, f, compression):
628 self.makeTestArchive(f, compression)
629
630 # Read the ZIP archive
631 zipfp = zipfile.ZipFile(f, "r", compression)
632 zipdata1 = []
633 zipopen1 = zipfp.open(TESTFN)
634 while 1:
635 read_data = zipopen1.read(randint(1, 1024))
636 if not read_data:
637 break
638 zipdata1.append(read_data)
639
640 testdata = ''.join(zipdata1)
641 self.assertEqual(len(testdata), len(self.data))
642 self.assertEqual(testdata, self.data)
643 zipfp.close()
Tim Petersea5962f2007-03-12 18:07:52 +0000644
645 def testRandomOpenStored(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000646 for f in (TESTFN2, TemporaryFile(), StringIO()):
647 self.zipRandomOpenTest(f, zipfile.ZIP_STORED)
648
649class TestsWithMultipleOpens(unittest.TestCase):
650 def setUp(self):
651 # Create the ZIP archive
652 zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED)
653 zipfp.writestr('ones', '1'*FIXEDTEST_SIZE)
654 zipfp.writestr('twos', '2'*FIXEDTEST_SIZE)
655 zipfp.close()
Tim Petersea5962f2007-03-12 18:07:52 +0000656
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000657 def testSameFile(self):
658 # Verify that (when the ZipFile is in control of creating file objects)
659 # multiple open() calls can be made without interfering with each other.
660 zipf = zipfile.ZipFile(TESTFN2, mode="r")
661 zopen1 = zipf.open('ones')
662 zopen2 = zipf.open('ones')
663 data1 = zopen1.read(500)
664 data2 = zopen2.read(500)
665 data1 += zopen1.read(500)
666 data2 += zopen2.read(500)
667 self.assertEqual(data1, data2)
668 zipf.close()
669
670 def testDifferentFile(self):
671 # Verify that (when the ZipFile is in control of creating file objects)
672 # multiple open() calls can be made without interfering with each other.
673 zipf = zipfile.ZipFile(TESTFN2, mode="r")
674 zopen1 = zipf.open('ones')
675 zopen2 = zipf.open('twos')
676 data1 = zopen1.read(500)
677 data2 = zopen2.read(500)
678 data1 += zopen1.read(500)
679 data2 += zopen2.read(500)
680 self.assertEqual(data1, '1'*FIXEDTEST_SIZE)
681 self.assertEqual(data2, '2'*FIXEDTEST_SIZE)
682 zipf.close()
683
684 def testInterleaved(self):
685 # Verify that (when the ZipFile is in control of creating file objects)
686 # multiple open() calls can be made without interfering with each other.
687 zipf = zipfile.ZipFile(TESTFN2, mode="r")
688 zopen1 = zipf.open('ones')
689 data1 = zopen1.read(500)
690 zopen2 = zipf.open('twos')
691 data2 = zopen2.read(500)
692 data1 += zopen1.read(500)
693 data2 += zopen2.read(500)
694 self.assertEqual(data1, '1'*FIXEDTEST_SIZE)
695 self.assertEqual(data2, '2'*FIXEDTEST_SIZE)
696 zipf.close()
Tim Petersea5962f2007-03-12 18:07:52 +0000697
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000698 def tearDown(self):
699 os.remove(TESTFN2)
Tim Petersea5962f2007-03-12 18:07:52 +0000700
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000701
702class UniversalNewlineTests(unittest.TestCase):
703 def setUp(self):
704 self.line_gen = ["Test of zipfile line %d." % i for i in xrange(FIXEDTEST_SIZE)]
705 self.seps = ('\r', '\r\n', '\n')
706 self.arcdata, self.arcfiles = {}, {}
707 for n, s in enumerate(self.seps):
708 self.arcdata[s] = s.join(self.line_gen) + s
709 self.arcfiles[s] = '%s-%d' % (TESTFN, n)
710 file(self.arcfiles[s], "wb").write(self.arcdata[s])
711
712 def makeTestArchive(self, f, compression):
713 # Create the ZIP archive
714 zipfp = zipfile.ZipFile(f, "w", compression)
715 for fn in self.arcfiles.values():
716 zipfp.write(fn, fn)
717 zipfp.close()
718
719 def readTest(self, f, compression):
720 self.makeTestArchive(f, compression)
721
722 # Read the ZIP archive
723 zipfp = zipfile.ZipFile(f, "r")
724 for sep, fn in self.arcfiles.items():
725 zipdata = zipfp.open(fn, "rU").read()
726 self.assertEqual(self.arcdata[sep], zipdata)
727
728 zipfp.close()
Tim Petersea5962f2007-03-12 18:07:52 +0000729
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000730 def readlineTest(self, f, compression):
731 self.makeTestArchive(f, compression)
732
733 # Read the ZIP archive
734 zipfp = zipfile.ZipFile(f, "r")
735 for sep, fn in self.arcfiles.items():
736 zipopen = zipfp.open(fn, "rU")
737 for line in self.line_gen:
738 linedata = zipopen.readline()
739 self.assertEqual(linedata, line + '\n')
740
741 zipfp.close()
742
743 def readlinesTest(self, f, compression):
744 self.makeTestArchive(f, compression)
745
746 # Read the ZIP archive
747 zipfp = zipfile.ZipFile(f, "r")
748 for sep, fn in self.arcfiles.items():
749 ziplines = zipfp.open(fn, "rU").readlines()
750 for line, zipline in zip(self.line_gen, ziplines):
751 self.assertEqual(zipline, line + '\n')
752
753 zipfp.close()
754
755 def iterlinesTest(self, f, compression):
756 self.makeTestArchive(f, compression)
757
758 # Read the ZIP archive
759 zipfp = zipfile.ZipFile(f, "r")
760 for sep, fn in self.arcfiles.items():
761 for line, zipline in zip(self.line_gen, zipfp.open(fn, "rU")):
762 self.assertEqual(zipline, line + '\n')
763
764 zipfp.close()
765
Tim Petersea5962f2007-03-12 18:07:52 +0000766 def testReadStored(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000767 for f in (TESTFN2, TemporaryFile(), StringIO()):
768 self.readTest(f, zipfile.ZIP_STORED)
Tim Petersea5962f2007-03-12 18:07:52 +0000769
770 def testReadlineStored(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000771 for f in (TESTFN2, TemporaryFile(), StringIO()):
772 self.readlineTest(f, zipfile.ZIP_STORED)
773
Tim Petersea5962f2007-03-12 18:07:52 +0000774 def testReadlinesStored(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000775 for f in (TESTFN2, TemporaryFile(), StringIO()):
776 self.readlinesTest(f, zipfile.ZIP_STORED)
777
Tim Petersea5962f2007-03-12 18:07:52 +0000778 def testIterlinesStored(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000779 for f in (TESTFN2, TemporaryFile(), StringIO()):
780 self.iterlinesTest(f, zipfile.ZIP_STORED)
Tim Petersea5962f2007-03-12 18:07:52 +0000781
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000782 if zlib:
Tim Petersea5962f2007-03-12 18:07:52 +0000783 def testReadDeflated(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000784 for f in (TESTFN2, TemporaryFile(), StringIO()):
785 self.readTest(f, zipfile.ZIP_DEFLATED)
786
Tim Petersea5962f2007-03-12 18:07:52 +0000787 def testReadlineDeflated(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000788 for f in (TESTFN2, TemporaryFile(), StringIO()):
789 self.readlineTest(f, zipfile.ZIP_DEFLATED)
790
Tim Petersea5962f2007-03-12 18:07:52 +0000791 def testReadlinesDeflated(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000792 for f in (TESTFN2, TemporaryFile(), StringIO()):
793 self.readlinesTest(f, zipfile.ZIP_DEFLATED)
794
Tim Petersea5962f2007-03-12 18:07:52 +0000795 def testIterlinesDeflated(self):
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000796 for f in (TESTFN2, TemporaryFile(), StringIO()):
797 self.iterlinesTest(f, zipfile.ZIP_DEFLATED)
798
799 def tearDown(self):
800 for sep, fn in self.arcfiles.items():
801 os.remove(fn)
802
803
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000804def test_main():
Tim Petersea5962f2007-03-12 18:07:52 +0000805 run_unittest(TestsWithSourceFile, TestZip64InSmallFiles, OtherTests,
806 PyZipFileTests, DecryptionTests, TestsWithMultipleOpens,
Martin v. Löwis3eb76482007-03-06 10:41:24 +0000807 UniversalNewlineTests, TestsWithRandomBinaryFiles)
808
Ronald Oussoren143cefb2006-06-15 08:14:18 +0000809 #run_unittest(TestZip64InSmallFiles)
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000810
811if __name__ == "__main__":
812 test_main()