forked from TrueCloudLab/restic
Add test that repo.List is only called once
This commit is contained in:
parent
fd33030556
commit
d2e53730d6
2 changed files with 61 additions and 2 deletions
|
@ -3,8 +3,11 @@ Enhancement: Improve pruning performance and make pruning more customizable
|
|||
The `prune` command is now much faster. This is especially the case for remote
|
||||
repositories or repositories with not much data to remove.
|
||||
Also the memory usage of the `prune` command is now reduced.
|
||||
Restic used to rebuild the index from scratch after pruning. This is now
|
||||
changed and the index rebuilding uses the information already known by `prune`.
|
||||
Restic used to rebuild the index from scratch after pruning. This could lead
|
||||
to missing packs in the index in some cases for eventually consistent
|
||||
backends, like e.g. AWS S3.
|
||||
This behavior is now changed and the index rebuilding uses the information
|
||||
already known by `prune`.
|
||||
|
||||
By default, the `prune` command no longer removes all unused data. This
|
||||
behavior can be fine-tuned by new options, like the acceptable amount of unused space or
|
||||
|
|
|
@ -1559,6 +1559,62 @@ func testEdgeCaseRepo(t *testing.T, tarfile string, optionsCheck CheckOptions, o
|
|||
}
|
||||
}
|
||||
|
||||
// a listOnceBackend only allows listing once per filetype
|
||||
// listing filetypes more than once may cause problems with eventually consistent
|
||||
// backends (like e.g. AWS S3) as the second listing may be inconsistent to what
|
||||
// is expected by the first listing + some operations.
|
||||
type listOnceBackend struct {
|
||||
restic.Backend
|
||||
listedFileType map[restic.FileType]bool
|
||||
}
|
||||
|
||||
func newListOnceBackend(be restic.Backend) *listOnceBackend {
|
||||
return &listOnceBackend{
|
||||
Backend: be,
|
||||
listedFileType: make(map[restic.FileType]bool),
|
||||
}
|
||||
}
|
||||
|
||||
func (be *listOnceBackend) List(ctx context.Context, t restic.FileType, fn func(restic.FileInfo) error) error {
|
||||
if t != restic.LockFile && be.listedFileType[t] {
|
||||
return errors.Errorf("tried listing type %v the second time", t)
|
||||
}
|
||||
be.listedFileType[t] = true
|
||||
return be.Backend.List(ctx, t, fn)
|
||||
}
|
||||
|
||||
func TestPruneListOnce(t *testing.T) {
|
||||
env, cleanup := withTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
env.gopts.backendTestHook = func(r restic.Backend) (restic.Backend, error) {
|
||||
return newListOnceBackend(r), nil
|
||||
}
|
||||
|
||||
pruneOpts := PruneOptions{MaxUnused: "0"}
|
||||
checkOpts := CheckOptions{ReadData: true, CheckUnused: true}
|
||||
|
||||
testSetupBackupData(t, env)
|
||||
opts := BackupOptions{}
|
||||
|
||||
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9")}, opts, env.gopts)
|
||||
firstSnapshot := testRunList(t, "snapshots", env.gopts)
|
||||
rtest.Assert(t, len(firstSnapshot) == 1,
|
||||
"expected one snapshot, got %v", firstSnapshot)
|
||||
|
||||
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9", "2")}, opts, env.gopts)
|
||||
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9", "3")}, opts, env.gopts)
|
||||
|
||||
snapshotIDs := testRunList(t, "snapshots", env.gopts)
|
||||
rtest.Assert(t, len(snapshotIDs) == 3,
|
||||
"expected 3 snapshot, got %v", snapshotIDs)
|
||||
|
||||
testRunForgetJSON(t, env.gopts)
|
||||
testRunForget(t, env.gopts, firstSnapshot[0].String())
|
||||
testRunPrune(t, env.gopts, pruneOpts)
|
||||
rtest.OK(t, runCheck(checkOpts, env.gopts, nil))
|
||||
}
|
||||
|
||||
func TestHardLink(t *testing.T) {
|
||||
// this test assumes a test set with a single directory containing hard linked files
|
||||
env, cleanup := withTestEnvironment(t)
|
||||
|
|
Loading…
Reference in a new issue