test_zip.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. from panda3d.core import ZipArchive, IStreamWrapper, StringStream, Filename
  2. from direct.stdpy.file import StreamIOWrapper
  3. import zipfile
  4. from io import BytesIO
  5. EMPTY_ZIP = b'PK\x05\x06' + b'\x00' * 18
  6. def test_zip_read_empty():
  7. stream = StringStream(EMPTY_ZIP)
  8. wrapper = IStreamWrapper(stream)
  9. zip = ZipArchive()
  10. zip.open_read(wrapper)
  11. assert zip.is_read_valid()
  12. assert not zip.is_write_valid()
  13. assert not zip.needs_repack()
  14. assert zip.get_num_subfiles() == 0
  15. zip.close()
  16. def test_zip_write_empty():
  17. stream = StringStream()
  18. zip = ZipArchive()
  19. zip.open_write(stream)
  20. assert not zip.is_read_valid()
  21. assert zip.is_write_valid()
  22. assert not zip.needs_repack()
  23. zip.close()
  24. assert stream.data == EMPTY_ZIP
  25. with zipfile.ZipFile(StreamIOWrapper(stream), 'r') as zf:
  26. assert zf.testzip() is None
  27. def test_zip_read_extract(tmp_path):
  28. stream = StringStream()
  29. zf = zipfile.ZipFile(StreamIOWrapper(stream), mode='w', allowZip64=True)
  30. zf.writestr("test.txt", b"test stored", compress_type=zipfile.ZIP_STORED)
  31. zf.writestr("test2.txt", b"test deflated", compress_type=zipfile.ZIP_DEFLATED)
  32. zf.writestr("dir/dtest.txt", b"test in dir")
  33. zf.writestr("dir1/dir2/test.txt", b"test nested dir")
  34. zf.writestr("emptydir/", b"", compress_type=zipfile.ZIP_STORED)
  35. zf.close()
  36. wrapper = IStreamWrapper(stream)
  37. zip = ZipArchive()
  38. zip.open_read(wrapper)
  39. assert zip.is_read_valid()
  40. assert not zip.is_write_valid()
  41. assert not zip.needs_repack()
  42. assert zip.verify()
  43. assert zip.find_subfile("nonexistent.txt") == -1
  44. sf = zip.find_subfile("test.txt")
  45. assert sf >= 0
  46. assert zip.read_subfile(sf) == b"test stored"
  47. assert zip.extract_subfile(sf, tmp_path / "test.txt")
  48. assert open(tmp_path / "test.txt", 'rb').read() == b"test stored"
  49. sf = zip.find_subfile("test2.txt")
  50. assert sf >= 0
  51. assert zip.read_subfile(sf) == b"test deflated"
  52. assert zip.extract_subfile(sf, tmp_path / "test2.txt")
  53. assert open(tmp_path / "test2.txt", 'rb').read() == b"test deflated"
  54. def test_zip_write():
  55. stream = StringStream()
  56. zip = ZipArchive()
  57. zip.open_write(stream)
  58. zip.add_subfile("test.txt", StringStream(b"test deflated"), 6)
  59. zip.add_subfile("test2.txt", StringStream(b"test stored"), 0)
  60. zip.close()
  61. with zipfile.ZipFile(StreamIOWrapper(stream), 'r') as zf:
  62. assert zf.testzip() is None
  63. assert tuple(sorted(zf.namelist())) == ("test.txt", "test2.txt")
  64. def test_zip_replace_subfile(tmp_path):
  65. stream = StringStream()
  66. zf = zipfile.ZipFile(StreamIOWrapper(stream), mode='w', allowZip64=True)
  67. zf.writestr("test1.txt", b"contents of first file")
  68. zf.writestr("test2.txt", b"")
  69. zf.writestr("test3.txt", b"contents of third file")
  70. zf.close()
  71. zip = ZipArchive()
  72. zip.open_read_write(stream)
  73. assert zip.is_read_valid()
  74. assert zip.is_write_valid()
  75. assert not zip.needs_repack()
  76. assert zip.verify()
  77. sf = zip.find_subfile("test2.txt")
  78. assert sf >= 0
  79. zip.add_subfile("test2.txt", StringStream(b"contents of second file"), 6)
  80. zip.close()
  81. with zipfile.ZipFile(StreamIOWrapper(stream), 'r') as zf:
  82. assert zf.testzip() is None
  83. assert zf.read("test1.txt") == b"contents of first file"
  84. assert zf.read("test2.txt") == b"contents of second file"
  85. assert zf.read("test3.txt") == b"contents of third file"
  86. def test_zip_remove_subfile(tmp_path):
  87. stream = StringStream()
  88. zf = zipfile.ZipFile(StreamIOWrapper(stream), mode='w', allowZip64=True)
  89. zf.writestr("test1.txt", b"contents of first file")
  90. zf.writestr("test2.txt", b"contents of second file")
  91. zf.writestr("test3.txt", b"contents of third file")
  92. zf.close()
  93. zip = ZipArchive()
  94. zip.open_read_write(stream)
  95. assert zip.is_read_valid()
  96. assert zip.is_write_valid()
  97. assert not zip.needs_repack()
  98. assert zip.verify()
  99. removed = zip.remove_subfile("test2.txt")
  100. assert removed
  101. zip.close()
  102. with zipfile.ZipFile(StreamIOWrapper(stream), 'r') as zf:
  103. assert zf.testzip() is None
  104. names = zf.namelist()
  105. assert "test1.txt" in names
  106. assert "test2.txt" not in names
  107. assert "test3.txt" in names
  108. def test_zip_repack(tmp_path):
  109. zip_path = tmp_path / "test_zip_repack.zip"
  110. zf = zipfile.ZipFile(zip_path, mode='w', allowZip64=True)
  111. zf.writestr("test1.txt", b"contents of first file")
  112. zf.writestr("test2.txt", b"contents of second file")
  113. zf.close()
  114. zip = ZipArchive()
  115. zip.open_read_write(zip_path)
  116. assert zip.is_read_valid()
  117. assert zip.is_write_valid()
  118. assert not zip.needs_repack()
  119. assert zip.verify()
  120. removed = zip.remove_subfile("test2.txt")
  121. assert removed
  122. zip.add_subfile("test3.txt", StringStream(b"contents of third file"), 6)
  123. assert zip.needs_repack()
  124. result = zip.repack()
  125. assert result
  126. assert not zip.needs_repack()
  127. assert zip.verify()
  128. zip.close()
  129. with zipfile.ZipFile(zip_path, 'r') as zf:
  130. assert zf.testzip() is None
  131. assert zf.read("test1.txt") == b"contents of first file"
  132. assert "test2.txt" not in zf.namelist()
  133. assert zf.read("test3.txt") == b"contents of third file"