forked from TrueCloudLab/rclone
readers: add NewPatternReader
This commit is contained in:
parent
98e2746e31
commit
84289d1d69
3 changed files with 62 additions and 28 deletions
|
@ -4,50 +4,25 @@ import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ncw/rclone/lib/readers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A test reader to return a test pattern of size
|
|
||||||
type testReader struct {
|
|
||||||
size int64
|
|
||||||
c byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reader is the interface that wraps the basic Read method.
|
|
||||||
func (r *testReader) Read(p []byte) (n int, err error) {
|
|
||||||
for i := range p {
|
|
||||||
if r.size <= 0 {
|
|
||||||
return n, io.EOF
|
|
||||||
}
|
|
||||||
p[i] = r.c
|
|
||||||
r.c = (r.c + 1) % 253
|
|
||||||
r.size--
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadMD5(t *testing.T) {
|
func TestReadMD5(t *testing.T) {
|
||||||
// smoke test the reader
|
|
||||||
b, err := ioutil.ReadAll(&testReader{size: 10})
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, b)
|
|
||||||
|
|
||||||
// Check readMD5 for different size and threshold
|
// Check readMD5 for different size and threshold
|
||||||
for _, size := range []int64{0, 1024, 10 * 1024, 100 * 1024} {
|
for _, size := range []int64{0, 1024, 10 * 1024, 100 * 1024} {
|
||||||
t.Run(fmt.Sprintf("%d", size), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%d", size), func(t *testing.T) {
|
||||||
hasher := md5.New()
|
hasher := md5.New()
|
||||||
n, err := io.Copy(hasher, &testReader{size: size})
|
n, err := io.Copy(hasher, readers.NewPatternReader(size))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, n, size)
|
assert.Equal(t, n, size)
|
||||||
wantMD5 := fmt.Sprintf("%x", hasher.Sum(nil))
|
wantMD5 := fmt.Sprintf("%x", hasher.Sum(nil))
|
||||||
for _, threshold := range []int64{512, 1024, 10 * 1024, 20 * 1024} {
|
for _, threshold := range []int64{512, 1024, 10 * 1024, 20 * 1024} {
|
||||||
t.Run(fmt.Sprintf("%d", threshold), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%d", threshold), func(t *testing.T) {
|
||||||
in := &testReader{size: size}
|
in := readers.NewPatternReader(size)
|
||||||
gotMD5, out, cleanup, err := readMD5(in, size, threshold)
|
gotMD5, out, cleanup, err := readMD5(in, size, threshold)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
29
lib/readers/pattern_reader.go
Normal file
29
lib/readers/pattern_reader.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package readers
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
// NewPatternReader creates a reader, that returns a deterministic byte pattern.
|
||||||
|
// After length bytes are read
|
||||||
|
func NewPatternReader(length int64) io.Reader {
|
||||||
|
return &patternReader{
|
||||||
|
length: length,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type patternReader struct {
|
||||||
|
length int64
|
||||||
|
c byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *patternReader) Read(p []byte) (n int, err error) {
|
||||||
|
for i := range p {
|
||||||
|
if r.length <= 0 {
|
||||||
|
return n, io.EOF
|
||||||
|
}
|
||||||
|
p[i] = r.c
|
||||||
|
r.c = (r.c + 1) % 253
|
||||||
|
r.length--
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
30
lib/readers/pattern_reader_test.go
Normal file
30
lib/readers/pattern_reader_test.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package readers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPatternReader(t *testing.T) {
|
||||||
|
b2 := make([]byte, 1)
|
||||||
|
|
||||||
|
r := NewPatternReader(0)
|
||||||
|
b, err := ioutil.ReadAll(r)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, []byte{}, b)
|
||||||
|
n, err := r.Read(b2)
|
||||||
|
require.Equal(t, io.EOF, err)
|
||||||
|
require.Equal(t, 0, n)
|
||||||
|
|
||||||
|
r = NewPatternReader(10)
|
||||||
|
b, err = ioutil.ReadAll(r)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, b)
|
||||||
|
n, err = r.Read(b2)
|
||||||
|
require.Equal(t, io.EOF, err)
|
||||||
|
require.Equal(t, 0, n)
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue