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