FindUsedBlobs: Test that seen blobs are skipped

This also copies the TreeLoader interface from internal/walker to allow
stubbing the repository in the call to `FindUsedBlobs`.
This commit is contained in:
Michael Eischer 2020-02-22 21:21:09 +01:00
parent 9ea1a78bd4
commit af66a62c04
2 changed files with 32 additions and 1 deletions

View file

@ -2,9 +2,14 @@ package restic
import "context"
// TreeLoader loads a tree from a repository.
type TreeLoader interface {
LoadTree(context.Context, ID) (*Tree, error)
}
// FindUsedBlobs traverses the tree ID and adds all seen blobs (trees and data
// blobs) to the set blobs. Already seen tree blobs will not be visited again.
func FindUsedBlobs(ctx context.Context, repo Repository, treeID ID, blobs BlobSet) error {
func FindUsedBlobs(ctx context.Context, repo TreeLoader, treeID ID, blobs BlobSet) error {
h := BlobHandle{ID: treeID, Type: TreeBlob}
if blobs.Has(h) {
return nil

View file

@ -12,6 +12,7 @@ import (
"testing"
"time"
"github.com/restic/restic/internal/errors"
"github.com/restic/restic/internal/repository"
"github.com/restic/restic/internal/restic"
)
@ -118,6 +119,31 @@ func TestFindUsedBlobs(t *testing.T) {
}
}
type ForbiddenRepo struct{}
func (r ForbiddenRepo) LoadTree(ctx context.Context, id restic.ID) (*restic.Tree, error) {
return nil, errors.New("should not be called")
}
func TestFindUsedBlobsSkipsSeenBlobs(t *testing.T) {
repo, cleanup := repository.TestRepository(t)
defer cleanup()
snapshot := restic.TestCreateSnapshot(t, repo, findTestTime, findTestDepth, 0)
t.Logf("snapshot %v saved, tree %v", snapshot.ID().Str(), snapshot.Tree.Str())
usedBlobs := restic.NewBlobSet()
err := restic.FindUsedBlobs(context.TODO(), repo, *snapshot.Tree, usedBlobs)
if err != nil {
t.Fatalf("FindUsedBlobs returned error: %v", err)
}
err = restic.FindUsedBlobs(context.TODO(), ForbiddenRepo{}, *snapshot.Tree, usedBlobs)
if err != nil {
t.Fatalf("FindUsedBlobs returned error: %v", err)
}
}
func BenchmarkFindUsedBlobs(b *testing.B) {
repo, cleanup := repository.TestRepository(b)
defer cleanup()