github.com/xhghs/rclone@v1.51.1-0.20200430155106-e186a28cced8/fstest/mockfs/mockfs.go (about) 1 package mockfs 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "io" 8 "path" 9 "time" 10 11 "github.com/rclone/rclone/fs" 12 "github.com/rclone/rclone/fs/hash" 13 ) 14 15 // Fs is a minimal mock Fs 16 type Fs struct { 17 name string // the name of the remote 18 root string // The root directory (OS path) 19 features *fs.Features // optional features 20 rootDir fs.DirEntries // directory listing of root 21 } 22 23 // ErrNotImplemented is returned by unimplemented methods 24 var ErrNotImplemented = errors.New("not implemented") 25 26 // NewFs returns a new mock Fs 27 func NewFs(name, root string) *Fs { 28 f := &Fs{ 29 name: name, 30 root: root, 31 } 32 f.features = (&fs.Features{}).Fill(f) 33 return f 34 } 35 36 // AddObject adds an Object for List to return 37 // Only works for the root for the moment 38 func (f *Fs) AddObject(o fs.Object) { 39 f.rootDir = append(f.rootDir, o) 40 // Make this object part of mockfs if possible 41 do, ok := o.(interface{ SetFs(f fs.Fs) }) 42 if ok { 43 do.SetFs(f) 44 } 45 } 46 47 // Name of the remote (as passed into NewFs) 48 func (f *Fs) Name() string { 49 return f.name 50 } 51 52 // Root of the remote (as passed into NewFs) 53 func (f *Fs) Root() string { 54 return f.root 55 } 56 57 // String returns a description of the FS 58 func (f *Fs) String() string { 59 return fmt.Sprintf("Mock file system at %s", f.root) 60 } 61 62 // Precision of the ModTimes in this Fs 63 func (f *Fs) Precision() time.Duration { 64 return time.Second 65 } 66 67 // Hashes returns the supported hash types of the filesystem 68 func (f *Fs) Hashes() hash.Set { 69 return hash.NewHashSet() 70 } 71 72 // Features returns the optional features of this Fs 73 func (f *Fs) Features() *fs.Features { 74 return f.features 75 } 76 77 // List the objects and directories in dir into entries. The 78 // entries can be returned in any order but should be for a 79 // complete directory. 80 // 81 // dir should be "" to list the root, and should not have 82 // trailing slashes. 83 // 84 // This should return ErrDirNotFound if the directory isn't 85 // found. 86 func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) { 87 if dir == "" { 88 return f.rootDir, nil 89 } 90 return entries, fs.ErrorDirNotFound 91 } 92 93 // NewObject finds the Object at remote. If it can't be found 94 // it returns the error ErrorObjectNotFound. 95 func (f *Fs) NewObject(ctx context.Context, remote string) (fs.Object, error) { 96 dirPath := path.Dir(remote) 97 if dirPath == "" || dirPath == "." { 98 for _, entry := range f.rootDir { 99 if entry.Remote() == remote { 100 return entry.(fs.Object), nil 101 } 102 } 103 } 104 return nil, fs.ErrorObjectNotFound 105 } 106 107 // Put in to the remote path with the modTime given of the given size 108 // 109 // May create the object even if it returns an error - if so 110 // will return the object and the error, otherwise will return 111 // nil and the error 112 func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (fs.Object, error) { 113 return nil, ErrNotImplemented 114 } 115 116 // Mkdir makes the directory (container, bucket) 117 // 118 // Shouldn't return an error if it already exists 119 func (f *Fs) Mkdir(ctx context.Context, dir string) error { 120 return ErrNotImplemented 121 } 122 123 // Rmdir removes the directory (container, bucket) if empty 124 // 125 // Return an error if it doesn't exist or isn't empty 126 func (f *Fs) Rmdir(ctx context.Context, dir string) error { 127 return ErrNotImplemented 128 } 129 130 // Assert it is the correct type 131 var _ fs.Fs = (*Fs)(nil)