test_zipfile64.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. # XXX(nnorwitz): disable this test by looking for extralargefile 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. support.requires(
  9. 'extralargefile',
  10. 'test requires loads of disk-space bytes and a long time to run'
  11. )
  12. import zipfile, os, unittest
  13. import time
  14. import sys
  15. from tempfile import TemporaryFile
  16. from test.support import os_helper
  17. from test.support import requires_zlib
  18. TESTFN = os_helper.TESTFN
  19. TESTFN2 = TESTFN + "2"
  20. # How much time in seconds can pass before we print a 'Still working' message.
  21. _PRINT_WORKING_MSG_INTERVAL = 60
  22. class TestsWithSourceFile(unittest.TestCase):
  23. def setUp(self):
  24. # Create test data.
  25. line_gen = ("Test of zipfile line %d." % i for i in range(1000000))
  26. self.data = '\n'.join(line_gen).encode('ascii')
  27. # And write it to a file.
  28. with open(TESTFN, "wb") as fp:
  29. fp.write(self.data)
  30. def zipTest(self, f, compression):
  31. # Create the ZIP archive.
  32. with zipfile.ZipFile(f, "w", compression) as zipfp:
  33. # It will contain enough copies of self.data to reach about 6 GiB of
  34. # raw data to store.
  35. filecount = 6*1024**3 // len(self.data)
  36. next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
  37. for num in range(filecount):
  38. zipfp.writestr("testfn%d" % num, self.data)
  39. # Print still working message since this test can be really slow
  40. if next_time <= time.monotonic():
  41. next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
  42. print((
  43. ' zipTest still writing %d of %d, be patient...' %
  44. (num, filecount)), file=sys.__stdout__)
  45. sys.__stdout__.flush()
  46. # Read the ZIP archive
  47. with zipfile.ZipFile(f, "r", compression) as zipfp:
  48. for num in range(filecount):
  49. self.assertEqual(zipfp.read("testfn%d" % num), self.data)
  50. # Print still working message since this test can be really slow
  51. if next_time <= time.monotonic():
  52. next_time = time.monotonic() + _PRINT_WORKING_MSG_INTERVAL
  53. print((
  54. ' zipTest still reading %d of %d, be patient...' %
  55. (num, filecount)), file=sys.__stdout__)
  56. sys.__stdout__.flush()
  57. def testStored(self):
  58. # Try the temp file first. If we do TESTFN2 first, then it hogs
  59. # gigabytes of disk space for the duration of the test.
  60. with TemporaryFile() as f:
  61. self.zipTest(f, zipfile.ZIP_STORED)
  62. self.assertFalse(f.closed)
  63. self.zipTest(TESTFN2, zipfile.ZIP_STORED)
  64. @requires_zlib()
  65. def testDeflated(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_DEFLATED)
  70. self.assertFalse(f.closed)
  71. self.zipTest(TESTFN2, zipfile.ZIP_DEFLATED)
  72. def tearDown(self):
  73. for fname in TESTFN, TESTFN2:
  74. if os.path.exists(fname):
  75. os.remove(fname)
  76. class OtherTests(unittest.TestCase):
  77. def testMoreThan64kFiles(self):
  78. # This test checks that more than 64k files can be added to an archive,
  79. # and that the resulting archive can be read properly by ZipFile
  80. with zipfile.ZipFile(TESTFN, mode="w", allowZip64=True) as zipf:
  81. zipf.debug = 100
  82. numfiles = (1 << 16) * 3//2
  83. for i in range(numfiles):
  84. zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
  85. self.assertEqual(len(zipf.namelist()), numfiles)
  86. with zipfile.ZipFile(TESTFN, mode="r") as zipf2:
  87. self.assertEqual(len(zipf2.namelist()), numfiles)
  88. for i in range(numfiles):
  89. content = zipf2.read("foo%08d" % i).decode('ascii')
  90. self.assertEqual(content, "%d" % (i**3 % 57))
  91. def testMoreThan64kFilesAppend(self):
  92. with zipfile.ZipFile(TESTFN, mode="w", allowZip64=False) as zipf:
  93. zipf.debug = 100
  94. numfiles = (1 << 16) - 1
  95. for i in range(numfiles):
  96. zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
  97. self.assertEqual(len(zipf.namelist()), numfiles)
  98. with self.assertRaises(zipfile.LargeZipFile):
  99. zipf.writestr("foo%08d" % numfiles, b'')
  100. self.assertEqual(len(zipf.namelist()), numfiles)
  101. with zipfile.ZipFile(TESTFN, mode="a", allowZip64=False) as zipf:
  102. zipf.debug = 100
  103. self.assertEqual(len(zipf.namelist()), numfiles)
  104. with self.assertRaises(zipfile.LargeZipFile):
  105. zipf.writestr("foo%08d" % numfiles, b'')
  106. self.assertEqual(len(zipf.namelist()), numfiles)
  107. with zipfile.ZipFile(TESTFN, mode="a", allowZip64=True) as zipf:
  108. zipf.debug = 100
  109. self.assertEqual(len(zipf.namelist()), numfiles)
  110. numfiles2 = (1 << 16) * 3//2
  111. for i in range(numfiles, numfiles2):
  112. zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57))
  113. self.assertEqual(len(zipf.namelist()), numfiles2)
  114. with zipfile.ZipFile(TESTFN, mode="r") as zipf2:
  115. self.assertEqual(len(zipf2.namelist()), numfiles2)
  116. for i in range(numfiles2):
  117. content = zipf2.read("foo%08d" % i).decode('ascii')
  118. self.assertEqual(content, "%d" % (i**3 % 57))
  119. def tearDown(self):
  120. os_helper.unlink(TESTFN)
  121. os_helper.unlink(TESTFN2)
  122. if __name__ == "__main__":
  123. unittest.main()