From 17688c23134af16f15e103f0ea59f42ceec048a8 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 22 Nov 2025 22:13:54 +0100 Subject: [PATCH] data: move TestTreeMap to data package to allow reuse --- internal/data/testing.go | 49 ++++++++++++++++++++++++++++++-- internal/walker/rewriter_test.go | 43 +++++----------------------- internal/walker/walker_test.go | 25 ++-------------- 3 files changed, 57 insertions(+), 60 deletions(-) diff --git a/internal/data/testing.go b/internal/data/testing.go index 52abc8864..19f7fa7b3 100644 --- a/internal/data/testing.go +++ b/internal/data/testing.go @@ -12,7 +12,6 @@ import ( "github.com/restic/chunker" "github.com/restic/restic/internal/restic" - "github.com/restic/restic/internal/test" rtest "github.com/restic/restic/internal/test" ) @@ -147,7 +146,7 @@ func TestCreateSnapshot(t testing.TB, repo restic.Repository, at time.Time, dept } var treeID restic.ID - test.OK(t, repo.WithBlobUploader(context.TODO(), func(ctx context.Context, uploader restic.BlobSaverWithAsync) error { + rtest.OK(t, repo.WithBlobUploader(context.TODO(), func(ctx context.Context, uploader restic.BlobSaverWithAsync) error { treeID = fs.saveTree(ctx, uploader, seed, depth) return nil })) @@ -199,3 +198,49 @@ func TestLoadAllSnapshots(ctx context.Context, repo restic.ListerLoaderUnpacked, return snapshots, nil } + +// TestTreeMap returns the trees from the map on LoadTree. +type TestTreeMap map[restic.ID][]byte + +func (t TestTreeMap) LoadBlob(_ context.Context, tpe restic.BlobType, id restic.ID, _ []byte) ([]byte, error) { + if tpe != restic.TreeBlob { + return nil, fmt.Errorf("can only load trees") + } + tree, ok := t[id] + if !ok { + return nil, fmt.Errorf("tree not found") + } + return tree, nil +} + +func (t TestTreeMap) Connections() uint { + return 2 +} + +// TestWritableTreeMap also support saving +type TestWritableTreeMap struct { + TestTreeMap +} + +func (t TestWritableTreeMap) SaveBlob(_ context.Context, tpe restic.BlobType, buf []byte, id restic.ID, _ bool) (newID restic.ID, known bool, size int, err error) { + if tpe != restic.TreeBlob { + return restic.ID{}, false, 0, fmt.Errorf("can only save trees") + } + + if id.IsNull() { + id = restic.Hash(buf) + } + _, ok := t.TestTreeMap[id] + if ok { + return id, false, 0, nil + } + + t.TestTreeMap[id] = append([]byte{}, buf...) + return id, true, len(buf), nil +} + +func (t TestWritableTreeMap) Dump(test testing.TB) { + for k, v := range t.TestTreeMap { + test.Logf("%v: %v", k, string(v)) + } +} diff --git a/internal/walker/rewriter_test.go b/internal/walker/rewriter_test.go index b26449a58..edc3685dc 100644 --- a/internal/walker/rewriter_test.go +++ b/internal/walker/rewriter_test.go @@ -5,40 +5,11 @@ import ( "slices" "testing" - "github.com/pkg/errors" "github.com/restic/restic/internal/data" "github.com/restic/restic/internal/restic" "github.com/restic/restic/internal/test" ) -// WritableTreeMap also support saving -type WritableTreeMap struct { - TreeMap -} - -func (t WritableTreeMap) SaveBlob(_ context.Context, tpe restic.BlobType, buf []byte, id restic.ID, _ bool) (newID restic.ID, known bool, size int, err error) { - if tpe != restic.TreeBlob { - return restic.ID{}, false, 0, errors.New("can only save trees") - } - - if id.IsNull() { - id = restic.Hash(buf) - } - _, ok := t.TreeMap[id] - if ok { - return id, false, 0, nil - } - - t.TreeMap[id] = append([]byte{}, buf...) - return id, true, len(buf), nil -} - -func (t WritableTreeMap) Dump(test testing.TB) { - for k, v := range t.TreeMap { - test.Logf("%v: %v", k, string(v)) - } -} - type checkRewriteFunc func(t testing.TB) (rewriter *TreeRewriter, final func(testing.TB)) // checkRewriteItemOrder ensures that the order of the 'path' arguments is the one passed in as 'want'. @@ -280,7 +251,7 @@ func TestRewriter(t *testing.T) { test.newTree = test.tree } expRepo, expRoot := BuildTreeMap(test.newTree) - modrepo := WritableTreeMap{repo} + modrepo := data.TestWritableTreeMap{TestTreeMap: repo} ctx, cancel := context.WithCancel(context.TODO()) defer cancel() @@ -298,7 +269,7 @@ func TestRewriter(t *testing.T) { t.Log("Got") modrepo.Dump(t) t.Log("Expected") - WritableTreeMap{expRepo}.Dump(t) + data.TestWritableTreeMap{TestTreeMap: expRepo}.Dump(t) } }) } @@ -321,7 +292,7 @@ func TestSnapshotSizeQuery(t *testing.T) { t.Run("", func(t *testing.T) { repo, root := BuildTreeMap(tree) expRepo, expRoot := BuildTreeMap(newTree) - modrepo := WritableTreeMap{repo} + modrepo := data.TestWritableTreeMap{TestTreeMap: repo} ctx, cancel := context.WithCancel(context.TODO()) defer cancel() @@ -352,17 +323,17 @@ func TestSnapshotSizeQuery(t *testing.T) { t.Log("Got") modrepo.Dump(t) t.Log("Expected") - WritableTreeMap{expRepo}.Dump(t) + data.TestWritableTreeMap{TestTreeMap: expRepo}.Dump(t) } }) } func TestRewriterFailOnUnknownFields(t *testing.T) { - tm := WritableTreeMap{TreeMap{}} + tm := data.TestWritableTreeMap{TestTreeMap: data.TestTreeMap{}} node := []byte(`{"nodes":[{"name":"subfile","type":"file","mtime":"0001-01-01T00:00:00Z","atime":"0001-01-01T00:00:00Z","ctime":"0001-01-01T00:00:00Z","uid":0,"gid":0,"content":null,"unknown_field":42}]}`) id := restic.Hash(node) - tm.TreeMap[id] = node + tm.TestTreeMap[id] = node ctx, cancel := context.WithCancel(context.TODO()) defer cancel() @@ -393,7 +364,7 @@ func TestRewriterFailOnUnknownFields(t *testing.T) { } func TestRewriterTreeLoadError(t *testing.T) { - tm := WritableTreeMap{TreeMap{}} + tm := data.TestWritableTreeMap{TestTreeMap: data.TestTreeMap{}} id := restic.NewRandomID() ctx, cancel := context.WithCancel(context.TODO()) diff --git a/internal/walker/walker_test.go b/internal/walker/walker_test.go index fa561bf19..fad95476d 100644 --- a/internal/walker/walker_test.go +++ b/internal/walker/walker_test.go @@ -6,7 +6,6 @@ import ( "sort" "testing" - "github.com/pkg/errors" "github.com/restic/restic/internal/data" "github.com/restic/restic/internal/restic" rtest "github.com/restic/restic/internal/test" @@ -20,13 +19,13 @@ type TestFile struct { Size uint64 } -func BuildTreeMap(tree TestTree) (m TreeMap, root restic.ID) { - m = TreeMap{} +func BuildTreeMap(tree TestTree) (m data.TestTreeMap, root restic.ID) { + m = data.TestTreeMap{} id := buildTreeMap(tree, m) return m, id } -func buildTreeMap(tree TestTree, m TreeMap) restic.ID { +func buildTreeMap(tree TestTree, m data.TestTreeMap) restic.ID { tb := data.NewTreeJSONBuilder() var names []string for name := range tree { @@ -75,24 +74,6 @@ func buildTreeMap(tree TestTree, m TreeMap) restic.ID { return id } -// TreeMap returns the trees from the map on LoadTree. -type TreeMap map[restic.ID][]byte - -func (t TreeMap) LoadBlob(_ context.Context, tpe restic.BlobType, id restic.ID, _ []byte) ([]byte, error) { - if tpe != restic.TreeBlob { - return nil, errors.New("can only load trees") - } - tree, ok := t[id] - if !ok { - return nil, errors.New("tree not found") - } - return tree, nil -} - -func (t TreeMap) Connections() uint { - return 2 -} - // checkFunc returns a function suitable for walking the tree to check // something, and a function which will check the final result. type checkFunc func(t testing.TB) (walker WalkFunc, leaveDir func(path string) error, final func(testing.TB, error))