blob: a6500da17954dbae2806174be9de58853936f12f [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
Guido van Rossumd8faa362007-04-27 19:54:29 +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
Guido van Rossumd8faa362007-04-27 19:54:29 +000011from random import randint, random
Tim Petersa19a1682001-03-29 04:36:09 +000012
Guido van Rossumd8faa362007-04-27 19:54:29 +000013import test.test_support as support
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000014from test.test_support import TESTFN, run_unittest
Guido van Rossum368f04a2000-04-10 13:23:04 +000015
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000016TESTFN2 = TESTFN + "2"
Guido van Rossumd8faa362007-04-27 19:54:29 +000017FIXEDTEST_SIZE = 10
Guido van Rossum368f04a2000-04-10 13:23:04 +000018
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000019class TestsWithSourceFile(unittest.TestCase):
20 def setUp(self):
Guido van Rossumd8faa362007-04-27 19:54:29 +000021 self.line_gen = ("Zipfile test line %d. random float: %f" % (i, random())
22 for i in xrange(FIXEDTEST_SIZE))
23 self.data = '\n'.join(self.line_gen) + '\n'
Fred Drake6e7e4852001-02-28 05:34:16 +000024
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000025 # Make a source file with some lines
26 fp = open(TESTFN, "wb")
27 fp.write(self.data)
28 fp.close()
Tim Peters7d3bad62001-04-04 18:56:49 +000029
Guido van Rossumd8faa362007-04-27 19:54:29 +000030 def makeTestArchive(self, f, compression):
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000031 # Create the ZIP archive
32 zipfp = zipfile.ZipFile(f, "w", compression)
33 zipfp.write(TESTFN, "another"+os.extsep+"name")
34 zipfp.write(TESTFN, TESTFN)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000035 zipfp.writestr("strfile", self.data)
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000036 zipfp.close()
Tim Peters7d3bad62001-04-04 18:56:49 +000037
Guido van Rossumd8faa362007-04-27 19:54:29 +000038 def zipTest(self, f, compression):
39 self.makeTestArchive(f, compression)
40
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000041 # Read the ZIP archive
42 zipfp = zipfile.ZipFile(f, "r", compression)
43 self.assertEqual(zipfp.read(TESTFN), self.data)
44 self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000045 self.assertEqual(zipfp.read("strfile"), self.data)
46
47 # Print the ZIP directory
48 fp = StringIO()
49 stdout = sys.stdout
50 try:
51 sys.stdout = fp
52
53 zipfp.printdir()
54 finally:
55 sys.stdout = stdout
56
57 directory = fp.getvalue()
58 lines = directory.splitlines()
59 self.assertEquals(len(lines), 4) # Number of files + header
60
61 self.assert_('File Name' in lines[0])
62 self.assert_('Modified' in lines[0])
63 self.assert_('Size' in lines[0])
64
65 fn, date, time, size = lines[1].split()
66 self.assertEquals(fn, 'another.name')
67 # XXX: timestamp is not tested
68 self.assertEquals(size, str(len(self.data)))
69
70 # Check the namelist
71 names = zipfp.namelist()
72 self.assertEquals(len(names), 3)
73 self.assert_(TESTFN in names)
74 self.assert_("another"+os.extsep+"name" in names)
75 self.assert_("strfile" in names)
76
77 # Check infolist
78 infos = zipfp.infolist()
79 names = [ i.filename for i in infos ]
80 self.assertEquals(len(names), 3)
81 self.assert_(TESTFN in names)
82 self.assert_("another"+os.extsep+"name" in names)
83 self.assert_("strfile" in names)
84 for i in infos:
85 self.assertEquals(i.file_size, len(self.data))
86
87 # check getinfo
88 for nm in (TESTFN, "another"+os.extsep+"name", "strfile"):
89 info = zipfp.getinfo(nm)
90 self.assertEquals(info.filename, nm)
91 self.assertEquals(info.file_size, len(self.data))
92
93 # Check that testzip doesn't raise an exception
94 zipfp.testzip()
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000095 zipfp.close()
Tim Peters7d3bad62001-04-04 18:56:49 +000096
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +000097 def testStored(self):
98 for f in (TESTFN2, TemporaryFile(), StringIO()):
99 self.zipTest(f, zipfile.ZIP_STORED)
Raymond Hettingerc0fac962003-06-27 22:25:03 +0000100
Guido van Rossumd8faa362007-04-27 19:54:29 +0000101 def zipOpenTest(self, f, compression):
102 self.makeTestArchive(f, compression)
103
104 # Read the ZIP archive
105 zipfp = zipfile.ZipFile(f, "r", compression)
106 zipdata1 = []
107 zipopen1 = zipfp.open(TESTFN)
108 while 1:
109 read_data = zipopen1.read(256)
110 if not read_data:
111 break
112 zipdata1.append(read_data)
113
114 zipdata2 = []
115 zipopen2 = zipfp.open("another"+os.extsep+"name")
116 while 1:
117 read_data = zipopen2.read(256)
118 if not read_data:
119 break
120 zipdata2.append(read_data)
121
122 self.assertEqual(''.join(zipdata1), self.data)
123 self.assertEqual(''.join(zipdata2), self.data)
124 zipfp.close()
125
126 def testOpenStored(self):
127 for f in (TESTFN2, TemporaryFile(), StringIO()):
128 self.zipOpenTest(f, zipfile.ZIP_STORED)
129
130 def zipRandomOpenTest(self, f, compression):
131 self.makeTestArchive(f, compression)
132
133 # Read the ZIP archive
134 zipfp = zipfile.ZipFile(f, "r", compression)
135 zipdata1 = []
136 zipopen1 = zipfp.open(TESTFN)
137 while 1:
138 read_data = zipopen1.read(randint(1, 1024))
139 if not read_data:
140 break
141 zipdata1.append(read_data)
142
143 self.assertEqual(''.join(zipdata1), self.data)
144 zipfp.close()
145
146 def testRandomOpenStored(self):
147 for f in (TESTFN2, TemporaryFile(), StringIO()):
148 self.zipRandomOpenTest(f, zipfile.ZIP_STORED)
149
150 def zipReadlineTest(self, f, compression):
151 self.makeTestArchive(f, compression)
152
153 # Read the ZIP archive
154 zipfp = zipfile.ZipFile(f, "r")
155 zipopen = zipfp.open(TESTFN)
156 for line in self.line_gen:
157 linedata = zipopen.readline()
158 self.assertEqual(linedata, line + '\n')
159
160 zipfp.close()
161
162 def zipReadlinesTest(self, f, compression):
163 self.makeTestArchive(f, compression)
164
165 # Read the ZIP archive
166 zipfp = zipfile.ZipFile(f, "r")
167 ziplines = zipfp.open(TESTFN).readlines()
168 for line, zipline in zip(self.line_gen, ziplines):
169 self.assertEqual(zipline, line + '\n')
170
171 zipfp.close()
172
173 def zipIterlinesTest(self, f, compression):
174 self.makeTestArchive(f, compression)
175
176 # Read the ZIP archive
177 zipfp = zipfile.ZipFile(f, "r")
178 for line, zipline in zip(self.line_gen, zipfp.open(TESTFN)):
179 self.assertEqual(zipline, line + '\n')
180
181 zipfp.close()
182
183 def testReadlineStored(self):
184 for f in (TESTFN2, TemporaryFile(), StringIO()):
185 self.zipReadlineTest(f, zipfile.ZIP_STORED)
186
187 def testReadlinesStored(self):
188 for f in (TESTFN2, TemporaryFile(), StringIO()):
189 self.zipReadlinesTest(f, zipfile.ZIP_STORED)
190
191 def testIterlinesStored(self):
192 for f in (TESTFN2, TemporaryFile(), StringIO()):
193 self.zipIterlinesTest(f, zipfile.ZIP_STORED)
194
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000195 if zlib:
196 def testDeflated(self):
197 for f in (TESTFN2, TemporaryFile(), StringIO()):
198 self.zipTest(f, zipfile.ZIP_DEFLATED)
Raymond Hettingerc0fac962003-06-27 22:25:03 +0000199
Guido van Rossumd8faa362007-04-27 19:54:29 +0000200 def testOpenDeflated(self):
201 for f in (TESTFN2, TemporaryFile(), StringIO()):
202 self.zipOpenTest(f, zipfile.ZIP_DEFLATED)
203
204 def testRandomOpenDeflated(self):
205 for f in (TESTFN2, TemporaryFile(), StringIO()):
206 self.zipRandomOpenTest(f, zipfile.ZIP_DEFLATED)
207
208 def testReadlineDeflated(self):
209 for f in (TESTFN2, TemporaryFile(), StringIO()):
210 self.zipReadlineTest(f, zipfile.ZIP_DEFLATED)
211
212 def testReadlinesDeflated(self):
213 for f in (TESTFN2, TemporaryFile(), StringIO()):
214 self.zipReadlinesTest(f, zipfile.ZIP_DEFLATED)
215
216 def testIterlinesDeflated(self):
217 for f in (TESTFN2, TemporaryFile(), StringIO()):
218 self.zipIterlinesTest(f, zipfile.ZIP_DEFLATED)
219
220 def testLowCompression(self):
221 # Checks for cases where compressed data is larger than original
222 # Create the ZIP archive
223 zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED)
224 zipfp.writestr("strfile", '12')
225 zipfp.close()
226
227 # Get an open object for strfile
228 zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_DEFLATED)
229 openobj = zipfp.open("strfile")
230 self.assertEqual(openobj.read(1), '1')
231 self.assertEqual(openobj.read(1), '2')
232
Georg Brandl8f7c54e2006-02-20 08:40:38 +0000233 def testAbsoluteArcnames(self):
234 zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED)
235 zipfp.write(TESTFN, "/absolute")
236 zipfp.close()
237
238 zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED)
239 self.assertEqual(zipfp.namelist(), ["absolute"])
240 zipfp.close()
Tim Peters32cbc962006-02-20 21:42:18 +0000241
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000242 def tearDown(self):
243 os.remove(TESTFN)
244 os.remove(TESTFN2)
245
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000246class TestZip64InSmallFiles(unittest.TestCase):
247 # These tests test the ZIP64 functionality without using large files,
248 # see test_zipfile64 for proper tests.
249
250 def setUp(self):
251 self._limit = zipfile.ZIP64_LIMIT
252 zipfile.ZIP64_LIMIT = 5
253
Guido van Rossumd8faa362007-04-27 19:54:29 +0000254 line_gen = ("Test of zipfile line %d." % i for i in range(0, FIXEDTEST_SIZE))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000255 self.data = '\n'.join(line_gen)
256
257 # Make a source file with some lines
258 fp = open(TESTFN, "wb")
259 fp.write(self.data)
260 fp.close()
261
262 def largeFileExceptionTest(self, f, compression):
263 zipfp = zipfile.ZipFile(f, "w", compression)
264 self.assertRaises(zipfile.LargeZipFile,
265 zipfp.write, TESTFN, "another"+os.extsep+"name")
266 zipfp.close()
267
268 def largeFileExceptionTest2(self, f, compression):
269 zipfp = zipfile.ZipFile(f, "w", compression)
270 self.assertRaises(zipfile.LargeZipFile,
271 zipfp.writestr, "another"+os.extsep+"name", self.data)
272 zipfp.close()
273
274 def testLargeFileException(self):
275 for f in (TESTFN2, TemporaryFile(), StringIO()):
276 self.largeFileExceptionTest(f, zipfile.ZIP_STORED)
277 self.largeFileExceptionTest2(f, zipfile.ZIP_STORED)
278
279 def zipTest(self, f, compression):
280 # Create the ZIP archive
281 zipfp = zipfile.ZipFile(f, "w", compression, allowZip64=True)
282 zipfp.write(TESTFN, "another"+os.extsep+"name")
283 zipfp.write(TESTFN, TESTFN)
284 zipfp.writestr("strfile", self.data)
285 zipfp.close()
286
287 # Read the ZIP archive
288 zipfp = zipfile.ZipFile(f, "r", compression)
289 self.assertEqual(zipfp.read(TESTFN), self.data)
290 self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data)
291 self.assertEqual(zipfp.read("strfile"), self.data)
292
293 # Print the ZIP directory
294 fp = StringIO()
295 stdout = sys.stdout
296 try:
297 sys.stdout = fp
298
299 zipfp.printdir()
300 finally:
301 sys.stdout = stdout
302
303 directory = fp.getvalue()
304 lines = directory.splitlines()
305 self.assertEquals(len(lines), 4) # Number of files + header
306
307 self.assert_('File Name' in lines[0])
308 self.assert_('Modified' in lines[0])
309 self.assert_('Size' in lines[0])
310
311 fn, date, time, size = lines[1].split()
312 self.assertEquals(fn, 'another.name')
313 # XXX: timestamp is not tested
314 self.assertEquals(size, str(len(self.data)))
315
316 # Check the namelist
317 names = zipfp.namelist()
318 self.assertEquals(len(names), 3)
319 self.assert_(TESTFN in names)
320 self.assert_("another"+os.extsep+"name" in names)
321 self.assert_("strfile" in names)
322
323 # Check infolist
324 infos = zipfp.infolist()
325 names = [ i.filename for i in infos ]
326 self.assertEquals(len(names), 3)
327 self.assert_(TESTFN in names)
328 self.assert_("another"+os.extsep+"name" in names)
329 self.assert_("strfile" in names)
330 for i in infos:
331 self.assertEquals(i.file_size, len(self.data))
332
333 # check getinfo
334 for nm in (TESTFN, "another"+os.extsep+"name", "strfile"):
335 info = zipfp.getinfo(nm)
336 self.assertEquals(info.filename, nm)
337 self.assertEquals(info.file_size, len(self.data))
338
339 # Check that testzip doesn't raise an exception
340 zipfp.testzip()
341
342
343 zipfp.close()
344
345 def testStored(self):
346 for f in (TESTFN2, TemporaryFile(), StringIO()):
347 self.zipTest(f, zipfile.ZIP_STORED)
348
349
350 if zlib:
351 def testDeflated(self):
352 for f in (TESTFN2, TemporaryFile(), StringIO()):
353 self.zipTest(f, zipfile.ZIP_DEFLATED)
354
355 def testAbsoluteArcnames(self):
356 zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED, allowZip64=True)
357 zipfp.write(TESTFN, "/absolute")
358 zipfp.close()
359
360 zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED)
361 self.assertEqual(zipfp.namelist(), ["absolute"])
362 zipfp.close()
363
364
365 def tearDown(self):
366 zipfile.ZIP64_LIMIT = self._limit
367 os.remove(TESTFN)
368 os.remove(TESTFN2)
369
370class PyZipFileTests(unittest.TestCase):
371 def testWritePyfile(self):
372 zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
373 fn = __file__
374 if fn.endswith('.pyc') or fn.endswith('.pyo'):
375 fn = fn[:-1]
376
377 zipfp.writepy(fn)
378
379 bn = os.path.basename(fn)
380 self.assert_(bn not in zipfp.namelist())
381 self.assert_(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist())
382 zipfp.close()
383
384
385 zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
386 fn = __file__
387 if fn.endswith('.pyc') or fn.endswith('.pyo'):
388 fn = fn[:-1]
389
390 zipfp.writepy(fn, "testpackage")
391
392 bn = "%s/%s"%("testpackage", os.path.basename(fn))
393 self.assert_(bn not in zipfp.namelist())
394 self.assert_(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist())
395 zipfp.close()
396
397 def testWritePythonPackage(self):
398 import email
399 packagedir = os.path.dirname(email.__file__)
400
401 zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
402 zipfp.writepy(packagedir)
403
404 # Check for a couple of modules at different levels of the hieararchy
405 names = zipfp.namelist()
406 self.assert_('email/__init__.pyo' in names or 'email/__init__.pyc' in names)
407 self.assert_('email/mime/text.pyo' in names or 'email/mime/text.pyc' in names)
408
409 def testWritePythonDirectory(self):
410 os.mkdir(TESTFN2)
411 try:
412 fp = open(os.path.join(TESTFN2, "mod1.py"), "w")
Guido van Rossum43fc78d2007-02-09 22:18:41 +0000413 fp.write("print(42)\n")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000414 fp.close()
415
416 fp = open(os.path.join(TESTFN2, "mod2.py"), "w")
Guido van Rossum43fc78d2007-02-09 22:18:41 +0000417 fp.write("print(42 * 42)\n")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000418 fp.close()
419
420 fp = open(os.path.join(TESTFN2, "mod2.txt"), "w")
421 fp.write("bla bla bla\n")
422 fp.close()
423
424 zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
425 zipfp.writepy(TESTFN2)
426
427 names = zipfp.namelist()
428 self.assert_('mod1.pyc' in names or 'mod1.pyo' in names)
429 self.assert_('mod2.pyc' in names or 'mod2.pyo' in names)
430 self.assert_('mod2.txt' not in names)
431
432 finally:
433 shutil.rmtree(TESTFN2)
434
435
436
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000437class OtherTests(unittest.TestCase):
Thomas Wouterscf297e42007-02-23 15:07:44 +0000438 def testCreateNonExistentFileForAppend(self):
439 if os.path.exists(TESTFN):
440 os.unlink(TESTFN)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000441
Thomas Wouterscf297e42007-02-23 15:07:44 +0000442 filename = 'testfile.txt'
443 content = 'hello, world. this is some content.'
Guido van Rossumd8faa362007-04-27 19:54:29 +0000444
Thomas Wouterscf297e42007-02-23 15:07:44 +0000445 try:
446 zf = zipfile.ZipFile(TESTFN, 'a')
447 zf.writestr(filename, content)
448 zf.close()
449 except IOError:
450 self.fail('Could not append data to a non-existent zip file.')
451
452 self.assert_(os.path.exists(TESTFN))
453
454 zf = zipfile.ZipFile(TESTFN, 'r')
455 self.assertEqual(zf.read(filename), content)
456 zf.close()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000457
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000458 def testCloseErroneousFile(self):
459 # This test checks that the ZipFile constructor closes the file object
460 # it opens if there's an error in the file. If it doesn't, the traceback
461 # holds a reference to the ZipFile object and, indirectly, the file object.
462 # On Windows, this causes the os.unlink() call to fail because the
463 # underlying file is still open. This is SF bug #412214.
464 #
465 fp = open(TESTFN, "w")
466 fp.write("this is not a legal zip file\n")
467 fp.close()
468 try:
469 zf = zipfile.ZipFile(TESTFN)
470 except zipfile.BadZipfile:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000471 pass
472
473 def testIsZipErroneousFile(self):
474 # This test checks that the is_zipfile function correctly identifies
475 # a file that is not a zip file
476 fp = open(TESTFN, "w")
477 fp.write("this is not a legal zip file\n")
478 fp.close()
479 chk = zipfile.is_zipfile(TESTFN)
480 self.assert_(chk is False)
481
482 def testIsZipValidFile(self):
483 # This test checks that the is_zipfile function correctly identifies
484 # a file that is a zip file
485 zipf = zipfile.ZipFile(TESTFN, mode="w")
486 zipf.writestr("foo.txt", "O, for a Muse of Fire!")
487 zipf.close()
488 chk = zipfile.is_zipfile(TESTFN)
489 self.assert_(chk is True)
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000490
491 def testNonExistentFileRaisesIOError(self):
492 # make sure we don't raise an AttributeError when a partially-constructed
493 # ZipFile instance is finalized; this tests for regression on SF tracker
494 # bug #403871.
495
496 # The bug we're testing for caused an AttributeError to be raised
497 # when a ZipFile instance was created for a file that did not
498 # exist; the .fp member was not initialized but was needed by the
499 # __del__() method. Since the AttributeError is in the __del__(),
500 # it is ignored, but the user should be sufficiently annoyed by
501 # the message on the output that regression will be noticed
502 # quickly.
503 self.assertRaises(IOError, zipfile.ZipFile, TESTFN)
504
505 def testClosedZipRaisesRuntimeError(self):
506 # Verify that testzip() doesn't swallow inappropriate exceptions.
507 data = StringIO()
508 zipf = zipfile.ZipFile(data, mode="w")
509 zipf.writestr("foo.txt", "O, for a Muse of Fire!")
510 zipf.close()
511
512 # This is correct; calling .read on a closed ZipFile should throw
513 # a RuntimeError, and so should calling .testzip. An earlier
514 # version of .testzip would swallow this exception (and any other)
515 # and report that the first file in the archive was corrupt.
516 self.assertRaises(RuntimeError, zipf.testzip)
517
Guido van Rossumd8faa362007-04-27 19:54:29 +0000518 def tearDown(self):
519 support.unlink(TESTFN)
520 support.unlink(TESTFN2)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000521
522class DecryptionTests(unittest.TestCase):
523 # This test checks that ZIP decryption works. Since the library does not
524 # support encryption at the moment, we use a pre-generated encrypted
525 # ZIP file
526
527 data = (
528 'PK\x03\x04\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00\x1a\x00'
529 '\x00\x00\x08\x00\x00\x00test.txt\xfa\x10\xa0gly|\xfa-\xc5\xc0=\xf9y'
530 '\x18\xe0\xa8r\xb3Z}Lg\xbc\xae\xf9|\x9b\x19\xe4\x8b\xba\xbb)\x8c\xb0\xdbl'
531 'PK\x01\x02\x14\x00\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00'
532 '\x1a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00 \x00\xb6\x81'
533 '\x00\x00\x00\x00test.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00'
534 '\x00\x00L\x00\x00\x00\x00\x00' )
535
536 plain = 'zipfile.py encryption test'
537
538 def setUp(self):
539 fp = open(TESTFN, "wb")
540 fp.write(self.data)
541 fp.close()
542 self.zip = zipfile.ZipFile(TESTFN, "r")
543
544 def tearDown(self):
545 self.zip.close()
546 os.unlink(TESTFN)
547
548 def testNoPassword(self):
549 # Reading the encrypted file without password
550 # must generate a RunTime exception
551 self.assertRaises(RuntimeError, self.zip.read, "test.txt")
552
553 def testBadPassword(self):
554 self.zip.setpassword("perl")
555 self.assertRaises(RuntimeError, self.zip.read, "test.txt")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000556
Thomas Wouterscf297e42007-02-23 15:07:44 +0000557 def testGoodPassword(self):
558 self.zip.setpassword("python")
559 self.assertEquals(self.zip.read("test.txt"), self.plain)
560
Guido van Rossumd8faa362007-04-27 19:54:29 +0000561
562class TestsWithRandomBinaryFiles(unittest.TestCase):
563 def setUp(self):
564 datacount = randint(16, 64)*1024 + randint(1, 1024)
565 self.data = ''.join((struct.pack('<f', random()*randint(-1000, 1000)) for i in xrange(datacount)))
566
567 # Make a source file with some lines
568 fp = open(TESTFN, "wb")
569 fp.write(self.data)
570 fp.close()
571
572 def tearDown(self):
573 support.unlink(TESTFN)
574 support.unlink(TESTFN2)
575
576 def makeTestArchive(self, f, compression):
577 # Create the ZIP archive
578 zipfp = zipfile.ZipFile(f, "w", compression)
579 zipfp.write(TESTFN, "another"+os.extsep+"name")
580 zipfp.write(TESTFN, TESTFN)
581 zipfp.close()
582
583 def zipTest(self, f, compression):
584 self.makeTestArchive(f, compression)
585
586 # Read the ZIP archive
587 zipfp = zipfile.ZipFile(f, "r", compression)
588 testdata = zipfp.read(TESTFN)
589 self.assertEqual(len(testdata), len(self.data))
590 self.assertEqual(testdata, self.data)
591 self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data)
592 zipfp.close()
593
594 def testStored(self):
595 for f in (TESTFN2, TemporaryFile(), StringIO()):
596 self.zipTest(f, zipfile.ZIP_STORED)
597
598 def zipOpenTest(self, f, compression):
599 self.makeTestArchive(f, compression)
600
601 # Read the ZIP archive
602 zipfp = zipfile.ZipFile(f, "r", compression)
603 zipdata1 = []
604 zipopen1 = zipfp.open(TESTFN)
605 while 1:
606 read_data = zipopen1.read(256)
607 if not read_data:
608 break
609 zipdata1.append(read_data)
610
611 zipdata2 = []
612 zipopen2 = zipfp.open("another"+os.extsep+"name")
613 while 1:
614 read_data = zipopen2.read(256)
615 if not read_data:
616 break
617 zipdata2.append(read_data)
618
619 testdata1 = ''.join(zipdata1)
620 self.assertEqual(len(testdata1), len(self.data))
621 self.assertEqual(testdata1, self.data)
622
623 testdata2 = ''.join(zipdata2)
624 self.assertEqual(len(testdata1), len(self.data))
625 self.assertEqual(testdata1, self.data)
626 zipfp.close()
627
628 def testOpenStored(self):
629 for f in (TESTFN2, TemporaryFile(), StringIO()):
630 self.zipOpenTest(f, zipfile.ZIP_STORED)
631
632 def zipRandomOpenTest(self, f, compression):
633 self.makeTestArchive(f, compression)
634
635 # Read the ZIP archive
636 zipfp = zipfile.ZipFile(f, "r", compression)
637 zipdata1 = []
638 zipopen1 = zipfp.open(TESTFN)
639 while 1:
640 read_data = zipopen1.read(randint(1, 1024))
641 if not read_data:
642 break
643 zipdata1.append(read_data)
644
645 testdata = ''.join(zipdata1)
646 self.assertEqual(len(testdata), len(self.data))
647 self.assertEqual(testdata, self.data)
648 zipfp.close()
649
650 def testRandomOpenStored(self):
651 for f in (TESTFN2, TemporaryFile(), StringIO()):
652 self.zipRandomOpenTest(f, zipfile.ZIP_STORED)
653
654class TestsWithMultipleOpens(unittest.TestCase):
655 def setUp(self):
656 # Create the ZIP archive
657 zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED)
658 zipfp.writestr('ones', '1'*FIXEDTEST_SIZE)
659 zipfp.writestr('twos', '2'*FIXEDTEST_SIZE)
660 zipfp.close()
661
662 def testSameFile(self):
663 # Verify that (when the ZipFile is in control of creating file objects)
664 # multiple open() calls can be made without interfering with each other.
665 zipf = zipfile.ZipFile(TESTFN2, mode="r")
666 zopen1 = zipf.open('ones')
667 zopen2 = zipf.open('ones')
668 data1 = zopen1.read(500)
669 data2 = zopen2.read(500)
670 data1 += zopen1.read(500)
671 data2 += zopen2.read(500)
672 self.assertEqual(data1, data2)
673 zipf.close()
674
675 def testDifferentFile(self):
676 # Verify that (when the ZipFile is in control of creating file objects)
677 # multiple open() calls can be made without interfering with each other.
678 zipf = zipfile.ZipFile(TESTFN2, mode="r")
679 zopen1 = zipf.open('ones')
680 zopen2 = zipf.open('twos')
681 data1 = zopen1.read(500)
682 data2 = zopen2.read(500)
683 data1 += zopen1.read(500)
684 data2 += zopen2.read(500)
685 self.assertEqual(data1, '1'*FIXEDTEST_SIZE)
686 self.assertEqual(data2, '2'*FIXEDTEST_SIZE)
687 zipf.close()
688
689 def testInterleaved(self):
690 # Verify that (when the ZipFile is in control of creating file objects)
691 # multiple open() calls can be made without interfering with each other.
692 zipf = zipfile.ZipFile(TESTFN2, mode="r")
693 zopen1 = zipf.open('ones')
694 data1 = zopen1.read(500)
695 zopen2 = zipf.open('twos')
696 data2 = zopen2.read(500)
697 data1 += zopen1.read(500)
698 data2 += zopen2.read(500)
699 self.assertEqual(data1, '1'*FIXEDTEST_SIZE)
700 self.assertEqual(data2, '2'*FIXEDTEST_SIZE)
701 zipf.close()
702
703 def tearDown(self):
704 os.remove(TESTFN2)
705
706
707class UniversalNewlineTests(unittest.TestCase):
708 def setUp(self):
709 self.line_gen = ["Test of zipfile line %d." % i for i in xrange(FIXEDTEST_SIZE)]
710 self.seps = ('\r', '\r\n', '\n')
711 self.arcdata, self.arcfiles = {}, {}
712 for n, s in enumerate(self.seps):
713 self.arcdata[s] = s.join(self.line_gen) + s
714 self.arcfiles[s] = '%s-%d' % (TESTFN, n)
715 file(self.arcfiles[s], "wb").write(self.arcdata[s])
716
717 def makeTestArchive(self, f, compression):
718 # Create the ZIP archive
719 zipfp = zipfile.ZipFile(f, "w", compression)
720 for fn in self.arcfiles.values():
721 zipfp.write(fn, fn)
722 zipfp.close()
723
724 def readTest(self, f, compression):
725 self.makeTestArchive(f, compression)
726
727 # Read the ZIP archive
728 zipfp = zipfile.ZipFile(f, "r")
729 for sep, fn in self.arcfiles.items():
730 zipdata = zipfp.open(fn, "rU").read()
731 self.assertEqual(self.arcdata[sep], zipdata)
732
733 zipfp.close()
734
735 def readlineTest(self, f, compression):
736 self.makeTestArchive(f, compression)
737
738 # Read the ZIP archive
739 zipfp = zipfile.ZipFile(f, "r")
740 for sep, fn in self.arcfiles.items():
741 zipopen = zipfp.open(fn, "rU")
742 for line in self.line_gen:
743 linedata = zipopen.readline()
744 self.assertEqual(linedata, line + '\n')
745
746 zipfp.close()
747
748 def readlinesTest(self, f, compression):
749 self.makeTestArchive(f, compression)
750
751 # Read the ZIP archive
752 zipfp = zipfile.ZipFile(f, "r")
753 for sep, fn in self.arcfiles.items():
754 ziplines = zipfp.open(fn, "rU").readlines()
755 for line, zipline in zip(self.line_gen, ziplines):
756 self.assertEqual(zipline, line + '\n')
757
758 zipfp.close()
759
760 def iterlinesTest(self, f, compression):
761 self.makeTestArchive(f, compression)
762
763 # Read the ZIP archive
764 zipfp = zipfile.ZipFile(f, "r")
765 for sep, fn in self.arcfiles.items():
766 for line, zipline in zip(self.line_gen, zipfp.open(fn, "rU")):
767 self.assertEqual(zipline, line + '\n')
768
769 zipfp.close()
770
771 def testReadStored(self):
772 for f in (TESTFN2, TemporaryFile(), StringIO()):
773 self.readTest(f, zipfile.ZIP_STORED)
774
775 def testReadlineStored(self):
776 for f in (TESTFN2, TemporaryFile(), StringIO()):
777 self.readlineTest(f, zipfile.ZIP_STORED)
778
779 def testReadlinesStored(self):
780 for f in (TESTFN2, TemporaryFile(), StringIO()):
781 self.readlinesTest(f, zipfile.ZIP_STORED)
782
783 def testIterlinesStored(self):
784 for f in (TESTFN2, TemporaryFile(), StringIO()):
785 self.iterlinesTest(f, zipfile.ZIP_STORED)
786
787 if zlib:
788 def testReadDeflated(self):
789 for f in (TESTFN2, TemporaryFile(), StringIO()):
790 self.readTest(f, zipfile.ZIP_DEFLATED)
791
792 def testReadlineDeflated(self):
793 for f in (TESTFN2, TemporaryFile(), StringIO()):
794 self.readlineTest(f, zipfile.ZIP_DEFLATED)
795
796 def testReadlinesDeflated(self):
797 for f in (TESTFN2, TemporaryFile(), StringIO()):
798 self.readlinesTest(f, zipfile.ZIP_DEFLATED)
799
800 def testIterlinesDeflated(self):
801 for f in (TESTFN2, TemporaryFile(), StringIO()):
802 self.iterlinesTest(f, zipfile.ZIP_DEFLATED)
803
804 def tearDown(self):
805 for sep, fn in self.arcfiles.items():
806 os.remove(fn)
807 support.unlink(TESTFN)
808 support.unlink(TESTFN2)
809
810
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000811def test_main():
Guido van Rossumd8faa362007-04-27 19:54:29 +0000812 run_unittest(TestsWithSourceFile, TestZip64InSmallFiles, OtherTests,
813 PyZipFileTests, DecryptionTests, TestsWithMultipleOpens,
814 UniversalNewlineTests, TestsWithRandomBinaryFiles)
Johannes Gijsbers3caf9c12004-08-19 15:11:50 +0000815
816if __name__ == "__main__":
817 test_main()