125 lines · 2.9 KB · Go
RawDownload
// +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/stretchr/testify/require") // waitFor runs fn() until it returns true or the timeout expiresfunc 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.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",	} 	fsys := cmount.NewFS(f)	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}