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
|
stdout io.Writer
|
||||||
stderr io.Writer
|
stderr io.Writer
|
||||||
|
|
||||||
backendTestHook backendWrapper
|
backendTestHook, backendInnerTestHook backendWrapper
|
||||||
|
|
||||||
// verbosity is set as follows:
|
// verbosity is set as follows:
|
||||||
// 0 means: don't print any messages except errors, this is used when --quiet is specified
|
// 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 {
|
switch loc.Scheme {
|
||||||
case "local":
|
case "local":
|
||||||
be, err = local.Open(globalOptions.ctx, cfg.(local.Config))
|
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":
|
case "sftp":
|
||||||
be, err = sftp.Open(globalOptions.ctx, cfg.(sftp.Config))
|
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":
|
case "s3":
|
||||||
be, err = s3.Open(globalOptions.ctx, cfg.(s3.Config), rt)
|
be, err = s3.Open(globalOptions.ctx, cfg.(s3.Config), rt)
|
||||||
case "gs":
|
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)
|
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
|
// check if config is there
|
||||||
fi, err := be.Stat(globalOptions.ctx, restic.Handle{Type: restic.ConfigFile})
|
fi, err := be.Stat(globalOptions.ctx, restic.Handle{Type: restic.ConfigFile})
|
||||||
if err != nil {
|
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)
|
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