mirror of
https://github.com/octoleo/restic.git
synced 2024-11-11 23:55:55 +00:00
Add mock.Repository, Rework SetupRepo
This commit is contained in:
parent
b5b3c0eaf8
commit
bef5c4acb8
@ -47,8 +47,8 @@ func benchmarkChunkEncrypt(b testing.TB, buf, buf2 []byte, rd Rdr, key *crypto.K
|
||||
}
|
||||
|
||||
func BenchmarkChunkEncrypt(b *testing.B) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(b)
|
||||
defer cleanup()
|
||||
|
||||
data := Random(23, 10<<20) // 10MiB
|
||||
rd := bytes.NewReader(data)
|
||||
@ -79,8 +79,8 @@ func benchmarkChunkEncryptP(b *testing.PB, buf []byte, rd Rdr, key *crypto.Key)
|
||||
}
|
||||
|
||||
func BenchmarkChunkEncryptParallel(b *testing.B) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(b)
|
||||
defer cleanup()
|
||||
|
||||
data := Random(23, 10<<20) // 10MiB
|
||||
|
||||
@ -98,8 +98,8 @@ func BenchmarkChunkEncryptParallel(b *testing.B) {
|
||||
}
|
||||
|
||||
func archiveDirectory(b testing.TB) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(b)
|
||||
defer cleanup()
|
||||
|
||||
arch := archiver.New(repo)
|
||||
|
||||
@ -136,8 +136,8 @@ func countPacks(repo restic.Repository, t restic.FileType) (n uint) {
|
||||
}
|
||||
|
||||
func archiveWithDedup(t testing.TB) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
if BenchArchiveDirectory == "" {
|
||||
t.Skip("benchdir not set, skipping TestArchiverDedup")
|
||||
@ -150,7 +150,7 @@ func archiveWithDedup(t testing.TB) {
|
||||
}
|
||||
|
||||
// archive a few files
|
||||
sn := SnapshotDir(t, repo, BenchArchiveDirectory, nil)
|
||||
sn := archiver.TestSnapshot(t, repo, BenchArchiveDirectory, nil)
|
||||
t.Logf("archived snapshot %v", sn.ID().Str())
|
||||
|
||||
// get archive stats
|
||||
@ -161,7 +161,7 @@ func archiveWithDedup(t testing.TB) {
|
||||
cnt.before.packs, cnt.before.dataBlobs, cnt.before.treeBlobs)
|
||||
|
||||
// archive the same files again, without parent snapshot
|
||||
sn2 := SnapshotDir(t, repo, BenchArchiveDirectory, nil)
|
||||
sn2 := archiver.TestSnapshot(t, repo, BenchArchiveDirectory, nil)
|
||||
t.Logf("archived snapshot %v", sn2.ID().Str())
|
||||
|
||||
// get archive stats again
|
||||
@ -178,7 +178,7 @@ func archiveWithDedup(t testing.TB) {
|
||||
}
|
||||
|
||||
// archive the same files again, with a parent snapshot
|
||||
sn3 := SnapshotDir(t, repo, BenchArchiveDirectory, sn2.ID())
|
||||
sn3 := archiver.TestSnapshot(t, repo, BenchArchiveDirectory, sn2.ID())
|
||||
t.Logf("archived snapshot %v, parent %v", sn3.ID().Str(), sn2.ID().Str())
|
||||
|
||||
// get archive stats again
|
||||
@ -208,8 +208,8 @@ func TestParallelSaveWithDuplication(t *testing.T) {
|
||||
}
|
||||
|
||||
func testParallelSaveWithDuplication(t *testing.T, seed int) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
dataSizeMb := 128
|
||||
duplication := 7
|
||||
|
16
src/restic/archiver/testing.go
Normal file
16
src/restic/archiver/testing.go
Normal file
@ -0,0 +1,16 @@
|
||||
package archiver
|
||||
|
||||
import (
|
||||
"restic"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestSnapshot creates a new snapshot of path.
|
||||
func TestSnapshot(t testing.TB, repo restic.Repository, path string, parent *restic.ID) *restic.Snapshot {
|
||||
arch := New(repo)
|
||||
sn, _, err := arch.Snapshot(nil, []string{path}, parent)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return sn
|
||||
}
|
@ -10,8 +10,8 @@ import (
|
||||
)
|
||||
|
||||
func TestLock(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
lock, err := restic.NewLock(repo)
|
||||
OK(t, err)
|
||||
@ -20,8 +20,8 @@ func TestLock(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDoubleUnlock(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
lock, err := restic.NewLock(repo)
|
||||
OK(t, err)
|
||||
@ -34,8 +34,8 @@ func TestDoubleUnlock(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMultipleLock(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
lock1, err := restic.NewLock(repo)
|
||||
OK(t, err)
|
||||
@ -48,8 +48,8 @@ func TestMultipleLock(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLockExclusive(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
elock, err := restic.NewExclusiveLock(repo)
|
||||
OK(t, err)
|
||||
@ -57,8 +57,8 @@ func TestLockExclusive(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLockOnExclusiveLockedRepo(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
elock, err := restic.NewExclusiveLock(repo)
|
||||
OK(t, err)
|
||||
@ -74,8 +74,8 @@ func TestLockOnExclusiveLockedRepo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExclusiveLockOnLockedRepo(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
elock, err := restic.NewLock(repo)
|
||||
OK(t, err)
|
||||
@ -168,8 +168,8 @@ func lockExists(repo restic.Repository, t testing.TB, id restic.ID) bool {
|
||||
}
|
||||
|
||||
func TestLockWithStaleLock(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
id1, err := createFakeLock(repo, time.Now().Add(-time.Hour), os.Getpid())
|
||||
OK(t, err)
|
||||
@ -193,8 +193,8 @@ func TestLockWithStaleLock(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRemoveAllLocks(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
id1, err := createFakeLock(repo, time.Now().Add(-time.Hour), os.Getpid())
|
||||
OK(t, err)
|
||||
@ -216,8 +216,8 @@ func TestRemoveAllLocks(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLockRefresh(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
lock, err := restic.NewLock(repo)
|
||||
OK(t, err)
|
||||
|
141
src/restic/mock/repository.go
Normal file
141
src/restic/mock/repository.go
Normal file
@ -0,0 +1,141 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"restic"
|
||||
"restic/crypto"
|
||||
)
|
||||
|
||||
// Repository implements a mock Repository.
|
||||
type Repository struct {
|
||||
BackendFn func() Backend
|
||||
|
||||
KeyFn func() *crypto.Key
|
||||
|
||||
SetIndexFn func(restic.Index)
|
||||
|
||||
IndexFn func() restic.Index
|
||||
SaveFullIndexFn func() error
|
||||
SaveIndexFn func() error
|
||||
LoadIndexFn func() error
|
||||
|
||||
ConfigFn func() restic.Config
|
||||
|
||||
LookupBlobSizeFn func(restic.ID, restic.BlobType) (uint, error)
|
||||
|
||||
ListFn func(restic.FileType, <-chan struct{}) <-chan restic.ID
|
||||
ListPackFn func(restic.ID) ([]restic.Blob, int64, error)
|
||||
|
||||
FlushFn func() error
|
||||
|
||||
SaveUnpackedFn func(restic.FileType, []byte) (restic.ID, error)
|
||||
SaveJSONUnpackedFn func(restic.FileType, interface{}) (restic.ID, error)
|
||||
|
||||
LoadJSONUnpackedFn func(restic.FileType, restic.ID, interface{}) error
|
||||
LoadAndDecryptFn func(restic.FileType, restic.ID) ([]byte, error)
|
||||
|
||||
LoadBlobFn func(restic.BlobType, restic.ID, []byte) (int, error)
|
||||
SaveBlobFn func(restic.BlobType, []byte, restic.ID) (restic.ID, error)
|
||||
|
||||
LoadTreeFn func(restic.ID) (*restic.Tree, error)
|
||||
SaveTreeFn func(t *restic.Tree) (restic.ID, error)
|
||||
}
|
||||
|
||||
// Backend is a stub method.
|
||||
func (repo *Repository) Backend() Backend {
|
||||
return repo.BackendFn()
|
||||
}
|
||||
|
||||
// Key is a stub method.
|
||||
func (repo *Repository) Key() *crypto.Key {
|
||||
return repo.KeyFn()
|
||||
}
|
||||
|
||||
// SetIndex is a stub method.
|
||||
func (repo *Repository) SetIndex(idx restic.Index) {
|
||||
repo.SetIndexFn(idx)
|
||||
}
|
||||
|
||||
// Index is a stub method.
|
||||
func (repo *Repository) Index() restic.Index {
|
||||
return repo.IndexFn()
|
||||
}
|
||||
|
||||
// SaveFullIndex is a stub method.
|
||||
func (repo *Repository) SaveFullIndex() error {
|
||||
return repo.SaveFullIndexFn()
|
||||
}
|
||||
|
||||
// SaveIndex is a stub method.
|
||||
func (repo *Repository) SaveIndex() error {
|
||||
return repo.SaveIndexFn()
|
||||
}
|
||||
|
||||
// LoadIndex is a stub method.
|
||||
func (repo *Repository) LoadIndex() error {
|
||||
return repo.LoadIndexFn()
|
||||
}
|
||||
|
||||
// Config is a stub method.
|
||||
func (repo *Repository) Config() restic.Config {
|
||||
return repo.ConfigFn()
|
||||
}
|
||||
|
||||
// LookupBlobSize is a stub method.
|
||||
func (repo *Repository) LookupBlobSize(id restic.ID, t restic.BlobType) (uint, error) {
|
||||
return repo.LookupBlobSizeFn(id, t)
|
||||
}
|
||||
|
||||
// List is a stub method.
|
||||
func (repo *Repository) List(t restic.FileType, done <-chan struct{}) <-chan restic.ID {
|
||||
return repo.ListFn(t, done)
|
||||
}
|
||||
|
||||
// ListPack is a stub method.
|
||||
func (repo *Repository) ListPack(id restic.ID) ([]restic.Blob, int64, error) {
|
||||
return repo.ListPackFn(id)
|
||||
}
|
||||
|
||||
// Flush is a stub method.
|
||||
func (repo *Repository) Flush() error {
|
||||
return repo.FlushFn()
|
||||
}
|
||||
|
||||
// SaveUnpacked is a stub method.
|
||||
func (repo *Repository) SaveUnpacked(t restic.FileType, buf []byte) (restic.ID, error) {
|
||||
return repo.SaveUnpackedFn(t, buf)
|
||||
}
|
||||
|
||||
// SaveJSONUnpacked is a stub method.
|
||||
func (repo *Repository) SaveJSONUnpacked(t restic.FileType, item interface{}) (restic.ID, error) {
|
||||
return repo.SaveJSONUnpackedFn(t, item)
|
||||
}
|
||||
|
||||
// LoadJSONUnpacked is a stub method.
|
||||
func (repo *Repository) LoadJSONUnpacked(t restic.FileType, id restic.ID, item interface{}) error {
|
||||
return repo.LoadJSONUnpackedFn(t, id, item)
|
||||
}
|
||||
|
||||
// LoadAndDecrypt is a stub method.
|
||||
func (repo *Repository) LoadAndDecrypt(t restic.FileType, id restic.ID) ([]byte, error) {
|
||||
return repo.LoadAndDecryptFn(t, id)
|
||||
}
|
||||
|
||||
// LoadBlob is a stub method.
|
||||
func (repo *Repository) LoadBlob(t restic.BlobType, id restic.ID, buf []byte) (int, error) {
|
||||
return repo.LoadBlobFn(t, id, buf)
|
||||
}
|
||||
|
||||
// SaveBlob is a stub method.
|
||||
func (repo *Repository) SaveBlob(t restic.BlobType, buf []byte, id restic.ID) (restic.ID, error) {
|
||||
return repo.SaveBlobFn(t, buf, id)
|
||||
}
|
||||
|
||||
// LoadTree is a stub method.
|
||||
func (repo *Repository) LoadTree(id restic.ID) (*restic.Tree, error) {
|
||||
return repo.LoadTreeFn(id)
|
||||
}
|
||||
|
||||
// SaveTree is a stub method.
|
||||
func (repo *Repository) SaveTree(t *restic.Tree) (restic.ID, error) {
|
||||
return repo.SaveTreeFn(t)
|
||||
}
|
@ -10,6 +10,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"restic"
|
||||
"restic/archiver"
|
||||
"restic/repository"
|
||||
. "restic/test"
|
||||
)
|
||||
@ -17,8 +18,8 @@ import (
|
||||
var testSizes = []int{5, 23, 2<<18 + 23, 1 << 20}
|
||||
|
||||
func TestSave(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
for _, size := range testSizes {
|
||||
data := make([]byte, size)
|
||||
@ -53,8 +54,8 @@ func TestSave(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSaveFrom(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
for _, size := range testSizes {
|
||||
data := make([]byte, size)
|
||||
@ -87,8 +88,8 @@ func TestSaveFrom(t *testing.T) {
|
||||
}
|
||||
|
||||
func BenchmarkSaveAndEncrypt(t *testing.B) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
size := 4 << 20 // 4MiB
|
||||
|
||||
@ -109,15 +110,15 @@ func BenchmarkSaveAndEncrypt(t *testing.B) {
|
||||
}
|
||||
|
||||
func TestLoadTree(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
if BenchArchiveDirectory == "" {
|
||||
t.Skip("benchdir not set, skipping")
|
||||
}
|
||||
|
||||
// archive a few files
|
||||
sn := SnapshotDir(t, repo, BenchArchiveDirectory, nil)
|
||||
sn := archiver.TestSnapshot(t, repo, BenchArchiveDirectory, nil)
|
||||
OK(t, repo.Flush())
|
||||
|
||||
_, err := repo.LoadTree(*sn.Tree)
|
||||
@ -125,15 +126,15 @@ func TestLoadTree(t *testing.T) {
|
||||
}
|
||||
|
||||
func BenchmarkLoadTree(t *testing.B) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
if BenchArchiveDirectory == "" {
|
||||
t.Skip("benchdir not set, skipping")
|
||||
}
|
||||
|
||||
// archive a few files
|
||||
sn := SnapshotDir(t, repo, BenchArchiveDirectory, nil)
|
||||
sn := archiver.TestSnapshot(t, repo, BenchArchiveDirectory, nil)
|
||||
OK(t, repo.Flush())
|
||||
|
||||
t.ResetTimer()
|
||||
@ -145,8 +146,8 @@ func BenchmarkLoadTree(t *testing.B) {
|
||||
}
|
||||
|
||||
func TestLoadJSONUnpacked(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
if BenchArchiveDirectory == "" {
|
||||
t.Skip("benchdir not set, skipping")
|
||||
@ -206,8 +207,8 @@ func saveRandomDataBlobs(t testing.TB, repo restic.Repository, num int, sizeMax
|
||||
}
|
||||
|
||||
func TestRepositoryIncrementalIndex(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
repository.IndexFull = func(*repository.Index) bool { return true }
|
||||
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"restic"
|
||||
"restic/archiver"
|
||||
"restic/backend/local"
|
||||
"restic/repository"
|
||||
)
|
||||
@ -50,54 +49,38 @@ func getBoolVar(name string, defaultValue bool) bool {
|
||||
}
|
||||
|
||||
// SetupRepo returns a repo setup in a temp dir.
|
||||
func SetupRepo() restic.Repository {
|
||||
func SetupRepo(t testing.TB) (repo restic.Repository, cleanup func()) {
|
||||
tempdir, err := ioutil.TempDir(TestTempDir, "restic-test-")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// create repository below temp dir
|
||||
b, err := local.Create(filepath.Join(tempdir, "repo"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
repo := repository.New(b)
|
||||
err = repo.Init(TestPassword)
|
||||
r := repository.New(b)
|
||||
err = r.Init(TestPassword)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
repo = r
|
||||
cleanup = func() {
|
||||
if !TestCleanupTempDirs {
|
||||
l := repo.Backend().(*local.Local)
|
||||
fmt.Printf("leaving local backend at %s\n", l.Location())
|
||||
return
|
||||
}
|
||||
|
||||
return repo
|
||||
}
|
||||
|
||||
// TeardownRepo removes a repository created by SetupRepo.
|
||||
func TeardownRepo(repo restic.Repository) {
|
||||
if !TestCleanupTempDirs {
|
||||
l := repo.Backend().(*local.Local)
|
||||
fmt.Printf("leaving local backend at %s\n", l.Location())
|
||||
return
|
||||
}
|
||||
|
||||
if r, ok := repo.(restic.Deleter); ok {
|
||||
err := r.Delete()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if r, ok := repo.(restic.Deleter); ok {
|
||||
err := r.Delete()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SnapshotDir creates a new snapshot of path.
|
||||
func SnapshotDir(t testing.TB, repo restic.Repository, path string, parent *restic.ID) *restic.Snapshot {
|
||||
arch := archiver.New(repo)
|
||||
sn, _, err := arch.Snapshot(nil, []string{path}, parent)
|
||||
OK(t, err)
|
||||
return sn
|
||||
}
|
||||
|
||||
// WithRepo runs the function t with a repository that is removed after f returns.
|
||||
func WithRepo(t testing.TB, f func(restic.Repository)) {
|
||||
repo := SetupRepo()
|
||||
f(repo)
|
||||
TeardownRepo(repo)
|
||||
return repo, cleanup
|
||||
}
|
||||
|
@ -92,8 +92,8 @@ func TestNodeComparison(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoadTree(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
// save tree
|
||||
tree := restic.NewTree()
|
||||
|
@ -15,8 +15,8 @@ import (
|
||||
)
|
||||
|
||||
func TestWalkTree(t *testing.T) {
|
||||
repo := SetupRepo()
|
||||
defer TeardownRepo(repo)
|
||||
repo, cleanup := SetupRepo(t)
|
||||
defer cleanup()
|
||||
|
||||
dirs, err := filepath.Glob(TestWalkerPath)
|
||||
OK(t, err)
|
||||
|
Loading…
Reference in New Issue
Block a user