github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/backend/cache/cache_mount_windows_test.go (about) 1 // +build windows 2 // +build !race 3 4 package cache_test 5 6 import ( 7 "fmt" 8 "os" 9 "testing" 10 "time" 11 12 "github.com/billziss-gh/cgofuse/fuse" 13 "github.com/pkg/errors" 14 "github.com/rclone/rclone/cmd/cmount" 15 "github.com/rclone/rclone/cmd/mountlib" 16 "github.com/rclone/rclone/fs" 17 "github.com/stretchr/testify/require" 18 ) 19 20 // waitFor runs fn() until it returns true or the timeout expires 21 func waitFor(fn func() bool) (ok bool) { 22 const totalWait = 10 * time.Second 23 const individualWait = 10 * time.Millisecond 24 for i := 0; i < int(totalWait/individualWait); i++ { 25 ok = fn() 26 if ok { 27 return ok 28 } 29 time.Sleep(individualWait) 30 } 31 return false 32 } 33 34 func (r *run) mountFs(t *testing.T, f fs.Fs) { 35 // FIXME implement cmount 36 t.Skip("windows not supported yet") 37 38 device := f.Name() + ":" + f.Root() 39 options := []string{ 40 "-o", "fsname=" + device, 41 "-o", "subtype=rclone", 42 "-o", fmt.Sprintf("max_readahead=%d", mountlib.MaxReadAhead), 43 "-o", "uid=-1", 44 "-o", "gid=-1", 45 "-o", "allow_other", 46 // This causes FUSE to supply O_TRUNC with the Open 47 // call which is more efficient for cmount. However 48 // it does not work with cgofuse on Windows with 49 // WinFSP so cmount must work with or without it. 50 "-o", "atomic_o_trunc", 51 "--FileSystemName=rclone", 52 } 53 54 fsys := cmount.NewFS(f) 55 host := fuse.NewFileSystemHost(fsys) 56 57 // Serve the mount point in the background returning error to errChan 58 r.unmountRes = make(chan error, 1) 59 go func() { 60 var err error 61 ok := host.Mount(r.mntDir, options) 62 if !ok { 63 err = errors.New("mount failed") 64 } 65 r.unmountRes <- err 66 }() 67 68 // unmount 69 r.unmountFn = func() error { 70 // Shutdown the VFS 71 fsys.VFS.Shutdown() 72 if host.Unmount() { 73 if !waitFor(func() bool { 74 _, err := os.Stat(r.mntDir) 75 return err != nil 76 }) { 77 t.Fatalf("mountpoint %q didn't disappear after unmount - continuing anyway", r.mntDir) 78 } 79 return nil 80 } 81 return errors.New("host unmount failed") 82 } 83 84 // Wait for the filesystem to become ready, checking the file 85 // system didn't blow up before starting 86 select { 87 case err := <-r.unmountRes: 88 require.NoError(t, err) 89 case <-time.After(time.Second * 3): 90 } 91 92 // Wait for the mount point to be available on Windows 93 // On Windows the Init signal comes slightly before the mount is ready 94 if !waitFor(func() bool { 95 _, err := os.Stat(r.mntDir) 96 return err == nil 97 }) { 98 t.Errorf("mountpoint %q didn't became available on mount", r.mntDir) 99 } 100 101 r.vfs = fsys.VFS 102 r.isMounted = true 103 } 104 105 func (r *run) unmountFs(t *testing.T, f fs.Fs) { 106 // FIXME implement cmount 107 t.Skip("windows not supported yet") 108 var err error 109 110 for i := 0; i < 4; i++ { 111 err = r.unmountFn() 112 if err != nil { 113 //log.Printf("signal to umount failed - retrying: %v", err) 114 time.Sleep(3 * time.Second) 115 continue 116 } 117 break 118 } 119 require.NoError(t, err) 120 err = <-r.unmountRes 121 require.NoError(t, err) 122 err = r.vfs.CleanUp() 123 require.NoError(t, err) 124 r.isMounted = false 125 }