mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 15:30:06 +08:00
vfs: make sure existing files opened for write show correct size
Before this change if an existing file was opened for write without truncate its size would show as 0 rather than the full size of the file.
This commit is contained in:
parent
a7d65bd519
commit
420ae905b5
|
@ -37,13 +37,19 @@ type File struct {
|
|||
}
|
||||
|
||||
// newFile creates a new File
|
||||
//
|
||||
// o may be nil
|
||||
func newFile(d *Dir, o fs.Object, leaf string) *File {
|
||||
return &File{
|
||||
f := &File{
|
||||
d: d,
|
||||
o: o,
|
||||
leaf: leaf,
|
||||
inode: newInode(),
|
||||
}
|
||||
if o != nil {
|
||||
f.size = o.Size()
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// String converts it to printable
|
||||
|
|
|
@ -21,16 +21,18 @@ func cleanup(t *testing.T, r *fstest.Run, vfs *VFS) {
|
|||
r.Finalise()
|
||||
}
|
||||
|
||||
// Open a file for write
|
||||
func rwHandleCreateReadOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) {
|
||||
// Create a file and open it with the flags passed in
|
||||
func rwHandleCreateFlags(t *testing.T, r *fstest.Run, create bool, filename string, flags int) (*VFS, *RWFileHandle) {
|
||||
opt := DefaultOpt
|
||||
opt.CacheMode = CacheModeFull
|
||||
vfs := New(r.Fremote, &opt)
|
||||
|
||||
file1 := r.WriteObject(context.Background(), "dir/file1", "0123456789abcdef", t1)
|
||||
fstest.CheckItems(t, r.Fremote, file1)
|
||||
if create {
|
||||
file1 := r.WriteObject(context.Background(), filename, "0123456789abcdef", t1)
|
||||
fstest.CheckItems(t, r.Fremote, file1)
|
||||
}
|
||||
|
||||
h, err := vfs.OpenFile("dir/file1", os.O_RDONLY, 0777)
|
||||
h, err := vfs.OpenFile(filename, flags, 0777)
|
||||
require.NoError(t, err)
|
||||
fh, ok := h.(*RWFileHandle)
|
||||
require.True(t, ok)
|
||||
|
@ -38,18 +40,14 @@ func rwHandleCreateReadOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) {
|
|||
return vfs, fh
|
||||
}
|
||||
|
||||
// Open a file for read
|
||||
func rwHandleCreateReadOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) {
|
||||
return rwHandleCreateFlags(t, r, true, "dir/file1", os.O_RDONLY)
|
||||
}
|
||||
|
||||
// Open a file for write
|
||||
func rwHandleCreateWriteOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) {
|
||||
opt := DefaultOpt
|
||||
opt.CacheMode = CacheModeFull
|
||||
vfs := New(r.Fremote, &opt)
|
||||
|
||||
h, err := vfs.OpenFile("file1", os.O_WRONLY|os.O_CREATE, 0777)
|
||||
require.NoError(t, err)
|
||||
fh, ok := h.(*RWFileHandle)
|
||||
require.True(t, ok)
|
||||
|
||||
return vfs, fh
|
||||
return rwHandleCreateFlags(t, r, false, "file1", os.O_WRONLY|os.O_CREATE)
|
||||
}
|
||||
|
||||
// read data from the string
|
||||
|
@ -494,6 +492,96 @@ func TestRWFileHandleReleaseWrite(t *testing.T) {
|
|||
assert.True(t, fh.closed)
|
||||
}
|
||||
|
||||
// check the size of the file through the open file (if not nil) and via stat
|
||||
func assertSize(t *testing.T, vfs *VFS, fh *RWFileHandle, filepath string, size int64) {
|
||||
if fh != nil {
|
||||
assert.Equal(t, size, fh.Size())
|
||||
}
|
||||
fi, err := vfs.Stat(filepath)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, size, fi.Size())
|
||||
}
|
||||
|
||||
func TestRWFileHandleSizeTruncateExisting(t *testing.T) {
|
||||
r := fstest.NewRun(t)
|
||||
vfs, fh := rwHandleCreateFlags(t, r, true, "dir/file1", os.O_WRONLY|os.O_TRUNC)
|
||||
defer cleanup(t, r, vfs)
|
||||
|
||||
// check initial size after opening
|
||||
assertSize(t, vfs, fh, "dir/file1", 0)
|
||||
|
||||
// write some bytes
|
||||
n, err := fh.Write([]byte("hello"))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 5, n)
|
||||
|
||||
// check size after writing
|
||||
assertSize(t, vfs, fh, "dir/file1", 5)
|
||||
|
||||
// close
|
||||
assert.NoError(t, fh.Close())
|
||||
|
||||
// check size after close
|
||||
assertSize(t, vfs, nil, "dir/file1", 5)
|
||||
}
|
||||
|
||||
func TestRWFileHandleSizeCreateExisting(t *testing.T) {
|
||||
r := fstest.NewRun(t)
|
||||
vfs, fh := rwHandleCreateFlags(t, r, true, "dir/file1", os.O_WRONLY|os.O_CREATE)
|
||||
defer cleanup(t, r, vfs)
|
||||
|
||||
// check initial size after opening
|
||||
assertSize(t, vfs, fh, "dir/file1", 16)
|
||||
|
||||
// write some bytes
|
||||
n, err := fh.Write([]byte("hello"))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 5, n)
|
||||
|
||||
// check size after writing
|
||||
assertSize(t, vfs, fh, "dir/file1", 16)
|
||||
|
||||
// write some more bytes
|
||||
n, err = fh.Write([]byte("helloHELLOhello"))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 15, n)
|
||||
|
||||
// check size after writing
|
||||
assertSize(t, vfs, fh, "dir/file1", 20)
|
||||
|
||||
// close
|
||||
assert.NoError(t, fh.Close())
|
||||
|
||||
// check size after close
|
||||
assertSize(t, vfs, nil, "dir/file1", 20)
|
||||
}
|
||||
|
||||
func TestRWFileHandleSizeCreateNew(t *testing.T) {
|
||||
r := fstest.NewRun(t)
|
||||
vfs, fh := rwHandleCreateFlags(t, r, false, "file1", os.O_WRONLY|os.O_CREATE)
|
||||
defer cleanup(t, r, vfs)
|
||||
|
||||
// check initial size after opening
|
||||
assertSize(t, vfs, fh, "file1", 0)
|
||||
|
||||
// write some bytes
|
||||
n, err := fh.Write([]byte("hello"))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 5, n)
|
||||
|
||||
// check size after writing
|
||||
assertSize(t, vfs, fh, "file1", 5)
|
||||
|
||||
// check size after writing
|
||||
assertSize(t, vfs, fh, "file1", 5)
|
||||
|
||||
// close
|
||||
assert.NoError(t, fh.Close())
|
||||
|
||||
// check size after close
|
||||
assertSize(t, vfs, nil, "file1", 5)
|
||||
}
|
||||
|
||||
func testRWFileHandleOpenTest(t *testing.T, vfs *VFS, test *openTest) {
|
||||
fileName := "open-test-file"
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user