mirror of https://github.com/restic/restic.git
Test that WriteTo of a backend's Load remains accessible
This commit is contained in:
parent
678e75e1c2
commit
f3442ce8a5
|
@ -71,7 +71,7 @@ type GlobalOptions struct {
|
|||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
|
||||
backendTestHook backendWrapper
|
||||
backendTestHook, backendInnerTestHook backendWrapper
|
||||
|
||||
// verbosity is set as follows:
|
||||
// 0 means: don't print any messages except errors, this is used when --quiet is specified
|
||||
|
@ -695,12 +695,8 @@ func open(s string, gopts GlobalOptions, opts options.Options) (restic.Backend,
|
|||
switch loc.Scheme {
|
||||
case "local":
|
||||
be, err = local.Open(globalOptions.ctx, cfg.(local.Config))
|
||||
// wrap the backend in a LimitBackend so that the throughput is limited
|
||||
be = limiter.LimitBackend(be, lim)
|
||||
case "sftp":
|
||||
be, err = sftp.Open(globalOptions.ctx, cfg.(sftp.Config))
|
||||
// wrap the backend in a LimitBackend so that the throughput is limited
|
||||
be = limiter.LimitBackend(be, lim)
|
||||
case "s3":
|
||||
be, err = s3.Open(globalOptions.ctx, cfg.(s3.Config), rt)
|
||||
case "gs":
|
||||
|
@ -724,6 +720,19 @@ func open(s string, gopts GlobalOptions, opts options.Options) (restic.Backend,
|
|||
return nil, errors.Fatalf("unable to open repo at %v: %v", location.StripPassword(s), err)
|
||||
}
|
||||
|
||||
// wrap backend if a test specified an inner hook
|
||||
if gopts.backendInnerTestHook != nil {
|
||||
be, err = gopts.backendInnerTestHook(be)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if loc.Scheme == "local" || loc.Scheme == "sftp" {
|
||||
// wrap the backend in a LimitBackend so that the throughput is limited
|
||||
be = limiter.LimitBackend(be, lim)
|
||||
}
|
||||
|
||||
// check if config is there
|
||||
fi, err := be.Stat(globalOptions.ctx, restic.Handle{Type: restic.ConfigFile})
|
||||
if err != nil {
|
||||
|
|
|
@ -1829,3 +1829,53 @@ func TestDiff(t *testing.T) {
|
|||
rtest.Assert(t, r.MatchString(out), "expected pattern %v in output, got\n%v", pattern, out)
|
||||
}
|
||||
}
|
||||
|
||||
type writeToOnly struct {
|
||||
rd io.Reader
|
||||
}
|
||||
|
||||
func (r *writeToOnly) Read(p []byte) (n int, err error) {
|
||||
return 0, fmt.Errorf("should have called WriteTo instead")
|
||||
}
|
||||
|
||||
func (r *writeToOnly) WriteTo(w io.Writer) (int64, error) {
|
||||
return io.Copy(w, r.rd)
|
||||
}
|
||||
|
||||
type onlyLoadWithWriteToBackend struct {
|
||||
restic.Backend
|
||||
}
|
||||
|
||||
func (be *onlyLoadWithWriteToBackend) Load(ctx context.Context, h restic.Handle,
|
||||
length int, offset int64, fn func(rd io.Reader) error) error {
|
||||
|
||||
return be.Backend.Load(ctx, h, length, offset, func(rd io.Reader) error {
|
||||
return fn(&writeToOnly{rd: rd})
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackendLoadWriteTo(t *testing.T) {
|
||||
env, cleanup := withTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
// setup backend which only works if it's WriteTo method is correctly propagated upwards
|
||||
env.gopts.backendInnerTestHook = func(r restic.Backend) (restic.Backend, error) {
|
||||
return &onlyLoadWithWriteToBackend{Backend: r}, nil
|
||||
}
|
||||
|
||||
testSetupBackupData(t, env)
|
||||
|
||||
// add some data, but make sure that it isn't cached during upload
|
||||
opts := BackupOptions{}
|
||||
env.gopts.NoCache = true
|
||||
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9")}, opts, env.gopts)
|
||||
|
||||
// loading snapshots must still work
|
||||
env.gopts.NoCache = false
|
||||
firstSnapshot := testRunList(t, "snapshots", env.gopts)
|
||||
rtest.Assert(t, len(firstSnapshot) == 1,
|
||||
"expected one snapshot, got %v", firstSnapshot)
|
||||
|
||||
// test readData using the hashing.Reader
|
||||
testRunCheck(t, env.gopts)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue