test_zipfile64.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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. # XXX(nnorwitz): disable this test by looking for extra largfile resource
  6. # which doesn't exist. This test takes over 30 minutes to run in general
  7. # and requires more disk space than most of the buildbots.
  8. test_support.requires(
  9. 'extralargefile',
  10. 'test requires loads of disk-space bytes and a long time to run'
  11. )
  12. # We can test part of the module without zlib.
  13. try:
  14. import zlib
  15. except ImportError:
  16. zlib = None
  17. import zipfile, os, unittest
  18. import time
  19. import sys
  20. from tempfile import TemporaryFile
  21. from test.test_support import TESTFN, run_unittest
  22. TESTFN2 = TESTFN + "2"
  23. # How much time in seconds can pass before we print a 'Still working' message.
  24. _PRINT_WORKING_MSG_INTERVAL = 5 * 60
  25. class TestsWithSourceFile(unittest.TestCase):
  26. def setUp(self):
  27. # Create test data.
  28. # xrange() is important here -- don't want to create immortal space
  29. # for a million ints.
  30. line_gen = ("Test of zipfile line %d." % i for i in xrange(1000000))
  31. self.data = '\n'.join(line_gen)
  32. # And write it to a file.
  33. fp = open(TESTFN, "wb")
  34. fp.write(self.data)
  35. fp.close()
  36. def zipTest(self, f, compression):
  37. # Create the ZIP archive.
  38. zipfp = zipfile.ZipFile(f, "w", compression, allowZip64=True)
  39. # It will contain enough copies of self.data to reach about 6GB of
  40. # raw data to store.
  41. filecount = 6*1024**3 // len(self.data)
  42. next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
  43. for num in range(filecount):
  44. zipfp.writestr("testfn%d" % num, self.data)
  45. # Print still working message since this test can be really slow
  46. if next_time <= time.time():
  47. next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
  48. print >>sys.__stdout__, (
  49. ' zipTest still writing %d of %d, be patient...' %
  50. (num, filecount))
  51. sys.__stdout__.flush()
  52. zipfp.close()
  53. # Read the ZIP archive
  54. zipfp = zipfile.ZipFile(f, "r", compression)
  55. for num in range(filecount):
  56. self.assertEqual(zipfp.read("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 reading %d of %d, be patient...' %
  62. (num, filecount))
  63. sys.__stdout__.flush()
  64. zipfp.close()
  65. def testStored(self):
  66. # Try the temp file first. If we do TESTFN2 first, then it hogs
  67. # gigabytes of disk space for the duration of the test.
  68. with TemporaryFile() as f:
  69. self.zipTest(f, zipfile.ZIP_STORED)
  70. self.assertFalse(f.closed)
  71. self.zipTest(TESTFN2, zipfile.ZIP_STORED)
  72. @unittest.skipUnless(zlib, "requires zlib")
  73. def testDeflated(self):
  74. # Try the temp file first. If we do TESTFN2 first, then it hogs
  75. # gigabytes of disk space for the duration of the test.
  76. with TemporaryFile() as f:
  77. self.zipTest(f, zipfile.ZIP_DEFLATED)
  78. self.assertFalse(f.closed)
  79. self.zipTest(TESTFN2, zipfile.ZIP_DEFLATED)
  80. def tearDown(self):
  81. for fname in TESTFN, TESTFN2:
  82. if os.path.exists(fname):
  83. os.remove(fname)
  84. class OtherTests(unittest.TestCase):
  85. def testMoreThan64kFiles(self):
  86. # This test checks that more than 64k files can be added to an archive,
  87. # and that the resulting archive can be read properly by ZipFile
  88. zipf = zipfile.ZipFile(TESTFN, mode="w", allowZip64=True)
  89. zipf.debug = 100
  90. numfiles = (1 << 16) * 3/2
  91. for i in xrange(numfiles):
  92. zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
  93. self.assertEqual(len(zipf.namelist()), numfiles)
  94. zipf.close()
  95. zipf2 = zipfile.ZipFile(TESTFN, mode="r")
  96. self.assertEqual(len(zipf2.namelist()), numfiles)
  97. for i in xrange(numfiles):
  98. self.assertEqual(zipf2.read("foo%08d" % i), "%d" % (i**3 % 57))
  99. zipf2.close()
  100. def testMoreThan64kFilesAppend(self):
  101. zipf = zipfile.ZipFile(TESTFN, mode="w", allowZip64=False)
  102. zipf.debug = 100
  103. numfiles = (1 << 16) - 1
  104. for i in range(numfiles):
  105. zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
  106. self.assertEqual(len(zipf.namelist()), numfiles)
  107. with self.assertRaises(zipfile.LargeZipFile):
  108. zipf.writestr("foo%08d" % numfiles, b'')
  109. self.assertEqual(len(zipf.namelist()), numfiles)
  110. zipf.close()
  111. zipf = zipfile.ZipFile(TESTFN, mode="a", allowZip64=False)
  112. zipf.debug = 100
  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. zipf.close()
  118. zipf = zipfile.ZipFile(TESTFN, mode="a", allowZip64=True)
  119. zipf.debug = 100
  120. self.assertEqual(len(zipf.namelist()), numfiles)
  121. numfiles2 = (1 << 16) * 3//2
  122. for i in range(numfiles, numfiles2):
  123. zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
  124. self.assertEqual(len(zipf.namelist()), numfiles2)
  125. zipf.close()
  126. zipf2 = zipfile.ZipFile(TESTFN, mode="r")
  127. self.assertEqual(len(zipf2.namelist()), numfiles2)
  128. for i in range(numfiles2):
  129. self.assertEqual(zipf2.read("foo%08d" % i), "%d" % (i**3 % 57))
  130. zipf2.close()
  131. def tearDown(self):
  132. test_support.unlink(TESTFN)
  133. test_support.unlink(TESTFN2)
  134. def test_main():
  135. run_unittest(TestsWithSourceFile, OtherTests)
  136. if __name__ == "__main__":
  137. test_main()