github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/vfs/read_test.go (about) 1 package vfs 2 3 import ( 4 "context" 5 "io" 6 "os" 7 "testing" 8 9 "github.com/rclone/rclone/fstest" 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 ) 13 14 // Open a file for write 15 func readHandleCreate(t *testing.T, r *fstest.Run) (*VFS, *ReadFileHandle) { 16 vfs := New(r.Fremote, nil) 17 18 file1 := r.WriteObject(context.Background(), "dir/file1", "0123456789abcdef", t1) 19 fstest.CheckItems(t, r.Fremote, file1) 20 21 h, err := vfs.OpenFile("dir/file1", os.O_RDONLY, 0777) 22 require.NoError(t, err) 23 fh, ok := h.(*ReadFileHandle) 24 require.True(t, ok) 25 26 return vfs, fh 27 } 28 29 // read data from the string 30 func readString(t *testing.T, fh *ReadFileHandle, n int) string { 31 buf := make([]byte, n) 32 n, err := fh.Read(buf) 33 if err != io.EOF { 34 assert.NoError(t, err) 35 } 36 return string(buf[:n]) 37 } 38 39 func TestReadFileHandleMethods(t *testing.T) { 40 r := fstest.NewRun(t) 41 defer r.Finalise() 42 _, fh := readHandleCreate(t, r) 43 44 // String 45 assert.Equal(t, "dir/file1 (r)", fh.String()) 46 assert.Equal(t, "<nil *ReadFileHandle>", (*ReadFileHandle)(nil).String()) 47 assert.Equal(t, "<nil *ReadFileHandle.file>", new(ReadFileHandle).String()) 48 49 // Node 50 node := fh.Node() 51 assert.Equal(t, "file1", node.Name()) 52 53 // Size 54 assert.Equal(t, int64(16), fh.Size()) 55 56 // Read 1 57 assert.Equal(t, "0", readString(t, fh, 1)) 58 59 // Read remainder 60 assert.Equal(t, "123456789abcdef", readString(t, fh, 256)) 61 62 // Read EOF 63 buf := make([]byte, 16) 64 _, err := fh.Read(buf) 65 assert.Equal(t, io.EOF, err) 66 67 // Stat 68 var fi os.FileInfo 69 fi, err = fh.Stat() 70 assert.NoError(t, err) 71 assert.Equal(t, int64(16), fi.Size()) 72 assert.Equal(t, "file1", fi.Name()) 73 74 // Close 75 assert.False(t, fh.closed) 76 assert.Equal(t, nil, fh.Close()) 77 assert.True(t, fh.closed) 78 79 // Close again 80 assert.Equal(t, ECLOSED, fh.Close()) 81 } 82 83 func TestReadFileHandleSeek(t *testing.T) { 84 r := fstest.NewRun(t) 85 defer r.Finalise() 86 _, fh := readHandleCreate(t, r) 87 88 assert.Equal(t, "0", readString(t, fh, 1)) 89 90 // 0 means relative to the origin of the file, 91 n, err := fh.Seek(5, io.SeekStart) 92 assert.NoError(t, err) 93 assert.Equal(t, int64(5), n) 94 assert.Equal(t, "5", readString(t, fh, 1)) 95 96 // 1 means relative to the current offset 97 n, err = fh.Seek(-3, io.SeekCurrent) 98 assert.NoError(t, err) 99 assert.Equal(t, int64(3), n) 100 assert.Equal(t, "3", readString(t, fh, 1)) 101 102 // 2 means relative to the end. 103 n, err = fh.Seek(-3, io.SeekEnd) 104 assert.NoError(t, err) 105 assert.Equal(t, int64(13), n) 106 assert.Equal(t, "d", readString(t, fh, 1)) 107 108 // Seek off the end 109 _, err = fh.Seek(100, io.SeekStart) 110 assert.NoError(t, err) 111 112 // Get the error on read 113 buf := make([]byte, 16) 114 l, err := fh.Read(buf) 115 assert.Equal(t, io.EOF, err) 116 assert.Equal(t, 0, l) 117 118 // Check if noSeek is set we get an error 119 fh.noSeek = true 120 _, err = fh.Seek(0, io.SeekStart) 121 assert.Equal(t, ESPIPE, err) 122 123 // Close 124 assert.Equal(t, nil, fh.Close()) 125 } 126 127 func TestReadFileHandleReadAt(t *testing.T) { 128 r := fstest.NewRun(t) 129 defer r.Finalise() 130 _, fh := readHandleCreate(t, r) 131 132 // read from start 133 buf := make([]byte, 1) 134 n, err := fh.ReadAt(buf, 0) 135 require.NoError(t, err) 136 assert.Equal(t, 1, n) 137 assert.Equal(t, "0", string(buf[:n])) 138 139 // seek forwards 140 n, err = fh.ReadAt(buf, 5) 141 require.NoError(t, err) 142 assert.Equal(t, 1, n) 143 assert.Equal(t, "5", string(buf[:n])) 144 145 // seek backwards 146 n, err = fh.ReadAt(buf, 1) 147 require.NoError(t, err) 148 assert.Equal(t, 1, n) 149 assert.Equal(t, "1", string(buf[:n])) 150 151 // read exactly to the end 152 buf = make([]byte, 6) 153 n, err = fh.ReadAt(buf, 10) 154 require.NoError(t, err) 155 assert.Equal(t, 6, n) 156 assert.Equal(t, "abcdef", string(buf[:n])) 157 158 // read off the end 159 buf = make([]byte, 256) 160 n, err = fh.ReadAt(buf, 10) 161 assert.Equal(t, io.EOF, err) 162 assert.Equal(t, 6, n) 163 assert.Equal(t, "abcdef", string(buf[:n])) 164 165 // read starting off the end 166 n, err = fh.ReadAt(buf, 100) 167 assert.Equal(t, io.EOF, err) 168 assert.Equal(t, 0, n) 169 170 // check noSeek gives an error 171 fh.noSeek = true 172 _, err = fh.ReadAt(buf, 100) 173 assert.Equal(t, ESPIPE, err) 174 175 // Properly close the file 176 assert.NoError(t, fh.Close()) 177 178 // check reading on closed file 179 fh.noSeek = true 180 _, err = fh.ReadAt(buf, 100) 181 assert.Equal(t, ECLOSED, err) 182 } 183 184 func TestReadFileHandleFlush(t *testing.T) { 185 r := fstest.NewRun(t) 186 defer r.Finalise() 187 _, fh := readHandleCreate(t, r) 188 189 // Check Flush does nothing if read not called 190 err := fh.Flush() 191 assert.NoError(t, err) 192 assert.False(t, fh.closed) 193 194 // Read data 195 buf := make([]byte, 256) 196 n, err := fh.Read(buf) 197 assert.Equal(t, io.EOF, err) 198 assert.Equal(t, 16, n) 199 200 // Check Flush does nothing if read called 201 err = fh.Flush() 202 assert.NoError(t, err) 203 assert.False(t, fh.closed) 204 205 // Check flush does nothing if called again 206 err = fh.Flush() 207 assert.NoError(t, err) 208 assert.False(t, fh.closed) 209 210 // Properly close the file 211 assert.NoError(t, fh.Close()) 212 } 213 214 func TestReadFileHandleRelease(t *testing.T) { 215 r := fstest.NewRun(t) 216 defer r.Finalise() 217 _, fh := readHandleCreate(t, r) 218 219 // Check Release does nothing if file not read from 220 err := fh.Release() 221 assert.NoError(t, err) 222 assert.False(t, fh.closed) 223 224 // Read data 225 buf := make([]byte, 256) 226 n, err := fh.Read(buf) 227 assert.Equal(t, io.EOF, err) 228 assert.Equal(t, 16, n) 229 230 // Check Release closes file 231 err = fh.Release() 232 assert.NoError(t, err) 233 assert.True(t, fh.closed) 234 235 // Check Release does nothing if called again 236 err = fh.Release() 237 assert.NoError(t, err) 238 assert.True(t, fh.closed) 239 }