blob: 810fdedef39dddbe46fae8c24b71be217b82db37 [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
Martin Panter6f9b0102015-12-17 10:18:28 +00006# XXX(nnorwitz): disable this test by looking for extralargefile resource,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007# 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
Thomas Wouters0e3f5912006-08-11 14:57:12 +000014import zipfile, os, unittest
15import time
16import sys
17
Thomas Wouters0e3f5912006-08-11 14:57:12 +000018from tempfile import TemporaryFile
19
Hai Shic6f282f2020-08-08 19:05:24 +080020from test.support import os_helper
Serhiy Storchakacfbb3942014-09-23 21:34:24 +030021from test.support import TESTFN, requires_zlib
Thomas Wouters0e3f5912006-08-11 14:57:12 +000022
23TESTFN2 = TESTFN + "2"
24
25# How much time in seconds can pass before we print a 'Still working' message.
Victor Stinner2cf4c202018-12-17 09:36:36 +010026_PRINT_WORKING_MSG_INTERVAL = 60
Thomas Wouters0e3f5912006-08-11 14:57:12 +000027
28class TestsWithSourceFile(unittest.TestCase):
29 def setUp(self):
30 # Create test data.
Guido van Rossum805365e2007-05-07 22:24:25 +000031 line_gen = ("Test of zipfile line %d." % i for i in range(1000000))
Amaury Forgeot d'Arc3be2f042008-11-12 01:57:36 +000032 self.data = '\n'.join(line_gen).encode('ascii')
Thomas Wouters0e3f5912006-08-11 14:57:12 +000033
34 # And write it to a file.
Serhiy Storchaka9e4861f2019-03-05 10:05:57 +020035 with open(TESTFN, "wb") as fp:
36 fp.write(self.data)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000037
38 def zipTest(self, f, compression):
39 # Create the ZIP archive.
Serhiy Storchaka9e4861f2019-03-05 10:05:57 +020040 with zipfile.ZipFile(f, "w", compression) as zipfp:
Thomas Wouters0e3f5912006-08-11 14:57:12 +000041
Serhiy Storchaka9e4861f2019-03-05 10:05:57 +020042 # It will contain enough copies of self.data to reach about 6 GiB of
43 # raw data to store.
44 filecount = 6*1024**3 // len(self.data)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000045
Serhiy Storchaka9e4861f2019-03-05 10:05:57 +020046 next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
47 for num in range(filecount):
48 zipfp.writestr("testfn%d" % num, self.data)
49 # Print still working message since this test can be really slow
50 if next_time <= time.monotonic():
51 next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
52 print((
53 ' zipTest still writing %d of %d, be patient...' %
54 (num, filecount)), file=sys.__stdout__)
55 sys.__stdout__.flush()
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056
57 # Read the ZIP archive
Serhiy Storchaka9e4861f2019-03-05 10:05:57 +020058 with zipfile.ZipFile(f, "r", compression) as zipfp:
59 for num in range(filecount):
60 self.assertEqual(zipfp.read("testfn%d" % num), self.data)
61 # Print still working message since this test can be really slow
62 if next_time <= time.monotonic():
63 next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
64 print((
65 ' zipTest still reading %d of %d, be patient...' %
66 (num, filecount)), file=sys.__stdout__)
67 sys.__stdout__.flush()
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068
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.
Serhiy Storchakaf8282182016-02-25 12:55:19 +020072 with TemporaryFile() as f:
Thomas Wouters0e3f5912006-08-11 14:57:12 +000073 self.zipTest(f, zipfile.ZIP_STORED)
Serhiy Storchakaf8282182016-02-25 12:55:19 +020074 self.assertFalse(f.closed)
75 self.zipTest(TESTFN2, zipfile.ZIP_STORED)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000076
Hai Shia3ec3ad2020-05-19 06:02:57 +080077 @requires_zlib()
Ezio Melotti975077a2011-05-19 22:03:22 +030078 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.
Serhiy Storchakaf8282182016-02-25 12:55:19 +020081 with TemporaryFile() as f:
Ezio Melotti975077a2011-05-19 22:03:22 +030082 self.zipTest(f, zipfile.ZIP_DEFLATED)
Serhiy Storchakaf8282182016-02-25 12:55:19 +020083 self.assertFalse(f.closed)
84 self.zipTest(TESTFN2, zipfile.ZIP_DEFLATED)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000085
86 def tearDown(self):
87 for fname in TESTFN, TESTFN2:
88 if os.path.exists(fname):
89 os.remove(fname)
90
Martin v. Löwisb09b8442008-07-03 14:13:42 +000091
92class OtherTests(unittest.TestCase):
93 def testMoreThan64kFiles(self):
94 # This test checks that more than 64k files can be added to an archive,
95 # and that the resulting archive can be read properly by ZipFile
Serhiy Storchaka9e4861f2019-03-05 10:05:57 +020096 with zipfile.ZipFile(TESTFN, mode="w", allowZip64=True) as zipf:
97 zipf.debug = 100
98 numfiles = (1 << 16) * 3//2
99 for i in range(numfiles):
100 zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
101 self.assertEqual(len(zipf.namelist()), numfiles)
Martin v. Löwisb09b8442008-07-03 14:13:42 +0000102
Serhiy Storchaka9e4861f2019-03-05 10:05:57 +0200103 with zipfile.ZipFile(TESTFN, mode="r") as zipf2:
104 self.assertEqual(len(zipf2.namelist()), numfiles)
105 for i in range(numfiles):
106 content = zipf2.read("foo%08d" % i).decode('ascii')
107 self.assertEqual(content, "%d" % (i**3 % 57))
Serhiy Storchakacfbb3942014-09-23 21:34:24 +0300108
109 def testMoreThan64kFilesAppend(self):
Serhiy Storchaka9e4861f2019-03-05 10:05:57 +0200110 with zipfile.ZipFile(TESTFN, mode="w", allowZip64=False) as zipf:
111 zipf.debug = 100
112 numfiles = (1 << 16) - 1
113 for i in range(numfiles):
114 zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
115 self.assertEqual(len(zipf.namelist()), numfiles)
116 with self.assertRaises(zipfile.LargeZipFile):
117 zipf.writestr("foo%08d" % numfiles, b'')
118 self.assertEqual(len(zipf.namelist()), numfiles)
Martin v. Löwisb09b8442008-07-03 14:13:42 +0000119
Serhiy Storchaka9e4861f2019-03-05 10:05:57 +0200120 with zipfile.ZipFile(TESTFN, mode="a", allowZip64=False) as zipf:
121 zipf.debug = 100
122 self.assertEqual(len(zipf.namelist()), numfiles)
123 with self.assertRaises(zipfile.LargeZipFile):
124 zipf.writestr("foo%08d" % numfiles, b'')
125 self.assertEqual(len(zipf.namelist()), numfiles)
Serhiy Storchakacfbb3942014-09-23 21:34:24 +0300126
Serhiy Storchaka9e4861f2019-03-05 10:05:57 +0200127 with zipfile.ZipFile(TESTFN, mode="a", allowZip64=True) as zipf:
128 zipf.debug = 100
129 self.assertEqual(len(zipf.namelist()), numfiles)
130 numfiles2 = (1 << 16) * 3//2
131 for i in range(numfiles, numfiles2):
132 zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
133 self.assertEqual(len(zipf.namelist()), numfiles2)
Serhiy Storchakacfbb3942014-09-23 21:34:24 +0300134
Serhiy Storchaka9e4861f2019-03-05 10:05:57 +0200135 with zipfile.ZipFile(TESTFN, mode="r") as zipf2:
136 self.assertEqual(len(zipf2.namelist()), numfiles2)
137 for i in range(numfiles2):
138 content = zipf2.read("foo%08d" % i).decode('ascii')
139 self.assertEqual(content, "%d" % (i**3 % 57))
Serhiy Storchakacfbb3942014-09-23 21:34:24 +0300140
Martin v. Löwisb09b8442008-07-03 14:13:42 +0000141 def tearDown(self):
Hai Shic6f282f2020-08-08 19:05:24 +0800142 os_helper.unlink(TESTFN)
143 os_helper.unlink(TESTFN2)
Martin v. Löwisb09b8442008-07-03 14:13:42 +0000144
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000145if __name__ == "__main__":
Serhiy Storchakacfbb3942014-09-23 21:34:24 +0300146 unittest.main()