test_sha256_pack.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. # test_sha256_pack.py -- Tests for SHA256 pack support
  2. # Copyright (C) 2024 The Dulwich contributors
  3. #
  4. # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  5. # Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
  6. # General Public License as public by the Free Software Foundation; version 2.0
  7. # or (at your option) any later version. You can redistribute it and/or
  8. # modify it under the terms of either of these two licenses.
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. #
  16. # You should have received a copy of the licenses; if not, see
  17. # <http://www.gnu.org/licenses/> for a copy of the GNU General Public License
  18. # and <http://www.apache.org/licenses/LICENSE-2.0> for a copy of the Apache
  19. # License, Version 2.0.
  20. #
  21. """Tests for SHA256 pack support in Dulwich."""
  22. import shutil
  23. import tempfile
  24. import unittest
  25. from io import BytesIO
  26. from dulwich.object_format import SHA256
  27. from dulwich.pack import (
  28. load_pack_index_file,
  29. write_pack_index_v2,
  30. )
  31. class SHA256PackTests(unittest.TestCase):
  32. """Tests for SHA256 pack support."""
  33. def setUp(self):
  34. """Set up test repository directory."""
  35. self.test_dir = tempfile.mkdtemp()
  36. def tearDown(self):
  37. """Clean up test repository."""
  38. shutil.rmtree(self.test_dir)
  39. def test_pack_index_v2_with_sha256(self):
  40. """Test that pack index v2 correctly handles SHA256 hashes."""
  41. # Create SHA256 entries manually (simulating what would happen in a SHA256 repo)
  42. entries = []
  43. for i in range(5):
  44. # Create a fake SHA256 hash
  45. sha256_hash = SHA256.hash_func(f"test object {i}".encode()).digest()
  46. offset = i * 1000 # Fake offsets
  47. crc32 = i # Fake CRC32
  48. entries.append((sha256_hash, offset, crc32))
  49. # Sort entries by SHA (required for pack index)
  50. entries.sort(key=lambda e: e[0])
  51. # Write SHA256 pack index with SHA1 pack checksum (Git always uses SHA1 for pack checksums)
  52. index_buf = BytesIO()
  53. from hashlib import sha1
  54. pack_checksum = sha1(b"fake pack data").digest()
  55. write_pack_index_v2(index_buf, entries, pack_checksum)
  56. # Load and verify the index
  57. index_buf.seek(0)
  58. pack_idx = load_pack_index_file("<memory>", index_buf, SHA256)
  59. # Check that the index loaded correctly
  60. self.assertEqual(len(pack_idx), 5)
  61. self.assertEqual(pack_idx.version, 2)
  62. # Verify hash_size detection
  63. self.assertEqual(pack_idx.hash_size, 32)
  64. # Verify we can look up objects by SHA256
  65. for sha256_hash, offset, _ in entries:
  66. # This should not raise KeyError
  67. found_offset = pack_idx.object_offset(sha256_hash)
  68. self.assertEqual(found_offset, offset)
  69. def test_pack_index_v1_with_sha256(self):
  70. """Test that pack index v1 correctly rejects SHA256 hashes."""
  71. # Create SHA256 entries manually
  72. entries = []
  73. for i in range(5):
  74. # Create a fake SHA256 hash
  75. sha256_hash = SHA256.hash_func(f"test v1 object {i}".encode()).digest()
  76. offset = i * 1000 # Fake offsets
  77. crc32 = None # v1 doesn't store CRC32
  78. entries.append((sha256_hash, offset, crc32))
  79. # Sort entries by SHA (required for pack index)
  80. entries.sort(key=lambda e: e[0])
  81. # Import write_pack_index_v1
  82. from dulwich.pack import write_pack_index_v1
  83. # Write SHA256 pack index v1 with SHA1 pack checksum
  84. index_buf = BytesIO()
  85. from hashlib import sha1
  86. pack_checksum = sha1(b"fake v1 pack data").digest()
  87. # Pack index v1 only supports SHA-1, so this should raise TypeError
  88. with self.assertRaises(TypeError) as cm:
  89. write_pack_index_v1(index_buf, entries, pack_checksum)
  90. self.assertIn("pack index v1 only supports SHA-1", str(cm.exception))
  91. if __name__ == "__main__":
  92. unittest.main()