github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/lib/readers/repeatable_test.go (about) 1 package readers 2 3 import ( 4 "bytes" 5 "io" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 ) 11 12 func TestRepeatableReader(t *testing.T) { 13 var dst []byte 14 var n int 15 var pos int64 16 var err error 17 18 b := []byte("Testbuffer") 19 buf := bytes.NewBuffer(b) 20 r := NewRepeatableReader(buf) 21 22 dst = make([]byte, 100) 23 n, err = r.Read(dst) 24 assert.Nil(t, err) 25 assert.Equal(t, 10, n) 26 require.Equal(t, b, dst[0:10]) 27 28 // Test read EOF 29 n, err = r.Read(dst) 30 assert.Equal(t, io.EOF, err) 31 assert.Equal(t, 0, n) 32 33 // Test Seek Back to start 34 dst = make([]byte, 10) 35 pos, err = r.Seek(0, io.SeekStart) 36 assert.Nil(t, err) 37 require.Equal(t, 0, int(pos)) 38 39 n, err = r.Read(dst) 40 assert.Nil(t, err) 41 assert.Equal(t, 10, n) 42 require.Equal(t, b, dst) 43 44 // Test partial read 45 buf = bytes.NewBuffer(b) 46 r = NewRepeatableReader(buf) 47 dst = make([]byte, 5) 48 n, err = r.Read(dst) 49 assert.Nil(t, err) 50 assert.Equal(t, 5, n) 51 require.Equal(t, b[0:5], dst) 52 n, err = r.Read(dst) 53 assert.Nil(t, err) 54 assert.Equal(t, 5, n) 55 require.Equal(t, b[5:], dst) 56 57 // Test Seek 58 buf = bytes.NewBuffer(b) 59 r = NewRepeatableReader(buf) 60 // Should not allow seek past cache index 61 pos, err = r.Seek(5, io.SeekCurrent) 62 assert.NotNil(t, err) 63 assert.Equal(t, "fs.RepeatableReader.Seek: offset is unavailable", err.Error()) 64 assert.Equal(t, 0, int(pos)) 65 66 // Should not allow seek to negative position start 67 pos, err = r.Seek(-1, io.SeekCurrent) 68 assert.NotNil(t, err) 69 assert.Equal(t, "fs.RepeatableReader.Seek: negative position", err.Error()) 70 assert.Equal(t, 0, int(pos)) 71 72 // Should not allow seek with invalid whence 73 pos, err = r.Seek(0, 3) 74 assert.NotNil(t, err) 75 assert.Equal(t, "fs.RepeatableReader.Seek: invalid whence", err.Error()) 76 assert.Equal(t, 0, int(pos)) 77 78 // Should seek from index with io.SeekCurrent(1) whence 79 dst = make([]byte, 5) 80 _, _ = r.Read(dst) 81 pos, err = r.Seek(-3, io.SeekCurrent) 82 assert.Nil(t, err) 83 require.Equal(t, 2, int(pos)) 84 pos, err = r.Seek(1, io.SeekCurrent) 85 assert.Nil(t, err) 86 require.Equal(t, 3, int(pos)) 87 88 // Should seek from cache end with io.SeekEnd(2) whence 89 pos, err = r.Seek(-3, io.SeekEnd) 90 assert.Nil(t, err) 91 require.Equal(t, 2, int(pos)) 92 93 // Should read from seek position and past it 94 dst = make([]byte, 5) 95 n, err = io.ReadFull(r, dst) 96 assert.Nil(t, err) 97 assert.Equal(t, 5, n) 98 assert.Equal(t, b[2:7], dst) 99 100 }