repair index: replace full index handling integration test with unit test

This commit is contained in:
Michael Eischer
2026-05-31 22:39:16 +02:00
parent f625190393
commit 3cb49556f5
2 changed files with 59 additions and 10 deletions
@@ -11,7 +11,6 @@ import (
"github.com/restic/restic/internal/backend"
"github.com/restic/restic/internal/errors"
"github.com/restic/restic/internal/global"
"github.com/restic/restic/internal/repository/index"
"github.com/restic/restic/internal/restic"
rtest "github.com/restic/restic/internal/test"
)
@@ -61,15 +60,6 @@ func TestRebuildIndex(t *testing.T) {
testRebuildIndex(t, nil)
}
func TestRebuildIndexAlwaysFull(t *testing.T) {
indexFull := index.Full
defer func() {
index.Full = indexFull
}()
index.Full = func(*index.Index) bool { return true }
testRebuildIndex(t, nil)
}
// indexErrorBackend modifies the first index after reading.
type indexErrorBackend struct {
backend.Backend
@@ -694,3 +694,62 @@ func TestRewriteSplitPacks(t *testing.T) {
blobs := mi.Lookup(blobOther.BlobHandle)
rtest.Equals(t, nil, blobs)
}
// TestRewriteFullPacks checks that Rewrite drops a duplicate full index for the same
// pack while keeping the other index files and blob lookups intact. Creates 3 indexes:
// - indexA: contains packA
// - indexB: contains packB
// - indexC: contains packB
// After the rewrite, indexC must be dropped. The other indexes must be kept.
func TestRewriteFullPacks(t *testing.T) {
originalFull := index.Full
defer func() {
index.Full = originalFull
}()
index.Full = func(*index.Index) bool { return true }
repo, unpacked, _ := repository.TestRepositoryWithVersion(t, restic.StableRepoVersion)
packA := restic.NewRandomID()
packB := restic.NewRandomID()
blobA := restic.PackedBlob{
PackID: packA,
Blob: restic.Blob{
BlobHandle: restic.NewRandomBlobHandle(),
Length: uint(crypto.CiphertextLength(10)),
Offset: 0,
},
}
blobB := restic.PackedBlob{
PackID: packB,
Blob: restic.Blob{
BlobHandle: restic.NewRandomBlobHandle(),
Length: uint(crypto.CiphertextLength(50)),
Offset: 0,
},
}
mi := index.NewMasterIndex()
rtest.OK(t, mi.StorePack(context.TODO(), packA, restic.Blobs{blobA.Blob}, unpacked))
rtest.OK(t, mi.Flush(context.TODO(), unpacked))
rtest.OK(t, mi.StorePack(context.TODO(), packB, restic.Blobs{blobB.Blob}, unpacked))
rtest.OK(t, mi.Flush(context.TODO(), unpacked))
rtest.OK(t, mi.StorePack(context.TODO(), packB, restic.Blobs{blobB.Blob}, unpacked))
rtest.OK(t, mi.Flush(context.TODO(), unpacked))
indexIDs := mi.IDs()
rtest.Equals(t, 3, len(indexIDs))
rtest.OK(t, mi.Rewrite(context.TODO(), unpacked, nil, indexIDs, nil, index.MasterIndexRewriteOpts{}))
mi2 := index.NewMasterIndex()
rtest.OK(t, mi2.Load(context.TODO(), repo, nil, nil))
afterRewrite := mi2.IDs()
rtest.Equals(t, 2, len(afterRewrite))
rtest.Equals(t, 2, len(afterRewrite.Intersect(indexIDs)))
rtest.Equals(t, []restic.PackedBlob{blobA}, mi2.Lookup(blobA.BlobHandle))
rtest.Equals(t, []restic.PackedBlob{blobB}, mi2.Lookup(blobB.BlobHandle))
}