1 # Tests of the full ZIP64 functionality of zipfile
2 # The support.requires call is the only reason for keeping this separate
3 # from test_zipfile
4 from test import support
5
6 # XXX(nnorwitz): disable this test by looking for extralargefile 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.
9 support.requires(
10 'extralargefile',
11 'test requires loads of disk-space bytes and a long time to run'
12 )
13
14 import zipfile, unittest
15 import time
16 import sys
17
18 from tempfile import TemporaryFile
19
20 from test.support import os_helper
21 from test.support import requires_zlib
22
23 TESTFN = os_helper.TESTFN
24 TESTFN2 = TESTFN + "2"
25
26 # How much time in seconds can pass before we print a 'Still working' message.
27 _PRINT_WORKING_MSG_INTERVAL = 60
28
29 class ESC[4;38;5;81mTestsWithSourceFile(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
30 def setUp(self):
31 # Create test data.
32 line_gen = ("Test of zipfile line %d." % i for i in range(1000000))
33 self.data = '\n'.join(line_gen).encode('ascii')
34
35 def zipTest(self, f, compression):
36 # Create the ZIP archive.
37 with zipfile.ZipFile(f, "w", compression) as zipfp:
38
39 # It will contain enough copies of self.data to reach about 6 GiB of
40 # raw data to store.
41 filecount = 6*1024**3 // len(self.data)
42
43 next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
44 for num in range(filecount):
45 zipfp.writestr("testfn%d" % num, self.data)
46 # Print still working message since this test can be really slow
47 if next_time <= time.monotonic():
48 next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
49 print((
50 ' zipTest still writing %d of %d, be patient...' %
51 (num, filecount)), file=sys.__stdout__)
52 sys.__stdout__.flush()
53
54 # Read the ZIP archive
55 with zipfile.ZipFile(f, "r", compression) as zipfp:
56 for num in range(filecount):
57 self.assertEqual(zipfp.read("testfn%d" % num), self.data)
58 # Print still working message since this test can be really slow
59 if next_time <= time.monotonic():
60 next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
61 print((
62 ' zipTest still reading %d of %d, be patient...' %
63 (num, filecount)), file=sys.__stdout__)
64 sys.__stdout__.flush()
65
66 # Check that testzip thinks the archive is valid
67 self.assertIsNone(zipfp.testzip())
68
69 def testStored(self):
70 # Try the temp file first. If we do TESTFN2 first, then it hogs
71 # gigabytes of disk space for the duration of the test.
72 with TemporaryFile() as f:
73 self.zipTest(f, zipfile.ZIP_STORED)
74 self.assertFalse(f.closed)
75 self.zipTest(TESTFN2, zipfile.ZIP_STORED)
76
77 @requires_zlib()
78 def testDeflated(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 with TemporaryFile() as f:
82 self.zipTest(f, zipfile.ZIP_DEFLATED)
83 self.assertFalse(f.closed)
84 self.zipTest(TESTFN2, zipfile.ZIP_DEFLATED)
85
86 def tearDown(self):
87 os_helper.unlink(TESTFN2)
88
89
90 class ESC[4;38;5;81mOtherTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
91 def testMoreThan64kFiles(self):
92 # This test checks that more than 64k files can be added to an archive,
93 # and that the resulting archive can be read properly by ZipFile
94 with zipfile.ZipFile(TESTFN, mode="w", allowZip64=True) as zipf:
95 zipf.debug = 100
96 numfiles = (1 << 16) * 3//2
97 for i in range(numfiles):
98 zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
99 self.assertEqual(len(zipf.namelist()), numfiles)
100
101 with zipfile.ZipFile(TESTFN, mode="r") as zipf2:
102 self.assertEqual(len(zipf2.namelist()), numfiles)
103 for i in range(numfiles):
104 content = zipf2.read("foo%08d" % i).decode('ascii')
105 self.assertEqual(content, "%d" % (i**3 % 57))
106
107 def testMoreThan64kFilesAppend(self):
108 with zipfile.ZipFile(TESTFN, mode="w", allowZip64=False) as zipf:
109 zipf.debug = 100
110 numfiles = (1 << 16) - 1
111 for i in range(numfiles):
112 zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
113 self.assertEqual(len(zipf.namelist()), numfiles)
114 with self.assertRaises(zipfile.LargeZipFile):
115 zipf.writestr("foo%08d" % numfiles, b'')
116 self.assertEqual(len(zipf.namelist()), numfiles)
117
118 with zipfile.ZipFile(TESTFN, mode="a", allowZip64=False) as zipf:
119 zipf.debug = 100
120 self.assertEqual(len(zipf.namelist()), numfiles)
121 with self.assertRaises(zipfile.LargeZipFile):
122 zipf.writestr("foo%08d" % numfiles, b'')
123 self.assertEqual(len(zipf.namelist()), numfiles)
124
125 with zipfile.ZipFile(TESTFN, mode="a", allowZip64=True) as zipf:
126 zipf.debug = 100
127 self.assertEqual(len(zipf.namelist()), numfiles)
128 numfiles2 = (1 << 16) * 3//2
129 for i in range(numfiles, numfiles2):
130 zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
131 self.assertEqual(len(zipf.namelist()), numfiles2)
132
133 with zipfile.ZipFile(TESTFN, mode="r") as zipf2:
134 self.assertEqual(len(zipf2.namelist()), numfiles2)
135 for i in range(numfiles2):
136 content = zipf2.read("foo%08d" % i).decode('ascii')
137 self.assertEqual(content, "%d" % (i**3 % 57))
138
139 def tearDown(self):
140 os_helper.unlink(TESTFN)
141 os_helper.unlink(TESTFN2)
142
143 if __name__ == "__main__":
144 unittest.main()