From ac7e1dbf62e44c6051fcb6c96c373d67e301cd48 Mon Sep 17 00:00:00 2001
From: Nick Craig-Wood <nick@craig-wood.com>
Date: Wed, 27 Feb 2019 17:14:32 +0000
Subject: [PATCH] test_all: add the vfs tests to the integration tests

Fix failing tests for some remotes
---
 fstest/test_all/config.yaml |  1 +
 vfs/dir_test.go             |  6 ++++++
 vfs/file_test.go            |  3 +++
 vfs/read_write_test.go      |  9 +++++++--
 vfs/vfs_test.go             |  4 ++++
 vfs/write_test.go           | 38 +++++++++++++++++++++++++++++++++++--
 6 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/fstest/test_all/config.yaml b/fstest/test_all/config.yaml
index 1521326c6..70e08de6e 100644
--- a/fstest/test_all/config.yaml
+++ b/fstest/test_all/config.yaml
@@ -8,6 +8,7 @@ tests:
  - path: fs/sync
    subdir:   true
    fastlist: true
+ - path: vfs
 backends:
  # - backend:  "amazonclouddrive"
  #   remote:   "TestAmazonCloudDrive:"
diff --git a/vfs/dir_test.go b/vfs/dir_test.go
index 43efa2a9a..9165d21e8 100644
--- a/vfs/dir_test.go
+++ b/vfs/dir_test.go
@@ -468,6 +468,12 @@ func TestDirRemoveName(t *testing.T) {
 func TestDirRename(t *testing.T) {
 	r := fstest.NewRun(t)
 	defer r.Finalise()
+
+	features := r.Fremote.Features()
+	if features.DirMove == nil && features.Move == nil && features.Copy == nil {
+		return // skip as can't rename directories
+	}
+
 	vfs, dir, file1 := dirCreate(t, r)
 	file3 := r.WriteObject("dir/file3", "file3 contents!", t1)
 	fstest.CheckListingWithPrecision(t, r.Fremote, []fstest.Item{file1, file3}, []string{"dir"}, r.Fremote.Precision())
diff --git a/vfs/file_test.go b/vfs/file_test.go
index 612086bc2..c3ed30896 100644
--- a/vfs/file_test.go
+++ b/vfs/file_test.go
@@ -77,6 +77,9 @@ func TestFileMethods(t *testing.T) {
 
 func TestFileSetModTime(t *testing.T) {
 	r := fstest.NewRun(t)
+	if !canSetModTime(t, r) {
+		return
+	}
 	defer r.Finalise()
 	vfs, file, file1 := fileCreate(t, r)
 
diff --git a/vfs/read_write_test.go b/vfs/read_write_test.go
index 9f147634d..b47c5b444 100644
--- a/vfs/read_write_test.go
+++ b/vfs/read_write_test.go
@@ -574,6 +574,9 @@ func TestRWFileHandleOpenTests(t *testing.T) {
 func TestRWFileModTimeWithOpenWriters(t *testing.T) {
 	r := fstest.NewRun(t)
 	defer r.Finalise()
+	if !canSetModTime(t, r) {
+		return
+	}
 	vfs, fh := rwHandleCreateWriteOnly(t, r)
 
 	mtime := time.Date(2012, time.November, 18, 17, 32, 31, 0, time.UTC)
@@ -590,6 +593,8 @@ func TestRWFileModTimeWithOpenWriters(t *testing.T) {
 	info, err := vfs.Stat("file1")
 	require.NoError(t, err)
 
-	// avoid errors because of timezone differences
-	assert.Equal(t, info.ModTime().Unix(), mtime.Unix())
+	if r.Fremote.Precision() != fs.ModTimeNotSupported {
+		// avoid errors because of timezone differences
+		assert.Equal(t, info.ModTime().Unix(), mtime.Unix())
+	}
 }
diff --git a/vfs/vfs_test.go b/vfs/vfs_test.go
index 1aa05550d..8ccd38e82 100644
--- a/vfs/vfs_test.go
+++ b/vfs/vfs_test.go
@@ -232,6 +232,10 @@ func TestVFSOpenFile(t *testing.T) {
 func TestVFSRename(t *testing.T) {
 	r := fstest.NewRun(t)
 	defer r.Finalise()
+	features := r.Fremote.Features()
+	if features.Move == nil && features.Copy == nil {
+		return // skip as can't rename files
+	}
 	vfs := New(r.Fremote, nil)
 
 	file1 := r.WriteObject("dir/file2", "file2 contents", t2)
diff --git a/vfs/write_test.go b/vfs/write_test.go
index fee7ddb12..ec721b9a3 100644
--- a/vfs/write_test.go
+++ b/vfs/write_test.go
@@ -2,6 +2,7 @@ package vfs
 
 import (
 	"os"
+	"sync"
 	"testing"
 	"time"
 
@@ -220,10 +221,41 @@ func TestWriteFileHandleRelease(t *testing.T) {
 	assert.True(t, fh.closed)
 }
 
+var (
+	canSetModTimeOnce  sync.Once
+	canSetModTimeValue = true
+)
+
+// returns whether the remote can set modtime
+func canSetModTime(t *testing.T, r *fstest.Run) bool {
+	canSetModTimeOnce.Do(func() {
+		mtime1 := time.Date(2008, time.November, 18, 17, 32, 31, 0, time.UTC)
+		_ = r.WriteObject("time_test", "stuff", mtime1)
+		obj, err := r.Fremote.NewObject("time_test")
+		require.NoError(t, err)
+		mtime2 := time.Date(2009, time.November, 18, 17, 32, 31, 0, time.UTC)
+		err = obj.SetModTime(mtime2)
+		switch err {
+		case nil:
+			canSetModTimeValue = true
+		case fs.ErrorCantSetModTime, fs.ErrorCantSetModTimeWithoutDelete:
+			canSetModTimeValue = false
+		default:
+			require.NoError(t, err)
+		}
+		require.NoError(t, obj.Remove())
+		fs.Debugf(nil, "Can set mod time: %v", canSetModTimeValue)
+	})
+	return canSetModTimeValue
+}
+
 // tests mod time on open files
 func TestWriteFileModTimeWithOpenWriters(t *testing.T) {
 	r := fstest.NewRun(t)
 	defer r.Finalise()
+	if !canSetModTime(t, r) {
+		return
+	}
 	vfs, fh := writeHandleCreate(t, r)
 
 	mtime := time.Date(2012, time.November, 18, 17, 32, 31, 0, time.UTC)
@@ -240,6 +272,8 @@ func TestWriteFileModTimeWithOpenWriters(t *testing.T) {
 	info, err := vfs.Stat("file1")
 	require.NoError(t, err)
 
-	// avoid errors because of timezone differences
-	assert.Equal(t, info.ModTime().Unix(), mtime.Unix())
+	if r.Fremote.Precision() != fs.ModTimeNotSupported {
+		// avoid errors because of timezone differences
+		assert.Equal(t, info.ModTime().Unix(), mtime.Unix())
+	}
 }