github.com/ncw/rclone@v1.48.1-0.20190724201158-a35aa1360e3e/fs/chunkedreader/chunkedreader_test.go (about) 1 package chunkedreader 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "math/rand" 8 "testing" 9 10 "github.com/ncw/rclone/fstest/mockobject" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestChunkedReader(t *testing.T) { 16 content := makeContent(t, 1024) 17 18 for _, mode := range mockobject.SeekModes { 19 t.Run(mode.String(), testRead(content, mode)) 20 } 21 } 22 23 func testRead(content []byte, mode mockobject.SeekMode) func(*testing.T) { 24 return func(t *testing.T) { 25 chunkSizes := []int64{-1, 0, 1, 15, 16, 17, 1023, 1024, 1025, 2000} 26 offsets := []int64{0, 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 27 63, 64, 65, 511, 512, 513, 1023, 1024, 1025} 28 limits := []int64{-1, 0, 1, 31, 32, 33, 1023, 1024, 1025} 29 cl := int64(len(content)) 30 bl := 32 31 buf := make([]byte, bl) 32 33 o := mockobject.New("test.bin").WithContent(content, mode) 34 for ics, cs := range chunkSizes { 35 for icsMax, csMax := range chunkSizes { 36 // skip tests where chunkSize is much bigger than maxChunkSize 37 if ics > icsMax+1 { 38 continue 39 } 40 41 t.Run(fmt.Sprintf("Chunksize_%d_%d", cs, csMax), func(t *testing.T) { 42 cr := New(context.Background(), o, cs, csMax) 43 44 for _, offset := range offsets { 45 for _, limit := range limits { 46 what := fmt.Sprintf("offset %d, limit %d", offset, limit) 47 48 p, err := cr.RangeSeek(context.Background(), offset, io.SeekStart, limit) 49 if offset >= cl { 50 require.Error(t, err, what) 51 return 52 } 53 require.NoError(t, err, what) 54 require.Equal(t, offset, p, what) 55 56 n, err := cr.Read(buf) 57 end := offset + int64(bl) 58 if end > cl { 59 end = cl 60 } 61 l := int(end - offset) 62 if l < bl { 63 require.Equal(t, io.EOF, err, what) 64 } else { 65 require.NoError(t, err, what) 66 } 67 require.Equal(t, l, n, what) 68 require.Equal(t, content[offset:end], buf[:n], what) 69 } 70 } 71 }) 72 } 73 } 74 } 75 } 76 77 func TestErrorAfterClose(t *testing.T) { 78 content := makeContent(t, 1024) 79 o := mockobject.New("test.bin").WithContent(content, mockobject.SeekModeNone) 80 81 // Close 82 cr := New(context.Background(), o, 0, 0) 83 require.NoError(t, cr.Close()) 84 require.Error(t, cr.Close()) 85 86 // Read 87 cr = New(context.Background(), o, 0, 0) 88 require.NoError(t, cr.Close()) 89 var buf [1]byte 90 _, err := cr.Read(buf[:]) 91 require.Error(t, err) 92 93 // Seek 94 cr = New(context.Background(), o, 0, 0) 95 require.NoError(t, cr.Close()) 96 _, err = cr.Seek(1, io.SeekCurrent) 97 require.Error(t, err) 98 99 // RangeSeek 100 cr = New(context.Background(), o, 0, 0) 101 require.NoError(t, cr.Close()) 102 _, err = cr.RangeSeek(context.Background(), 1, io.SeekCurrent, 0) 103 require.Error(t, err) 104 } 105 106 func makeContent(t *testing.T, size int) []byte { 107 content := make([]byte, size) 108 r := rand.New(rand.NewSource(42)) 109 _, err := io.ReadFull(r, content) 110 assert.NoError(t, err) 111 return content 112 }