lib/readers: factor ErrorReader from multiple sources

This commit is contained in:
Nick Craig-Wood 2020-03-27 11:12:21 +00:00
parent 36d2c46bcf
commit cd3c699f28
6 changed files with 39 additions and 43 deletions

View File

@ -12,6 +12,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/rclone/rclone/backend/crypt/pkcs7" "github.com/rclone/rclone/backend/crypt/pkcs7"
"github.com/rclone/rclone/lib/readers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -784,7 +785,7 @@ func TestNewEncrypterErrUnexpectedEOF(t *testing.T) {
c, err := newCipher(NameEncryptionStandard, "", "", true) c, err := newCipher(NameEncryptionStandard, "", "", true)
assert.NoError(t, err) assert.NoError(t, err)
in := &errorReader{io.ErrUnexpectedEOF} in := &readers.ErrorReader{Err: io.ErrUnexpectedEOF}
fh, err := c.newEncrypter(in, nil) fh, err := c.newEncrypter(in, nil)
assert.NoError(t, err) assert.NoError(t, err)
@ -793,14 +794,6 @@ func TestNewEncrypterErrUnexpectedEOF(t *testing.T) {
assert.Equal(t, int64(32), n) assert.Equal(t, int64(32), n)
} }
type errorReader struct {
err error
}
func (er errorReader) Read(p []byte) (n int, err error) {
return 0, er.err
}
type closeDetector struct { type closeDetector struct {
io.Reader io.Reader
closed int closed int
@ -838,7 +831,7 @@ func TestNewDecrypter(t *testing.T) {
assert.Equal(t, 1, cd.closed) assert.Equal(t, 1, cd.closed)
} }
er := &errorReader{errors.New("potato")} er := &readers.ErrorReader{Err: errors.New("potato")}
cd = newCloseDetector(er) cd = newCloseDetector(er)
fh, err = c.newDecrypter(cd) fh, err = c.newDecrypter(cd)
assert.Nil(t, fh) assert.Nil(t, fh)
@ -864,7 +857,7 @@ func TestNewDecrypterErrUnexpectedEOF(t *testing.T) {
c, err := newCipher(NameEncryptionStandard, "", "", true) c, err := newCipher(NameEncryptionStandard, "", "", true)
assert.NoError(t, err) assert.NoError(t, err)
in2 := &errorReader{io.ErrUnexpectedEOF} in2 := &readers.ErrorReader{Err: io.ErrUnexpectedEOF}
in1 := bytes.NewBuffer(file16) in1 := bytes.NewBuffer(file16)
in := ioutil.NopCloser(io.MultiReader(in1, in2)) in := ioutil.NopCloser(io.MultiReader(in1, in2))
@ -1118,7 +1111,7 @@ func TestDecrypterRead(t *testing.T) {
// Test producing an error on the file on Read the underlying file // Test producing an error on the file on Read the underlying file
in1 := bytes.NewBuffer(file1) in1 := bytes.NewBuffer(file1)
in2 := &errorReader{errors.New("potato")} in2 := &readers.ErrorReader{Err: errors.New("potato")}
in := io.MultiReader(in1, in2) in := io.MultiReader(in1, in2)
cd := newCloseDetector(in) cd := newCloseDetector(in)
fh, err := c.newDecrypter(cd) fh, err := c.newDecrypter(cd)

View File

@ -45,6 +45,7 @@ import (
"github.com/rclone/rclone/fs/operations" "github.com/rclone/rclone/fs/operations"
"github.com/rclone/rclone/fstest" "github.com/rclone/rclone/fstest"
"github.com/rclone/rclone/lib/random" "github.com/rclone/rclone/lib/random"
"github.com/rclone/rclone/lib/readers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -1156,14 +1157,6 @@ func TestOverlapping(t *testing.T) {
} }
} }
type errorReader struct {
err error
}
func (er errorReader) Read(p []byte) (n int, err error) {
return 0, er.err
}
func TestCheckEqualReaders(t *testing.T) { func TestCheckEqualReaders(t *testing.T) {
b65a := make([]byte, 65*1024) b65a := make([]byte, 65*1024)
b65b := make([]byte, 65*1024) b65b := make([]byte, 65*1024)
@ -1189,7 +1182,7 @@ func TestCheckEqualReaders(t *testing.T) {
myErr := errors.New("sentinel") myErr := errors.New("sentinel")
wrap := func(b []byte) io.Reader { wrap := func(b []byte) io.Reader {
r := bytes.NewBuffer(b) r := bytes.NewBuffer(b)
e := errorReader{myErr} e := readers.ErrorReader{Err: myErr}
return io.MultiReader(r, e) return io.MultiReader(r, e)
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fs/hash"
"github.com/rclone/rclone/fstest/mockobject" "github.com/rclone/rclone/fstest/mockobject"
"github.com/rclone/rclone/lib/readers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -44,23 +45,13 @@ func (o *reOpenTestObject) Open(ctx context.Context, options ...fs.OpenOption) (
return nil, errorTestError return nil, errorTestError
} }
// Read N bytes then an error // Read N bytes then an error
r := io.MultiReader(&io.LimitedReader{R: rc, N: N}, errorReader{errorTestError}) r := io.MultiReader(&io.LimitedReader{R: rc, N: N}, readers.ErrorReader{Err: errorTestError})
// Wrap with Close in a new readCloser // Wrap with Close in a new readCloser
rc = readCloser{Reader: r, Closer: rc} rc = readCloser{Reader: r, Closer: rc}
} }
return rc, nil return rc, nil
} }
// Return an error only
type errorReader struct {
err error
}
// Read returning an error
func (er errorReader) Read(p []byte) (n int, err error) {
return 0, er.err
}
func TestReOpen(t *testing.T) { func TestReOpen(t *testing.T) {
for testIndex, testName := range []string{"Seek", "Range"} { for testIndex, testName := range []string{"Seek", "Range"} {
t.Run(testName, func(t *testing.T) { t.Run(testName, func(t *testing.T) {

View File

@ -225,16 +225,6 @@ func TestPutLarge(ctx context.Context, t *testing.T, f fs.Fs, file *fstest.Item)
require.NoError(t, obj.Remove(ctx)) require.NoError(t, obj.Remove(ctx))
} }
// errorReader just returns an error on Read
type errorReader struct {
err error
}
// Read returns an error immediately
func (er errorReader) Read(p []byte) (n int, err error) {
return 0, er.err
}
// read the contents of an object as a string // read the contents of an object as a string
func readObject(ctx context.Context, t *testing.T, obj fs.Object, limit int64, options ...fs.OpenOption) string { func readObject(ctx context.Context, t *testing.T, obj fs.Object, limit int64, options ...fs.OpenOption) string {
what := fmt.Sprintf("readObject(%q) limit=%d, options=%+v", obj, limit, options) what := fmt.Sprintf("readObject(%q) limit=%d, options=%+v", obj, limit, options)
@ -637,7 +627,7 @@ func Run(t *testing.T, opt *Opt) {
// Read N bytes then produce an error // Read N bytes then produce an error
contents := random.String(int(N)) contents := random.String(int(N))
buf := bytes.NewBufferString(contents) buf := bytes.NewBufferString(contents)
er := &errorReader{errors.New("potato")} er := &readers.ErrorReader{Err: errors.New("potato")}
in := io.MultiReader(buf, er) in := io.MultiReader(buf, er)
obji := object.NewStaticObjectInfo(file2.Path, file2.ModTime, 2*N, true, nil, nil) obji := object.NewStaticObjectInfo(file2.Path, file2.ModTime, 2*N, true, nil, nil)

11
lib/readers/error.go Normal file
View File

@ -0,0 +1,11 @@
package readers
// ErrorReader wraps an error to return on Read
type ErrorReader struct {
Err error
}
// Read always returns the error
func (er ErrorReader) Read(p []byte) (n int, err error) {
return 0, er.Err
}

18
lib/readers/error_test.go Normal file
View File

@ -0,0 +1,18 @@
package readers
import (
"testing"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestErrorReader(t *testing.T) {
errRead := errors.New("boom")
r := ErrorReader{errRead}
buf := make([]byte, 16)
n, err := r.Read(buf)
assert.Equal(t, errRead, err)
assert.Equal(t, 0, n)
}