From 8f9d5af26d517f6eedc6dc728af69f9774a047f6 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 24 Jul 2020 10:59:39 +0100 Subject: [PATCH] cache: remove mount tests as they aren't being run and cause maintenance issues Before this change the cache backend contained its own routines for mounting testing on that mount. These tests are never run on the CI and cause a maintenance burden. This commit removes the tests. --- backend/cache/cache_internal_test.go | 350 +++------------------- backend/cache/cache_mount_other_test.go | 21 -- backend/cache/cache_mount_unix_test.go | 82 ----- backend/cache/cache_mount_windows_test.go | 128 -------- 4 files changed, 39 insertions(+), 542 deletions(-) delete mode 100644 backend/cache/cache_mount_other_test.go delete mode 100644 backend/cache/cache_mount_unix_test.go delete mode 100644 backend/cache/cache_mount_windows_test.go diff --git a/backend/cache/cache_internal_test.go b/backend/cache/cache_internal_test.go index 2f13340f9..be2cbfcba 100644 --- a/backend/cache/cache_internal_test.go +++ b/backend/cache/cache_internal_test.go @@ -16,7 +16,6 @@ import ( "os" "path" "path/filepath" - "runtime" "runtime/debug" "strings" "testing" @@ -31,13 +30,10 @@ import ( "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" "github.com/rclone/rclone/fs/object" - "github.com/rclone/rclone/fs/rc" "github.com/rclone/rclone/fstest" "github.com/rclone/rclone/fstest/testy" "github.com/rclone/rclone/lib/random" - "github.com/rclone/rclone/vfs" "github.com/rclone/rclone/vfs/vfsflags" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -53,9 +49,7 @@ const ( var ( remoteName string - mountDir string uploadDir string - useMount bool runInstance *run errNotSupported = errors.New("not supported") decryptedToEncryptedRemotes = map[string]string{ @@ -91,9 +85,7 @@ var ( func init() { goflag.StringVar(&remoteName, "remote-internal", "TestInternalCache", "Remote to test with, defaults to local filesystem") - goflag.StringVar(&mountDir, "mount-dir-internal", "", "") goflag.StringVar(&uploadDir, "upload-dir-internal", "", "") - goflag.BoolVar(&useMount, "cache-use-mount", false, "Test only with mount") } // TestMain drives the tests @@ -101,7 +93,7 @@ func TestMain(m *testing.M) { goflag.Parse() var rc int - log.Printf("Running with the following params: \n remote: %v, \n mount: %v", remoteName, useMount) + log.Printf("Running with the following params: \n remote: %v", remoteName) runInstance = newRun() rc = m.Run() os.Exit(rc) @@ -274,31 +266,6 @@ func TestInternalObjNotFound(t *testing.T) { require.Nil(t, obj) } -func TestInternalRemoteWrittenFileFoundInMount(t *testing.T) { - if !runInstance.useMount { - t.Skip("test needs mount mode") - } - id := fmt.Sprintf("tirwffim%v", time.Now().Unix()) - rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, true, true, nil, nil) - defer runInstance.cleanupFs(t, rootFs, boltDb) - - cfs, err := runInstance.getCacheFs(rootFs) - require.NoError(t, err) - - var testData []byte - if runInstance.rootIsCrypt { - testData, err = base64.StdEncoding.DecodeString(cryptedTextBase64) - require.NoError(t, err) - } else { - testData = []byte("test content") - } - - runInstance.writeObjectBytes(t, cfs.UnWrap(), runInstance.encryptRemoteIfNeeded(t, "test"), testData) - data, err := runInstance.readDataFromRemote(t, rootFs, "test", 0, int64(len([]byte("test content"))), false) - require.NoError(t, err) - require.Equal(t, "test content", string(data)) -} - func TestInternalCachedWrittenContentMatches(t *testing.T) { testy.SkipUnreliable(t) id := fmt.Sprintf("ticwcm%v", time.Now().Unix()) @@ -694,79 +661,6 @@ func TestInternalChangeSeenAfterDirCacheFlush(t *testing.T) { require.Equal(t, wrappedTime.Unix(), co.ModTime(context.Background()).Unix()) } -func TestInternalChangeSeenAfterRc(t *testing.T) { - cacheExpire := rc.Calls.Get("cache/expire") - assert.NotNil(t, cacheExpire) - - id := fmt.Sprintf("ticsarc%v", time.Now().Unix()) - rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, false, true, nil, nil) - defer runInstance.cleanupFs(t, rootFs, boltDb) - - if !runInstance.useMount { - t.Skipf("needs mount") - } - if !runInstance.wrappedIsExternal { - t.Skipf("needs drive") - } - - cfs, err := runInstance.getCacheFs(rootFs) - require.NoError(t, err) - chunkSize := cfs.ChunkSize() - - // create some rand test data - testData := randStringBytes(int(chunkSize*4 + chunkSize/2)) - runInstance.writeRemoteBytes(t, rootFs, "data.bin", testData) - - // update in the wrapped fs - o, err := cfs.UnWrap().NewObject(context.Background(), runInstance.encryptRemoteIfNeeded(t, "data.bin")) - require.NoError(t, err) - wrappedTime := time.Now().Add(-1 * time.Hour) - err = o.SetModTime(context.Background(), wrappedTime) - require.NoError(t, err) - - // get a new instance from the cache - co, err := rootFs.NewObject(context.Background(), "data.bin") - require.NoError(t, err) - require.NotEqual(t, o.ModTime(context.Background()).String(), co.ModTime(context.Background()).String()) - - // Call the rc function - m, err := cacheExpire.Fn(context.Background(), rc.Params{"remote": "data.bin"}) - require.NoError(t, err) - require.Contains(t, m, "status") - require.Contains(t, m, "message") - require.Equal(t, "ok", m["status"]) - require.Contains(t, m["message"], "cached file cleared") - - // get a new instance from the cache - co, err = rootFs.NewObject(context.Background(), "data.bin") - require.NoError(t, err) - require.Equal(t, wrappedTime.Unix(), co.ModTime(context.Background()).Unix()) - _, err = runInstance.list(t, rootFs, "") - require.NoError(t, err) - - // create some rand test data - testData2 := randStringBytes(int(chunkSize)) - runInstance.writeObjectBytes(t, cfs.UnWrap(), runInstance.encryptRemoteIfNeeded(t, "test2"), testData2) - - // list should have 1 item only - li1, err := runInstance.list(t, rootFs, "") - require.NoError(t, err) - require.Len(t, li1, 1) - - // Call the rc function - m, err = cacheExpire.Fn(context.Background(), rc.Params{"remote": "/"}) - require.NoError(t, err) - require.Contains(t, m, "status") - require.Contains(t, m, "message") - require.Equal(t, "ok", m["status"]) - require.Contains(t, m["message"], "cached directory cleared") - - // list should have 2 items now - li2, err := runInstance.list(t, rootFs, "") - require.NoError(t, err) - require.Len(t, li2, 2) -} - func TestInternalCacheWrites(t *testing.T) { id := "ticw" rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, false, true, nil, map[string]string{"writes": "true"}) @@ -914,15 +808,9 @@ func TestInternalBug2117(t *testing.T) { type run struct { okDiff time.Duration runDefaultCfgMap configmap.Simple - mntDir string tmpUploadDir string - useMount bool - isMounted bool rootIsCrypt bool wrappedIsExternal bool - unmountFn func() error - unmountRes chan error - vfs *vfs.VFS tempFiles []*os.File dbPath string chunkPath string @@ -932,9 +820,7 @@ type run struct { func newRun() *run { var err error r := &run{ - okDiff: time.Second * 9, // really big diff here but the build machines seem to be slow. need a different way for this - useMount: useMount, - isMounted: false, + okDiff: time.Second * 9, // really big diff here but the build machines seem to be slow. need a different way for this } // Read in all the defaults for all the options @@ -947,32 +833,6 @@ func newRun() *run { r.runDefaultCfgMap.Set(option.Name, fmt.Sprint(option.Default)) } - if mountDir == "" { - if runtime.GOOS != "windows" { - r.mntDir, err = ioutil.TempDir("", "rclonecache-mount") - if err != nil { - log.Fatalf("Failed to create mount dir: %v", err) - return nil - } - } else { - // Find a free drive letter - drive := "" - for letter := 'E'; letter <= 'Z'; letter++ { - drive = string(letter) + ":" - _, err := os.Stat(drive + "\\") - if os.IsNotExist(err) { - goto found - } - } - log.Print("Couldn't find free drive letter for test") - found: - r.mntDir = drive - } - } else { - r.mntDir = mountDir - } - log.Printf("Mount Dir: %v", r.mntDir) - if uploadDir == "" { r.tmpUploadDir, err = ioutil.TempDir("", "rclonecache-tmp") if err != nil { @@ -1091,28 +951,16 @@ func (r *run) newCacheFs(t *testing.T, remote, id string, needRemote, purge bool } err = f.Mkdir(context.Background(), "") require.NoError(t, err) - if r.useMount && !r.isMounted { - r.mountFs(t, f) - } - return f, boltDb } func (r *run) cleanupFs(t *testing.T, f fs.Fs, b *cache.Persistent) { - if r.useMount && r.isMounted { - r.unmountFs(t, f) - } - err := f.Features().Purge(context.Background()) require.NoError(t, err) cfs, err := r.getCacheFs(f) require.NoError(t, err) cfs.StopBackgroundRunners() - if r.useMount && runtime.GOOS != "windows" { - err = os.RemoveAll(r.mntDir) - require.NoError(t, err) - } err = os.RemoveAll(r.tmpUploadDir) require.NoError(t, err) @@ -1152,37 +1000,11 @@ func (r *run) writeObjectString(t *testing.T, f fs.Fs, remote, content string) f } func (r *run) writeRemoteBytes(t *testing.T, f fs.Fs, remote string, data []byte) { - var err error - - if r.useMount { - err = r.retryBlock(func() error { - return ioutil.WriteFile(path.Join(r.mntDir, remote), data, 0600) - }, 3, time.Second*3) - require.NoError(t, err) - r.vfs.WaitForWriters(10 * time.Second) - } else { - r.writeObjectBytes(t, f, remote, data) - } + r.writeObjectBytes(t, f, remote, data) } func (r *run) writeRemoteReader(t *testing.T, f fs.Fs, remote string, in io.ReadCloser) { - defer func() { - _ = in.Close() - }() - - if r.useMount { - out, err := os.Create(path.Join(r.mntDir, remote)) - require.NoError(t, err) - defer func() { - _ = out.Close() - }() - - _, err = io.Copy(out, in) - require.NoError(t, err) - r.vfs.WaitForWriters(10 * time.Second) - } else { - r.writeObjectReader(t, f, remote, in) - } + r.writeObjectReader(t, f, remote, in) } func (r *run) writeObjectBytes(t *testing.T, f fs.Fs, remote string, data []byte) fs.Object { @@ -1199,10 +1021,6 @@ func (r *run) writeObjectReader(t *testing.T, f fs.Fs, remote string, in io.Read objInfo := object.NewStaticObjectInfo(remote, modTime, -1, true, nil, f) obj, err := f.Put(context.Background(), in, objInfo) require.NoError(t, err) - if r.useMount { - r.vfs.WaitForWriters(10 * time.Second) - } - return obj } @@ -1210,26 +1028,16 @@ func (r *run) updateObjectRemote(t *testing.T, f fs.Fs, remote string, data1 []b var err error var obj fs.Object - if r.useMount { - err = ioutil.WriteFile(path.Join(r.mntDir, remote), data1, 0600) - require.NoError(t, err) - r.vfs.WaitForWriters(10 * time.Second) - err = ioutil.WriteFile(path.Join(r.mntDir, remote), data2, 0600) - require.NoError(t, err) - r.vfs.WaitForWriters(10 * time.Second) - obj, err = f.NewObject(context.Background(), remote) - } else { - in1 := bytes.NewReader(data1) - in2 := bytes.NewReader(data2) - objInfo1 := object.NewStaticObjectInfo(remote, time.Now(), int64(len(data1)), true, nil, f) - objInfo2 := object.NewStaticObjectInfo(remote, time.Now(), int64(len(data2)), true, nil, f) + in1 := bytes.NewReader(data1) + in2 := bytes.NewReader(data2) + objInfo1 := object.NewStaticObjectInfo(remote, time.Now(), int64(len(data1)), true, nil, f) + objInfo2 := object.NewStaticObjectInfo(remote, time.Now(), int64(len(data2)), true, nil, f) - obj, err = f.Put(context.Background(), in1, objInfo1) - require.NoError(t, err) - obj, err = f.NewObject(context.Background(), remote) - require.NoError(t, err) - err = obj.Update(context.Background(), in2, objInfo2) - } + obj, err = f.Put(context.Background(), in1, objInfo1) + require.NoError(t, err) + obj, err = f.NewObject(context.Background(), remote) + require.NoError(t, err) + err = obj.Update(context.Background(), in2, objInfo2) require.NoError(t, err) return obj @@ -1239,30 +1047,12 @@ func (r *run) readDataFromRemote(t *testing.T, f fs.Fs, remote string, offset, e size := end - offset checkSample := make([]byte, size) - if r.useMount { - f, err := os.Open(path.Join(r.mntDir, remote)) - defer func() { - _ = f.Close() - }() - if err != nil { - return checkSample, err - } - _, _ = f.Seek(offset, io.SeekStart) - totalRead, err := io.ReadFull(f, checkSample) - checkSample = checkSample[:totalRead] - if err == io.EOF || err == io.ErrUnexpectedEOF { - err = nil - } - if err != nil { - return checkSample, err - } - } else { - co, err := f.NewObject(context.Background(), remote) - if err != nil { - return checkSample, err - } - checkSample = r.readDataFromObj(t, co, offset, end, noLengthCheck) + co, err := f.NewObject(context.Background(), remote) + if err != nil { + return checkSample, err } + checkSample = r.readDataFromObj(t, co, offset, end, noLengthCheck) + if !noLengthCheck && size != int64(len(checkSample)) { return checkSample, errors.Errorf("read size doesn't match expected: %v <> %v", len(checkSample), size) } @@ -1285,28 +1075,19 @@ func (r *run) readDataFromObj(t *testing.T, o fs.Object, offset, end int64, noLe } func (r *run) mkdir(t *testing.T, f fs.Fs, remote string) { - var err error - if r.useMount { - err = os.Mkdir(path.Join(r.mntDir, remote), 0700) - } else { - err = f.Mkdir(context.Background(), remote) - } + err := f.Mkdir(context.Background(), remote) require.NoError(t, err) } func (r *run) rm(t *testing.T, f fs.Fs, remote string) error { var err error - if r.useMount { - err = os.Remove(path.Join(r.mntDir, remote)) + var obj fs.Object + obj, err = f.NewObject(context.Background(), remote) + if err != nil { + err = f.Rmdir(context.Background(), remote) } else { - var obj fs.Object - obj, err = f.NewObject(context.Background(), remote) - if err != nil { - err = f.Rmdir(context.Background(), remote) - } else { - err = obj.Remove(context.Background()) - } + err = obj.Remove(context.Background()) } return err @@ -1315,18 +1096,10 @@ func (r *run) rm(t *testing.T, f fs.Fs, remote string) error { func (r *run) list(t *testing.T, f fs.Fs, remote string) ([]interface{}, error) { var err error var l []interface{} - if r.useMount { - var list []os.FileInfo - list, err = ioutil.ReadDir(path.Join(r.mntDir, remote)) - for _, ll := range list { - l = append(l, ll) - } - } else { - var list fs.DirEntries - list, err = f.List(context.Background(), remote) - for _, ll := range list { - l = append(l, ll) - } + var list fs.DirEntries + list, err = f.List(context.Background(), remote) + for _, ll := range list { + l = append(l, ll) } return l, err } @@ -1355,13 +1128,7 @@ func (r *run) copyFile(t *testing.T, f fs.Fs, src, dst string) error { func (r *run) dirMove(t *testing.T, rootFs fs.Fs, src, dst string) error { var err error - if runInstance.useMount { - err = os.Rename(path.Join(runInstance.mntDir, src), path.Join(runInstance.mntDir, dst)) - if err != nil { - return err - } - r.vfs.WaitForWriters(10 * time.Second) - } else if rootFs.Features().DirMove != nil { + if rootFs.Features().DirMove != nil { err = rootFs.Features().DirMove(context.Background(), rootFs, src, dst) if err != nil { return err @@ -1377,13 +1144,7 @@ func (r *run) dirMove(t *testing.T, rootFs fs.Fs, src, dst string) error { func (r *run) move(t *testing.T, rootFs fs.Fs, src, dst string) error { var err error - if runInstance.useMount { - err = os.Rename(path.Join(runInstance.mntDir, src), path.Join(runInstance.mntDir, dst)) - if err != nil { - return err - } - r.vfs.WaitForWriters(10 * time.Second) - } else if rootFs.Features().Move != nil { + if rootFs.Features().Move != nil { obj1, err := rootFs.NewObject(context.Background(), src) if err != nil { return err @@ -1403,13 +1164,7 @@ func (r *run) move(t *testing.T, rootFs fs.Fs, src, dst string) error { func (r *run) copy(t *testing.T, rootFs fs.Fs, src, dst string) error { var err error - if r.useMount { - err = r.copyFile(t, rootFs, path.Join(r.mntDir, src), path.Join(r.mntDir, dst)) - if err != nil { - return err - } - r.vfs.WaitForWriters(10 * time.Second) - } else if rootFs.Features().Copy != nil { + if rootFs.Features().Copy != nil { obj, err := rootFs.NewObject(context.Background(), src) if err != nil { return err @@ -1429,13 +1184,6 @@ func (r *run) copy(t *testing.T, rootFs fs.Fs, src, dst string) error { func (r *run) modTime(t *testing.T, rootFs fs.Fs, src string) (time.Time, error) { var err error - if r.useMount { - fi, err := os.Stat(path.Join(runInstance.mntDir, src)) - if err != nil { - return time.Time{}, err - } - return fi.ModTime(), nil - } obj1, err := rootFs.NewObject(context.Background(), src) if err != nil { return time.Time{}, err @@ -1446,13 +1194,6 @@ func (r *run) modTime(t *testing.T, rootFs fs.Fs, src string) (time.Time, error) func (r *run) size(t *testing.T, rootFs fs.Fs, src string) (int64, error) { var err error - if r.useMount { - fi, err := os.Stat(path.Join(runInstance.mntDir, src)) - if err != nil { - return int64(0), err - } - return fi.Size(), nil - } obj1, err := rootFs.NewObject(context.Background(), src) if err != nil { return int64(0), err @@ -1463,28 +1204,15 @@ func (r *run) size(t *testing.T, rootFs fs.Fs, src string) (int64, error) { func (r *run) updateData(t *testing.T, rootFs fs.Fs, src, data, append string) error { var err error - if r.useMount { - var f *os.File - f, err = os.OpenFile(path.Join(runInstance.mntDir, src), os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return err - } - defer func() { - _ = f.Close() - r.vfs.WaitForWriters(10 * time.Second) - }() - _, err = f.WriteString(data + append) - } else { - var obj1 fs.Object - obj1, err = rootFs.NewObject(context.Background(), src) - if err != nil { - return err - } - data1 := []byte(data + append) - r := bytes.NewReader(data1) - objInfo1 := object.NewStaticObjectInfo(src, time.Now(), int64(len(data1)), true, nil, rootFs) - err = obj1.Update(context.Background(), r, objInfo1) + var obj1 fs.Object + obj1, err = rootFs.NewObject(context.Background(), src) + if err != nil { + return err } + data1 := []byte(data + append) + reader := bytes.NewReader(data1) + objInfo1 := object.NewStaticObjectInfo(src, time.Now(), int64(len(data1)), true, nil, rootFs) + err = obj1.Update(context.Background(), reader, objInfo1) return err } diff --git a/backend/cache/cache_mount_other_test.go b/backend/cache/cache_mount_other_test.go deleted file mode 100644 index fc1f61260..000000000 --- a/backend/cache/cache_mount_other_test.go +++ /dev/null @@ -1,21 +0,0 @@ -// +build !linux !go1.13 -// +build !darwin !go1.13 -// +build !freebsd !go1.13 -// +build !windows -// +build !race - -package cache_test - -import ( - "testing" - - "github.com/rclone/rclone/fs" -) - -func (r *run) mountFs(t *testing.T, f fs.Fs) { - panic("mountFs not defined for this platform") -} - -func (r *run) unmountFs(t *testing.T, f fs.Fs) { - panic("unmountFs not defined for this platform") -} diff --git a/backend/cache/cache_mount_unix_test.go b/backend/cache/cache_mount_unix_test.go deleted file mode 100644 index 44ab30ed5..000000000 --- a/backend/cache/cache_mount_unix_test.go +++ /dev/null @@ -1,82 +0,0 @@ -// +build linux,go1.13 darwin,go1.13 freebsd,go1.13 -// +build !race - -package cache_test - -import ( - "os" - "testing" - "time" - - "bazil.org/fuse" - fusefs "bazil.org/fuse/fs" - "github.com/rclone/rclone/cmd/mount" - "github.com/rclone/rclone/cmd/mountlib" - "github.com/rclone/rclone/fs" - "github.com/rclone/rclone/vfs" - "github.com/rclone/rclone/vfs/vfsflags" - "github.com/stretchr/testify/require" -) - -func (r *run) mountFs(t *testing.T, f fs.Fs) { - device := f.Name() + ":" + f.Root() - var options = []fuse.MountOption{ - fuse.MaxReadahead(uint32(mountlib.Opt.MaxReadAhead)), - fuse.Subtype("rclone"), - fuse.FSName(device), fuse.VolumeName(device), - fuse.NoAppleDouble(), - fuse.NoAppleXattr(), - //fuse.AllowOther(), - } - err := os.MkdirAll(r.mntDir, os.ModePerm) - require.NoError(t, err) - c, err := fuse.Mount(r.mntDir, options...) - require.NoError(t, err) - VFS := vfs.New(f, &vfsflags.Opt) - filesys := mount.NewFS(VFS, &mountlib.Opt) - server := fusefs.New(c, nil) - - // Serve the mount point in the background returning error to errChan - r.unmountRes = make(chan error, 1) - go func() { - err := server.Serve(filesys) - closeErr := c.Close() - if err == nil { - err = closeErr - } - r.unmountRes <- err - }() - - // check if the mount process has an error to report - <-c.Ready - require.NoError(t, c.MountError) - - r.unmountFn = func() error { - // Shutdown the VFS - filesys.VFS.Shutdown() - return fuse.Unmount(r.mntDir) - } - - r.vfs = filesys.VFS - r.isMounted = true -} - -func (r *run) unmountFs(t *testing.T, f fs.Fs) { - var err error - - for i := 0; i < 4; i++ { - err = r.unmountFn() - if err != nil { - //log.Printf("signal to umount failed - retrying: %v", err) - time.Sleep(3 * time.Second) - continue - } - break - } - require.NoError(t, err) - err = <-r.unmountRes - require.NoError(t, err) - err = r.vfs.CleanUp() - require.NoError(t, err) - r.isMounted = false -} diff --git a/backend/cache/cache_mount_windows_test.go b/backend/cache/cache_mount_windows_test.go deleted file mode 100644 index b55edd627..000000000 --- a/backend/cache/cache_mount_windows_test.go +++ /dev/null @@ -1,128 +0,0 @@ -// +build windows -// +build !race - -package cache_test - -import ( - "fmt" - "os" - "testing" - "time" - - "github.com/billziss-gh/cgofuse/fuse" - "github.com/pkg/errors" - "github.com/rclone/rclone/cmd/cmount" - "github.com/rclone/rclone/cmd/mountlib" - "github.com/rclone/rclone/fs" - "github.com/rclone/rclone/vfs" - "github.com/rclone/rclone/vfs/vfsflags" - "github.com/stretchr/testify/require" -) - -// waitFor runs fn() until it returns true or the timeout expires -func waitFor(fn func() bool) (ok bool) { - const totalWait = 10 * time.Second - const individualWait = 10 * time.Millisecond - for i := 0; i < int(totalWait/individualWait); i++ { - ok = fn() - if ok { - return ok - } - time.Sleep(individualWait) - } - return false -} - -func (r *run) mountFs(t *testing.T, f fs.Fs) { - // FIXME implement cmount - t.Skip("windows not supported yet") - - device := f.Name() + ":" + f.Root() - options := []string{ - "-o", "fsname=" + device, - "-o", "subtype=rclone", - "-o", fmt.Sprintf("max_readahead=%d", mountlib.Opt.MaxReadAhead), - "-o", "uid=-1", - "-o", "gid=-1", - "-o", "allow_other", - // This causes FUSE to supply O_TRUNC with the Open - // call which is more efficient for cmount. However - // it does not work with cgofuse on Windows with - // WinFSP so cmount must work with or without it. - "-o", "atomic_o_trunc", - "--FileSystemName=rclone", - } - - VFS := vfs.New(f, &vfsflags.Opt) - fsys := cmount.NewFS(VFS) - host := fuse.NewFileSystemHost(fsys) - - // Serve the mount point in the background returning error to errChan - r.unmountRes = make(chan error, 1) - go func() { - var err error - ok := host.Mount(r.mntDir, options) - if !ok { - err = errors.New("mount failed") - } - r.unmountRes <- err - }() - - // unmount - r.unmountFn = func() error { - // Shutdown the VFS - fsys.VFS.Shutdown() - if host.Unmount() { - if !waitFor(func() bool { - _, err := os.Stat(r.mntDir) - return err != nil - }) { - t.Fatalf("mountpoint %q didn't disappear after unmount - continuing anyway", r.mntDir) - } - return nil - } - return errors.New("host unmount failed") - } - - // Wait for the filesystem to become ready, checking the file - // system didn't blow up before starting - select { - case err := <-r.unmountRes: - require.NoError(t, err) - case <-time.After(time.Second * 3): - } - - // Wait for the mount point to be available on Windows - // On Windows the Init signal comes slightly before the mount is ready - if !waitFor(func() bool { - _, err := os.Stat(r.mntDir) - return err == nil - }) { - t.Errorf("mountpoint %q didn't became available on mount", r.mntDir) - } - - r.vfs = fsys.VFS - r.isMounted = true -} - -func (r *run) unmountFs(t *testing.T, f fs.Fs) { - // FIXME implement cmount - t.Skip("windows not supported yet") - var err error - - for i := 0; i < 4; i++ { - err = r.unmountFn() - if err != nil { - //log.Printf("signal to umount failed - retrying: %v", err) - time.Sleep(3 * time.Second) - continue - } - break - } - require.NoError(t, err) - err = <-r.unmountRes - require.NoError(t, err) - err = r.vfs.CleanUp() - require.NoError(t, err) - r.isMounted = false -}