mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 14:51:48 +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
|
// newFile creates a new File
|
||||||
|
//
|
||||||
|
// o may be nil
|
||||||
func newFile(d *Dir, o fs.Object, leaf string) *File {
|
func newFile(d *Dir, o fs.Object, leaf string) *File {
|
||||||
return &File{
|
f := &File{
|
||||||
d: d,
|
d: d,
|
||||||
o: o,
|
o: o,
|
||||||
leaf: leaf,
|
leaf: leaf,
|
||||||
inode: newInode(),
|
inode: newInode(),
|
||||||
}
|
}
|
||||||
|
if o != nil {
|
||||||
|
f.size = o.Size()
|
||||||
|
}
|
||||||
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
// String converts it to printable
|
// String converts it to printable
|
||||||
|
|
|
@ -21,16 +21,18 @@ func cleanup(t *testing.T, r *fstest.Run, vfs *VFS) {
|
||||||
r.Finalise()
|
r.Finalise()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open a file for write
|
// Create a file and open it with the flags passed in
|
||||||
func rwHandleCreateReadOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) {
|
func rwHandleCreateFlags(t *testing.T, r *fstest.Run, create bool, filename string, flags int) (*VFS, *RWFileHandle) {
|
||||||
opt := DefaultOpt
|
opt := DefaultOpt
|
||||||
opt.CacheMode = CacheModeFull
|
opt.CacheMode = CacheModeFull
|
||||||
vfs := New(r.Fremote, &opt)
|
vfs := New(r.Fremote, &opt)
|
||||||
|
|
||||||
file1 := r.WriteObject(context.Background(), "dir/file1", "0123456789abcdef", t1)
|
if create {
|
||||||
fstest.CheckItems(t, r.Fremote, file1)
|
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)
|
require.NoError(t, err)
|
||||||
fh, ok := h.(*RWFileHandle)
|
fh, ok := h.(*RWFileHandle)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
|
@ -38,18 +40,14 @@ func rwHandleCreateReadOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) {
|
||||||
return vfs, fh
|
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
|
// Open a file for write
|
||||||
func rwHandleCreateWriteOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) {
|
func rwHandleCreateWriteOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) {
|
||||||
opt := DefaultOpt
|
return rwHandleCreateFlags(t, r, false, "file1", os.O_WRONLY|os.O_CREATE)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read data from the string
|
// read data from the string
|
||||||
|
@ -494,6 +492,96 @@ func TestRWFileHandleReleaseWrite(t *testing.T) {
|
||||||
assert.True(t, fh.closed)
|
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) {
|
func testRWFileHandleOpenTest(t *testing.T, vfs *VFS, test *openTest) {
|
||||||
fileName := "open-test-file"
|
fileName := "open-test-file"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user