diff --git a/cmd/restic/integration_test.go b/cmd/restic/integration_test.go index 1267db0a0..3868e02bb 100644 --- a/cmd/restic/integration_test.go +++ b/cmd/restic/integration_test.go @@ -1283,6 +1283,81 @@ func TestPruneWithDamagedRepository(t *testing.T) { t.Log(err) } +// Test repos for edge cases +func TestEdgeCaseRepos(t *testing.T) { + opts := CheckOptions{} + + // repo where index is completely missing + // => check and prune should fail + t.Run("no-index", func(t *testing.T) { + testEdgeCaseRepo(t, "repo-index-missing.tar.gz", opts, false, false) + }) + + // repo where an existing and used blob is missing from the index + // => check should fail, prune should heal this + t.Run("index-missing-blob", func(t *testing.T) { + testEdgeCaseRepo(t, "repo-index-missing-blob.tar.gz", opts, false, true) + }) + + // repo where a blob is missing + // => check and prune should fail + t.Run("no-data", func(t *testing.T) { + testEdgeCaseRepo(t, "repo-data-missing.tar.gz", opts, false, false) + }) + + // repo where data exists that is not referenced + // => check and prune should fully work + t.Run("unreferenced-data", func(t *testing.T) { + testEdgeCaseRepo(t, "repo-unreferenced-data.tar.gz", opts, true, true) + }) + + // repo where an obsolete index still exists + // => check and prune should fully work + t.Run("obsolete-index", func(t *testing.T) { + testEdgeCaseRepo(t, "repo-obsolete-index.tar.gz", opts, true, true) + }) + + // repo which contains mixed (data/tree) packs + // => check and prune should fully work + t.Run("mixed-packs", func(t *testing.T) { + testEdgeCaseRepo(t, "repo-mixed.tar.gz", opts, true, true) + }) + + // repo which contains duplicate blobs + // => checking for unused data should report an error and prune resolves the + // situation + opts = CheckOptions{ + ReadData: true, + CheckUnused: true, + } + t.Run("duplicates", func(t *testing.T) { + testEdgeCaseRepo(t, "repo-duplicates.tar.gz", opts, false, true) + }) +} + +func testEdgeCaseRepo(t *testing.T, tarfile string, options CheckOptions, checkOK, pruneOK bool) { + env, cleanup := withTestEnvironment(t) + defer cleanup() + + datafile := filepath.Join("testdata", tarfile) + rtest.SetupTarTestFixture(t, env.base, datafile) + + if checkOK { + testRunCheck(t, env.gopts) + } else { + rtest.Assert(t, runCheck(options, env.gopts, nil) != nil, + "check should have reported an error") + } + + if pruneOK { + testRunPrune(t, env.gopts) + testRunCheck(t, env.gopts) + } else { + rtest.Assert(t, runPrune(env.gopts) != nil, + "prune should have reported an error") + } +} + func TestHardLink(t *testing.T) { // this test assumes a test set with a single directory containing hard linked files env, cleanup := withTestEnvironment(t) diff --git a/cmd/restic/testdata/repo-data-missing.tar.gz b/cmd/restic/testdata/repo-data-missing.tar.gz new file mode 100644 index 000000000..d13c6f789 Binary files /dev/null and b/cmd/restic/testdata/repo-data-missing.tar.gz differ diff --git a/cmd/restic/testdata/repo-duplicates.tar.gz b/cmd/restic/testdata/repo-duplicates.tar.gz new file mode 100644 index 000000000..a0325160d Binary files /dev/null and b/cmd/restic/testdata/repo-duplicates.tar.gz differ diff --git a/cmd/restic/testdata/repo-index-missing-blob.tar.gz b/cmd/restic/testdata/repo-index-missing-blob.tar.gz new file mode 100644 index 000000000..43c512f76 Binary files /dev/null and b/cmd/restic/testdata/repo-index-missing-blob.tar.gz differ diff --git a/cmd/restic/testdata/repo-index-missing.tar.gz b/cmd/restic/testdata/repo-index-missing.tar.gz new file mode 100644 index 000000000..b88810ebd Binary files /dev/null and b/cmd/restic/testdata/repo-index-missing.tar.gz differ diff --git a/cmd/restic/testdata/repo-mixed.tar.gz b/cmd/restic/testdata/repo-mixed.tar.gz new file mode 100644 index 000000000..5108ad984 Binary files /dev/null and b/cmd/restic/testdata/repo-mixed.tar.gz differ diff --git a/cmd/restic/testdata/repo-obsolete-index.tar.gz b/cmd/restic/testdata/repo-obsolete-index.tar.gz new file mode 100644 index 000000000..f870b919f Binary files /dev/null and b/cmd/restic/testdata/repo-obsolete-index.tar.gz differ diff --git a/cmd/restic/testdata/repo-unreferenced-data.tar.gz b/cmd/restic/testdata/repo-unreferenced-data.tar.gz new file mode 100644 index 000000000..f00eb2d0b Binary files /dev/null and b/cmd/restic/testdata/repo-unreferenced-data.tar.gz differ