17db96d56Sopenharmony_ci# Tests of the full ZIP64 functionality of zipfile
27db96d56Sopenharmony_ci# The support.requires call is the only reason for keeping this separate
37db96d56Sopenharmony_ci# from test_zipfile
47db96d56Sopenharmony_cifrom test import support
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ci# XXX(nnorwitz): disable this test by looking for extralargefile resource,
77db96d56Sopenharmony_ci# which doesn't exist.  This test takes over 30 minutes to run in general
87db96d56Sopenharmony_ci# and requires more disk space than most of the buildbots.
97db96d56Sopenharmony_cisupport.requires(
107db96d56Sopenharmony_ci        'extralargefile',
117db96d56Sopenharmony_ci        'test requires loads of disk-space bytes and a long time to run'
127db96d56Sopenharmony_ci    )
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_ciimport zipfile, os, unittest
157db96d56Sopenharmony_ciimport time
167db96d56Sopenharmony_ciimport sys
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_cifrom tempfile import TemporaryFile
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_cifrom test.support import os_helper
217db96d56Sopenharmony_cifrom test.support import requires_zlib
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ciTESTFN = os_helper.TESTFN
247db96d56Sopenharmony_ciTESTFN2 = TESTFN + "2"
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ci# How much time in seconds can pass before we print a 'Still working' message.
277db96d56Sopenharmony_ci_PRINT_WORKING_MSG_INTERVAL = 60
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ciclass TestsWithSourceFile(unittest.TestCase):
307db96d56Sopenharmony_ci    def setUp(self):
317db96d56Sopenharmony_ci        # Create test data.
327db96d56Sopenharmony_ci        line_gen = ("Test of zipfile line %d." % i for i in range(1000000))
337db96d56Sopenharmony_ci        self.data = '\n'.join(line_gen).encode('ascii')
347db96d56Sopenharmony_ci
357db96d56Sopenharmony_ci        # And write it to a file.
367db96d56Sopenharmony_ci        with open(TESTFN, "wb") as fp:
377db96d56Sopenharmony_ci            fp.write(self.data)
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci    def zipTest(self, f, compression):
407db96d56Sopenharmony_ci        # Create the ZIP archive.
417db96d56Sopenharmony_ci        with zipfile.ZipFile(f, "w", compression) as zipfp:
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ci            # It will contain enough copies of self.data to reach about 6 GiB of
447db96d56Sopenharmony_ci            # raw data to store.
457db96d56Sopenharmony_ci            filecount = 6*1024**3 // len(self.data)
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ci            next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
487db96d56Sopenharmony_ci            for num in range(filecount):
497db96d56Sopenharmony_ci                zipfp.writestr("testfn%d" % num, self.data)
507db96d56Sopenharmony_ci                # Print still working message since this test can be really slow
517db96d56Sopenharmony_ci                if next_time <= time.monotonic():
527db96d56Sopenharmony_ci                    next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
537db96d56Sopenharmony_ci                    print((
547db96d56Sopenharmony_ci                    '  zipTest still writing %d of %d, be patient...' %
557db96d56Sopenharmony_ci                    (num, filecount)), file=sys.__stdout__)
567db96d56Sopenharmony_ci                    sys.__stdout__.flush()
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ci        # Read the ZIP archive
597db96d56Sopenharmony_ci        with zipfile.ZipFile(f, "r", compression) as zipfp:
607db96d56Sopenharmony_ci            for num in range(filecount):
617db96d56Sopenharmony_ci                self.assertEqual(zipfp.read("testfn%d" % num), self.data)
627db96d56Sopenharmony_ci                # Print still working message since this test can be really slow
637db96d56Sopenharmony_ci                if next_time <= time.monotonic():
647db96d56Sopenharmony_ci                    next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
657db96d56Sopenharmony_ci                    print((
667db96d56Sopenharmony_ci                    '  zipTest still reading %d of %d, be patient...' %
677db96d56Sopenharmony_ci                    (num, filecount)), file=sys.__stdout__)
687db96d56Sopenharmony_ci                    sys.__stdout__.flush()
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ci    def testStored(self):
717db96d56Sopenharmony_ci        # Try the temp file first.  If we do TESTFN2 first, then it hogs
727db96d56Sopenharmony_ci        # gigabytes of disk space for the duration of the test.
737db96d56Sopenharmony_ci        with TemporaryFile() as f:
747db96d56Sopenharmony_ci            self.zipTest(f, zipfile.ZIP_STORED)
757db96d56Sopenharmony_ci            self.assertFalse(f.closed)
767db96d56Sopenharmony_ci        self.zipTest(TESTFN2, zipfile.ZIP_STORED)
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ci    @requires_zlib()
797db96d56Sopenharmony_ci    def testDeflated(self):
807db96d56Sopenharmony_ci        # Try the temp file first.  If we do TESTFN2 first, then it hogs
817db96d56Sopenharmony_ci        # gigabytes of disk space for the duration of the test.
827db96d56Sopenharmony_ci        with TemporaryFile() as f:
837db96d56Sopenharmony_ci            self.zipTest(f, zipfile.ZIP_DEFLATED)
847db96d56Sopenharmony_ci            self.assertFalse(f.closed)
857db96d56Sopenharmony_ci        self.zipTest(TESTFN2, zipfile.ZIP_DEFLATED)
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ci    def tearDown(self):
887db96d56Sopenharmony_ci        for fname in TESTFN, TESTFN2:
897db96d56Sopenharmony_ci            if os.path.exists(fname):
907db96d56Sopenharmony_ci                os.remove(fname)
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ci
937db96d56Sopenharmony_ciclass OtherTests(unittest.TestCase):
947db96d56Sopenharmony_ci    def testMoreThan64kFiles(self):
957db96d56Sopenharmony_ci        # This test checks that more than 64k files can be added to an archive,
967db96d56Sopenharmony_ci        # and that the resulting archive can be read properly by ZipFile
977db96d56Sopenharmony_ci        with zipfile.ZipFile(TESTFN, mode="w", allowZip64=True) as zipf:
987db96d56Sopenharmony_ci            zipf.debug = 100
997db96d56Sopenharmony_ci            numfiles = (1 << 16) * 3//2
1007db96d56Sopenharmony_ci            for i in range(numfiles):
1017db96d56Sopenharmony_ci                zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
1027db96d56Sopenharmony_ci            self.assertEqual(len(zipf.namelist()), numfiles)
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ci        with zipfile.ZipFile(TESTFN, mode="r") as zipf2:
1057db96d56Sopenharmony_ci            self.assertEqual(len(zipf2.namelist()), numfiles)
1067db96d56Sopenharmony_ci            for i in range(numfiles):
1077db96d56Sopenharmony_ci                content = zipf2.read("foo%08d" % i).decode('ascii')
1087db96d56Sopenharmony_ci                self.assertEqual(content, "%d" % (i**3 % 57))
1097db96d56Sopenharmony_ci
1107db96d56Sopenharmony_ci    def testMoreThan64kFilesAppend(self):
1117db96d56Sopenharmony_ci        with zipfile.ZipFile(TESTFN, mode="w", allowZip64=False) as zipf:
1127db96d56Sopenharmony_ci            zipf.debug = 100
1137db96d56Sopenharmony_ci            numfiles = (1 << 16) - 1
1147db96d56Sopenharmony_ci            for i in range(numfiles):
1157db96d56Sopenharmony_ci                zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
1167db96d56Sopenharmony_ci            self.assertEqual(len(zipf.namelist()), numfiles)
1177db96d56Sopenharmony_ci            with self.assertRaises(zipfile.LargeZipFile):
1187db96d56Sopenharmony_ci                zipf.writestr("foo%08d" % numfiles, b'')
1197db96d56Sopenharmony_ci            self.assertEqual(len(zipf.namelist()), numfiles)
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_ci        with zipfile.ZipFile(TESTFN, mode="a", allowZip64=False) as zipf:
1227db96d56Sopenharmony_ci            zipf.debug = 100
1237db96d56Sopenharmony_ci            self.assertEqual(len(zipf.namelist()), numfiles)
1247db96d56Sopenharmony_ci            with self.assertRaises(zipfile.LargeZipFile):
1257db96d56Sopenharmony_ci                zipf.writestr("foo%08d" % numfiles, b'')
1267db96d56Sopenharmony_ci            self.assertEqual(len(zipf.namelist()), numfiles)
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_ci        with zipfile.ZipFile(TESTFN, mode="a", allowZip64=True) as zipf:
1297db96d56Sopenharmony_ci            zipf.debug = 100
1307db96d56Sopenharmony_ci            self.assertEqual(len(zipf.namelist()), numfiles)
1317db96d56Sopenharmony_ci            numfiles2 = (1 << 16) * 3//2
1327db96d56Sopenharmony_ci            for i in range(numfiles, numfiles2):
1337db96d56Sopenharmony_ci                zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
1347db96d56Sopenharmony_ci            self.assertEqual(len(zipf.namelist()), numfiles2)
1357db96d56Sopenharmony_ci
1367db96d56Sopenharmony_ci        with zipfile.ZipFile(TESTFN, mode="r") as zipf2:
1377db96d56Sopenharmony_ci            self.assertEqual(len(zipf2.namelist()), numfiles2)
1387db96d56Sopenharmony_ci            for i in range(numfiles2):
1397db96d56Sopenharmony_ci                content = zipf2.read("foo%08d" % i).decode('ascii')
1407db96d56Sopenharmony_ci                self.assertEqual(content, "%d" % (i**3 % 57))
1417db96d56Sopenharmony_ci
1427db96d56Sopenharmony_ci    def tearDown(self):
1437db96d56Sopenharmony_ci        os_helper.unlink(TESTFN)
1447db96d56Sopenharmony_ci        os_helper.unlink(TESTFN2)
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_ciif __name__ == "__main__":
1477db96d56Sopenharmony_ci    unittest.main()
148