restic: Cleanup and simplify TestCreateSnapshot

This commit is contained in:
Michael Eischer 2023-07-16 15:55:05 +02:00
parent 321cc35cde
commit 090f9d6237
7 changed files with 37 additions and 74 deletions

View File

@ -73,7 +73,7 @@ func TestFuseFile(t *testing.T) {
timestamp, err := time.Parse(time.RFC3339, "2017-01-24T10:42:56+01:00") timestamp, err := time.Parse(time.RFC3339, "2017-01-24T10:42:56+01:00")
rtest.OK(t, err) rtest.OK(t, err)
restic.TestCreateSnapshot(t, repo, timestamp, 2, 0.1) restic.TestCreateSnapshot(t, repo, timestamp, 2)
sn := loadFirstSnapshot(t, repo) sn := loadFirstSnapshot(t, repo)
tree := loadTree(t, repo, *sn.Tree) tree := loadTree(t, repo, *sn.Tree)
@ -180,7 +180,7 @@ func TestFuseDir(t *testing.T) {
// Test top-level directories for their UID and GID. // Test top-level directories for their UID and GID.
func TestTopUIDGID(t *testing.T) { func TestTopUIDGID(t *testing.T) {
repo := repository.TestRepository(t) repo := repository.TestRepository(t)
restic.TestCreateSnapshot(t, repo, time.Unix(1460289341, 207401672), 0, 0) restic.TestCreateSnapshot(t, repo, time.Unix(1460289341, 207401672), 0)
testTopUIDGID(t, Config{}, repo, uint32(os.Getuid()), uint32(os.Getgid())) testTopUIDGID(t, Config{}, repo, uint32(os.Getuid()), uint32(os.Getgid()))
testTopUIDGID(t, Config{OwnerIsRoot: true}, repo, 0, 0) testTopUIDGID(t, Config{OwnerIsRoot: true}, repo, 0, 0)

View File

@ -340,11 +340,11 @@ var (
depth = 3 depth = 3
) )
func createFilledRepo(t testing.TB, snapshots int, dup float32, version uint) restic.Repository { func createFilledRepo(t testing.TB, snapshots int, version uint) restic.Repository {
repo := repository.TestRepositoryWithVersion(t, version) repo := repository.TestRepositoryWithVersion(t, version)
for i := 0; i < snapshots; i++ { for i := 0; i < snapshots; i++ {
restic.TestCreateSnapshot(t, repo, snapshotTime.Add(time.Duration(i)*time.Second), depth, dup) restic.TestCreateSnapshot(t, repo, snapshotTime.Add(time.Duration(i)*time.Second), depth)
} }
return repo return repo
} }
@ -354,7 +354,7 @@ func TestIndexSave(t *testing.T) {
} }
func testIndexSave(t *testing.T, version uint) { func testIndexSave(t *testing.T, version uint) {
repo := createFilledRepo(t, 3, 0, version) repo := createFilledRepo(t, 3, version)
err := repo.LoadIndex(context.TODO()) err := repo.LoadIndex(context.TODO())
if err != nil { if err != nil {

View File

@ -88,7 +88,7 @@ func TestFindUsedBlobs(t *testing.T) {
var snapshots []*restic.Snapshot var snapshots []*restic.Snapshot
for i := 0; i < findTestSnapshots; i++ { for i := 0; i < findTestSnapshots; i++ {
sn := restic.TestCreateSnapshot(t, repo, findTestTime.Add(time.Duration(i)*time.Second), findTestDepth, 0) sn := restic.TestCreateSnapshot(t, repo, findTestTime.Add(time.Duration(i)*time.Second), findTestDepth)
t.Logf("snapshot %v saved, tree %v", sn.ID().Str(), sn.Tree.Str()) t.Logf("snapshot %v saved, tree %v", sn.ID().Str(), sn.Tree.Str())
snapshots = append(snapshots, sn) snapshots = append(snapshots, sn)
} }
@ -131,7 +131,7 @@ func TestMultiFindUsedBlobs(t *testing.T) {
var snapshotTrees restic.IDs var snapshotTrees restic.IDs
for i := 0; i < findTestSnapshots; i++ { for i := 0; i < findTestSnapshots; i++ {
sn := restic.TestCreateSnapshot(t, repo, findTestTime.Add(time.Duration(i)*time.Second), findTestDepth, 0) sn := restic.TestCreateSnapshot(t, repo, findTestTime.Add(time.Duration(i)*time.Second), findTestDepth)
t.Logf("snapshot %v saved, tree %v", sn.ID().Str(), sn.Tree.Str()) t.Logf("snapshot %v saved, tree %v", sn.ID().Str(), sn.Tree.Str())
snapshotTrees = append(snapshotTrees, *sn.Tree) snapshotTrees = append(snapshotTrees, *sn.Tree)
} }
@ -177,7 +177,7 @@ func (r ForbiddenRepo) Connections() uint {
func TestFindUsedBlobsSkipsSeenBlobs(t *testing.T) { func TestFindUsedBlobsSkipsSeenBlobs(t *testing.T) {
repo := repository.TestRepository(t) repo := repository.TestRepository(t)
snapshot := restic.TestCreateSnapshot(t, repo, findTestTime, findTestDepth, 0) snapshot := restic.TestCreateSnapshot(t, repo, findTestTime, findTestDepth)
t.Logf("snapshot %v saved, tree %v", snapshot.ID().Str(), snapshot.Tree.Str()) t.Logf("snapshot %v saved, tree %v", snapshot.ID().Str(), snapshot.Tree.Str())
usedBlobs := restic.NewBlobSet() usedBlobs := restic.NewBlobSet()
@ -195,7 +195,7 @@ func TestFindUsedBlobsSkipsSeenBlobs(t *testing.T) {
func BenchmarkFindUsedBlobs(b *testing.B) { func BenchmarkFindUsedBlobs(b *testing.B) {
repo := repository.TestRepository(b) repo := repository.TestRepository(b)
sn := restic.TestCreateSnapshot(b, repo, findTestTime, findTestDepth, 0) sn := restic.TestCreateSnapshot(b, repo, findTestTime, findTestDepth)
b.ResetTimer() b.ResetTimer()

View File

@ -11,9 +11,9 @@ import (
func TestFindLatestSnapshot(t *testing.T) { func TestFindLatestSnapshot(t *testing.T) {
repo := repository.TestRepository(t) repo := repository.TestRepository(t)
restic.TestCreateSnapshot(t, repo, parseTimeUTC("2015-05-05 05:05:05"), 1, 0) restic.TestCreateSnapshot(t, repo, parseTimeUTC("2015-05-05 05:05:05"), 1)
restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:07"), 1, 0) restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:07"), 1)
latestSnapshot := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2019-09-09 09:09:09"), 1, 0) latestSnapshot := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2019-09-09 09:09:09"), 1)
f := restic.SnapshotFilter{Hosts: []string{"foo"}} f := restic.SnapshotFilter{Hosts: []string{"foo"}}
sn, _, err := f.FindLatest(context.TODO(), repo.Backend(), repo, "latest") sn, _, err := f.FindLatest(context.TODO(), repo.Backend(), repo, "latest")
@ -28,9 +28,9 @@ func TestFindLatestSnapshot(t *testing.T) {
func TestFindLatestSnapshotWithMaxTimestamp(t *testing.T) { func TestFindLatestSnapshotWithMaxTimestamp(t *testing.T) {
repo := repository.TestRepository(t) repo := repository.TestRepository(t)
restic.TestCreateSnapshot(t, repo, parseTimeUTC("2015-05-05 05:05:05"), 1, 0) restic.TestCreateSnapshot(t, repo, parseTimeUTC("2015-05-05 05:05:05"), 1)
desiredSnapshot := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:07"), 1, 0) desiredSnapshot := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:07"), 1)
restic.TestCreateSnapshot(t, repo, parseTimeUTC("2019-09-09 09:09:09"), 1, 0) restic.TestCreateSnapshot(t, repo, parseTimeUTC("2019-09-09 09:09:09"), 1)
sn, _, err := (&restic.SnapshotFilter{ sn, _, err := (&restic.SnapshotFilter{
Hosts: []string{"foo"}, Hosts: []string{"foo"},
@ -47,8 +47,8 @@ func TestFindLatestSnapshotWithMaxTimestamp(t *testing.T) {
func TestFindLatestWithSubpath(t *testing.T) { func TestFindLatestWithSubpath(t *testing.T) {
repo := repository.TestRepository(t) repo := repository.TestRepository(t)
restic.TestCreateSnapshot(t, repo, parseTimeUTC("2015-05-05 05:05:05"), 1, 0) restic.TestCreateSnapshot(t, repo, parseTimeUTC("2015-05-05 05:05:05"), 1)
desiredSnapshot := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:07"), 1, 0) desiredSnapshot := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:07"), 1)
for _, exp := range []struct { for _, exp := range []struct {
query string query string
@ -75,7 +75,7 @@ func TestFindLatestWithSubpath(t *testing.T) {
func TestFindAllSubpathError(t *testing.T) { func TestFindAllSubpathError(t *testing.T) {
repo := repository.TestRepository(t) repo := repository.TestRepository(t)
desiredSnapshot := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:07"), 1, 0) desiredSnapshot := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:07"), 1)
count := 0 count := 0
test.OK(t, (&restic.SnapshotFilter{}).FindAll(context.TODO(), repo.Backend(), repo, test.OK(t, (&restic.SnapshotFilter{}).FindAll(context.TODO(), repo.Backend(), repo,

View File

@ -2,7 +2,6 @@ package restic
import ( import (
"context" "context"
"encoding/json"
"fmt" "fmt"
"io" "io"
"math/rand" "math/rand"
@ -19,12 +18,11 @@ func fakeFile(seed, size int64) io.Reader {
} }
type fakeFileSystem struct { type fakeFileSystem struct {
t testing.TB t testing.TB
repo Repository repo Repository
duplication float32 buf []byte
buf []byte chunker *chunker.Chunker
chunker *chunker.Chunker rand *rand.Rand
rand *rand.Rand
} }
// saveFile reads from rd and saves the blobs in the repository. The list of // saveFile reads from rd and saves the blobs in the repository. The list of
@ -51,13 +49,9 @@ func (fs *fakeFileSystem) saveFile(ctx context.Context, rd io.Reader) (blobs IDs
fs.t.Fatalf("unable to save chunk in repo: %v", err) fs.t.Fatalf("unable to save chunk in repo: %v", err)
} }
id := Hash(chunk.Data) id, _, _, err := fs.repo.SaveBlob(ctx, DataBlob, chunk.Data, ID{}, false)
if !fs.blobIsKnown(BlobHandle{ID: id, Type: DataBlob}) { if err != nil {
_, _, _, err := fs.repo.SaveBlob(ctx, DataBlob, chunk.Data, id, true) fs.t.Fatalf("error saving chunk: %v", err)
if err != nil {
fs.t.Fatalf("error saving chunk: %v", err)
}
} }
blobs = append(blobs, id) blobs = append(blobs, id)
@ -72,31 +66,6 @@ const (
maxNodes = 15 maxNodes = 15
) )
func (fs *fakeFileSystem) treeIsKnown(tree *Tree) (bool, []byte, ID) {
tree.Sort()
data, err := json.Marshal(tree)
if err != nil {
fs.t.Fatalf("json.Marshal(tree) returned error: %v", err)
return false, nil, ID{}
}
data = append(data, '\n')
id := Hash(data)
return fs.blobIsKnown(BlobHandle{ID: id, Type: TreeBlob}), data, id
}
func (fs *fakeFileSystem) blobIsKnown(bh BlobHandle) bool {
if fs.rand.Float32() < fs.duplication {
return false
}
if fs.repo.Index().Has(bh) {
return true
}
return false
}
// saveTree saves a tree of fake files in the repo and returns the ID. // saveTree saves a tree of fake files in the repo and returns the ID.
func (fs *fakeFileSystem) saveTree(ctx context.Context, seed int64, depth int) ID { func (fs *fakeFileSystem) saveTree(ctx context.Context, seed int64, depth int) ID {
rnd := rand.NewSource(seed) rnd := rand.NewSource(seed)
@ -135,16 +104,12 @@ func (fs *fakeFileSystem) saveTree(ctx context.Context, seed int64, depth int) I
tree.Nodes = append(tree.Nodes, node) tree.Nodes = append(tree.Nodes, node)
} }
known, buf, id := fs.treeIsKnown(&tree) tree.Sort()
if known {
return id
}
_, _, _, err := fs.repo.SaveBlob(ctx, TreeBlob, buf, id, false) id, err := SaveTree(ctx, fs.repo, &tree)
if err != nil { if err != nil {
fs.t.Fatal(err) fs.t.Fatalf("SaveTree returned error: %v", err)
} }
return id return id
} }
@ -153,22 +118,20 @@ func (fs *fakeFileSystem) saveTree(ctx context.Context, seed int64, depth int) I
// also used as the snapshot's timestamp. The tree's depth can be specified // also used as the snapshot's timestamp. The tree's depth can be specified
// with the parameter depth. The parameter duplication is a probability that // with the parameter depth. The parameter duplication is a probability that
// the same blob will saved again. // the same blob will saved again.
func TestCreateSnapshot(t testing.TB, repo Repository, at time.Time, depth int, duplication float32) *Snapshot { func TestCreateSnapshot(t testing.TB, repo Repository, at time.Time, depth int) *Snapshot {
seed := at.Unix() seed := at.Unix()
t.Logf("create fake snapshot at %s with seed %d", at, seed) t.Logf("create fake snapshot at %s with seed %d", at, seed)
fakedir := fmt.Sprintf("fakedir-at-%v", at.Format("2006-01-02 15:04:05")) fakedir := fmt.Sprintf("fakedir-at-%v", at.Format("2006-01-02 15:04:05"))
snapshot, err := NewSnapshot([]string{fakedir}, []string{"test"}, "foo", time.Now()) snapshot, err := NewSnapshot([]string{fakedir}, []string{"test"}, "foo", at)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
snapshot.Time = at
fs := fakeFileSystem{ fs := fakeFileSystem{
t: t, t: t,
repo: repo, repo: repo,
duplication: duplication, rand: rand.New(rand.NewSource(seed)),
rand: rand.New(rand.NewSource(seed)),
} }
var wg errgroup.Group var wg errgroup.Group

View File

@ -39,7 +39,7 @@ func loadAllSnapshots(ctx context.Context, repo restic.Repository, excludeIDs re
func TestCreateSnapshot(t *testing.T) { func TestCreateSnapshot(t *testing.T) {
repo := repository.TestRepository(t) repo := repository.TestRepository(t)
for i := 0; i < testCreateSnapshots; i++ { for i := 0; i < testCreateSnapshots; i++ {
restic.TestCreateSnapshot(t, repo, testSnapshotTime.Add(time.Duration(i)*time.Second), testDepth, 0) restic.TestCreateSnapshot(t, repo, testSnapshotTime.Add(time.Duration(i)*time.Second), testDepth)
} }
snapshots, err := loadAllSnapshots(context.TODO(), repo, restic.NewIDSet()) snapshots, err := loadAllSnapshots(context.TODO(), repo, restic.NewIDSet())
@ -73,6 +73,6 @@ func BenchmarkTestCreateSnapshot(t *testing.B) {
t.ResetTimer() t.ResetTimer()
for i := 0; i < t.N; i++ { for i := 0; i < t.N; i++ {
restic.TestCreateSnapshot(t, repo, testSnapshotTime.Add(time.Duration(i)*time.Second), testDepth, 0) restic.TestCreateSnapshot(t, repo, testSnapshotTime.Add(time.Duration(i)*time.Second), testDepth)
} }
} }

View File

@ -213,7 +213,7 @@ func benchmarkLoadTree(t *testing.B, version uint) {
func TestFindTreeDirectory(t *testing.T) { func TestFindTreeDirectory(t *testing.T) {
repo := repository.TestRepository(t) repo := repository.TestRepository(t)
sn := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:08"), 3, 0) sn := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:08"), 3)
for _, exp := range []struct { for _, exp := range []struct {
subpath string subpath string