2
2
mirror of https://github.com/octoleo/restic.git synced 2024-12-22 10:58:55 +00:00

repository: properly return invalid data error in LoadUnpacked

The retry backend does not return the original error, if its execution
is interrupted by canceling the context. Thus, we have to manually
ensure that the invalid data error gets returned.

Additionally, use the retry backend for some of the repository tests, as
this is the configuration which will be used by restic.
This commit is contained in:
Michael Eischer 2023-01-14 16:06:35 +01:00
parent 6d9675c323
commit 1adf28a2b5
2 changed files with 11 additions and 0 deletions

View File

@ -188,6 +188,7 @@ func (r *Repository) LoadUnpacked(ctx context.Context, t restic.FileType, id res
h := restic.Handle{Type: t, Name: id.String()} h := restic.Handle{Type: t, Name: id.String()}
retriedInvalidData := false retriedInvalidData := false
var dataErr error
err := r.be.Load(ctx, h, 0, 0, func(rd io.Reader) error { err := r.be.Load(ctx, h, 0, 0, func(rd io.Reader) error {
// make sure this call is idempotent, in case an error occurs // make sure this call is idempotent, in case an error occurs
wr := bytes.NewBuffer(buf[:0]) wr := bytes.NewBuffer(buf[:0])
@ -202,6 +203,9 @@ func (r *Repository) LoadUnpacked(ctx context.Context, t restic.FileType, id res
if !retriedInvalidData { if !retriedInvalidData {
retriedInvalidData = true retriedInvalidData = true
} else { } else {
// with a canceled context there is not guarantee which error will
// be returned by `be.Load`.
dataErr = fmt.Errorf("load(%v): %w", h, restic.ErrInvalidData)
cancel() cancel()
} }
return restic.ErrInvalidData return restic.ErrInvalidData
@ -210,6 +214,9 @@ func (r *Repository) LoadUnpacked(ctx context.Context, t restic.FileType, id res
return nil return nil
}) })
if dataErr != nil {
return nil, dataErr
}
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -8,6 +8,7 @@ import (
"github.com/restic/restic/internal/backend/local" "github.com/restic/restic/internal/backend/local"
"github.com/restic/restic/internal/backend/mem" "github.com/restic/restic/internal/backend/mem"
"github.com/restic/restic/internal/backend/retry"
"github.com/restic/restic/internal/crypto" "github.com/restic/restic/internal/crypto"
"github.com/restic/restic/internal/restic" "github.com/restic/restic/internal/restic"
"github.com/restic/restic/internal/test" "github.com/restic/restic/internal/test"
@ -97,11 +98,14 @@ func TestRepositoryWithVersion(t testing.TB, version uint) restic.Repository {
// TestOpenLocal opens a local repository. // TestOpenLocal opens a local repository.
func TestOpenLocal(t testing.TB, dir string) (r restic.Repository) { func TestOpenLocal(t testing.TB, dir string) (r restic.Repository) {
var be restic.Backend
be, err := local.Open(context.TODO(), local.Config{Path: dir, Connections: 2}) be, err := local.Open(context.TODO(), local.Config{Path: dir, Connections: 2})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
be = retry.New(be, 3, nil, nil)
repo, err := New(be, Options{}) repo, err := New(be, Options{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)