From af66a62c04b4e926796c60db969073b741f0e8f7 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 22 Feb 2020 21:21:09 +0100 Subject: [PATCH] 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`. --- internal/restic/find.go | 7 ++++++- internal/restic/find_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/internal/restic/find.go b/internal/restic/find.go index 40ed2dac8..b5bef0720 100644 --- a/internal/restic/find.go +++ b/internal/restic/find.go @@ -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 diff --git a/internal/restic/find_test.go b/internal/restic/find_test.go index 7e52dd681..635421d8b 100644 --- a/internal/restic/find_test.go +++ b/internal/restic/find_test.go @@ -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()