forked from TrueCloudLab/restic
Check in integration test that snapshots are listed before the index
As an exception prune is still allowed to load the index before snapshots, as it uses exclusive locks. In case of problems with locking it is also better to load snapshots created after loading the index, as this will lead to a prune sanity check failure instead of a broken snapshot.
This commit is contained in:
parent
7b9ae91e04
commit
ebab35581c
3 changed files with 32 additions and 0 deletions
|
@ -154,6 +154,8 @@ func TestMount(t *testing.T) {
|
|||
}
|
||||
|
||||
env, cleanup := withTestEnvironment(t)
|
||||
// must list snapshots more than once
|
||||
env.gopts.backendTestHook = nil
|
||||
defer cleanup()
|
||||
|
||||
testRunInit(t, env.gopts)
|
||||
|
@ -197,6 +199,8 @@ func TestMountSameTimestamps(t *testing.T) {
|
|||
}
|
||||
|
||||
env, cleanup := withTestEnvironment(t)
|
||||
// must list snapshots more than once
|
||||
env.gopts.backendTestHook = nil
|
||||
defer cleanup()
|
||||
|
||||
rtest.SetupTarTestFixture(t, env.base, filepath.Join("testdata", "repo-same-timestamps.tar.gz"))
|
||||
|
|
|
@ -198,6 +198,9 @@ func withTestEnvironment(t testing.TB) (env *testEnvironment, cleanup func()) {
|
|||
stdout: os.Stdout,
|
||||
stderr: os.Stderr,
|
||||
extended: make(options.Options),
|
||||
|
||||
// replace this hook with "nil" if listing a filetype more than once is necessary
|
||||
backendTestHook: func(r restic.Backend) (restic.Backend, error) { return newOrderedListOnceBackend(r), nil },
|
||||
}
|
||||
|
||||
// always overwrite global options
|
||||
|
|
|
@ -275,6 +275,11 @@ func testRunForgetJSON(t testing.TB, gopts GlobalOptions, args ...string) {
|
|||
}
|
||||
|
||||
func testRunPrune(t testing.TB, gopts GlobalOptions, opts PruneOptions) {
|
||||
oldHook := gopts.backendTestHook
|
||||
gopts.backendTestHook = func(r restic.Backend) (restic.Backend, error) { return newListOnceBackend(r), nil }
|
||||
defer func() {
|
||||
gopts.backendTestHook = oldHook
|
||||
}()
|
||||
rtest.OK(t, runPrune(opts, gopts))
|
||||
}
|
||||
|
||||
|
@ -1065,6 +1070,8 @@ func TestKeyAddRemove(t *testing.T) {
|
|||
}
|
||||
|
||||
env, cleanup := withTestEnvironment(t)
|
||||
// must list keys more than once
|
||||
env.gopts.backendTestHook = nil
|
||||
defer cleanup()
|
||||
|
||||
testRunInit(t, env.gopts)
|
||||
|
@ -1659,6 +1666,11 @@ func TestPruneWithDamagedRepository(t *testing.T) {
|
|||
rtest.Assert(t, len(snapshotIDs) == 1,
|
||||
"expected one snapshot, got %v", snapshotIDs)
|
||||
|
||||
oldHook := env.gopts.backendTestHook
|
||||
env.gopts.backendTestHook = func(r restic.Backend) (restic.Backend, error) { return newListOnceBackend(r), nil }
|
||||
defer func() {
|
||||
env.gopts.backendTestHook = oldHook
|
||||
}()
|
||||
// prune should fail
|
||||
rtest.Assert(t, runPrune(pruneDefaultOptions, env.gopts) == errorPacksMissing,
|
||||
"prune should have reported index not complete error")
|
||||
|
@ -1752,12 +1764,22 @@ func testEdgeCaseRepo(t *testing.T, tarfile string, optionsCheck CheckOptions, o
|
|||
type listOnceBackend struct {
|
||||
restic.Backend
|
||||
listedFileType map[restic.FileType]bool
|
||||
strictOrder bool
|
||||
}
|
||||
|
||||
func newListOnceBackend(be restic.Backend) *listOnceBackend {
|
||||
return &listOnceBackend{
|
||||
Backend: be,
|
||||
listedFileType: make(map[restic.FileType]bool),
|
||||
strictOrder: false,
|
||||
}
|
||||
}
|
||||
|
||||
func newOrderedListOnceBackend(be restic.Backend) *listOnceBackend {
|
||||
return &listOnceBackend{
|
||||
Backend: be,
|
||||
listedFileType: make(map[restic.FileType]bool),
|
||||
strictOrder: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1765,6 +1787,9 @@ func (be *listOnceBackend) List(ctx context.Context, t restic.FileType, fn func(
|
|||
if t != restic.LockFile && be.listedFileType[t] {
|
||||
return errors.Errorf("tried listing type %v the second time", t)
|
||||
}
|
||||
if be.strictOrder && t == restic.SnapshotFile && be.listedFileType[restic.IndexFile] {
|
||||
return errors.Errorf("tried listing type snapshots after index")
|
||||
}
|
||||
be.listedFileType[t] = true
|
||||
return be.Backend.List(ctx, t, fn)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue