union: fix so all integration tests pass

* Fix error handling in List and NewObject
* Fix Precision in case we have precision > time.Second
* Fix Features - all binary features are possible
* Fix integration tests using new test facilities
This commit is contained in:
Nick Craig-Wood 2018-09-03 18:00:23 +01:00
parent e05ec2b77e
commit 1b2cc781e5
2 changed files with 29 additions and 12 deletions

View file

@ -1,7 +1,6 @@
package union package union
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"path" "path"
@ -13,6 +12,7 @@ import (
"github.com/ncw/rclone/fs/config/configmap" "github.com/ncw/rclone/fs/config/configmap"
"github.com/ncw/rclone/fs/config/configstruct" "github.com/ncw/rclone/fs/config/configstruct"
"github.com/ncw/rclone/fs/hash" "github.com/ncw/rclone/fs/hash"
"github.com/pkg/errors"
) )
// Register with Fs // Register with Fs
@ -100,16 +100,23 @@ func (f *Fs) Put(in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (fs.
// found. // found.
func (f *Fs) List(dir string) (entries fs.DirEntries, err error) { func (f *Fs) List(dir string) (entries fs.DirEntries, err error) {
set := make(map[string]fs.DirEntry) set := make(map[string]fs.DirEntry)
found := false
for _, remote := range f.remotes { for _, remote := range f.remotes {
var remoteEntries, err = remote.List(dir) var remoteEntries, err = remote.List(dir)
if err != nil { if err == fs.ErrorDirNotFound {
continue continue
} }
if err != nil {
return nil, errors.Wrapf(err, "List failed on %v", remote)
}
found = true
for _, remoteEntry := range remoteEntries { for _, remoteEntry := range remoteEntries {
set[remoteEntry.Remote()] = remoteEntry set[remoteEntry.Remote()] = remoteEntry
} }
} }
if !found {
return nil, fs.ErrorDirNotFound
}
for key := range set { for key := range set {
entries = append(entries, set[key]) entries = append(entries, set[key])
} }
@ -121,9 +128,12 @@ func (f *Fs) NewObject(path string) (fs.Object, error) {
for i := range f.remotes { for i := range f.remotes {
var remote = f.remotes[len(f.remotes)-i-1] var remote = f.remotes[len(f.remotes)-i-1]
var obj, err = remote.NewObject(path) var obj, err = remote.NewObject(path)
if err != nil { if err == fs.ErrorObjectNotFound {
continue continue
} }
if err != nil {
return nil, errors.Wrapf(err, "NewObject failed on %v", remote)
}
return obj, nil return obj, nil
} }
return nil, fs.ErrorObjectNotFound return nil, fs.ErrorObjectNotFound
@ -131,12 +141,11 @@ func (f *Fs) NewObject(path string) (fs.Object, error) {
// Precision is the greatest Precision of all remotes // Precision is the greatest Precision of all remotes
func (f *Fs) Precision() time.Duration { func (f *Fs) Precision() time.Duration {
var greatestPrecision = time.Second var greatestPrecision time.Duration
for _, remote := range f.remotes { for _, remote := range f.remotes {
if remote.Precision() <= greatestPrecision { if remote.Precision() > greatestPrecision {
continue greatestPrecision = remote.Precision()
} }
greatestPrecision = remote.Precision()
} }
return greatestPrecision return greatestPrecision
} }
@ -196,7 +205,14 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
opt: *opt, opt: *opt,
remotes: remotes, remotes: remotes,
} }
var features = (&fs.Features{}).Fill(f) var features = (&fs.Features{
CaseInsensitive: true,
DuplicateFiles: false,
ReadMimeType: true,
WriteMimeType: true,
CanHaveEmptyDirectories: true,
BucketBased: true,
}).Fill(f)
for _, remote := range f.remotes { for _, remote := range f.remotes {
features = features.Mask(remote) features = features.Mask(remote)
} }

View file

@ -4,14 +4,15 @@ package union_test
import ( import (
"testing" "testing"
"github.com/ncw/rclone/backend/local" _ "github.com/ncw/rclone/backend/local"
"github.com/ncw/rclone/fstest/fstests" "github.com/ncw/rclone/fstest/fstests"
) )
// TestIntegration runs integration tests against the remote // TestIntegration runs integration tests against the remote
func TestIntegration(t *testing.T) { func TestIntegration(t *testing.T) {
fstests.Run(t, &fstests.Opt{ fstests.Run(t, &fstests.Opt{
RemoteName: "TestUnion:", RemoteName: "TestUnion:",
NilObject: (*local.Object)(nil), NilObject: nil,
SkipFsMatch: true,
}) })
} }