repository: assert compact_pack complete coverage reaches pack end

This commit is contained in:
Mrityunjay Raj 2026-06-28 03:46:08 +05:30
parent 2a4671c1ab
commit 2dcb50f30e
2 changed files with 22 additions and 0 deletions

View file

@ -864,6 +864,12 @@ class Repository:
if keep:
kept.append((offset, obj_id, size))
if complete: # the listed objects must reach the pack's end, no trailing object unaccounted for
pack_size = self.store.info(pack_key).size
assert (
covered == pack_size
), f"pack {bin_to_hex(pack_id)}: {pack_size - covered} trailing bytes unaccounted for"
for drop_id in drop_ids: # remove dropped objects from the index
del self.chunks[drop_id]

View file

@ -267,6 +267,22 @@ def test_compact_pack_keep_all_is_noop(repo_fixtures, request):
assert new_pack_id == old_pack_id
assert pdchunk(repository.get(H(0))) == b"DATA0"
assert pdchunk(repository.get(H(1))) == b"DATA1"
def test_compact_pack_complete_detects_short_coverage(repo_fixtures, request):
# complete=True must catch a pack whose listed objects do not reach its end: shrink the last
# object's recorded obj_size so the summed coverage falls short of the actual pack file size.
chunk0 = fchunk(b"DATA0", chunk_id=H(0))
chunk1 = fchunk(b"DATA1", chunk_id=H(1))
repository = get_repository_from_fixture(repo_fixtures, request)
build_one_pack(repository, [(H(0), chunk0), (H(1), chunk1)])
with repository:
old_pack_id = repository.chunks[H(0)].pack_id
entry = repository.chunks[H(1)]
repository.chunks[H(1)] = entry._replace(obj_size=entry.obj_size - 1) # leave 1 trailing byte unaccounted
with pytest.raises(AssertionError):
repository.compact_pack(old_pack_id, keep_ids={H(0), H(1)}, drop_ids=set())
assert bin_to_hex(old_pack_id) in [info.name for info in repository.store_list("packs")]