mirror of
https://github.com/rclone/rclone
synced 2024-12-25 17:03:45 +01:00
fstest: add tests for coverage of optional methods for wrapping Fs
This commit is contained in:
parent
16d8014cbb
commit
2f21aa86b4
29
fs/fs.go
29
fs/fs.go
@ -370,6 +370,35 @@ type GetTierer interface {
|
||||
GetTier() string
|
||||
}
|
||||
|
||||
// ObjectOptionalInterfaces returns the names of supported and
|
||||
// unsupported optional interfaces for an Object
|
||||
func ObjectOptionalInterfaces(o Object) (supported, unsupported []string) {
|
||||
store := func(ok bool, name string) {
|
||||
if ok {
|
||||
supported = append(supported, name)
|
||||
} else {
|
||||
unsupported = append(unsupported, name)
|
||||
}
|
||||
}
|
||||
|
||||
_, ok := o.(MimeTyper)
|
||||
store(ok, "MimeType")
|
||||
|
||||
_, ok = o.(IDer)
|
||||
store(ok, "ID")
|
||||
|
||||
_, ok = o.(ObjectUnWrapper)
|
||||
store(ok, "UnWrap")
|
||||
|
||||
_, ok = o.(SetTierer)
|
||||
store(ok, "SetTier")
|
||||
|
||||
_, ok = o.(GetTierer)
|
||||
store(ok, "GetTier")
|
||||
|
||||
return supported, unsupported
|
||||
}
|
||||
|
||||
// ListRCallback defines a callback function for ListR to use
|
||||
//
|
||||
// It is called for each tranche of entries read from the listing and
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
@ -241,13 +242,27 @@ type ExtraConfigItem struct{ Name, Key, Value string }
|
||||
|
||||
// Opt is options for Run
|
||||
type Opt struct {
|
||||
RemoteName string
|
||||
NilObject fs.Object
|
||||
ExtraConfig []ExtraConfigItem
|
||||
SkipBadWindowsCharacters bool // skips unusable characters for windows if set
|
||||
SkipFsMatch bool // if set skip exact matching of Fs value
|
||||
TiersToTest []string // List of tiers which can be tested in setTier test
|
||||
ChunkedUpload ChunkedUploadConfig
|
||||
RemoteName string
|
||||
NilObject fs.Object
|
||||
ExtraConfig []ExtraConfigItem
|
||||
SkipBadWindowsCharacters bool // skips unusable characters for windows if set
|
||||
SkipFsMatch bool // if set skip exact matching of Fs value
|
||||
TiersToTest []string // List of tiers which can be tested in setTier test
|
||||
ChunkedUpload ChunkedUploadConfig
|
||||
UnimplementableFsMethods []string // List of methods which can't be implemented in this wrapping Fs
|
||||
UnimplementableObjectMethods []string // List of methods which can't be implemented in this wrapping Fs
|
||||
SkipFsCheckWrap bool // if set skip FsCheckWrap
|
||||
SkipObjectCheckWrap bool // if set skip ObjectCheckWrap
|
||||
}
|
||||
|
||||
// returns true if x is found in ss
|
||||
func stringsContains(x string, ss []string) bool {
|
||||
for _, s := range ss {
|
||||
if x == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Run runs the basic integration tests for a remote using the options passed in.
|
||||
@ -360,6 +375,34 @@ func Run(t *testing.T, opt *Opt) {
|
||||
// Skip the rest if it failed
|
||||
skipIfNotOk(t)
|
||||
|
||||
// Check to see if Fs that wrap other Fs implement all the optional methods
|
||||
t.Run("FsCheckWrap", func(t *testing.T) {
|
||||
skipIfNotOk(t)
|
||||
if opt.SkipFsCheckWrap {
|
||||
t.Skip("Skipping FsCheckWrap on this Fs")
|
||||
}
|
||||
ft := new(fs.Features).Fill(remote)
|
||||
if ft.UnWrap == nil {
|
||||
t.Skip("Not a wrapping Fs")
|
||||
}
|
||||
v := reflect.ValueOf(ft).Elem()
|
||||
vType := v.Type()
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
vName := vType.Field(i).Name
|
||||
if stringsContains(vName, opt.UnimplementableFsMethods) {
|
||||
continue
|
||||
}
|
||||
field := v.Field(i)
|
||||
// skip the bools
|
||||
if field.Type().Kind() == reflect.Bool {
|
||||
continue
|
||||
}
|
||||
if field.IsNil() {
|
||||
t.Errorf("Missing Fs wrapper for %s", vName)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// TestFsRmdirNotFound tests deleting a non existent directory
|
||||
t.Run("FsRmdirNotFound", func(t *testing.T) {
|
||||
skipIfNotOk(t)
|
||||
@ -1367,6 +1410,25 @@ func Run(t *testing.T, opt *Opt) {
|
||||
}
|
||||
})
|
||||
|
||||
// Check to see if Fs that wrap other Objects implement all the optional methods
|
||||
t.Run("ObjectCheckWrap", func(t *testing.T) {
|
||||
skipIfNotOk(t)
|
||||
if opt.SkipObjectCheckWrap {
|
||||
t.Skip("Skipping FsCheckWrap on this Fs")
|
||||
}
|
||||
ft := new(fs.Features).Fill(remote)
|
||||
if ft.UnWrap == nil {
|
||||
t.Skip("Not a wrapping Fs")
|
||||
}
|
||||
obj := findObject(t, remote, file1.Path)
|
||||
_, unsupported := fs.ObjectOptionalInterfaces(obj)
|
||||
for _, name := range unsupported {
|
||||
if !stringsContains(name, opt.UnimplementableObjectMethods) {
|
||||
t.Errorf("Missing Object wrapper for %s", name)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// TestObjectRemove tests Remove
|
||||
t.Run("ObjectRemove", func(t *testing.T) {
|
||||
skipIfNotOk(t)
|
||||
|
Loading…
Reference in New Issue
Block a user