vfs: make objects of unknown size readable through the VFS

These objects (eg Google Docs) appear with 0 length in the VFS.

Before this change, these only read 0 bytes.

After this change, even though the size appears to be 0, the objects
can be read to the end.  If the objects are read to the end then the
size on the handle will be updated.
This commit is contained in:
Nick Craig-Wood 2019-09-14 13:09:07 +01:00
parent 2e80e035c9
commit ba121eddf0
2 changed files with 75 additions and 20 deletions

View file

@ -7,6 +7,8 @@ import (
"testing"
"github.com/rclone/rclone/fstest"
"github.com/rclone/rclone/fstest/mockfs"
"github.com/rclone/rclone/fstest/mockobject"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -110,6 +112,51 @@ func TestFileOpenRead(t *testing.T) {
require.NoError(t, fd.Close())
}
func TestFileOpenReadUnknownSize(t *testing.T) {
var (
contents = []byte("file contents")
remote = "file.txt"
ctx = context.Background()
)
// create a mock object which returns size -1
o := mockobject.New(remote).WithContent(contents, mockobject.SeekModeNone)
o.SetUnknownSize(true)
assert.Equal(t, int64(-1), o.Size())
// add it to a mock fs
f := mockfs.NewFs("test", "root")
f.AddObject(o)
testObj, err := f.NewObject(ctx, remote)
require.NoError(t, err)
assert.Equal(t, int64(-1), testObj.Size())
// create a VFS from that mockfs
vfs := New(f, nil)
// find the file
node, err := vfs.Stat(remote)
require.NoError(t, err)
require.True(t, node.IsFile())
file := node.(*File)
// open it
fd, err := file.openRead()
require.NoError(t, err)
assert.Equal(t, int64(0), fd.Size())
// check the contents are not empty even though size is empty
gotContents, err := ioutil.ReadAll(fd)
require.NoError(t, err)
assert.Equal(t, contents, gotContents)
t.Logf("gotContents = %q", gotContents)
// check that file size has been updated
assert.Equal(t, int64(len(contents)), fd.Size())
require.NoError(t, fd.Close())
}
func TestFileOpenWrite(t *testing.T) {
r := fstest.NewRun(t)
defer r.Finalise()