vfstests: move functional tests from mountlib and make them work with VFS
The tests are now run for the mount commands and for the plain VFS. This makes the tests much easier to debug when running with a VFS than through a mount.
This commit is contained in:
parent
b25f5eb0d1
commit
fd39cbc193
16 changed files with 259 additions and 67 deletions
|
@ -11,9 +11,9 @@ package cmount
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/rclone/rclone/cmd/mountlib/mounttest"
|
||||
"github.com/rclone/rclone/vfs/vfstest"
|
||||
)
|
||||
|
||||
func TestMount(t *testing.T) {
|
||||
mounttest.RunTests(t, mount)
|
||||
vfstest.RunTests(t, false, mount)
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@ import (
|
|||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/rclone/rclone/cmd/mountlib/mounttest"
|
||||
"github.com/rclone/rclone/vfs/vfstest"
|
||||
)
|
||||
|
||||
func TestMount(t *testing.T) {
|
||||
if runtime.NumCPU() <= 2 {
|
||||
t.Skip("FIXME skipping mount tests as they lock up on <= 2 CPUs - See: https://github.com/rclone/rclone/issues/3154")
|
||||
}
|
||||
mounttest.RunTests(t, mount)
|
||||
vfstest.RunTests(t, false, mount)
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@ package mount2
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/rclone/rclone/cmd/mountlib/mounttest"
|
||||
"github.com/rclone/rclone/vfs/vfstest"
|
||||
)
|
||||
|
||||
func TestMount(t *testing.T) {
|
||||
mounttest.RunTests(t, mount)
|
||||
vfstest.RunTests(t, false, mount)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package mounttest
|
||||
package vfstest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -37,7 +36,7 @@ func TestDirCreateAndRemoveDir(t *testing.T) {
|
|||
run.checkDir(t, "dir/|dir/subdir/")
|
||||
|
||||
// Check we can't delete a directory with stuff in
|
||||
err := os.Remove(run.path("dir"))
|
||||
err := run.os.Remove(run.path("dir"))
|
||||
assert.Error(t, err, "file exists")
|
||||
|
||||
// Now delete subdir then dir - should produce no errors
|
||||
|
@ -56,7 +55,7 @@ func TestDirCreateAndRemoveFile(t *testing.T) {
|
|||
run.checkDir(t, "dir/|dir/file 6")
|
||||
|
||||
// Check we can't delete a directory with stuff in
|
||||
err := os.Remove(run.path("dir"))
|
||||
err := run.os.Remove(run.path("dir"))
|
||||
assert.Error(t, err, "file exists")
|
||||
|
||||
// Now delete file
|
||||
|
@ -75,14 +74,14 @@ func TestDirRenameFile(t *testing.T) {
|
|||
run.createFile(t, "file", "potato")
|
||||
run.checkDir(t, "dir/|file 6")
|
||||
|
||||
err := os.Rename(run.path("file"), run.path("file2"))
|
||||
err := run.os.Rename(run.path("file"), run.path("file2"))
|
||||
require.NoError(t, err)
|
||||
run.checkDir(t, "dir/|file2 6")
|
||||
|
||||
data := run.readFile(t, "file2")
|
||||
assert.Equal(t, "potato", data)
|
||||
|
||||
err = os.Rename(run.path("file2"), run.path("dir/file3"))
|
||||
err = run.os.Rename(run.path("file2"), run.path("dir/file3"))
|
||||
require.NoError(t, err)
|
||||
run.checkDir(t, "dir/|dir/file3 6")
|
||||
|
||||
|
@ -103,11 +102,11 @@ func TestDirRenameEmptyDir(t *testing.T) {
|
|||
run.mkdir(t, "dir1")
|
||||
run.checkDir(t, "dir/|dir1/")
|
||||
|
||||
err := os.Rename(run.path("dir1"), run.path("dir/dir2"))
|
||||
err := run.os.Rename(run.path("dir1"), run.path("dir/dir2"))
|
||||
require.NoError(t, err)
|
||||
run.checkDir(t, "dir/|dir/dir2/")
|
||||
|
||||
err = os.Rename(run.path("dir/dir2"), run.path("dir/dir3"))
|
||||
err = run.os.Rename(run.path("dir/dir2"), run.path("dir/dir3"))
|
||||
require.NoError(t, err)
|
||||
run.checkDir(t, "dir/|dir/dir3/")
|
||||
|
||||
|
@ -125,11 +124,11 @@ func TestDirRenameFullDir(t *testing.T) {
|
|||
run.createFile(t, "dir1/potato.txt", "maris piper")
|
||||
run.checkDir(t, "dir/|dir1/|dir1/potato.txt 11")
|
||||
|
||||
err := os.Rename(run.path("dir1"), run.path("dir/dir2"))
|
||||
err := run.os.Rename(run.path("dir1"), run.path("dir/dir2"))
|
||||
require.NoError(t, err)
|
||||
run.checkDir(t, "dir/|dir/dir2/|dir/dir2/potato.txt 11")
|
||||
|
||||
err = os.Rename(run.path("dir/dir2"), run.path("dir/dir3"))
|
||||
err = run.os.Rename(run.path("dir/dir2"), run.path("dir/dir3"))
|
||||
require.NoError(t, err)
|
||||
run.checkDir(t, "dir/|dir/dir3/|dir/dir3/potato.txt 11")
|
||||
|
||||
|
@ -145,10 +144,10 @@ func TestDirModTime(t *testing.T) {
|
|||
|
||||
run.mkdir(t, "dir")
|
||||
mtime := time.Date(2012, time.November, 18, 17, 32, 31, 0, time.UTC)
|
||||
err := os.Chtimes(run.path("dir"), mtime, mtime)
|
||||
err := run.os.Chtimes(run.path("dir"), mtime, mtime)
|
||||
require.NoError(t, err)
|
||||
|
||||
info, err := os.Stat(run.path("dir"))
|
||||
info, err := run.os.Stat(run.path("dir"))
|
||||
require.NoError(t, err)
|
||||
|
||||
// avoid errors because of timezone differences
|
||||
|
@ -214,7 +213,7 @@ func TestDirCacheFlushOnDirRename(t *testing.T) {
|
|||
run.readLocal(t, localDm, "")
|
||||
assert.Equal(t, dm, localDm, "expected vs fuse mount")
|
||||
|
||||
err = os.Rename(run.path("dir"), run.path("rid"))
|
||||
err = run.os.Rename(run.path("dir"), run.path("rid"))
|
||||
require.NoError(t, err)
|
||||
|
||||
dm = newDirMap("rid/|rid/subdir/|rid/file 1")
|
|
@ -1,7 +1,6 @@
|
|||
package mounttest
|
||||
package vfstest
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
|
@ -43,7 +42,7 @@ func TestRenameOpenHandle(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// attempt to rename open file
|
||||
err = os.Rename(path, path+"bla")
|
||||
err = run.os.Rename(path, path+"bla")
|
||||
require.NoError(t, err)
|
||||
|
||||
// close open writers to allow rename on remote to go through
|
|
@ -1,4 +1,4 @@
|
|||
package mounttest
|
||||
package vfstest
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
@ -6,6 +6,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -17,10 +18,10 @@ func TestFileModTime(t *testing.T) {
|
|||
run.createFile(t, "file", "123")
|
||||
|
||||
mtime := time.Date(2012, time.November, 18, 17, 32, 31, 0, time.UTC)
|
||||
err := os.Chtimes(run.path("file"), mtime, mtime)
|
||||
err := run.os.Chtimes(run.path("file"), mtime, mtime)
|
||||
require.NoError(t, err)
|
||||
|
||||
info, err := os.Stat(run.path("file"))
|
||||
info, err := run.os.Stat(run.path("file"))
|
||||
require.NoError(t, err)
|
||||
|
||||
// avoid errors because of timezone differences
|
||||
|
@ -29,14 +30,14 @@ func TestFileModTime(t *testing.T) {
|
|||
run.rm(t, "file")
|
||||
}
|
||||
|
||||
// os.Create without opening for write too
|
||||
func osCreate(name string) (*os.File, error) {
|
||||
return os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
// run.os.Create without opening for write too
|
||||
func osCreate(name string) (vfs.OsFiler, error) {
|
||||
return run.os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
}
|
||||
|
||||
// os.Create with append
|
||||
func osAppend(name string) (*os.File, error) {
|
||||
return os.OpenFile(name, os.O_WRONLY|os.O_APPEND, 0666)
|
||||
// run.os.Create with append
|
||||
func osAppend(name string) (vfs.OsFiler, error) {
|
||||
return run.os.OpenFile(name, os.O_WRONLY|os.O_APPEND, 0666)
|
||||
}
|
||||
|
||||
// TestFileModTimeWithOpenWriters tests mod time on open files
|
||||
|
@ -55,7 +56,7 @@ func TestFileModTimeWithOpenWriters(t *testing.T) {
|
|||
_, err = f.Write([]byte{104, 105})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.Chtimes(filepath, mtime, mtime)
|
||||
err = run.os.Chtimes(filepath, mtime, mtime)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = f.Close()
|
||||
|
@ -63,7 +64,7 @@ func TestFileModTimeWithOpenWriters(t *testing.T) {
|
|||
|
||||
run.waitForWriters()
|
||||
|
||||
info, err := os.Stat(filepath)
|
||||
info, err := run.os.Stat(filepath)
|
||||
require.NoError(t, err)
|
||||
|
||||
// avoid errors because of timezone differences
|
|
@ -1,6 +1,6 @@
|
|||
// Test suite for rclonefs
|
||||
|
||||
package mounttest
|
||||
package vfstest
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -23,7 +23,6 @@ import (
|
|||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/fs/walk"
|
||||
"github.com/rclone/rclone/fstest"
|
||||
"github.com/rclone/rclone/lib/file"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -33,7 +32,7 @@ type (
|
|||
// UnmountFn is called to unmount the file system
|
||||
UnmountFn func() error
|
||||
// MountFn is called to mount the file system
|
||||
MountFn func(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, error)
|
||||
MountFn func(f fs.Fs, mountpoint string) (vfs *vfs.VFS, unmountResult <-chan error, unmount func() error, err error)
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -41,7 +40,9 @@ var (
|
|||
)
|
||||
|
||||
// RunTests runs all the tests against all the VFS cache modes
|
||||
func RunTests(t *testing.T, fn MountFn) {
|
||||
//
|
||||
// If useVFS is set then it runs the tests against a VFS rather than amount
|
||||
func RunTests(t *testing.T, useVFS bool, fn MountFn) {
|
||||
mountFn = fn
|
||||
flag.Parse()
|
||||
cacheModes := []vfs.CacheMode{
|
||||
|
@ -50,7 +51,7 @@ func RunTests(t *testing.T, fn MountFn) {
|
|||
vfs.CacheModeWrites,
|
||||
vfs.CacheModeFull,
|
||||
}
|
||||
run = newRun()
|
||||
run = newRun(useVFS)
|
||||
for _, cacheMode := range cacheModes {
|
||||
run.cacheMode(cacheMode)
|
||||
log.Printf("Starting test run with cache mode %v", cacheMode)
|
||||
|
@ -92,7 +93,9 @@ func RunTests(t *testing.T, fn MountFn) {
|
|||
|
||||
// Run holds the remotes for a test run
|
||||
type Run struct {
|
||||
os Oser
|
||||
vfs *vfs.VFS
|
||||
useVFS bool // set if we are testing a VFS not a mount
|
||||
mountPath string
|
||||
fremote fs.Fs
|
||||
fremoteName string
|
||||
|
@ -111,11 +114,11 @@ var run *Run
|
|||
// r.fremote is an empty remote Fs
|
||||
//
|
||||
// Finalise() will tidy them away when done.
|
||||
func newRun() *Run {
|
||||
func newRun(useVFS bool) *Run {
|
||||
r := &Run{
|
||||
useVFS: useVFS,
|
||||
umountResult: make(chan error, 1),
|
||||
}
|
||||
|
||||
fstest.Initialise()
|
||||
|
||||
var err error
|
||||
|
@ -129,7 +132,9 @@ func newRun() *Run {
|
|||
log.Fatalf("Failed to open mkdir %q: %v", *fstest.RemoteName, err)
|
||||
}
|
||||
|
||||
r.mountPath = findMountPath()
|
||||
if !r.useVFS {
|
||||
r.mountPath = findMountPath()
|
||||
}
|
||||
// Mount it up
|
||||
r.mount()
|
||||
|
||||
|
@ -169,6 +174,12 @@ func (r *Run) mount() {
|
|||
} else {
|
||||
log.Printf("mount OK")
|
||||
}
|
||||
if r.useVFS {
|
||||
r.os = vfsOs{r.vfs}
|
||||
} else {
|
||||
r.os = realOs{}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (r *Run) umount() {
|
||||
|
@ -238,18 +249,31 @@ func (r *Run) skipIfNoFUSE(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *Run) skipIfVFS(t *testing.T) {
|
||||
if r.useVFS {
|
||||
t.Skip("Not running under VFS")
|
||||
}
|
||||
}
|
||||
|
||||
// Finalise cleans the remote and unmounts
|
||||
func (r *Run) Finalise() {
|
||||
r.umount()
|
||||
r.cleanRemote()
|
||||
err := os.RemoveAll(r.mountPath)
|
||||
if err != nil {
|
||||
log.Printf("Failed to clean mountPath %q: %v", r.mountPath, err)
|
||||
if r.useVFS {
|
||||
// FIXME
|
||||
} else {
|
||||
err := os.RemoveAll(r.mountPath)
|
||||
if err != nil {
|
||||
log.Printf("Failed to clean mountPath %q: %v", r.mountPath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// path returns an OS local path for filepath
|
||||
func (r *Run) path(filePath string) string {
|
||||
if r.useVFS {
|
||||
return filePath
|
||||
}
|
||||
// return windows drive letter root as E:\
|
||||
if filePath == "" && runtime.GOOS == "windows" {
|
||||
return run.mountPath + `\`
|
||||
|
@ -284,7 +308,7 @@ func (dm dirMap) filesOnly() dirMap {
|
|||
// reads the local tree into dir
|
||||
func (r *Run) readLocal(t *testing.T, dir dirMap, filePath string) {
|
||||
realPath := r.path(filePath)
|
||||
files, err := ioutil.ReadDir(realPath)
|
||||
files, err := r.os.ReadDir(realPath)
|
||||
require.NoError(t, err)
|
||||
for _, fi := range files {
|
||||
name := path.Join(filePath, fi.Name())
|
||||
|
@ -353,13 +377,13 @@ func (r *Run) waitForWriters() {
|
|||
// If there is an error writing then writeFile
|
||||
// deletes it an existing file and tries again.
|
||||
func writeFile(filename string, data []byte, perm os.FileMode) error {
|
||||
f, err := file.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
|
||||
f, err := run.os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
|
||||
if err != nil {
|
||||
err = os.Remove(filename)
|
||||
err = run.os.Remove(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err = file.OpenFile(filename, os.O_WRONLY|os.O_CREATE, perm)
|
||||
f, err = run.os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, perm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -383,7 +407,7 @@ func (r *Run) createFile(t *testing.T, filepath string, contents string) {
|
|||
|
||||
func (r *Run) readFile(t *testing.T, filepath string) string {
|
||||
filepath = r.path(filepath)
|
||||
result, err := ioutil.ReadFile(filepath)
|
||||
result, err := run.os.ReadFile(filepath)
|
||||
require.NoError(t, err)
|
||||
time.Sleep(100 * time.Millisecond) // FIXME wait for Release
|
||||
return string(result)
|
||||
|
@ -391,18 +415,18 @@ func (r *Run) readFile(t *testing.T, filepath string) string {
|
|||
|
||||
func (r *Run) mkdir(t *testing.T, filepath string) {
|
||||
filepath = r.path(filepath)
|
||||
err := os.Mkdir(filepath, 0700)
|
||||
err := run.os.Mkdir(filepath, 0700)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func (r *Run) rm(t *testing.T, filepath string) {
|
||||
filepath = r.path(filepath)
|
||||
err := os.Remove(filepath)
|
||||
err := run.os.Remove(filepath)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Wait for file to disappear from listing
|
||||
for i := 0; i < 100; i++ {
|
||||
_, err := os.Stat(filepath)
|
||||
_, err := run.os.Stat(filepath)
|
||||
if os.IsNotExist(err) {
|
||||
return
|
||||
}
|
||||
|
@ -413,13 +437,14 @@ func (r *Run) rm(t *testing.T, filepath string) {
|
|||
|
||||
func (r *Run) rmdir(t *testing.T, filepath string) {
|
||||
filepath = r.path(filepath)
|
||||
err := os.Remove(filepath)
|
||||
err := run.os.Remove(filepath)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// TestMount checks that the Fs is mounted by seeing if the mountpoint
|
||||
// is in the mount output
|
||||
func TestMount(t *testing.T) {
|
||||
run.skipIfVFS(t)
|
||||
run.skipIfNoFUSE(t)
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("not running on windows")
|
||||
|
@ -432,6 +457,7 @@ func TestMount(t *testing.T) {
|
|||
|
||||
// TestRoot checks root directory is present and correct
|
||||
func TestRoot(t *testing.T) {
|
||||
run.skipIfVFS(t)
|
||||
run.skipIfNoFUSE(t)
|
||||
|
||||
fi, err := os.Lstat(run.mountPath)
|
116
vfs/vfstest/os.go
Normal file
116
vfs/vfstest/os.go
Normal file
|
@ -0,0 +1,116 @@
|
|||
package vfstest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/rclone/rclone/lib/file"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
)
|
||||
|
||||
// Oser defines the things that the "os" package can do
|
||||
//
|
||||
// This covers what the VFS can do also
|
||||
type Oser interface {
|
||||
Chtimes(name string, atime time.Time, mtime time.Time) error
|
||||
Create(name string) (vfs.Handle, error)
|
||||
Mkdir(name string, perm os.FileMode) error
|
||||
Open(name string) (vfs.Handle, error)
|
||||
OpenFile(name string, flags int, perm os.FileMode) (fd vfs.Handle, err error)
|
||||
ReadDir(dirname string) ([]os.FileInfo, error)
|
||||
ReadFile(filename string) (b []byte, err error)
|
||||
Remove(name string) error
|
||||
Rename(oldName, newName string) error
|
||||
Stat(path string) (os.FileInfo, error)
|
||||
}
|
||||
|
||||
// realOs is an implementation of Oser backed by the "os" package
|
||||
type realOs struct {
|
||||
}
|
||||
|
||||
// realOsFile is an implementation of vfs.Handle
|
||||
type realOsFile struct {
|
||||
*os.File
|
||||
}
|
||||
|
||||
// Flush
|
||||
func (f realOsFile) Flush() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Release
|
||||
func (f realOsFile) Release() error {
|
||||
return f.File.Close()
|
||||
}
|
||||
|
||||
// Node
|
||||
func (f realOsFile) Node() vfs.Node {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Chtimes
|
||||
func (r realOs) Chtimes(name string, atime time.Time, mtime time.Time) error {
|
||||
return os.Chtimes(name, atime, mtime)
|
||||
}
|
||||
|
||||
// Create
|
||||
func (r realOs) Create(name string) (vfs.Handle, error) {
|
||||
fd, err := file.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return realOsFile{File: fd}, err
|
||||
}
|
||||
|
||||
// Mkdir
|
||||
func (r realOs) Mkdir(name string, perm os.FileMode) error {
|
||||
return os.Mkdir(name, perm)
|
||||
}
|
||||
|
||||
// Open
|
||||
func (r realOs) Open(name string) (vfs.Handle, error) {
|
||||
fd, err := os.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return realOsFile{File: fd}, err
|
||||
}
|
||||
|
||||
// OpenFile
|
||||
func (r realOs) OpenFile(name string, flags int, perm os.FileMode) (vfs.Handle, error) {
|
||||
fd, err := file.OpenFile(name, flags, perm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return realOsFile{File: fd}, err
|
||||
}
|
||||
|
||||
// ReadDir
|
||||
func (r realOs) ReadDir(dirname string) ([]os.FileInfo, error) {
|
||||
return ioutil.ReadDir(dirname)
|
||||
}
|
||||
|
||||
// ReadFile
|
||||
func (r realOs) ReadFile(filename string) (b []byte, err error) {
|
||||
return ioutil.ReadFile(filename)
|
||||
}
|
||||
|
||||
// Remove
|
||||
func (r realOs) Remove(name string) error {
|
||||
return os.Remove(name)
|
||||
}
|
||||
|
||||
// Rename
|
||||
func (r realOs) Rename(oldName, newName string) error {
|
||||
return os.Rename(oldName, newName)
|
||||
}
|
||||
|
||||
// Stat
|
||||
func (r realOs) Stat(path string) (os.FileInfo, error) {
|
||||
return os.Stat(path)
|
||||
}
|
||||
|
||||
// Check interfaces
|
||||
var _ Oser = &realOs{}
|
||||
var _ vfs.Handle = &realOsFile{}
|
|
@ -1,9 +1,8 @@
|
|||
package mounttest
|
||||
package vfstest
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -19,7 +18,7 @@ func TestReadByByte(t *testing.T) {
|
|||
run.checkDir(t, "testfile 10")
|
||||
|
||||
for i := 0; i < len(data); i++ {
|
||||
fd, err := os.Open(run.path("testfile"))
|
||||
fd, err := run.os.Open(run.path("testfile"))
|
||||
assert.NoError(t, err)
|
||||
for j := 0; j < i; j++ {
|
||||
buf := make([]byte, 1)
|
||||
|
@ -50,7 +49,7 @@ func TestReadChecksum(t *testing.T) {
|
|||
|
||||
// The hash comparison would fail in Flush, if we did not
|
||||
// ensure we read the whole file
|
||||
fd, err := os.Open(run.path("bigfile"))
|
||||
fd, err := run.os.Open(run.path("bigfile"))
|
||||
assert.NoError(t, err)
|
||||
buf := make([]byte, 10)
|
||||
_, err = io.ReadFull(fd, buf)
|
||||
|
@ -60,7 +59,7 @@ func TestReadChecksum(t *testing.T) {
|
|||
|
||||
// The hash comparison would fail, because we only read parts
|
||||
// of the file
|
||||
fd, err = os.Open(run.path("bigfile"))
|
||||
fd, err = run.os.Open(run.path("bigfile"))
|
||||
assert.NoError(t, err)
|
||||
// read at start
|
||||
_, err = io.ReadFull(fd, buf)
|
||||
|
@ -85,7 +84,7 @@ func TestReadSeek(t *testing.T) {
|
|||
run.createFile(t, "testfile", string(data))
|
||||
run.checkDir(t, "testfile 10")
|
||||
|
||||
fd, err := os.Open(run.path("testfile"))
|
||||
fd, err := run.os.Open(run.path("testfile"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Seek to half way
|
|
@ -1,6 +1,6 @@
|
|||
// +build !linux,!darwin,!freebsd
|
||||
|
||||
package mounttest
|
||||
package vfstest
|
||||
|
||||
import (
|
||||
"runtime"
|
|
@ -1,9 +1,8 @@
|
|||
// +build linux darwin freebsd
|
||||
|
||||
package mounttest
|
||||
package vfstest
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
|
@ -12,11 +11,12 @@ import (
|
|||
|
||||
// TestReadFileDoubleClose tests double close on read
|
||||
func TestReadFileDoubleClose(t *testing.T) {
|
||||
run.skipIfVFS(t)
|
||||
run.skipIfNoFUSE(t)
|
||||
|
||||
run.createFile(t, "testdoubleclose", "hello")
|
||||
|
||||
in, err := os.Open(run.path("testdoubleclose"))
|
||||
in, err := run.os.Open(run.path("testdoubleclose"))
|
||||
assert.NoError(t, err)
|
||||
fd := in.Fd()
|
||||
|
20
vfs/vfstest/vfs.go
Normal file
20
vfs/vfstest/vfs.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
package vfstest
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/rclone/rclone/vfs"
|
||||
)
|
||||
|
||||
// vfsOs is an implementation of Oser backed by the "vfs" package
|
||||
type vfsOs struct {
|
||||
*vfs.VFS
|
||||
}
|
||||
|
||||
// Stat
|
||||
func (v vfsOs) Stat(path string) (os.FileInfo, error) {
|
||||
return v.VFS.Stat(path)
|
||||
}
|
||||
|
||||
// Check interfaces
|
||||
var _ Oser = vfsOs{}
|
|
@ -1,4 +1,4 @@
|
|||
package mounttest
|
||||
package vfstest
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
@ -89,6 +89,7 @@ func TestWriteFileFsync(t *testing.T) {
|
|||
|
||||
// TestWriteFileDup tests behavior of mmap() in Python by using dup() on a file handle
|
||||
func TestWriteFileDup(t *testing.T) {
|
||||
run.skipIfVFS(t)
|
||||
run.skipIfNoFUSE(t)
|
||||
|
||||
if run.vfs.Opt.CacheMode < vfs.CacheModeWrites {
|
||||
|
@ -169,7 +170,7 @@ func TestWriteFileAppend(t *testing.T) {
|
|||
err = fh.Close()
|
||||
require.NoError(t, err)
|
||||
|
||||
info, err := os.Stat(filepath)
|
||||
info, err := run.os.Stat(filepath)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, len(testData)+len(appendData), info.Size())
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// +build !linux,!darwin,!freebsd
|
||||
|
||||
package mounttest
|
||||
package vfstest
|
||||
|
||||
import (
|
||||
"runtime"
|
|
@ -1,6 +1,6 @@
|
|||
// +build linux darwin freebsd
|
||||
|
||||
package mounttest
|
||||
package vfstest
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
@ -14,6 +14,7 @@ import (
|
|||
|
||||
// TestWriteFileDoubleClose tests double close on write
|
||||
func TestWriteFileDoubleClose(t *testing.T) {
|
||||
run.skipIfVFS(t)
|
||||
run.skipIfNoFUSE(t)
|
||||
if runtime.GOOS == "darwin" {
|
||||
t.Skip("Skipping test on OSX")
|
30
vfs/vfstest_test.go
Normal file
30
vfs/vfstest_test.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Run the more functional vfstest package on the vfs
|
||||
|
||||
package vfs_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
_ "github.com/rclone/rclone/backend/all" // import all the backends
|
||||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/fstest"
|
||||
"github.com/rclone/rclone/vfs"
|
||||
"github.com/rclone/rclone/vfs/vfstest"
|
||||
)
|
||||
|
||||
// TestExt runs more functional tests all the tests against all the
|
||||
// VFS cache modes
|
||||
func TestFunctional(t *testing.T) {
|
||||
if *fstest.RemoteName != "" {
|
||||
t.Skip("Skip on non local")
|
||||
}
|
||||
vfstest.RunTests(t, true, func(f fs.Fs, mountpoint string) (VFS *vfs.VFS, unmountResult <-chan error, unmount func() error, err error) {
|
||||
unmountResultChan := make(chan (error), 1)
|
||||
unmount = func() error {
|
||||
unmountResultChan <- nil
|
||||
return nil
|
||||
}
|
||||
VFS = vfs.New(f, nil)
|
||||
return VFS, unmountResultChan, unmount, nil
|
||||
})
|
||||
}
|
Loading…
Reference in a new issue