test_zipfile64.py 4.17 KB
Newer Older
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 7 8
# XXX(nnorwitz): disable this test by looking for extra largfile resource
# which doesn't exist.  This test takes over 30 minutes to run in general
# and requires more disk space than most of the buildbots.
9
support.requires(
10 11 12 13 14 15 16 17
        'extralargefile',
        'test requires loads of disk-space bytes and a long time to run'
    )

import zipfile, os, unittest
import time
import sys

18
from io import StringIO
19 20
from tempfile import TemporaryFile

21
from test.support import TESTFN, run_unittest, requires_zlib
22 23 24 25 26 27 28 29 30

TESTFN2 = TESTFN + "2"

# How much time in seconds can pass before we print a 'Still working' message.
_PRINT_WORKING_MSG_INTERVAL = 5 * 60

class TestsWithSourceFile(unittest.TestCase):
    def setUp(self):
        # Create test data.
31
        line_gen = ("Test of zipfile line %d." % i for i in range(1000000))
32
        self.data = '\n'.join(line_gen).encode('ascii')
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

        # And write it to a file.
        fp = open(TESTFN, "wb")
        fp.write(self.data)
        fp.close()

    def zipTest(self, f, compression):
        # Create the ZIP archive.
        zipfp = zipfile.ZipFile(f, "w", compression, allowZip64=True)

        # It will contain enough copies of self.data to reach about 6GB of
        # raw data to store.
        filecount = 6*1024**3 // len(self.data)

        next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
        for num in range(filecount):
            zipfp.writestr("testfn%d" % num, self.data)
            # Print still working message since this test can be really slow
            if next_time <= time.time():
                next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
53
                print((
54
                   '  zipTest still writing %d of %d, be patient...' %
55
                   (num, filecount)), file=sys.__stdout__)
56 57 58 59 60 61 62 63 64 65
                sys.__stdout__.flush()
        zipfp.close()

        # Read the ZIP archive
        zipfp = zipfile.ZipFile(f, "r", compression)
        for num in range(filecount):
            self.assertEqual(zipfp.read("testfn%d" % num), self.data)
            # Print still working message since this test can be really slow
            if next_time <= time.time():
                next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
66
                print((
67
                   '  zipTest still reading %d of %d, be patient...' %
68
                   (num, filecount)), file=sys.__stdout__)
69 70 71 72 73 74 75 76 77
                sys.__stdout__.flush()
        zipfp.close()

    def testStored(self):
        # Try the temp file first.  If we do TESTFN2 first, then it hogs
        # gigabytes of disk space for the duration of the test.
        for f in TemporaryFile(), TESTFN2:
            self.zipTest(f, zipfile.ZIP_STORED)

78 79 80 81 82 83
    @requires_zlib
    def testDeflated(self):
        # Try the temp file first.  If we do TESTFN2 first, then it hogs
        # gigabytes of disk space for the duration of the test.
        for f in TemporaryFile(), TESTFN2:
            self.zipTest(f, zipfile.ZIP_DEFLATED)
84 85 86 87 88 89

    def tearDown(self):
        for fname in TESTFN, TESTFN2:
            if os.path.exists(fname):
                os.remove(fname)

90 91 92 93 94 95 96

class OtherTests(unittest.TestCase):
    def testMoreThan64kFiles(self):
        # This test checks that more than 64k files can be added to an archive,
        # and that the resulting archive can be read properly by ZipFile
        zipf = zipfile.ZipFile(TESTFN, mode="w")
        zipf.debug = 100
97 98
        numfiles = (1 << 16) * 3//2
        for i in range(numfiles):
99 100 101 102 103 104
            zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
        self.assertEqual(len(zipf.namelist()), numfiles)
        zipf.close()

        zipf2 = zipfile.ZipFile(TESTFN, mode="r")
        self.assertEqual(len(zipf2.namelist()), numfiles)
105 106 107
        for i in range(numfiles):
            content = zipf2.read("foo%08d" % i).decode('ascii')
            self.assertEqual(content, "%d" % (i**3 % 57))
108 109 110
        zipf.close()

    def tearDown(self):
111 112
        support.unlink(TESTFN)
        support.unlink(TESTFN2)
113

114
def test_main():
115
    run_unittest(TestsWithSourceFile, OtherTests)
116 117 118

if __name__ == "__main__":
    test_main()