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