data: move TestTreeMap to data package to allow reuse

This commit is contained in:
Michael Eischer 2025-11-22 22:13:54 +01:00
parent e1a5550a27
commit 17688c2313
3 changed files with 57 additions and 60 deletions

View file

@ -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))
}
}

View file

@ -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())

View file

@ -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))