diff --git a/internal/archiver/archiver_test.go b/internal/archiver/archiver_test.go index e18156ceb..0d6295c39 100644 --- a/internal/archiver/archiver_test.go +++ b/internal/archiver/archiver_test.go @@ -1894,7 +1894,7 @@ func TestArchiverContextCanceled(t *testing.T) { defer removeTempdir() // Ensure that the archiver itself reports the canceled context and not just the backend - repo, _ := repository.TestRepositoryWithBackend(t, &noCancelBackend{mem.New()}) + repo, _ := repository.TestRepositoryWithBackend(t, &noCancelBackend{mem.New()}, 0) back := restictest.Chdir(t, tempdir) defer back() diff --git a/internal/repository/master_index_test.go b/internal/repository/master_index_test.go index 2470dadfc..28a2c1251 100644 --- a/internal/repository/master_index_test.go +++ b/internal/repository/master_index_test.go @@ -335,8 +335,8 @@ var ( depth = 3 ) -func createFilledRepo(t testing.TB, snapshots int, dup float32) (restic.Repository, func()) { - repo, cleanup := repository.TestRepository(t) +func createFilledRepo(t testing.TB, snapshots int, dup float32, version uint) (restic.Repository, func()) { + repo, cleanup := repository.TestRepositoryWithVersion(t, version) for i := 0; i < 3; i++ { restic.TestCreateSnapshot(t, repo, snapshotTime.Add(time.Duration(i)*time.Second), depth, dup) @@ -346,7 +346,11 @@ func createFilledRepo(t testing.TB, snapshots int, dup float32) (restic.Reposito } func TestIndexSave(t *testing.T) { - repo, cleanup := createFilledRepo(t, 3, 0) + repository.TestAllVersions(t, testIndexSave) +} + +func testIndexSave(t *testing.T, version uint) { + repo, cleanup := createFilledRepo(t, 3, 0, version) defer cleanup() err := repo.LoadIndex(context.TODO()) diff --git a/internal/repository/repack_test.go b/internal/repository/repack_test.go index e40f5f6af..b86c8c95d 100644 --- a/internal/repository/repack_test.go +++ b/internal/repository/repack_test.go @@ -212,7 +212,11 @@ func reloadIndex(t *testing.T, repo restic.Repository) { } func TestRepack(t *testing.T) { - repo, cleanup := repository.TestRepository(t) + repository.TestAllVersions(t, testRepack) +} + +func testRepack(t *testing.T, version uint) { + repo, cleanup := repository.TestRepositoryWithVersion(t, version) defer cleanup() seed := time.Now().UnixNano() @@ -279,9 +283,13 @@ func TestRepack(t *testing.T) { } func TestRepackCopy(t *testing.T) { - repo, cleanup := repository.TestRepository(t) + repository.TestAllVersions(t, testRepackCopy) +} + +func testRepackCopy(t *testing.T, version uint) { + repo, cleanup := repository.TestRepositoryWithVersion(t, version) defer cleanup() - dstRepo, dstCleanup := repository.TestRepository(t) + dstRepo, dstCleanup := repository.TestRepositoryWithVersion(t, version) defer dstCleanup() seed := time.Now().UnixNano() @@ -318,7 +326,11 @@ func TestRepackCopy(t *testing.T) { } func TestRepackWrongBlob(t *testing.T) { - repo, cleanup := repository.TestRepository(t) + repository.TestAllVersions(t, testRepackWrongBlob) +} + +func testRepackWrongBlob(t *testing.T, version uint) { + repo, cleanup := repository.TestRepositoryWithVersion(t, version) defer cleanup() seed := time.Now().UnixNano() diff --git a/internal/repository/repository_test.go b/internal/repository/repository_test.go index 6da685ff3..f2daaf194 100644 --- a/internal/repository/repository_test.go +++ b/internal/repository/repository_test.go @@ -28,7 +28,11 @@ var testSizes = []int{5, 23, 2<<18 + 23, 1 << 20} var rnd = rand.New(rand.NewSource(time.Now().UnixNano())) func TestSave(t *testing.T) { - repo, cleanup := repository.TestRepository(t) + repository.TestAllVersions(t, testSave) +} + +func testSave(t *testing.T, version uint) { + repo, cleanup := repository.TestRepositoryWithVersion(t, version) defer cleanup() for _, size := range testSizes { @@ -63,7 +67,11 @@ func TestSave(t *testing.T) { } func TestSaveFrom(t *testing.T) { - repo, cleanup := repository.TestRepository(t) + repository.TestAllVersions(t, testSaveFrom) +} + +func testSaveFrom(t *testing.T, version uint) { + repo, cleanup := repository.TestRepositoryWithVersion(t, version) defer cleanup() for _, size := range testSizes { @@ -96,7 +104,11 @@ func TestSaveFrom(t *testing.T) { } func BenchmarkSaveAndEncrypt(t *testing.B) { - repo, cleanup := repository.TestRepository(t) + repository.BenchmarkAllVersions(t, benchmarkSaveAndEncrypt) +} + +func benchmarkSaveAndEncrypt(t *testing.B, version uint) { + repo, cleanup := repository.TestRepositoryWithVersion(t, version) defer cleanup() size := 4 << 20 // 4MiB @@ -118,7 +130,11 @@ func BenchmarkSaveAndEncrypt(t *testing.B) { } func TestLoadTree(t *testing.T) { - repo, cleanup := repository.TestRepository(t) + repository.TestAllVersions(t, testLoadTree) +} + +func testLoadTree(t *testing.T, version uint) { + repo, cleanup := repository.TestRepositoryWithVersion(t, version) defer cleanup() if rtest.BenchArchiveDirectory == "" { @@ -134,7 +150,11 @@ func TestLoadTree(t *testing.T) { } func BenchmarkLoadTree(t *testing.B) { - repo, cleanup := repository.TestRepository(t) + repository.BenchmarkAllVersions(t, benchmarkLoadTree) +} + +func benchmarkLoadTree(t *testing.B, version uint) { + repo, cleanup := repository.TestRepositoryWithVersion(t, version) defer cleanup() if rtest.BenchArchiveDirectory == "" { @@ -154,7 +174,11 @@ func BenchmarkLoadTree(t *testing.B) { } func TestLoadBlob(t *testing.T) { - repo, cleanup := repository.TestRepository(t) + repository.TestAllVersions(t, testLoadBlob) +} + +func testLoadBlob(t *testing.T, version uint) { + repo, cleanup := repository.TestRepositoryWithVersion(t, version) defer cleanup() length := 1000000 @@ -183,7 +207,11 @@ func TestLoadBlob(t *testing.T) { } func BenchmarkLoadBlob(b *testing.B) { - repo, cleanup := repository.TestRepository(b) + repository.BenchmarkAllVersions(b, benchmarkLoadBlob) +} + +func benchmarkLoadBlob(b *testing.B, version uint) { + repo, cleanup := repository.TestRepositoryWithVersion(b, version) defer cleanup() length := 1000000 @@ -219,7 +247,11 @@ func BenchmarkLoadBlob(b *testing.B) { } func BenchmarkLoadUnpacked(b *testing.B) { - repo, cleanup := repository.TestRepository(b) + repository.BenchmarkAllVersions(b, benchmarkLoadUnpacked) +} + +func benchmarkLoadUnpacked(b *testing.B, version uint) { + repo, cleanup := repository.TestRepositoryWithVersion(b, version) defer cleanup() length := 1000000 @@ -255,7 +287,11 @@ func BenchmarkLoadUnpacked(b *testing.B) { } func TestLoadJSONUnpacked(t *testing.T) { - repo, cleanup := repository.TestRepository(t) + repository.TestAllVersions(t, testLoadJSONUnpacked) +} + +func testLoadJSONUnpacked(t *testing.T, version uint) { + repo, cleanup := repository.TestRepositoryWithVersion(t, version) defer cleanup() if rtest.BenchArchiveDirectory == "" { @@ -313,9 +349,13 @@ func loadIndex(ctx context.Context, repo restic.Repository, id restic.ID) (*repo } func BenchmarkLoadIndex(b *testing.B) { + repository.BenchmarkAllVersions(b, benchmarkLoadIndex) +} + +func benchmarkLoadIndex(b *testing.B, version uint) { repository.TestUseLowSecurityKDFParameters(b) - repo, cleanup := repository.TestRepository(b) + repo, cleanup := repository.TestRepositoryWithVersion(b, version) defer cleanup() idx := repository.NewIndex() @@ -362,7 +402,11 @@ func saveRandomDataBlobs(t testing.TB, repo restic.Repository, num int, sizeMax } func TestRepositoryIncrementalIndex(t *testing.T) { - r, cleanup := repository.TestRepository(t) + repository.TestAllVersions(t, testRepositoryIncrementalIndex) +} + +func testRepositoryIncrementalIndex(t *testing.T, version uint) { + r, cleanup := repository.TestRepositoryWithVersion(t, version) defer cleanup() repo := r.(*repository.Repository) diff --git a/internal/repository/testing.go b/internal/repository/testing.go index fbe334467..05dfab64d 100644 --- a/internal/repository/testing.go +++ b/internal/repository/testing.go @@ -2,6 +2,7 @@ package repository import ( "context" + "fmt" "os" "testing" @@ -41,7 +42,7 @@ const TestChunkerPol = chunker.Pol(0x3DA3358B4DC173) // 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) (r restic.Repository, cleanup func()) { +func TestRepositoryWithBackend(t testing.TB, be restic.Backend, version uint) (r restic.Repository, cleanup func()) { t.Helper() TestUseLowSecurityKDFParameters(t) restic.TestDisableCheckPolynomial(t) @@ -53,7 +54,7 @@ func TestRepositoryWithBackend(t testing.TB, be restic.Backend) (r restic.Reposi repo := New(be, Options{}) - cfg := restic.TestCreateConfig(t, TestChunkerPol) + cfg := restic.TestCreateConfig(t, TestChunkerPol, version) err := repo.init(context.TODO(), test.TestPassword, cfg) if err != nil { t.Fatalf("TestRepository(): initialize repo failed: %v", err) @@ -71,6 +72,11 @@ func TestRepositoryWithBackend(t testing.TB, be restic.Backend) (r restic.Reposi // 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. 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() dir := os.Getenv("RESTIC_TEST_REPO") if dir != "" { @@ -80,7 +86,7 @@ func TestRepository(t testing.TB) (r restic.Repository, cleanup func()) { if err != nil { t.Fatalf("error creating local backend at %v: %v", dir, err) } - return TestRepositoryWithBackend(t, be) + return TestRepositoryWithBackend(t, be, version) } if err == nil { @@ -88,7 +94,7 @@ func TestRepository(t testing.TB) (r restic.Repository, cleanup func()) { } } - return TestRepositoryWithBackend(t, nil) + return TestRepositoryWithBackend(t, nil, version) } // TestOpenLocal opens a local repository. @@ -106,3 +112,23 @@ func TestOpenLocal(t testing.TB, dir string) (r restic.Repository) { 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)) + }) + } +} diff --git a/internal/restic/config.go b/internal/restic/config.go index 3a6bab746..6df32e2ef 100644 --- a/internal/restic/config.go +++ b/internal/restic/config.go @@ -51,11 +51,17 @@ func CreateConfig(version uint) (Config, error) { } // TestCreateConfig creates a config for use within tests. -func TestCreateConfig(t testing.TB, pol chunker.Pol) (cfg Config) { +func TestCreateConfig(t testing.TB, pol chunker.Pol, version uint) (cfg Config) { cfg.ChunkerPolynomial = pol cfg.ID = NewRandomID().String() - cfg.Version = StableRepoVersion + if version == 0 { + version = StableRepoVersion + } + if version < MinRepoVersion || version > MaxRepoVersion { + t.Fatalf("version %d is out of range", version) + } + cfg.Version = version return cfg }