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)