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  }