restic/internal/repository/testing.go

151 lines
4 KiB
Go
Raw Normal View History

2016-04-10 14:52:15 +00:00
package repository
import (
2017-06-04 09:16:55 +00:00
"context"
"fmt"
2016-04-10 14:52:15 +00:00
"os"
"testing"
2017-07-23 12:21:03 +00:00
"github.com/restic/restic/internal/backend/local"
"github.com/restic/restic/internal/backend/mem"
"github.com/restic/restic/internal/crypto"
2017-07-24 15:42:25 +00:00
"github.com/restic/restic/internal/restic"
2017-07-23 12:21:03 +00:00
"github.com/restic/restic/internal/test"
"github.com/restic/chunker"
2016-04-10 14:52:15 +00:00
)
// testKDFParams are the parameters for the KDF to be used during testing.
2017-10-28 08:28:29 +00:00
var testKDFParams = crypto.Params{
N: 128,
R: 1,
P: 1,
}
type logger interface {
Logf(format string, args ...interface{})
}
// TestUseLowSecurityKDFParameters configures low-security KDF parameters for testing.
func TestUseLowSecurityKDFParameters(t logger) {
t.Logf("using low-security KDF parameters for test")
2017-10-28 08:28:29 +00:00
Params = &testKDFParams
}
2016-04-10 14:52:15 +00:00
// TestBackend returns a fully configured in-memory backend.
2016-08-31 18:29:54 +00:00
func TestBackend(t testing.TB) (be restic.Backend, cleanup func()) {
2016-04-10 14:52:15 +00:00
return mem.New(), func() {}
}
const TestChunkerPol = chunker.Pol(0x3DA3358B4DC173)
2016-04-10 14:52:15 +00:00
// TestRepositoryWithBackend returns a repository initialized with a test
// password. If be is nil, an in-memory backend is used. A constant polynomial
// is used for the chunker and low-security test parameters.
func TestRepositoryWithBackend(t testing.TB, be restic.Backend, version uint) (r restic.Repository, cleanup func()) {
t.Helper()
TestUseLowSecurityKDFParameters(t)
2018-03-11 20:42:39 +00:00
restic.TestDisableCheckPolynomial(t)
2016-04-10 14:52:15 +00:00
var beCleanup func()
if be == nil {
be, beCleanup = TestBackend(t)
}
2022-07-02 21:30:26 +00:00
repo, err := New(be, Options{})
if err != nil {
t.Fatalf("TestRepository(): new repo failed: %v", err)
}
2016-04-10 14:52:15 +00:00
cfg := restic.TestCreateConfig(t, TestChunkerPol, version)
2022-07-02 21:30:26 +00:00
err = repo.init(context.TODO(), test.TestPassword, cfg)
2016-04-10 14:52:15 +00:00
if err != nil {
t.Fatalf("TestRepository(): initialize repo failed: %v", err)
2016-04-10 14:52:15 +00:00
}
2016-09-04 12:29:04 +00:00
return repo, func() {
2016-04-10 14:52:15 +00:00
if beCleanup != nil {
beCleanup()
}
}
}
// TestRepository returns a repository initialized with a test password on an
// in-memory backend. When the environment variable RESTIC_TEST_REPO is set to
// a non-existing directory, a local backend is created there and this is used
// instead. The directory is not removed, but left there for inspection.
2016-09-04 12:29:04 +00:00
func TestRepository(t testing.TB) (r restic.Repository, cleanup func()) {
t.Helper()
return TestRepositoryWithVersion(t, 0)
}
func TestRepositoryWithVersion(t testing.TB, version uint) (r restic.Repository, cleanup func()) {
t.Helper()
2016-04-10 14:52:15 +00:00
dir := os.Getenv("RESTIC_TEST_REPO")
if dir != "" {
_, err := os.Stat(dir)
if err != nil {
be, err := local.Create(context.TODO(), local.Config{Path: dir})
2016-04-10 14:52:15 +00:00
if err != nil {
t.Fatalf("error creating local backend at %v: %v", dir, err)
}
return TestRepositoryWithBackend(t, be, version)
2016-04-10 14:52:15 +00:00
}
if err == nil {
t.Logf("directory at %v already exists, using mem backend", dir)
}
}
return TestRepositoryWithBackend(t, nil, version)
2016-04-10 14:52:15 +00:00
}
2016-09-04 12:29:04 +00:00
// TestOpenLocal opens a local repository.
func TestOpenLocal(t testing.TB, dir string) (r restic.Repository) {
be, err := local.Open(context.TODO(), local.Config{Path: dir, Connections: 2})
2016-09-04 12:29:04 +00:00
if err != nil {
t.Fatal(err)
}
2022-07-02 21:30:26 +00:00
repo, err := New(be, Options{})
if err != nil {
t.Fatal(err)
}
2018-11-25 14:10:45 +00:00
err = repo.SearchKey(context.TODO(), test.TestPassword, 10, "")
2016-09-04 12:29:04 +00:00
if err != nil {
t.Fatal(err)
}
return repo
}
type VersionedTest func(t *testing.T, version uint)
func TestAllVersions(t *testing.T, test VersionedTest) {
for version := restic.MinRepoVersion; version <= restic.MaxRepoVersion; version++ {
t.Run(fmt.Sprintf("v%d", version), func(t *testing.T) {
test(t, uint(version))
})
}
}
type VersionedBenchmark func(b *testing.B, version uint)
func BenchmarkAllVersions(b *testing.B, bench VersionedBenchmark) {
for version := restic.MinRepoVersion; version <= restic.MaxRepoVersion; version++ {
b.Run(fmt.Sprintf("v%d", version), func(b *testing.B) {
bench(b, uint(version))
})
}
}
func TestMergeIndex(t testing.TB, mi *MasterIndex) ([]*Index, int) {
finalIndexes := mi.finalizeNotFinalIndexes()
for _, idx := range finalIndexes {
test.OK(t, idx.SetID(restic.NewRandomID()))
}
test.OK(t, mi.MergeFinalIndexes())
return finalIndexes, len(mi.idx)
}