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

     1  package vfstest
     2  
     3  import (
     4  	"os"
     5  	"runtime"
     6  	"testing"
     7  
     8  	"github.com/rclone/rclone/vfs/vfscommon"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  // TestWriteFileNoWrite tests writing a file with no write()'s to it
    14  func TestWriteFileNoWrite(t *testing.T) {
    15  	run.skipIfNoFUSE(t)
    16  
    17  	fd, err := osCreate(run.path("testnowrite"))
    18  	assert.NoError(t, err)
    19  
    20  	err = fd.Close()
    21  	assert.NoError(t, err)
    22  
    23  	run.waitForWriters()
    24  
    25  	run.checkDir(t, "testnowrite 0")
    26  
    27  	run.rm(t, "testnowrite")
    28  }
    29  
    30  // FIXMETestWriteOpenFileInDirListing tests open file in directory listing
    31  func FIXMETestWriteOpenFileInDirListing(t *testing.T) {
    32  	run.skipIfNoFUSE(t)
    33  
    34  	fd, err := osCreate(run.path("testnowrite"))
    35  	assert.NoError(t, err)
    36  
    37  	run.checkDir(t, "testnowrite 0")
    38  
    39  	err = fd.Close()
    40  	assert.NoError(t, err)
    41  
    42  	run.waitForWriters()
    43  
    44  	run.rm(t, "testnowrite")
    45  }
    46  
    47  // TestWriteFileWrite tests writing a file and reading it back
    48  func TestWriteFileWrite(t *testing.T) {
    49  	run.skipIfNoFUSE(t)
    50  
    51  	run.createFile(t, "testwrite", "data")
    52  	run.checkDir(t, "testwrite 4")
    53  	contents := run.readFile(t, "testwrite")
    54  	assert.Equal(t, "data", contents)
    55  	run.rm(t, "testwrite")
    56  }
    57  
    58  // TestWriteFileOverwrite tests overwriting a file
    59  func TestWriteFileOverwrite(t *testing.T) {
    60  	run.skipIfNoFUSE(t)
    61  
    62  	run.createFile(t, "testwrite", "data")
    63  	run.checkDir(t, "testwrite 4")
    64  	run.createFile(t, "testwrite", "potato")
    65  	contents := run.readFile(t, "testwrite")
    66  	assert.Equal(t, "potato", contents)
    67  	run.rm(t, "testwrite")
    68  }
    69  
    70  // TestWriteFileFsync tests Fsync
    71  //
    72  // NB the code for this is in file.go rather than write.go
    73  func TestWriteFileFsync(t *testing.T) {
    74  	run.skipIfNoFUSE(t)
    75  
    76  	filepath := run.path("to be synced")
    77  	fd, err := osCreate(filepath)
    78  	require.NoError(t, err)
    79  	_, err = fd.Write([]byte("hello"))
    80  	require.NoError(t, err)
    81  	err = fd.Sync()
    82  	require.NoError(t, err)
    83  	err = fd.Close()
    84  	require.NoError(t, err)
    85  	run.waitForWriters()
    86  	run.rm(t, "to be synced")
    87  }
    88  
    89  // TestWriteFileDup tests behavior of mmap() in Python by using dup() on a file handle
    90  func TestWriteFileDup(t *testing.T) {
    91  	run.skipIfVFS(t)
    92  	run.skipIfNoFUSE(t)
    93  
    94  	if run.vfs.Opt.CacheMode < vfscommon.CacheModeWrites {
    95  		t.Skip("not supported on vfs-cache-mode < writes")
    96  		return
    97  	}
    98  
    99  	filepath := run.path("to be synced")
   100  	fh, err := osCreate(filepath)
   101  	require.NoError(t, err)
   102  
   103  	testData := []byte("0123456789")
   104  
   105  	err = fh.Truncate(int64(len(testData) + 2))
   106  	require.NoError(t, err)
   107  
   108  	err = fh.Sync()
   109  	require.NoError(t, err)
   110  
   111  	var dupFd uintptr
   112  	dupFd, err = writeTestDup(fh.Fd())
   113  	require.NoError(t, err)
   114  
   115  	dupFile := os.NewFile(dupFd, fh.Name())
   116  	_, err = dupFile.Write(testData)
   117  	require.NoError(t, err)
   118  
   119  	err = dupFile.Close()
   120  	require.NoError(t, err)
   121  
   122  	_, err = fh.Seek(int64(len(testData)), 0)
   123  	require.NoError(t, err)
   124  
   125  	_, err = fh.Write([]byte("10"))
   126  	require.NoError(t, err)
   127  
   128  	err = fh.Close()
   129  	require.NoError(t, err)
   130  
   131  	run.waitForWriters()
   132  	run.rm(t, "to be synced")
   133  }
   134  
   135  // TestWriteFileAppend tests that O_APPEND works on cache backends >= writes
   136  func TestWriteFileAppend(t *testing.T) {
   137  	run.skipIfNoFUSE(t)
   138  
   139  	if run.vfs.Opt.CacheMode < vfscommon.CacheModeWrites {
   140  		t.Skip("not supported on vfs-cache-mode < writes")
   141  		return
   142  	}
   143  
   144  	// TODO: Windows needs the v1.5 release of WinFsp to handle O_APPEND properly.
   145  	// Until it gets released, skip this test on Windows.
   146  	if runtime.GOOS == "windows" {
   147  		t.Skip("currently unsupported on Windows")
   148  	}
   149  
   150  	filepath := run.path("to be synced")
   151  	fh, err := osCreate(filepath)
   152  	require.NoError(t, err)
   153  
   154  	testData := []byte("0123456789")
   155  	appendData := []byte("10")
   156  
   157  	_, err = fh.Write(testData)
   158  	require.NoError(t, err)
   159  
   160  	err = fh.Close()
   161  	require.NoError(t, err)
   162  
   163  	fh, err = osAppend(filepath)
   164  	require.NoError(t, err)
   165  
   166  	_, err = fh.Write(appendData)
   167  	require.NoError(t, err)
   168  
   169  	err = fh.Close()
   170  	require.NoError(t, err)
   171  
   172  	info, err := run.os.Stat(filepath)
   173  	require.NoError(t, err)
   174  	require.EqualValues(t, len(testData)+len(appendData), info.Size())
   175  
   176  	run.waitForWriters()
   177  	run.rm(t, "to be synced")
   178  }