blob: 197170a96eac0466a5c0dfd7df0e03c6a6fff31f [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
Guido van Rossumd6ca5462007-05-22 01:29:33 +00006import zipfile, os, unittest, sys, shutil, struct, io
Tim Petersa45cacf2004-08-20 03:47:14 +00007
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +00008from tempfile import TemporaryFile
Guido van Rossumd8faa362007-04-27 19:54:29 +00009from random import randint, random
Tim Petersa19a1682001-03-29 04:36:09 +000010
Guido van Rossumd8faa362007-04-27 19:54:29 +000011import test.test_support as support
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000012from test.test_support import TESTFN, run_unittest
Guido van Rossum368f04a2000-04-10 13:23:04 +000013
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000014TESTFN2 = TESTFN + "2"
Guido van Rossumd8faa362007-04-27 19:54:29 +000015FIXEDTEST_SIZE = 10
Guido van Rossum368f04a2000-04-10 13:23:04 +000016
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000017class TestsWithSourceFile(unittest.TestCase):
18 def setUp(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +000019 self.line_gen = (bytes("Zipfile test line %d. random float: %f" %
20 (i, random()))
21 for i in range(FIXEDTEST_SIZE))
22 self.data = b'\n'.join(self.line_gen) + b'\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
Guido van Rossumd8faa362007-04-27 19:54:29 +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)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000034 zipfp.writestr("strfile", self.data)
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000035 zipfp.close()
Tim Peters7d3bad62001-04-04 18:56:49 +000036
Guido van Rossumd8faa362007-04-27 19:54:29 +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)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000044 self.assertEqual(zipfp.read("strfile"), self.data)
45
46 # Print the ZIP directory
Guido van Rossumd6ca5462007-05-22 01:29:33 +000047 fp = io.StringIO()
48 zipfp.printdir(file=fp)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049
50 directory = fp.getvalue()
51 lines = directory.splitlines()
52 self.assertEquals(len(lines), 4) # Number of files + header
53
54 self.assert_('File Name' in lines[0])
55 self.assert_('Modified' in lines[0])
56 self.assert_('Size' in lines[0])
57
58 fn, date, time, size = lines[1].split()
59 self.assertEquals(fn, 'another.name')
60 # XXX: timestamp is not tested
61 self.assertEquals(size, str(len(self.data)))
62
63 # Check the namelist
64 names = zipfp.namelist()
65 self.assertEquals(len(names), 3)
66 self.assert_(TESTFN in names)
67 self.assert_("another"+os.extsep+"name" in names)
68 self.assert_("strfile" in names)
69
70 # Check infolist
71 infos = zipfp.infolist()
72 names = [ i.filename for i in infos ]
73 self.assertEquals(len(names), 3)
74 self.assert_(TESTFN in names)
75 self.assert_("another"+os.extsep+"name" in names)
76 self.assert_("strfile" in names)
77 for i in infos:
78 self.assertEquals(i.file_size, len(self.data))
79
80 # check getinfo
81 for nm in (TESTFN, "another"+os.extsep+"name", "strfile"):
82 info = zipfp.getinfo(nm)
83 self.assertEquals(info.filename, nm)
84 self.assertEquals(info.file_size, len(self.data))
85
86 # Check that testzip doesn't raise an exception
87 zipfp.testzip()
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000088 zipfp.close()
Tim Peters7d3bad62001-04-04 18:56:49 +000089
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000090 def testStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +000091 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000092 self.zipTest(f, zipfile.ZIP_STORED)
Raymond Hettingerc0fac962003-06-27 22:25:03 +000093
Guido van Rossumd8faa362007-04-27 19:54:29 +000094 def zipOpenTest(self, f, compression):
95 self.makeTestArchive(f, compression)
96
97 # Read the ZIP archive
98 zipfp = zipfile.ZipFile(f, "r", compression)
99 zipdata1 = []
100 zipopen1 = zipfp.open(TESTFN)
101 while 1:
102 read_data = zipopen1.read(256)
103 if not read_data:
104 break
105 zipdata1.append(read_data)
106
107 zipdata2 = []
108 zipopen2 = zipfp.open("another"+os.extsep+"name")
109 while 1:
110 read_data = zipopen2.read(256)
111 if not read_data:
112 break
113 zipdata2.append(read_data)
114
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000115 self.assertEqual(b''.join(zipdata1), self.data)
116 self.assertEqual(b''.join(zipdata2), self.data)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000117 zipfp.close()
118
119 def testOpenStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000120 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000121 self.zipOpenTest(f, zipfile.ZIP_STORED)
122
123 def zipRandomOpenTest(self, f, compression):
124 self.makeTestArchive(f, compression)
125
126 # Read the ZIP archive
127 zipfp = zipfile.ZipFile(f, "r", compression)
128 zipdata1 = []
129 zipopen1 = zipfp.open(TESTFN)
130 while 1:
131 read_data = zipopen1.read(randint(1, 1024))
132 if not read_data:
133 break
134 zipdata1.append(read_data)
135
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000136 self.assertEqual(b''.join(zipdata1), self.data)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000137 zipfp.close()
138
139 def testRandomOpenStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000140 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000141 self.zipRandomOpenTest(f, zipfile.ZIP_STORED)
142
143 def zipReadlineTest(self, f, compression):
144 self.makeTestArchive(f, compression)
145
146 # Read the ZIP archive
147 zipfp = zipfile.ZipFile(f, "r")
148 zipopen = zipfp.open(TESTFN)
149 for line in self.line_gen:
150 linedata = zipopen.readline()
151 self.assertEqual(linedata, line + '\n')
152
153 zipfp.close()
154
155 def zipReadlinesTest(self, f, compression):
156 self.makeTestArchive(f, compression)
157
158 # Read the ZIP archive
159 zipfp = zipfile.ZipFile(f, "r")
160 ziplines = zipfp.open(TESTFN).readlines()
161 for line, zipline in zip(self.line_gen, ziplines):
162 self.assertEqual(zipline, line + '\n')
163
164 zipfp.close()
165
166 def zipIterlinesTest(self, f, compression):
167 self.makeTestArchive(f, compression)
168
169 # Read the ZIP archive
170 zipfp = zipfile.ZipFile(f, "r")
171 for line, zipline in zip(self.line_gen, zipfp.open(TESTFN)):
172 self.assertEqual(zipline, line + '\n')
173
174 zipfp.close()
175
176 def testReadlineStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000177 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000178 self.zipReadlineTest(f, zipfile.ZIP_STORED)
179
180 def testReadlinesStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000181 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000182 self.zipReadlinesTest(f, zipfile.ZIP_STORED)
183
184 def testIterlinesStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000185 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000186 self.zipIterlinesTest(f, zipfile.ZIP_STORED)
187
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000188 if zlib:
189 def testDeflated(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000190 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000191 self.zipTest(f, zipfile.ZIP_DEFLATED)
Raymond Hettingerc0fac962003-06-27 22:25:03 +0000192
Guido van Rossumd8faa362007-04-27 19:54:29 +0000193 def testOpenDeflated(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000194 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000195 self.zipOpenTest(f, zipfile.ZIP_DEFLATED)
196
197 def testRandomOpenDeflated(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000198 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000199 self.zipRandomOpenTest(f, zipfile.ZIP_DEFLATED)
200
201 def testReadlineDeflated(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000202 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000203 self.zipReadlineTest(f, zipfile.ZIP_DEFLATED)
204
205 def testReadlinesDeflated(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000206 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000207 self.zipReadlinesTest(f, zipfile.ZIP_DEFLATED)
208
209 def testIterlinesDeflated(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000210 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000211 self.zipIterlinesTest(f, zipfile.ZIP_DEFLATED)
212
213 def testLowCompression(self):
214 # Checks for cases where compressed data is larger than original
215 # Create the ZIP archive
216 zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED)
217 zipfp.writestr("strfile", '12')
218 zipfp.close()
219
220 # Get an open object for strfile
221 zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_DEFLATED)
222 openobj = zipfp.open("strfile")
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000223 self.assertEqual(openobj.read(1), b'1')
224 self.assertEqual(openobj.read(1), b'2')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000225
Georg Brandl8f7c54e2006-02-20 08:40:38 +0000226 def testAbsoluteArcnames(self):
227 zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED)
228 zipfp.write(TESTFN, "/absolute")
229 zipfp.close()
230
231 zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED)
232 self.assertEqual(zipfp.namelist(), ["absolute"])
233 zipfp.close()
Tim Peters32cbc962006-02-20 21:42:18 +0000234
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000235 def tearDown(self):
236 os.remove(TESTFN)
237 os.remove(TESTFN2)
238
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000239class TestZip64InSmallFiles(unittest.TestCase):
240 # These tests test the ZIP64 functionality without using large files,
241 # see test_zipfile64 for proper tests.
242
243 def setUp(self):
244 self._limit = zipfile.ZIP64_LIMIT
245 zipfile.ZIP64_LIMIT = 5
246
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000247 line_gen = (bytes("Test of zipfile line %d." % i)
248 for i in range(0, FIXEDTEST_SIZE))
249 self.data = b'\n'.join(line_gen)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000250
251 # Make a source file with some lines
252 fp = open(TESTFN, "wb")
253 fp.write(self.data)
254 fp.close()
255
256 def largeFileExceptionTest(self, f, compression):
257 zipfp = zipfile.ZipFile(f, "w", compression)
258 self.assertRaises(zipfile.LargeZipFile,
259 zipfp.write, TESTFN, "another"+os.extsep+"name")
260 zipfp.close()
261
262 def largeFileExceptionTest2(self, f, compression):
263 zipfp = zipfile.ZipFile(f, "w", compression)
264 self.assertRaises(zipfile.LargeZipFile,
265 zipfp.writestr, "another"+os.extsep+"name", self.data)
266 zipfp.close()
267
268 def testLargeFileException(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000269 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000270 self.largeFileExceptionTest(f, zipfile.ZIP_STORED)
271 self.largeFileExceptionTest2(f, zipfile.ZIP_STORED)
272
273 def zipTest(self, f, compression):
274 # Create the ZIP archive
275 zipfp = zipfile.ZipFile(f, "w", compression, allowZip64=True)
276 zipfp.write(TESTFN, "another"+os.extsep+"name")
277 zipfp.write(TESTFN, TESTFN)
278 zipfp.writestr("strfile", self.data)
279 zipfp.close()
280
281 # Read the ZIP archive
282 zipfp = zipfile.ZipFile(f, "r", compression)
283 self.assertEqual(zipfp.read(TESTFN), self.data)
284 self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data)
285 self.assertEqual(zipfp.read("strfile"), self.data)
286
287 # Print the ZIP directory
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000288 fp = io.StringIO()
289 zipfp.printdir(fp)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000290
291 directory = fp.getvalue()
292 lines = directory.splitlines()
293 self.assertEquals(len(lines), 4) # Number of files + header
294
295 self.assert_('File Name' in lines[0])
296 self.assert_('Modified' in lines[0])
297 self.assert_('Size' in lines[0])
298
299 fn, date, time, size = lines[1].split()
300 self.assertEquals(fn, 'another.name')
301 # XXX: timestamp is not tested
302 self.assertEquals(size, str(len(self.data)))
303
304 # Check the namelist
305 names = zipfp.namelist()
306 self.assertEquals(len(names), 3)
307 self.assert_(TESTFN in names)
308 self.assert_("another"+os.extsep+"name" in names)
309 self.assert_("strfile" in names)
310
311 # Check infolist
312 infos = zipfp.infolist()
313 names = [ i.filename for i in infos ]
314 self.assertEquals(len(names), 3)
315 self.assert_(TESTFN in names)
316 self.assert_("another"+os.extsep+"name" in names)
317 self.assert_("strfile" in names)
318 for i in infos:
319 self.assertEquals(i.file_size, len(self.data))
320
321 # check getinfo
322 for nm in (TESTFN, "another"+os.extsep+"name", "strfile"):
323 info = zipfp.getinfo(nm)
324 self.assertEquals(info.filename, nm)
325 self.assertEquals(info.file_size, len(self.data))
326
327 # Check that testzip doesn't raise an exception
328 zipfp.testzip()
329
330
331 zipfp.close()
332
333 def testStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000334 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000335 self.zipTest(f, zipfile.ZIP_STORED)
336
337
338 if zlib:
339 def testDeflated(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000340 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000341 self.zipTest(f, zipfile.ZIP_DEFLATED)
342
343 def testAbsoluteArcnames(self):
344 zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED, allowZip64=True)
345 zipfp.write(TESTFN, "/absolute")
346 zipfp.close()
347
348 zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED)
349 self.assertEqual(zipfp.namelist(), ["absolute"])
350 zipfp.close()
351
352
353 def tearDown(self):
354 zipfile.ZIP64_LIMIT = self._limit
355 os.remove(TESTFN)
356 os.remove(TESTFN2)
357
358class PyZipFileTests(unittest.TestCase):
359 def testWritePyfile(self):
360 zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
361 fn = __file__
362 if fn.endswith('.pyc') or fn.endswith('.pyo'):
363 fn = fn[:-1]
364
365 zipfp.writepy(fn)
366
367 bn = os.path.basename(fn)
368 self.assert_(bn not in zipfp.namelist())
369 self.assert_(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist())
370 zipfp.close()
371
372
373 zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
374 fn = __file__
375 if fn.endswith('.pyc') or fn.endswith('.pyo'):
376 fn = fn[:-1]
377
378 zipfp.writepy(fn, "testpackage")
379
380 bn = "%s/%s"%("testpackage", os.path.basename(fn))
381 self.assert_(bn not in zipfp.namelist())
382 self.assert_(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist())
383 zipfp.close()
384
385 def testWritePythonPackage(self):
386 import email
387 packagedir = os.path.dirname(email.__file__)
388
389 zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
390 zipfp.writepy(packagedir)
391
392 # Check for a couple of modules at different levels of the hieararchy
393 names = zipfp.namelist()
394 self.assert_('email/__init__.pyo' in names or 'email/__init__.pyc' in names)
395 self.assert_('email/mime/text.pyo' in names or 'email/mime/text.pyc' in names)
396
397 def testWritePythonDirectory(self):
398 os.mkdir(TESTFN2)
399 try:
400 fp = open(os.path.join(TESTFN2, "mod1.py"), "w")
Guido van Rossum43fc78d2007-02-09 22:18:41 +0000401 fp.write("print(42)\n")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000402 fp.close()
403
404 fp = open(os.path.join(TESTFN2, "mod2.py"), "w")
Guido van Rossum43fc78d2007-02-09 22:18:41 +0000405 fp.write("print(42 * 42)\n")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000406 fp.close()
407
408 fp = open(os.path.join(TESTFN2, "mod2.txt"), "w")
409 fp.write("bla bla bla\n")
410 fp.close()
411
412 zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
413 zipfp.writepy(TESTFN2)
414
415 names = zipfp.namelist()
416 self.assert_('mod1.pyc' in names or 'mod1.pyo' in names)
417 self.assert_('mod2.pyc' in names or 'mod2.pyo' in names)
418 self.assert_('mod2.txt' not in names)
419
420 finally:
421 shutil.rmtree(TESTFN2)
422
423
424
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000425class OtherTests(unittest.TestCase):
Thomas Wouterscf297e42007-02-23 15:07:44 +0000426 def testCreateNonExistentFileForAppend(self):
427 if os.path.exists(TESTFN):
428 os.unlink(TESTFN)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000429
Thomas Wouterscf297e42007-02-23 15:07:44 +0000430 filename = 'testfile.txt'
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000431 content = b'hello, world. this is some content.'
Guido van Rossumd8faa362007-04-27 19:54:29 +0000432
Thomas Wouterscf297e42007-02-23 15:07:44 +0000433 try:
434 zf = zipfile.ZipFile(TESTFN, 'a')
435 zf.writestr(filename, content)
436 zf.close()
437 except IOError:
438 self.fail('Could not append data to a non-existent zip file.')
439
440 self.assert_(os.path.exists(TESTFN))
441
442 zf = zipfile.ZipFile(TESTFN, 'r')
443 self.assertEqual(zf.read(filename), content)
444 zf.close()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000445
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000446 def testCloseErroneousFile(self):
447 # This test checks that the ZipFile constructor closes the file object
448 # it opens if there's an error in the file. If it doesn't, the traceback
449 # holds a reference to the ZipFile object and, indirectly, the file object.
450 # On Windows, this causes the os.unlink() call to fail because the
451 # underlying file is still open. This is SF bug #412214.
452 #
453 fp = open(TESTFN, "w")
454 fp.write("this is not a legal zip file\n")
455 fp.close()
456 try:
457 zf = zipfile.ZipFile(TESTFN)
458 except zipfile.BadZipfile:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000459 pass
460
461 def testIsZipErroneousFile(self):
462 # This test checks that the is_zipfile function correctly identifies
463 # a file that is not a zip file
464 fp = open(TESTFN, "w")
465 fp.write("this is not a legal zip file\n")
466 fp.close()
467 chk = zipfile.is_zipfile(TESTFN)
468 self.assert_(chk is False)
469
470 def testIsZipValidFile(self):
471 # This test checks that the is_zipfile function correctly identifies
472 # a file that is a zip file
473 zipf = zipfile.ZipFile(TESTFN, mode="w")
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000474 zipf.writestr("foo.txt", b"O, for a Muse of Fire!")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000475 zipf.close()
476 chk = zipfile.is_zipfile(TESTFN)
477 self.assert_(chk is True)
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000478
479 def testNonExistentFileRaisesIOError(self):
480 # make sure we don't raise an AttributeError when a partially-constructed
481 # ZipFile instance is finalized; this tests for regression on SF tracker
482 # bug #403871.
483
484 # The bug we're testing for caused an AttributeError to be raised
485 # when a ZipFile instance was created for a file that did not
486 # exist; the .fp member was not initialized but was needed by the
487 # __del__() method. Since the AttributeError is in the __del__(),
488 # it is ignored, but the user should be sufficiently annoyed by
489 # the message on the output that regression will be noticed
490 # quickly.
491 self.assertRaises(IOError, zipfile.ZipFile, TESTFN)
492
493 def testClosedZipRaisesRuntimeError(self):
494 # Verify that testzip() doesn't swallow inappropriate exceptions.
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000495 data = io.BytesIO()
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000496 zipf = zipfile.ZipFile(data, mode="w")
497 zipf.writestr("foo.txt", "O, for a Muse of Fire!")
498 zipf.close()
499
500 # This is correct; calling .read on a closed ZipFile should throw
501 # a RuntimeError, and so should calling .testzip. An earlier
502 # version of .testzip would swallow this exception (and any other)
503 # and report that the first file in the archive was corrupt.
504 self.assertRaises(RuntimeError, zipf.testzip)
505
Guido van Rossumd8faa362007-04-27 19:54:29 +0000506 def tearDown(self):
507 support.unlink(TESTFN)
508 support.unlink(TESTFN2)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000509
510class DecryptionTests(unittest.TestCase):
511 # This test checks that ZIP decryption works. Since the library does not
512 # support encryption at the moment, we use a pre-generated encrypted
513 # ZIP file
514
515 data = (
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000516 b'PK\x03\x04\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00\x1a\x00'
517 b'\x00\x00\x08\x00\x00\x00test.txt\xfa\x10\xa0gly|\xfa-\xc5\xc0=\xf9y'
518 b'\x18\xe0\xa8r\xb3Z}Lg\xbc\xae\xf9|\x9b\x19\xe4\x8b\xba\xbb)\x8c\xb0\xdbl'
519 b'PK\x01\x02\x14\x00\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00'
520 b'\x1a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00 \x00\xb6\x81'
521 b'\x00\x00\x00\x00test.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00'
522 b'\x00\x00L\x00\x00\x00\x00\x00' )
Thomas Wouterscf297e42007-02-23 15:07:44 +0000523
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000524 plain = b'zipfile.py encryption test'
Thomas Wouterscf297e42007-02-23 15:07:44 +0000525
526 def setUp(self):
527 fp = open(TESTFN, "wb")
528 fp.write(self.data)
529 fp.close()
530 self.zip = zipfile.ZipFile(TESTFN, "r")
531
532 def tearDown(self):
533 self.zip.close()
534 os.unlink(TESTFN)
535
536 def testNoPassword(self):
537 # Reading the encrypted file without password
538 # must generate a RunTime exception
539 self.assertRaises(RuntimeError, self.zip.read, "test.txt")
540
541 def testBadPassword(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000542 self.zip.setpassword(b"perl")
Thomas Wouterscf297e42007-02-23 15:07:44 +0000543 self.assertRaises(RuntimeError, self.zip.read, "test.txt")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000544
Thomas Wouterscf297e42007-02-23 15:07:44 +0000545 def testGoodPassword(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000546 self.zip.setpassword(b"python")
Thomas Wouterscf297e42007-02-23 15:07:44 +0000547 self.assertEquals(self.zip.read("test.txt"), self.plain)
548
Guido van Rossumd8faa362007-04-27 19:54:29 +0000549
550class TestsWithRandomBinaryFiles(unittest.TestCase):
551 def setUp(self):
552 datacount = randint(16, 64)*1024 + randint(1, 1024)
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000553 self.data = b''.join(struct.pack('<f', random()*randint(-1000, 1000))
554 for i in range(datacount))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000555
556 # Make a source file with some lines
557 fp = open(TESTFN, "wb")
558 fp.write(self.data)
559 fp.close()
560
561 def tearDown(self):
562 support.unlink(TESTFN)
563 support.unlink(TESTFN2)
564
565 def makeTestArchive(self, f, compression):
566 # Create the ZIP archive
567 zipfp = zipfile.ZipFile(f, "w", compression)
568 zipfp.write(TESTFN, "another"+os.extsep+"name")
569 zipfp.write(TESTFN, TESTFN)
570 zipfp.close()
571
572 def zipTest(self, f, compression):
573 self.makeTestArchive(f, compression)
574
575 # Read the ZIP archive
576 zipfp = zipfile.ZipFile(f, "r", compression)
577 testdata = zipfp.read(TESTFN)
578 self.assertEqual(len(testdata), len(self.data))
579 self.assertEqual(testdata, self.data)
580 self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data)
581 zipfp.close()
582
583 def testStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000584 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000585 self.zipTest(f, zipfile.ZIP_STORED)
586
587 def zipOpenTest(self, f, compression):
588 self.makeTestArchive(f, compression)
589
590 # Read the ZIP archive
591 zipfp = zipfile.ZipFile(f, "r", compression)
592 zipdata1 = []
593 zipopen1 = zipfp.open(TESTFN)
594 while 1:
595 read_data = zipopen1.read(256)
596 if not read_data:
597 break
598 zipdata1.append(read_data)
599
600 zipdata2 = []
601 zipopen2 = zipfp.open("another"+os.extsep+"name")
602 while 1:
603 read_data = zipopen2.read(256)
604 if not read_data:
605 break
606 zipdata2.append(read_data)
607
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000608 testdata1 = b''.join(zipdata1)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000609 self.assertEqual(len(testdata1), len(self.data))
610 self.assertEqual(testdata1, self.data)
611
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000612 testdata2 = b''.join(zipdata2)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000613 self.assertEqual(len(testdata1), len(self.data))
614 self.assertEqual(testdata1, self.data)
615 zipfp.close()
616
617 def testOpenStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000618 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000619 self.zipOpenTest(f, zipfile.ZIP_STORED)
620
621 def zipRandomOpenTest(self, f, compression):
622 self.makeTestArchive(f, compression)
623
624 # Read the ZIP archive
625 zipfp = zipfile.ZipFile(f, "r", compression)
626 zipdata1 = []
627 zipopen1 = zipfp.open(TESTFN)
628 while 1:
629 read_data = zipopen1.read(randint(1, 1024))
630 if not read_data:
631 break
632 zipdata1.append(read_data)
633
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000634 testdata = b''.join(zipdata1)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000635 self.assertEqual(len(testdata), len(self.data))
636 self.assertEqual(testdata, self.data)
637 zipfp.close()
638
639 def testRandomOpenStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000640 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000641 self.zipRandomOpenTest(f, zipfile.ZIP_STORED)
642
643class TestsWithMultipleOpens(unittest.TestCase):
644 def setUp(self):
645 # Create the ZIP archive
646 zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED)
647 zipfp.writestr('ones', '1'*FIXEDTEST_SIZE)
648 zipfp.writestr('twos', '2'*FIXEDTEST_SIZE)
649 zipfp.close()
650
651 def testSameFile(self):
652 # Verify that (when the ZipFile is in control of creating file objects)
653 # multiple open() calls can be made without interfering with each other.
654 zipf = zipfile.ZipFile(TESTFN2, mode="r")
655 zopen1 = zipf.open('ones')
656 zopen2 = zipf.open('ones')
657 data1 = zopen1.read(500)
658 data2 = zopen2.read(500)
659 data1 += zopen1.read(500)
660 data2 += zopen2.read(500)
661 self.assertEqual(data1, data2)
662 zipf.close()
663
664 def testDifferentFile(self):
665 # Verify that (when the ZipFile is in control of creating file objects)
666 # multiple open() calls can be made without interfering with each other.
667 zipf = zipfile.ZipFile(TESTFN2, mode="r")
668 zopen1 = zipf.open('ones')
669 zopen2 = zipf.open('twos')
670 data1 = zopen1.read(500)
671 data2 = zopen2.read(500)
672 data1 += zopen1.read(500)
673 data2 += zopen2.read(500)
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000674 self.assertEqual(data1, b'1'*FIXEDTEST_SIZE)
675 self.assertEqual(data2, b'2'*FIXEDTEST_SIZE)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000676 zipf.close()
677
678 def testInterleaved(self):
679 # Verify that (when the ZipFile is in control of creating file objects)
680 # multiple open() calls can be made without interfering with each other.
681 zipf = zipfile.ZipFile(TESTFN2, mode="r")
682 zopen1 = zipf.open('ones')
683 data1 = zopen1.read(500)
684 zopen2 = zipf.open('twos')
685 data2 = zopen2.read(500)
686 data1 += zopen1.read(500)
687 data2 += zopen2.read(500)
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000688 self.assertEqual(data1, b'1'*FIXEDTEST_SIZE)
689 self.assertEqual(data2, b'2'*FIXEDTEST_SIZE)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000690 zipf.close()
691
692 def tearDown(self):
693 os.remove(TESTFN2)
694
695
696class UniversalNewlineTests(unittest.TestCase):
697 def setUp(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000698 self.line_gen = [bytes("Test of zipfile line %d." % i)
699 for i in range(FIXEDTEST_SIZE)]
Guido van Rossumd8faa362007-04-27 19:54:29 +0000700 self.seps = ('\r', '\r\n', '\n')
701 self.arcdata, self.arcfiles = {}, {}
702 for n, s in enumerate(self.seps):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000703 b = s.encode("ascii")
704 self.arcdata[s] = b.join(self.line_gen) + b
Guido van Rossumd8faa362007-04-27 19:54:29 +0000705 self.arcfiles[s] = '%s-%d' % (TESTFN, n)
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000706 f = open(self.arcfiles[s], "wb")
707 try:
708 f.write(self.arcdata[s])
709 finally:
710 f.close()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000711
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()
729
730 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()
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000739 self.assertEqual(linedata, line + b'\n')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000740
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):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000751 self.assertEqual(zipline, line + b'\n')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000752
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")):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000762 self.assertEqual(zipline, line + b'\n')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000763
764 zipfp.close()
765
766 def testReadStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000767 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000768 self.readTest(f, zipfile.ZIP_STORED)
769
770 def testReadlineStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000771 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000772 self.readlineTest(f, zipfile.ZIP_STORED)
773
774 def testReadlinesStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000775 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000776 self.readlinesTest(f, zipfile.ZIP_STORED)
777
778 def testIterlinesStored(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000779 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000780 self.iterlinesTest(f, zipfile.ZIP_STORED)
781
782 if zlib:
783 def testReadDeflated(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000784 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000785 self.readTest(f, zipfile.ZIP_DEFLATED)
786
787 def testReadlineDeflated(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000788 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000789 self.readlineTest(f, zipfile.ZIP_DEFLATED)
790
791 def testReadlinesDeflated(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000792 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000793 self.readlinesTest(f, zipfile.ZIP_DEFLATED)
794
795 def testIterlinesDeflated(self):
Guido van Rossumd6ca5462007-05-22 01:29:33 +0000796 for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000797 self.iterlinesTest(f, zipfile.ZIP_DEFLATED)
798
799 def tearDown(self):
800 for sep, fn in self.arcfiles.items():
801 os.remove(fn)
802 support.unlink(TESTFN)
803 support.unlink(TESTFN2)
804
805
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000806def test_main():
Guido van Rossumd8faa362007-04-27 19:54:29 +0000807 run_unittest(TestsWithSourceFile, TestZip64InSmallFiles, OtherTests,
808 PyZipFileTests, DecryptionTests, TestsWithMultipleOpens,
809 UniversalNewlineTests, TestsWithRandomBinaryFiles)
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000810
811if __name__ == "__main__":
812 test_main()