blob: 0e7d73f1fffd0f65692e713d6ce7000a39e0dd3b [file] [log] [blame]
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001# Tests of the full ZIP64 functionality of zipfile
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002# The support.requires call is the only reason for keeping this separate
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003# from test_zipfile
Benjamin Petersonee8712c2008-05-20 21:35:26 +00004from test import support
Martin v. Löwisb09b8442008-07-03 14:13:42 +00005
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006# XXX(nnorwitz): disable this test by looking for extra largfile resource
7# which doesn't exist. This test takes over 30 minutes to run in general
8# and requires more disk space than most of the buildbots.
Benjamin Petersonee8712c2008-05-20 21:35:26 +00009support.requires(
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010 'extralargefile',
11 'test requires loads of disk-space bytes and a long time to run'
12 )
13
14# We can test part of the module without zlib.
15try:
16 import zlib
17except ImportError:
18 zlib = None
19
20import zipfile, os, unittest
21import time
22import sys
23
Guido van Rossum34d19282007-08-09 01:03:29 +000024from io import StringIO
Thomas Wouters0e3f5912006-08-11 14:57:12 +000025from tempfile import TemporaryFile
26
Benjamin Petersonee8712c2008-05-20 21:35:26 +000027from test.support import TESTFN, run_unittest
Thomas Wouters0e3f5912006-08-11 14:57:12 +000028
29TESTFN2 = TESTFN + "2"
30
31# How much time in seconds can pass before we print a 'Still working' message.
32_PRINT_WORKING_MSG_INTERVAL = 5 * 60
33
34class TestsWithSourceFile(unittest.TestCase):
35 def setUp(self):
36 # Create test data.
Guido van Rossum805365e2007-05-07 22:24:25 +000037 line_gen = ("Test of zipfile line %d." % i for i in range(1000000))
Amaury Forgeot d'Arc3be2f042008-11-12 01:57:36 +000038 self.data = '\n'.join(line_gen).encode('ascii')
Thomas Wouters0e3f5912006-08-11 14:57:12 +000039
40 # And write it to a file.
41 fp = open(TESTFN, "wb")
42 fp.write(self.data)
43 fp.close()
44
45 def zipTest(self, f, compression):
46 # Create the ZIP archive.
47 zipfp = zipfile.ZipFile(f, "w", compression, allowZip64=True)
48
49 # It will contain enough copies of self.data to reach about 6GB of
50 # raw data to store.
51 filecount = 6*1024**3 // len(self.data)
52
53 next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
54 for num in range(filecount):
55 zipfp.writestr("testfn%d" % num, self.data)
56 # Print still working message since this test can be really slow
57 if next_time <= time.time():
58 next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
Guido van Rossumbe19ed72007-02-09 05:37:30 +000059 print((
Thomas Wouters0e3f5912006-08-11 14:57:12 +000060 ' zipTest still writing %d of %d, be patient...' %
Guido van Rossumbe19ed72007-02-09 05:37:30 +000061 (num, filecount)), file=sys.__stdout__)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000062 sys.__stdout__.flush()
63 zipfp.close()
64
65 # Read the ZIP archive
66 zipfp = zipfile.ZipFile(f, "r", compression)
67 for num in range(filecount):
68 self.assertEqual(zipfp.read("testfn%d" % num), self.data)
69 # Print still working message since this test can be really slow
70 if next_time <= time.time():
71 next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
Guido van Rossumbe19ed72007-02-09 05:37:30 +000072 print((
Thomas Wouters0e3f5912006-08-11 14:57:12 +000073 ' zipTest still reading %d of %d, be patient...' %
Guido van Rossumbe19ed72007-02-09 05:37:30 +000074 (num, filecount)), file=sys.__stdout__)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075 sys.__stdout__.flush()
76 zipfp.close()
77
78 def testStored(self):
79 # Try the temp file first. If we do TESTFN2 first, then it hogs
80 # gigabytes of disk space for the duration of the test.
81 for f in TemporaryFile(), TESTFN2:
82 self.zipTest(f, zipfile.ZIP_STORED)
83
84 if zlib:
85 def testDeflated(self):
86 # Try the temp file first. If we do TESTFN2 first, then it hogs
87 # gigabytes of disk space for the duration of the test.
88 for f in TemporaryFile(), TESTFN2:
89 self.zipTest(f, zipfile.ZIP_DEFLATED)
90
91 def tearDown(self):
92 for fname in TESTFN, TESTFN2:
93 if os.path.exists(fname):
94 os.remove(fname)
95
Martin v. Löwisb09b8442008-07-03 14:13:42 +000096
97class OtherTests(unittest.TestCase):
98 def testMoreThan64kFiles(self):
99 # This test checks that more than 64k files can be added to an archive,
100 # and that the resulting archive can be read properly by ZipFile
101 zipf = zipfile.ZipFile(TESTFN, mode="w")
102 zipf.debug = 100
Amaury Forgeot d'Arc3be2f042008-11-12 01:57:36 +0000103 numfiles = (1 << 16) * 3//2
104 for i in range(numfiles):
Martin v. Löwisb09b8442008-07-03 14:13:42 +0000105 zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
106 self.assertEqual(len(zipf.namelist()), numfiles)
107 zipf.close()
108
109 zipf2 = zipfile.ZipFile(TESTFN, mode="r")
110 self.assertEqual(len(zipf2.namelist()), numfiles)
Amaury Forgeot d'Arc3be2f042008-11-12 01:57:36 +0000111 for i in range(numfiles):
112 content = zipf2.read("foo%08d" % i).decode('ascii')
113 self.assertEqual(content, "%d" % (i**3 % 57))
Martin v. Löwisb09b8442008-07-03 14:13:42 +0000114 zipf.close()
115
116 def tearDown(self):
Amaury Forgeot d'Arc3be2f042008-11-12 01:57:36 +0000117 support.unlink(TESTFN)
118 support.unlink(TESTFN2)
Martin v. Löwisb09b8442008-07-03 14:13:42 +0000119
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000120def test_main():
Martin v. Löwisb09b8442008-07-03 14:13:42 +0000121 run_unittest(TestsWithSourceFile, OtherTests)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000122
123if __name__ == "__main__":
124 test_main()