mirror of
https://github.com/rclone/rclone.git
synced 2024-11-25 09:41:44 +08:00
lib/readers: factor ErrorReader from multiple sources
This commit is contained in:
parent
36d2c46bcf
commit
cd3c699f28
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
11
lib/readers/error.go
Normal 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
18
lib/readers/error_test.go
Normal 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)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user