github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/vfs/read_write_test.go (about)

     1  package vfs
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"os"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/pkg/errors"
    13  	"github.com/rclone/rclone/fs"
    14  	"github.com/rclone/rclone/fs/operations"
    15  	"github.com/rclone/rclone/fstest"
    16  	"github.com/rclone/rclone/vfs/vfscommon"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func cleanup(t *testing.T, r *fstest.Run, vfs *VFS) {
    22  	assert.NoError(t, vfs.CleanUp())
    23  	vfs.Shutdown()
    24  	r.Finalise()
    25  }
    26  
    27  // Create a file and open it with the flags passed in
    28  func rwHandleCreateFlags(t *testing.T, r *fstest.Run, create bool, filename string, flags int) (*VFS, *RWFileHandle) {
    29  	opt := vfscommon.DefaultOpt
    30  	opt.CacheMode = vfscommon.CacheModeFull
    31  	vfs := New(r.Fremote, &opt)
    32  
    33  	if create {
    34  		file1 := r.WriteObject(context.Background(), filename, "0123456789abcdef", t1)
    35  		fstest.CheckItems(t, r.Fremote, file1)
    36  	}
    37  
    38  	h, err := vfs.OpenFile(filename, flags, 0777)
    39  	require.NoError(t, err)
    40  	fh, ok := h.(*RWFileHandle)
    41  	require.True(t, ok)
    42  
    43  	return vfs, fh
    44  }
    45  
    46  // Open a file for read
    47  func rwHandleCreateReadOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) {
    48  	return rwHandleCreateFlags(t, r, true, "dir/file1", os.O_RDONLY)
    49  }
    50  
    51  // Open a file for write
    52  func rwHandleCreateWriteOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) {
    53  	return rwHandleCreateFlags(t, r, false, "file1", os.O_WRONLY|os.O_CREATE)
    54  }
    55  
    56  // read data from the string
    57  func rwReadString(t *testing.T, fh *RWFileHandle, n int) string {
    58  	buf := make([]byte, n)
    59  	n, err := fh.Read(buf)
    60  	if err != io.EOF {
    61  		assert.NoError(t, err)
    62  	}
    63  	return string(buf[:n])
    64  }
    65  
    66  func TestRWFileHandleMethodsRead(t *testing.T) {
    67  	r := fstest.NewRun(t)
    68  	vfs, fh := rwHandleCreateReadOnly(t, r)
    69  	defer cleanup(t, r, vfs)
    70  
    71  	// String
    72  	assert.Equal(t, "dir/file1 (rw)", fh.String())
    73  	assert.Equal(t, "<nil *RWFileHandle>", (*RWFileHandle)(nil).String())
    74  	assert.Equal(t, "<nil *RWFileHandle.file>", new(RWFileHandle).String())
    75  
    76  	// Node
    77  	node := fh.Node()
    78  	assert.Equal(t, "file1", node.Name())
    79  
    80  	// Size
    81  	assert.Equal(t, int64(16), fh.Size())
    82  
    83  	// No opens yet
    84  	assert.Equal(t, 0, fh.file.rwOpens())
    85  
    86  	// Read 1
    87  	assert.Equal(t, "0", rwReadString(t, fh, 1))
    88  
    89  	// Open after the read
    90  	assert.Equal(t, 1, fh.file.rwOpens())
    91  
    92  	// Read remainder
    93  	assert.Equal(t, "123456789abcdef", rwReadString(t, fh, 256))
    94  
    95  	// Read EOF
    96  	buf := make([]byte, 16)
    97  	_, err := fh.Read(buf)
    98  	assert.Equal(t, io.EOF, err)
    99  
   100  	// Sync
   101  	err = fh.Sync()
   102  	assert.NoError(t, err)
   103  
   104  	// Stat
   105  	var fi os.FileInfo
   106  	fi, err = fh.Stat()
   107  	assert.NoError(t, err)
   108  	assert.Equal(t, int64(16), fi.Size())
   109  	assert.Equal(t, "file1", fi.Name())
   110  
   111  	// Close
   112  	assert.False(t, fh.closed)
   113  	assert.Equal(t, nil, fh.Close())
   114  	assert.True(t, fh.closed)
   115  
   116  	// No opens again
   117  	assert.Equal(t, 0, fh.file.rwOpens())
   118  
   119  	// Close again
   120  	assert.Equal(t, ECLOSED, fh.Close())
   121  }
   122  
   123  func TestRWFileHandleSeek(t *testing.T) {
   124  	r := fstest.NewRun(t)
   125  	vfs, fh := rwHandleCreateReadOnly(t, r)
   126  	defer cleanup(t, r, vfs)
   127  
   128  	assert.Equal(t, fh.opened, false)
   129  
   130  	// Check null seeks don't open the file
   131  	n, err := fh.Seek(0, io.SeekStart)
   132  	assert.NoError(t, err)
   133  	assert.Equal(t, int64(0), n)
   134  	assert.Equal(t, fh.opened, false)
   135  	n, err = fh.Seek(0, io.SeekCurrent)
   136  	assert.NoError(t, err)
   137  	assert.Equal(t, int64(0), n)
   138  	assert.Equal(t, fh.opened, false)
   139  
   140  	assert.Equal(t, "0", rwReadString(t, fh, 1))
   141  
   142  	// 0 means relative to the origin of the file,
   143  	n, err = fh.Seek(5, io.SeekStart)
   144  	assert.NoError(t, err)
   145  	assert.Equal(t, int64(5), n)
   146  	assert.Equal(t, "5", rwReadString(t, fh, 1))
   147  
   148  	// 1 means relative to the current offset
   149  	n, err = fh.Seek(-3, io.SeekCurrent)
   150  	assert.NoError(t, err)
   151  	assert.Equal(t, int64(3), n)
   152  	assert.Equal(t, "3", rwReadString(t, fh, 1))
   153  
   154  	// 2 means relative to the end.
   155  	n, err = fh.Seek(-3, io.SeekEnd)
   156  	assert.NoError(t, err)
   157  	assert.Equal(t, int64(13), n)
   158  	assert.Equal(t, "d", rwReadString(t, fh, 1))
   159  
   160  	// Seek off the end
   161  	_, err = fh.Seek(100, io.SeekStart)
   162  	assert.NoError(t, err)
   163  
   164  	// Get the error on read
   165  	buf := make([]byte, 16)
   166  	l, err := fh.Read(buf)
   167  	assert.Equal(t, io.EOF, err)
   168  	assert.Equal(t, 0, l)
   169  
   170  	// Close
   171  	assert.Equal(t, nil, fh.Close())
   172  }
   173  
   174  func TestRWFileHandleReadAt(t *testing.T) {
   175  	r := fstest.NewRun(t)
   176  	vfs, fh := rwHandleCreateReadOnly(t, r)
   177  	defer cleanup(t, r, vfs)
   178  
   179  	// read from start
   180  	buf := make([]byte, 1)
   181  	n, err := fh.ReadAt(buf, 0)
   182  	require.NoError(t, err)
   183  	assert.Equal(t, 1, n)
   184  	assert.Equal(t, "0", string(buf[:n]))
   185  
   186  	// seek forwards
   187  	n, err = fh.ReadAt(buf, 5)
   188  	require.NoError(t, err)
   189  	assert.Equal(t, 1, n)
   190  	assert.Equal(t, "5", string(buf[:n]))
   191  
   192  	// seek backwards
   193  	n, err = fh.ReadAt(buf, 1)
   194  	require.NoError(t, err)
   195  	assert.Equal(t, 1, n)
   196  	assert.Equal(t, "1", string(buf[:n]))
   197  
   198  	// read exactly to the end
   199  	buf = make([]byte, 6)
   200  	n, err = fh.ReadAt(buf, 10)
   201  	require.NoError(t, err)
   202  	assert.Equal(t, 6, n)
   203  	assert.Equal(t, "abcdef", string(buf[:n]))
   204  
   205  	// read off the end
   206  	buf = make([]byte, 256)
   207  	n, err = fh.ReadAt(buf, 10)
   208  	assert.Equal(t, io.EOF, err)
   209  	assert.Equal(t, 6, n)
   210  	assert.Equal(t, "abcdef", string(buf[:n]))
   211  
   212  	// read starting off the end
   213  	n, err = fh.ReadAt(buf, 100)
   214  	assert.Equal(t, io.EOF, err)
   215  	assert.Equal(t, 0, n)
   216  
   217  	// Properly close the file
   218  	assert.NoError(t, fh.Close())
   219  
   220  	// check reading on closed file
   221  	_, err = fh.ReadAt(buf, 100)
   222  	assert.Equal(t, ECLOSED, err)
   223  }
   224  
   225  func TestRWFileHandleFlushRead(t *testing.T) {
   226  	r := fstest.NewRun(t)
   227  	vfs, fh := rwHandleCreateReadOnly(t, r)
   228  	defer cleanup(t, r, vfs)
   229  
   230  	// Check Flush does nothing if read not called
   231  	err := fh.Flush()
   232  	assert.NoError(t, err)
   233  	assert.False(t, fh.closed)
   234  
   235  	// Read data
   236  	buf := make([]byte, 256)
   237  	n, err := fh.Read(buf)
   238  	assert.True(t, err == io.EOF || err == nil)
   239  	assert.Equal(t, 16, n)
   240  
   241  	// Check Flush does nothing if read called
   242  	err = fh.Flush()
   243  	assert.NoError(t, err)
   244  	assert.False(t, fh.closed)
   245  
   246  	// Check flush does nothing if called again
   247  	err = fh.Flush()
   248  	assert.NoError(t, err)
   249  	assert.False(t, fh.closed)
   250  
   251  	// Properly close the file
   252  	assert.NoError(t, fh.Close())
   253  }
   254  
   255  func TestRWFileHandleReleaseRead(t *testing.T) {
   256  	r := fstest.NewRun(t)
   257  	vfs, fh := rwHandleCreateReadOnly(t, r)
   258  	defer cleanup(t, r, vfs)
   259  
   260  	// Read data
   261  	buf := make([]byte, 256)
   262  	n, err := fh.Read(buf)
   263  	assert.True(t, err == io.EOF || err == nil)
   264  	assert.Equal(t, 16, n)
   265  
   266  	// Check Release closes file
   267  	err = fh.Release()
   268  	assert.NoError(t, err)
   269  	assert.True(t, fh.closed)
   270  
   271  	// Check Release does nothing if called again
   272  	err = fh.Release()
   273  	assert.NoError(t, err)
   274  	assert.True(t, fh.closed)
   275  }
   276  
   277  /// ------------------------------------------------------------
   278  
   279  func TestRWFileHandleMethodsWrite(t *testing.T) {
   280  	r := fstest.NewRun(t)
   281  	vfs, fh := rwHandleCreateWriteOnly(t, r)
   282  	defer cleanup(t, r, vfs)
   283  
   284  	// 1 opens since we opened with O_CREATE and the file didn't
   285  	// exist in the cache
   286  	assert.Equal(t, 1, fh.file.rwOpens())
   287  
   288  	// String
   289  	assert.Equal(t, "file1 (rw)", fh.String())
   290  	assert.Equal(t, "<nil *RWFileHandle>", (*RWFileHandle)(nil).String())
   291  	assert.Equal(t, "<nil *RWFileHandle.file>", new(RWFileHandle).String())
   292  
   293  	// Node
   294  	node := fh.Node()
   295  	assert.Equal(t, "file1", node.Name())
   296  
   297  	offset := func() int64 {
   298  		n, err := fh.Seek(0, io.SeekCurrent)
   299  		require.NoError(t, err)
   300  		return n
   301  	}
   302  
   303  	// Offset #1
   304  	assert.Equal(t, int64(0), offset())
   305  	assert.Equal(t, int64(0), node.Size())
   306  
   307  	// Size #1
   308  	assert.Equal(t, int64(0), fh.Size())
   309  
   310  	// Write
   311  	n, err := fh.Write([]byte("hello"))
   312  	assert.NoError(t, err)
   313  	assert.Equal(t, 5, n)
   314  
   315  	// Open after the write
   316  	assert.Equal(t, 1, fh.file.rwOpens())
   317  
   318  	// Offset #2
   319  	assert.Equal(t, int64(5), offset())
   320  	assert.Equal(t, int64(5), node.Size())
   321  
   322  	// Size #2
   323  	assert.Equal(t, int64(5), fh.Size())
   324  
   325  	// WriteString
   326  	n, err = fh.WriteString(" world!")
   327  	assert.NoError(t, err)
   328  	assert.Equal(t, 7, n)
   329  
   330  	// Sync
   331  	err = fh.Sync()
   332  	assert.NoError(t, err)
   333  
   334  	// Stat
   335  	var fi os.FileInfo
   336  	fi, err = fh.Stat()
   337  	assert.NoError(t, err)
   338  	assert.Equal(t, int64(12), fi.Size())
   339  	assert.Equal(t, "file1", fi.Name())
   340  
   341  	// Truncate
   342  	err = fh.Truncate(11)
   343  	assert.NoError(t, err)
   344  
   345  	// Close
   346  	assert.NoError(t, fh.Close())
   347  
   348  	// No opens again
   349  	assert.Equal(t, 0, fh.file.rwOpens())
   350  
   351  	// Check double close
   352  	err = fh.Close()
   353  	assert.Equal(t, ECLOSED, err)
   354  
   355  	// check vfs
   356  	root, err := vfs.Root()
   357  	require.NoError(t, err)
   358  	checkListing(t, root, []string{"file1,11,false"})
   359  
   360  	// check the underlying r.Fremote but not the modtime
   361  	file1 := fstest.NewItem("file1", "hello world", t1)
   362  	fstest.CheckListingWithPrecision(t, r.Fremote, []fstest.Item{file1}, []string{}, fs.ModTimeNotSupported)
   363  }
   364  
   365  func TestRWFileHandleWriteAt(t *testing.T) {
   366  	r := fstest.NewRun(t)
   367  	vfs, fh := rwHandleCreateWriteOnly(t, r)
   368  	defer cleanup(t, r, vfs)
   369  
   370  	offset := func() int64 {
   371  		n, err := fh.Seek(0, io.SeekCurrent)
   372  		require.NoError(t, err)
   373  		return n
   374  	}
   375  
   376  	// Preconditions
   377  	assert.Equal(t, int64(0), offset())
   378  	assert.True(t, fh.opened)
   379  	assert.False(t, fh.writeCalled)
   380  	assert.True(t, fh.changed)
   381  
   382  	// Write the data
   383  	n, err := fh.WriteAt([]byte("hello**"), 0)
   384  	assert.NoError(t, err)
   385  	assert.Equal(t, 7, n)
   386  
   387  	// After write
   388  	assert.Equal(t, int64(0), offset())
   389  	assert.True(t, fh.writeCalled)
   390  
   391  	// Write more data
   392  	n, err = fh.WriteAt([]byte(" world"), 5)
   393  	assert.NoError(t, err)
   394  	assert.Equal(t, 6, n)
   395  
   396  	// Close
   397  	assert.NoError(t, fh.Close())
   398  
   399  	// Check can't write on closed handle
   400  	n, err = fh.WriteAt([]byte("hello"), 0)
   401  	assert.Equal(t, ECLOSED, err)
   402  	assert.Equal(t, 0, n)
   403  
   404  	// check vfs
   405  	root, err := vfs.Root()
   406  	require.NoError(t, err)
   407  	checkListing(t, root, []string{"file1,11,false"})
   408  
   409  	// check the underlying r.Fremote but not the modtime
   410  	file1 := fstest.NewItem("file1", "hello world", t1)
   411  	fstest.CheckListingWithPrecision(t, r.Fremote, []fstest.Item{file1}, []string{}, fs.ModTimeNotSupported)
   412  }
   413  
   414  func TestRWFileHandleWriteNoWrite(t *testing.T) {
   415  	r := fstest.NewRun(t)
   416  	vfs, fh := rwHandleCreateWriteOnly(t, r)
   417  	defer cleanup(t, r, vfs)
   418  
   419  	// Close the file without writing to it
   420  	err := fh.Close()
   421  	if errors.Cause(err) == fs.ErrorCantUploadEmptyFiles {
   422  		t.Logf("skipping test: %v", err)
   423  		return
   424  	}
   425  	assert.NoError(t, err)
   426  
   427  	// Create a different file (not in the cache)
   428  	h, err := vfs.OpenFile("file2", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
   429  	require.NoError(t, err)
   430  
   431  	// Close it with Flush and Release
   432  	err = h.Flush()
   433  	assert.NoError(t, err)
   434  	err = h.Release()
   435  	assert.NoError(t, err)
   436  
   437  	// check vfs
   438  	root, err := vfs.Root()
   439  	require.NoError(t, err)
   440  	checkListing(t, root, []string{"file1,0,false", "file2,0,false"})
   441  
   442  	// check the underlying r.Fremote but not the modtime
   443  	file1 := fstest.NewItem("file1", "", t1)
   444  	file2 := fstest.NewItem("file2", "", t1)
   445  	fstest.CheckListingWithPrecision(t, r.Fremote, []fstest.Item{file1, file2}, []string{}, fs.ModTimeNotSupported)
   446  }
   447  
   448  func TestRWFileHandleFlushWrite(t *testing.T) {
   449  	r := fstest.NewRun(t)
   450  	vfs, fh := rwHandleCreateWriteOnly(t, r)
   451  	defer cleanup(t, r, vfs)
   452  
   453  	// Check that the file has been create and is open
   454  	assert.True(t, fh.opened)
   455  
   456  	// Write some data
   457  	n, err := fh.Write([]byte("hello"))
   458  	assert.NoError(t, err)
   459  	assert.Equal(t, 5, n)
   460  
   461  	// Check Flush does not close file if write called
   462  	err = fh.Flush()
   463  	assert.NoError(t, err)
   464  	assert.False(t, fh.closed)
   465  
   466  	// Check flush does nothing if called again
   467  	err = fh.Flush()
   468  	assert.NoError(t, err)
   469  	assert.False(t, fh.closed)
   470  
   471  	// Check that Close closes the file
   472  	err = fh.Close()
   473  	assert.NoError(t, err)
   474  	assert.True(t, fh.closed)
   475  }
   476  
   477  func TestRWFileHandleReleaseWrite(t *testing.T) {
   478  	r := fstest.NewRun(t)
   479  	vfs, fh := rwHandleCreateWriteOnly(t, r)
   480  	defer cleanup(t, r, vfs)
   481  
   482  	// Write some data
   483  	n, err := fh.Write([]byte("hello"))
   484  	assert.NoError(t, err)
   485  	assert.Equal(t, 5, n)
   486  
   487  	// Check Release closes file
   488  	err = fh.Release()
   489  	assert.NoError(t, err)
   490  	assert.True(t, fh.closed)
   491  
   492  	// Check Release does nothing if called again
   493  	err = fh.Release()
   494  	assert.NoError(t, err)
   495  	assert.True(t, fh.closed)
   496  }
   497  
   498  // check the size of the file through the open file (if not nil) and via stat
   499  func assertSize(t *testing.T, vfs *VFS, fh *RWFileHandle, filepath string, size int64) {
   500  	if fh != nil {
   501  		assert.Equal(t, size, fh.Size())
   502  	}
   503  	fi, err := vfs.Stat(filepath)
   504  	require.NoError(t, err)
   505  	assert.Equal(t, size, fi.Size())
   506  }
   507  
   508  func TestRWFileHandleSizeTruncateExisting(t *testing.T) {
   509  	r := fstest.NewRun(t)
   510  	vfs, fh := rwHandleCreateFlags(t, r, true, "dir/file1", os.O_WRONLY|os.O_TRUNC)
   511  	defer cleanup(t, r, vfs)
   512  
   513  	// check initial size after opening
   514  	assertSize(t, vfs, fh, "dir/file1", 0)
   515  
   516  	// write some bytes
   517  	n, err := fh.Write([]byte("hello"))
   518  	assert.NoError(t, err)
   519  	assert.Equal(t, 5, n)
   520  
   521  	// check size after writing
   522  	assertSize(t, vfs, fh, "dir/file1", 5)
   523  
   524  	// close
   525  	assert.NoError(t, fh.Close())
   526  
   527  	// check size after close
   528  	assertSize(t, vfs, nil, "dir/file1", 5)
   529  }
   530  
   531  func TestRWFileHandleSizeCreateExisting(t *testing.T) {
   532  	r := fstest.NewRun(t)
   533  	vfs, fh := rwHandleCreateFlags(t, r, true, "dir/file1", os.O_WRONLY|os.O_CREATE)
   534  	defer cleanup(t, r, vfs)
   535  
   536  	// check initial size after opening
   537  	assertSize(t, vfs, fh, "dir/file1", 16)
   538  
   539  	// write some bytes
   540  	n, err := fh.Write([]byte("hello"))
   541  	assert.NoError(t, err)
   542  	assert.Equal(t, 5, n)
   543  
   544  	// check size after writing
   545  	assertSize(t, vfs, fh, "dir/file1", 16)
   546  
   547  	// write some more bytes
   548  	n, err = fh.Write([]byte("helloHELLOhello"))
   549  	assert.NoError(t, err)
   550  	assert.Equal(t, 15, n)
   551  
   552  	// check size after writing
   553  	assertSize(t, vfs, fh, "dir/file1", 20)
   554  
   555  	// close
   556  	assert.NoError(t, fh.Close())
   557  
   558  	// check size after close
   559  	assertSize(t, vfs, nil, "dir/file1", 20)
   560  }
   561  
   562  func TestRWFileHandleSizeCreateNew(t *testing.T) {
   563  	r := fstest.NewRun(t)
   564  	vfs, fh := rwHandleCreateFlags(t, r, false, "file1", os.O_WRONLY|os.O_CREATE)
   565  	defer cleanup(t, r, vfs)
   566  
   567  	// check initial size after opening
   568  	assertSize(t, vfs, fh, "file1", 0)
   569  
   570  	// write some bytes
   571  	n, err := fh.Write([]byte("hello"))
   572  	assert.NoError(t, err)
   573  	assert.Equal(t, 5, n)
   574  
   575  	// check size after writing
   576  	assertSize(t, vfs, fh, "file1", 5)
   577  
   578  	// check size after writing
   579  	assertSize(t, vfs, fh, "file1", 5)
   580  
   581  	// close
   582  	assert.NoError(t, fh.Close())
   583  
   584  	// check size after close
   585  	assertSize(t, vfs, nil, "file1", 5)
   586  }
   587  
   588  func testRWFileHandleOpenTest(t *testing.T, vfs *VFS, test *openTest) {
   589  	fileName := "open-test-file"
   590  
   591  	// first try with file not existing
   592  	_, err := vfs.Stat(fileName)
   593  	require.True(t, os.IsNotExist(err), test.what)
   594  
   595  	f, openNonExistentErr := vfs.OpenFile(fileName, test.flags, 0666)
   596  
   597  	var readNonExistentErr error
   598  	var writeNonExistentErr error
   599  	if openNonExistentErr == nil {
   600  		// read some bytes
   601  		buf := []byte{0, 0}
   602  		_, readNonExistentErr = f.Read(buf)
   603  
   604  		// write some bytes
   605  		_, writeNonExistentErr = f.Write([]byte("hello"))
   606  
   607  		// close
   608  		err = f.Close()
   609  		require.NoError(t, err, test.what)
   610  	}
   611  
   612  	// write the file
   613  	f, err = vfs.OpenFile(fileName, os.O_WRONLY|os.O_CREATE, 0777)
   614  	require.NoError(t, err, test.what)
   615  	_, err = f.Write([]byte("hello"))
   616  	require.NoError(t, err, test.what)
   617  	err = f.Close()
   618  	require.NoError(t, err, test.what)
   619  
   620  	// then open file and try with file existing
   621  
   622  	f, openExistingErr := vfs.OpenFile(fileName, test.flags, 0666)
   623  	var readExistingErr error
   624  	var writeExistingErr error
   625  	if openExistingErr == nil {
   626  		// read some bytes
   627  		buf := []byte{0, 0}
   628  		_, readExistingErr = f.Read(buf)
   629  
   630  		// write some bytes
   631  		_, writeExistingErr = f.Write([]byte("HEL"))
   632  
   633  		// close
   634  		err = f.Close()
   635  		require.NoError(t, err, test.what)
   636  	}
   637  
   638  	// read the file
   639  	f, err = vfs.OpenFile(fileName, os.O_RDONLY, 0)
   640  	require.NoError(t, err, test.what)
   641  	buf, err := ioutil.ReadAll(f)
   642  	require.NoError(t, err, test.what)
   643  	err = f.Close()
   644  	require.NoError(t, err, test.what)
   645  	contents := string(buf)
   646  
   647  	// remove file
   648  	node, err := vfs.Stat(fileName)
   649  	require.NoError(t, err, test.what)
   650  	err = node.Remove()
   651  	require.NoError(t, err, test.what)
   652  
   653  	// check
   654  	assert.Equal(t, test.openNonExistentErr, openNonExistentErr, "openNonExistentErr: %s: want=%v, got=%v", test.what, test.openNonExistentErr, openNonExistentErr)
   655  	assert.Equal(t, test.readNonExistentErr, readNonExistentErr, "readNonExistentErr: %s: want=%v, got=%v", test.what, test.readNonExistentErr, readNonExistentErr)
   656  	assert.Equal(t, test.writeNonExistentErr, writeNonExistentErr, "writeNonExistentErr: %s: want=%v, got=%v", test.what, test.writeNonExistentErr, writeNonExistentErr)
   657  	assert.Equal(t, test.openExistingErr, openExistingErr, "openExistingErr: %s: want=%v, got=%v", test.what, test.openExistingErr, openExistingErr)
   658  	assert.Equal(t, test.readExistingErr, readExistingErr, "readExistingErr: %s: want=%v, got=%v", test.what, test.readExistingErr, readExistingErr)
   659  	assert.Equal(t, test.writeExistingErr, writeExistingErr, "writeExistingErr: %s: want=%v, got=%v", test.what, test.writeExistingErr, writeExistingErr)
   660  	assert.Equal(t, test.contents, contents, test.what)
   661  }
   662  
   663  func TestRWFileHandleOpenTests(t *testing.T) {
   664  	r := fstest.NewRun(t)
   665  	opt := vfscommon.DefaultOpt
   666  	opt.CacheMode = vfscommon.CacheModeFull
   667  	vfs := New(r.Fremote, &opt)
   668  	defer cleanup(t, r, vfs)
   669  
   670  	for _, test := range openTests {
   671  		testRWFileHandleOpenTest(t, vfs, &test)
   672  	}
   673  }
   674  
   675  // tests mod time on open files
   676  func TestRWFileModTimeWithOpenWriters(t *testing.T) {
   677  	r := fstest.NewRun(t)
   678  	defer r.Finalise()
   679  	if !canSetModTime(t, r) {
   680  		return
   681  	}
   682  	vfs, fh := rwHandleCreateWriteOnly(t, r)
   683  
   684  	mtime := time.Date(2012, time.November, 18, 17, 32, 31, 0, time.UTC)
   685  
   686  	_, err := fh.Write([]byte{104, 105})
   687  	require.NoError(t, err)
   688  
   689  	err = fh.Node().SetModTime(mtime)
   690  	require.NoError(t, err)
   691  
   692  	// Using Flush/Release to mimic mount instead of Close
   693  
   694  	err = fh.Flush()
   695  	require.NoError(t, err)
   696  
   697  	err = fh.Release()
   698  	require.NoError(t, err)
   699  
   700  	info, err := vfs.Stat("file1")
   701  	require.NoError(t, err)
   702  
   703  	if r.Fremote.Precision() != fs.ModTimeNotSupported {
   704  		// avoid errors because of timezone differences
   705  		assert.Equal(t, info.ModTime().Unix(), mtime.Unix(), fmt.Sprintf("Time mismatch: %v != %v", info.ModTime(), mtime))
   706  	}
   707  
   708  	file1 := fstest.NewItem("file1", "hi", mtime)
   709  	fstest.CheckItems(t, r.Fremote, file1)
   710  }
   711  
   712  func TestRWCacheRename(t *testing.T) {
   713  	r := fstest.NewRun(t)
   714  	defer r.Finalise()
   715  
   716  	if !operations.CanServerSideMove(r.Fremote) {
   717  		t.Skip("skip as can't rename files")
   718  	}
   719  
   720  	opt := vfscommon.DefaultOpt
   721  	opt.CacheMode = vfscommon.CacheModeFull
   722  	vfs := New(r.Fremote, &opt)
   723  
   724  	h, err := vfs.OpenFile("rename_me", os.O_WRONLY|os.O_CREATE, 0777)
   725  	require.NoError(t, err)
   726  	_, err = h.WriteString("hello")
   727  	require.NoError(t, err)
   728  	fh, ok := h.(*RWFileHandle)
   729  	require.True(t, ok)
   730  
   731  	err = fh.Sync()
   732  	require.NoError(t, err)
   733  	err = fh.Close()
   734  	require.NoError(t, err)
   735  
   736  	assert.True(t, vfs.cache.Exists("rename_me"))
   737  
   738  	err = vfs.Rename("rename_me", "i_was_renamed")
   739  	require.NoError(t, err)
   740  
   741  	assert.False(t, vfs.cache.Exists("rename_me"))
   742  	assert.True(t, vfs.cache.Exists("i_was_renamed"))
   743  }