Home | History | Annotate | Download | only in test
      1 # Tests of the full ZIP64 functionality of zipfile
      2 # The test_support.requires call is the only reason for keeping this separate
      3 # from test_zipfile
      4 from test import test_support
      5 
      6 # 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.
      9 test_support.requires(
     10         '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.
     15 try:
     16     import zlib
     17 except ImportError:
     18     zlib = None
     19 
     20 import zipfile, os, unittest
     21 import time
     22 import sys
     23 
     24 from tempfile import TemporaryFile
     25 
     26 from test.test_support import TESTFN, run_unittest
     27 
     28 TESTFN2 = TESTFN + "2"
     29 
     30 # How much time in seconds can pass before we print a 'Still working' message.
     31 _PRINT_WORKING_MSG_INTERVAL = 5 * 60
     32 
     33 class TestsWithSourceFile(unittest.TestCase):
     34     def setUp(self):
     35         # Create test data.
     36         # xrange() is important here -- don't want to create immortal space
     37         # for a million ints.
     38         line_gen = ("Test of zipfile line %d." % i for i in xrange(1000000))
     39         self.data = '\n'.join(line_gen)
     40 
     41         # And write it to a file.
     42         fp = open(TESTFN, "wb")
     43         fp.write(self.data)
     44         fp.close()
     45 
     46     def zipTest(self, f, compression):
     47         # Create the ZIP archive.
     48         zipfp = zipfile.ZipFile(f, "w", compression, allowZip64=True)
     49 
     50         # It will contain enough copies of self.data to reach about 6GB of
     51         # raw data to store.
     52         filecount = 6*1024**3 // len(self.data)
     53 
     54         next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
     55         for num in range(filecount):
     56             zipfp.writestr("testfn%d" % num, self.data)
     57             # Print still working message since this test can be really slow
     58             if next_time <= time.time():
     59                 next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
     60                 print >>sys.__stdout__, (
     61                    '  zipTest still writing %d of %d, be patient...' %
     62                    (num, filecount))
     63                 sys.__stdout__.flush()
     64         zipfp.close()
     65 
     66         # Read the ZIP archive
     67         zipfp = zipfile.ZipFile(f, "r", compression)
     68         for num in range(filecount):
     69             self.assertEqual(zipfp.read("testfn%d" % num), self.data)
     70             # Print still working message since this test can be really slow
     71             if next_time <= time.time():
     72                 next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
     73                 print >>sys.__stdout__, (
     74                    '  zipTest still reading %d of %d, be patient...' %
     75                    (num, filecount))
     76                 sys.__stdout__.flush()
     77         zipfp.close()
     78 
     79     def testStored(self):
     80         # Try the temp file first.  If we do TESTFN2 first, then it hogs
     81         # gigabytes of disk space for the duration of the test.
     82         with TemporaryFile() as f:
     83             self.zipTest(f, zipfile.ZIP_STORED)
     84             self.assertFalse(f.closed)
     85         self.zipTest(TESTFN2, zipfile.ZIP_STORED)
     86 
     87     @unittest.skipUnless(zlib, "requires zlib")
     88     def testDeflated(self):
     89         # Try the temp file first.  If we do TESTFN2 first, then it hogs
     90         # gigabytes of disk space for the duration of the test.
     91         with TemporaryFile() as f:
     92             self.zipTest(f, zipfile.ZIP_DEFLATED)
     93             self.assertFalse(f.closed)
     94         self.zipTest(TESTFN2, zipfile.ZIP_DEFLATED)
     95 
     96     def tearDown(self):
     97         for fname in TESTFN, TESTFN2:
     98             if os.path.exists(fname):
     99                 os.remove(fname)
    100 
    101 
    102 class OtherTests(unittest.TestCase):
    103     def testMoreThan64kFiles(self):
    104         # This test checks that more than 64k files can be added to an archive,
    105         # and that the resulting archive can be read properly by ZipFile
    106         zipf = zipfile.ZipFile(TESTFN, mode="w", allowZip64=True)
    107         zipf.debug = 100
    108         numfiles = (1 << 16) * 3/2
    109         for i in xrange(numfiles):
    110             zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
    111         self.assertEqual(len(zipf.namelist()), numfiles)
    112         zipf.close()
    113 
    114         zipf2 = zipfile.ZipFile(TESTFN, mode="r")
    115         self.assertEqual(len(zipf2.namelist()), numfiles)
    116         for i in xrange(numfiles):
    117             self.assertEqual(zipf2.read("foo%08d" % i), "%d" % (i**3 % 57))
    118         zipf2.close()
    119 
    120     def testMoreThan64kFilesAppend(self):
    121         zipf = zipfile.ZipFile(TESTFN, mode="w", allowZip64=False)
    122         zipf.debug = 100
    123         numfiles = (1 << 16) - 1
    124         for i in range(numfiles):
    125             zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
    126         self.assertEqual(len(zipf.namelist()), numfiles)
    127         with self.assertRaises(zipfile.LargeZipFile):
    128             zipf.writestr("foo%08d" % numfiles, b'')
    129         self.assertEqual(len(zipf.namelist()), numfiles)
    130         zipf.close()
    131 
    132         zipf = zipfile.ZipFile(TESTFN, mode="a", allowZip64=False)
    133         zipf.debug = 100
    134         self.assertEqual(len(zipf.namelist()), numfiles)
    135         with self.assertRaises(zipfile.LargeZipFile):
    136             zipf.writestr("foo%08d" % numfiles, b'')
    137         self.assertEqual(len(zipf.namelist()), numfiles)
    138         zipf.close()
    139 
    140         zipf = zipfile.ZipFile(TESTFN, mode="a", allowZip64=True)
    141         zipf.debug = 100
    142         self.assertEqual(len(zipf.namelist()), numfiles)
    143         numfiles2 = (1 << 16) * 3//2
    144         for i in range(numfiles, numfiles2):
    145             zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
    146         self.assertEqual(len(zipf.namelist()), numfiles2)
    147         zipf.close()
    148 
    149         zipf2 = zipfile.ZipFile(TESTFN, mode="r")
    150         self.assertEqual(len(zipf2.namelist()), numfiles2)
    151         for i in range(numfiles2):
    152             self.assertEqual(zipf2.read("foo%08d" % i), "%d" % (i**3 % 57))
    153         zipf2.close()
    154 
    155     def tearDown(self):
    156         test_support.unlink(TESTFN)
    157         test_support.unlink(TESTFN2)
    158 
    159 def test_main():
    160     run_unittest(TestsWithSourceFile, OtherTests)
    161 
    162 if __name__ == "__main__":
    163     test_main()
    164