mirror of
https://github.com/restic/restic.git
synced 2024-12-27 02:08:37 +00:00
prune: Test for abort on damaged repositories
This commit is contained in:
parent
575ed9a47e
commit
1c84aceb39
1 changed files with 77 additions and 20 deletions
|
@ -359,6 +359,28 @@ func TestBackupNonExistingFile(t *testing.T) {
|
||||||
testRunBackup(t, "", dirs, opts, env.gopts)
|
testRunBackup(t, "", dirs, opts, env.gopts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func removeDataPacksExcept(gopts GlobalOptions, t *testing.T, keep restic.IDSet) {
|
||||||
|
r, err := OpenRepository(gopts)
|
||||||
|
rtest.OK(t, err)
|
||||||
|
|
||||||
|
// Get all tree packs
|
||||||
|
rtest.OK(t, r.LoadIndex(gopts.ctx))
|
||||||
|
treePacks := restic.NewIDSet()
|
||||||
|
for _, idx := range r.Index().(*repository.MasterIndex).All() {
|
||||||
|
for _, id := range idx.TreePacks() {
|
||||||
|
treePacks.Insert(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove all packs containing data blobs
|
||||||
|
rtest.OK(t, r.List(gopts.ctx, restic.PackFile, func(id restic.ID, size int64) error {
|
||||||
|
if treePacks.Has(id) || keep.Has(id) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return r.Backend().Remove(gopts.ctx, restic.Handle{Type: restic.PackFile, Name: id.String()})
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
func TestBackupSelfHealing(t *testing.T) {
|
func TestBackupSelfHealing(t *testing.T) {
|
||||||
env, cleanup := withTestEnvironment(t)
|
env, cleanup := withTestEnvironment(t)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
@ -374,25 +396,8 @@ func TestBackupSelfHealing(t *testing.T) {
|
||||||
testRunBackup(t, filepath.Dir(env.testdata), []string{filepath.Base(env.testdata)}, opts, env.gopts)
|
testRunBackup(t, filepath.Dir(env.testdata), []string{filepath.Base(env.testdata)}, opts, env.gopts)
|
||||||
testRunCheck(t, env.gopts)
|
testRunCheck(t, env.gopts)
|
||||||
|
|
||||||
r, err := OpenRepository(env.gopts)
|
// remove all data packs
|
||||||
rtest.OK(t, err)
|
removeDataPacksExcept(env.gopts, t, restic.NewIDSet())
|
||||||
|
|
||||||
// Get all tree packs
|
|
||||||
rtest.OK(t, r.LoadIndex(env.gopts.ctx))
|
|
||||||
treePacks := restic.NewIDSet()
|
|
||||||
for _, idx := range r.Index().(*repository.MasterIndex).All() {
|
|
||||||
for _, id := range idx.TreePacks() {
|
|
||||||
treePacks.Insert(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove all packs containing data blobs
|
|
||||||
rtest.OK(t, r.List(env.gopts.ctx, restic.PackFile, func(id restic.ID, size int64) error {
|
|
||||||
if treePacks.Has(id) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return r.Backend().Remove(env.gopts.ctx, restic.Handle{Type: restic.PackFile, Name: id.String()})
|
|
||||||
}))
|
|
||||||
|
|
||||||
testRunRebuildIndex(t, env.gopts)
|
testRunRebuildIndex(t, env.gopts)
|
||||||
// now the repo is also missing the data blob in the index; check should report this
|
// now the repo is also missing the data blob in the index; check should report this
|
||||||
|
@ -400,7 +405,7 @@ func TestBackupSelfHealing(t *testing.T) {
|
||||||
"check should have reported an error")
|
"check should have reported an error")
|
||||||
|
|
||||||
// second backup should report an error but "heal" this situation
|
// second backup should report an error but "heal" this situation
|
||||||
err = testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{filepath.Base(env.testdata)}, opts, env.gopts)
|
err := testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{filepath.Base(env.testdata)}, opts, env.gopts)
|
||||||
rtest.Assert(t, err != nil,
|
rtest.Assert(t, err != nil,
|
||||||
"backup should have reported an error")
|
"backup should have reported an error")
|
||||||
testRunCheck(t, env.gopts)
|
testRunCheck(t, env.gopts)
|
||||||
|
@ -1226,6 +1231,58 @@ func TestPrune(t *testing.T) {
|
||||||
testRunCheck(t, env.gopts)
|
testRunCheck(t, env.gopts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func listPacks(gopts GlobalOptions, t *testing.T) restic.IDSet {
|
||||||
|
r, err := OpenRepository(gopts)
|
||||||
|
rtest.OK(t, err)
|
||||||
|
|
||||||
|
packs := restic.NewIDSet()
|
||||||
|
|
||||||
|
rtest.OK(t, r.List(gopts.ctx, restic.PackFile, func(id restic.ID, size int64) error {
|
||||||
|
packs.Insert(id)
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
return packs
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPruneWithDamagedRepository(t *testing.T) {
|
||||||
|
env, cleanup := withTestEnvironment(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
datafile := filepath.Join("testdata", "backup-data.tar.gz")
|
||||||
|
testRunInit(t, env.gopts)
|
||||||
|
|
||||||
|
rtest.SetupTarTestFixture(t, env.testdata, datafile)
|
||||||
|
opts := BackupOptions{}
|
||||||
|
|
||||||
|
// create and delete snapshot to create unused blobs
|
||||||
|
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9", "2")}, opts, env.gopts)
|
||||||
|
firstSnapshot := testRunList(t, "snapshots", env.gopts)
|
||||||
|
rtest.Assert(t, len(firstSnapshot) == 1,
|
||||||
|
"expected one snapshot, got %v", firstSnapshot)
|
||||||
|
testRunForget(t, env.gopts, firstSnapshot[0].String())
|
||||||
|
|
||||||
|
oldPacks := listPacks(env.gopts, t)
|
||||||
|
|
||||||
|
// create new snapshot, but lose all data
|
||||||
|
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9", "3")}, opts, env.gopts)
|
||||||
|
snapshotIDs := testRunList(t, "snapshots", env.gopts)
|
||||||
|
|
||||||
|
removeDataPacksExcept(env.gopts, t, oldPacks)
|
||||||
|
|
||||||
|
rtest.Assert(t, len(snapshotIDs) == 1,
|
||||||
|
"expected one snapshot, got %v", snapshotIDs)
|
||||||
|
|
||||||
|
// prune should fail
|
||||||
|
err := runPrune(env.gopts)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected prune to fail")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "blob seems to be missing") {
|
||||||
|
t.Fatalf("did not find hint for missing blobs")
|
||||||
|
}
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestHardLink(t *testing.T) {
|
func TestHardLink(t *testing.T) {
|
||||||
// this test assumes a test set with a single directory containing hard linked files
|
// this test assumes a test set with a single directory containing hard linked files
|
||||||
env, cleanup := withTestEnvironment(t)
|
env, cleanup := withTestEnvironment(t)
|
||||||
|
|
Loading…
Reference in a new issue