package mountlib_test import ( "context" "io/ioutil" "os" "path/filepath" "runtime" "testing" "time" _ "github.com/rclone/rclone/backend/local" _ "github.com/rclone/rclone/cmd/cmount" _ "github.com/rclone/rclone/cmd/mount" _ "github.com/rclone/rclone/cmd/mount2" "github.com/rclone/rclone/cmd/mountlib" "github.com/rclone/rclone/fs/config/configfile" "github.com/rclone/rclone/fs/rc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestRc(t *testing.T) { ctx := context.Background() configfile.Install() mount := rc.Calls.Get("mount/mount") assert.NotNil(t, mount) unmount := rc.Calls.Get("mount/unmount") assert.NotNil(t, unmount) getMountTypes := rc.Calls.Get("mount/types") assert.NotNil(t, getMountTypes) localDir, err := ioutil.TempDir("", "rclone-mountlib-localDir") require.NoError(t, err) defer func() { _ = os.RemoveAll(localDir) }() err = ioutil.WriteFile(filepath.Join(localDir, "file.txt"), []byte("hello"), 0666) require.NoError(t, err) mountPoint, err := ioutil.TempDir("", "rclone-mountlib-mountPoint") require.NoError(t, err) if runtime.GOOS == "windows" { // Windows requires the mount point not to exist require.NoError(t, os.RemoveAll(mountPoint)) } else { defer func() { _ = os.RemoveAll(mountPoint) }() } out, err := getMountTypes.Fn(ctx, nil) require.NoError(t, err) var mountTypes []string err = out.GetStruct("mountTypes", &mountTypes) require.NoError(t, err) t.Logf("Mount types %v", mountTypes) t.Run("Errors", func(t *testing.T) { _, err := mount.Fn(ctx, rc.Params{}) assert.Error(t, err) _, err = mount.Fn(ctx, rc.Params{"fs": "/tmp"}) assert.Error(t, err) _, err = mount.Fn(ctx, rc.Params{"mountPoint": "/tmp"}) assert.Error(t, err) }) t.Run("Mount", func(t *testing.T) { if len(mountTypes) == 0 { t.Skip("Can't mount") } in := rc.Params{ "fs": localDir, "mountPoint": mountPoint, "vfsOpt": rc.Params{ "FilePerms": 0400, }, } // check file.txt is not there filePath := filepath.Join(mountPoint, "file.txt") _, err := os.Stat(filePath) require.Error(t, err) require.True(t, os.IsNotExist(err)) // mount _, err = mount.Fn(ctx, in) if err != nil { t.Skipf("Mount failed - skipping test: %v", err) } // check file.txt is there now fi, err := os.Stat(filePath) require.NoError(t, err) assert.Equal(t, int64(5), fi.Size()) if runtime.GOOS == "linux" { assert.Equal(t, os.FileMode(0400), fi.Mode()) } // check mount point list checkMountList := func() []mountlib.MountInfo { listCall := rc.Calls.Get("mount/listmounts") require.NotNil(t, listCall) listReply, err := listCall.Fn(ctx, rc.Params{}) require.NoError(t, err) mountPointsReply, err := listReply.Get("mountPoints") require.NoError(t, err) mountPoints, ok := mountPointsReply.([]mountlib.MountInfo) require.True(t, ok) return mountPoints } mountPoints := checkMountList() require.Equal(t, 1, len(mountPoints)) require.Equal(t, mountPoint, mountPoints[0].MountPoint) // FIXME the OS sometimes appears to be using the mount // immediately after it appears so wait a moment time.Sleep(100 * time.Millisecond) t.Run("Unmount", func(t *testing.T) { _, err := unmount.Fn(ctx, in) require.NoError(t, err) assert.Equal(t, 0, len(checkMountList())) }) }) }