fstests: add tests for operations from the root of the Fs #3421

This commit is contained in:
Nick Craig-Wood 2019-08-08 22:42:43 +01:00
parent 743dabf159
commit df8bdf0dcb
2 changed files with 115 additions and 3 deletions

View file

@ -263,13 +263,15 @@ func filterEmptyDirs(t *testing.T, items []Item, expectedDirs []string) (newExpe
return newExpectedDirs return newExpectedDirs
} }
// CheckListingWithPrecision checks the fs to see if it has the // CheckListingWithRoot checks the fs to see if it has the
// expected contents with the given precision. // expected contents with the given precision.
// //
// If expectedDirs is non nil then we check those too. Note that no // If expectedDirs is non nil then we check those too. Note that no
// directories returned is also OK as some remotes don't return // directories returned is also OK as some remotes don't return
// directories. // directories.
func CheckListingWithPrecision(t *testing.T, f fs.Fs, items []Item, expectedDirs []string, precision time.Duration) { //
// dir is the directory used for the listing.
func CheckListingWithRoot(t *testing.T, f fs.Fs, dir string, items []Item, expectedDirs []string, precision time.Duration) {
if expectedDirs != nil && !f.Features().CanHaveEmptyDirectories { if expectedDirs != nil && !f.Features().CanHaveEmptyDirectories {
expectedDirs = filterEmptyDirs(t, items, expectedDirs) expectedDirs = filterEmptyDirs(t, items, expectedDirs)
} }
@ -285,7 +287,7 @@ func CheckListingWithPrecision(t *testing.T, f fs.Fs, items []Item, expectedDirs
gotListing := "<unset>" gotListing := "<unset>"
listingOK := false listingOK := false
for i := 1; i <= retries; i++ { for i := 1; i <= retries; i++ {
objs, dirs, err = walk.GetAll(ctx, f, "", true, -1) objs, dirs, err = walk.GetAll(ctx, f, dir, true, -1)
if err != nil && err != fs.ErrorDirNotFound { if err != nil && err != fs.ErrorDirNotFound {
t.Fatalf("Error listing: %v", err) t.Fatalf("Error listing: %v", err)
} }
@ -336,6 +338,16 @@ func CheckListingWithPrecision(t *testing.T, f fs.Fs, items []Item, expectedDirs
} }
} }
// CheckListingWithPrecision checks the fs to see if it has the
// expected contents with the given precision.
//
// If expectedDirs is non nil then we check those too. Note that no
// directories returned is also OK as some remotes don't return
// directories.
func CheckListingWithPrecision(t *testing.T, f fs.Fs, items []Item, expectedDirs []string, precision time.Duration) {
CheckListingWithRoot(t, f, "", items, expectedDirs, precision)
}
// CheckListing checks the fs to see if it has the expected contents // CheckListing checks the fs to see if it has the expected contents
func CheckListing(t *testing.T, f fs.Fs, items []Item) { func CheckListing(t *testing.T, f fs.Fs, items []Item) {
precision := f.Precision() precision := f.Precision()

View file

@ -26,6 +26,7 @@ import (
"github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config"
"github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/fserrors"
"github.com/rclone/rclone/fs/fspath"
"github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fs/hash"
"github.com/rclone/rclone/fs/object" "github.com/rclone/rclone/fs/object"
"github.com/rclone/rclone/fs/operations" "github.com/rclone/rclone/fs/operations"
@ -1377,6 +1378,105 @@ func Run(t *testing.T, opt *Opt) {
fstest.CheckListing(t, fileRemote, []fstest.Item{}) fstest.CheckListing(t, fileRemote, []fstest.Item{})
}) })
// Test that things work from the root
t.Run("FromRoot", func(t *testing.T) {
if features := remote.Features(); features.BucketBased && !features.BucketBasedRootOK {
t.Skip("Can't list from root on this remote")
}
configName, configLeaf := fspath.Parse(subRemoteName)
if configName == "" {
configName, configLeaf = path.Split(subRemoteName)
} else {
configName += ":"
}
t.Logf("Opening root remote %q path %q from %q", configName, configLeaf, subRemoteName)
rootRemote, err := fs.NewFs(configName)
require.NoError(t, err)
file1Root := file1
file1Root.Path = path.Join(configLeaf, file1Root.Path)
file2Root := file2
file2Root.Path = path.Join(configLeaf, file2Root.Path)
file2Root.WinPath = path.Join(configLeaf, file2Root.WinPath)
var dirs []string
dir := file2.Path
for {
dir = path.Dir(dir)
if dir == "" || dir == "." || dir == "/" {
break
}
dirs = append(dirs, path.Join(configLeaf, dir))
}
// Check that we can see file1 and file2 from the root
t.Run("List", func(t *testing.T) {
fstest.CheckListingWithRoot(t, rootRemote, configLeaf, []fstest.Item{file1Root, file2Root}, dirs, rootRemote.Precision())
})
// Check that that listing the entries is OK
t.Run("ListEntries", func(t *testing.T) {
entries, err := rootRemote.List(context.Background(), configLeaf)
require.NoError(t, err)
fstest.CompareItems(t, entries, []fstest.Item{file1Root}, dirs[len(dirs)-1:], rootRemote.Precision(), "ListEntries")
})
// List the root with ListR
t.Run("ListR", func(t *testing.T) {
doListR := rootRemote.Features().ListR
if doListR == nil {
t.Skip("FS has no ListR interface")
}
file1Found, file2Found := false, false
stopTime := time.Now().Add(10 * time.Second)
errTooMany := errors.New("too many files")
errFound := errors.New("found")
err := doListR(context.Background(), "", func(entries fs.DirEntries) error {
for _, entry := range entries {
remote := entry.Remote()
if remote == file1Root.Path {
file1Found = true
}
if remote == file2Root.Path {
file2Found = true
}
if file1Found && file2Found {
return errFound
}
}
if time.Now().After(stopTime) {
return errTooMany
}
return nil
})
if err != errFound && err != errTooMany {
assert.NoError(t, err)
}
if err != errTooMany {
assert.True(t, file1Found, "file1Root not found")
assert.True(t, file2Found, "file2Root not found")
} else {
t.Logf("Too many files to list - giving up")
}
})
// Create a new file
t.Run("Put", func(t *testing.T) {
file3Root := fstest.Item{
ModTime: time.Now(),
Path: path.Join(configLeaf, "created from root.txt"),
}
_, file3Obj := testPut(t, rootRemote, &file3Root)
fstest.CheckListingWithRoot(t, rootRemote, configLeaf, []fstest.Item{file1Root, file2Root, file3Root}, nil, rootRemote.Precision())
// And then remove it
t.Run("Remove", func(t *testing.T) {
require.NoError(t, file3Obj.Remove(context.Background()))
fstest.CheckListingWithRoot(t, rootRemote, configLeaf, []fstest.Item{file1Root, file2Root}, nil, rootRemote.Precision())
})
})
})
// TestPublicLink tests creation of sharable, public links // TestPublicLink tests creation of sharable, public links
// go test -v -run 'TestIntegration/Test(Setup|Init|FsMkdir|FsPutFile1|FsPutFile2|FsUpdateFile1|PublicLink)$' // go test -v -run 'TestIntegration/Test(Setup|Init|FsMkdir|FsPutFile1|FsPutFile2|FsUpdateFile1|PublicLink)$'
t.Run("PublicLink", func(t *testing.T) { t.Run("PublicLink", func(t *testing.T) {