vfs

package module
v1.7.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 29, 2020 License: MIT Imports: 8 Imported by: 54

README

go-vfs

PkgGoDev Report Card

Package vfs provides an abstraction of the os and ioutil packages that is easy to test.

Key features

  • File system abstraction layer for commonly-used os and ioutil functions from the standard library.

  • Powerful and easy-to-use declarative testing framework, vfst. You declare the desired state of the filesystem after your code has run, and vfst tests that the filesystem matches that state. For a quick tour of vfst's features, see the examples in the documentation.

  • Compatibility with github.com/spf13/afero and github.com/src-d/go-billy.

Quick start

vfs provides implementations of the FS interface:

// An FS is an abstraction over commonly-used functions in the os and ioutil
// packages.
type FS interface {
    Chmod(name string, mode os.FileMode) error
    Chown(name string, uid, git int) error
    Chtimes(name string, atime, mtime time.Time) error
    Create(name string) (*os.File, error)
    FileSeparator() rune
    Glob(pattern string) ([]string, error)
    Lchown(name string, uid, git int) error
    Lstat(name string) (os.FileInfo, error)
    Mkdir(name string, perm os.FileMode) error
    Open(name string) (*os.File, error)
    OpenFile(name string, flag int, perm os.ModePerm) (*os.File, error)
    RawPath(name string) (string, error)
    ReadDir(dirname string) ([]os.FileInfo, error)
    ReadFile(filename string) ([]byte, error)
    Readlink(name string) (string, error)
    Remove(name string) error
    RemoveAll(name string) error
    Rename(oldpath, newpath string) error
    Stat(name string) (os.FileInfo, error)
    Symlink(oldname, newname string) error
    Truncate(name string, size int64) error
    WriteFile(filename string, data []byte, perm os.FileMode) error
}

To use vfs, you write your code to use the FS interface, and then use vfst to test it.

vfs also provides functions MkdirAll (equivalent to os.MkdirAll), Contains (an improved filepath.HasPrefix), and Walk (equivalent to filepath.Walk) that operate on an FS.

The implementations of FS provided are:

  • OSFS which calls the underlying os and ioutil functions directly.

  • PathFS which transforms all paths to provide a poor-man's chroot.

  • ReadOnlyFS which prevents modification of the underlying FS.

  • TestFS which assists running tests on a real filesystem but in a temporary directory that is easily cleaned up. It uses OSFS under the hood.

Example usage:

// writeConfigFile is the function we're going to test. It can make arbitrary
// changes to the filesystem through fs.
func writeConfigFile(fs vfs.FS) error {
    return fs.WriteFile("/home/user/app.conf", []byte(`app config`), 0644)
}

// TestWriteConfigFile is our test function.
func TestWriteConfigFile(t *testing.T) {
    // Create and populate an temporary directory with a home directory.
    fs, cleanup, err := vfst.NewTestFS(map[string]interface{}{
        "/home/user/.bashrc": "# contents of user's .bashrc\n",
    })

    // Check that the directory was populated successfully.
    if err != nil {
        t.Fatalf("vfsTest.NewTestFS(_) == _, _, %v, want _, _, <nil>", err)
    }

    // Ensure that the temporary directory is removed.
    defer cleanup()

    // Call the function we want to test.
    if err := writeConfigFile(fs); err != nil {
        t.Error(err)
    }

    // Check properties of the filesystem after our function has modified it.
    vfst.RunTest(t, fs, "app_conf",
        vfst.PathTest("/home/user/app.conf",
            vfst.TestModeIsRegular,
            vfst.TestModePerm(0644),
            vfst.TestContentsString("app config"),
        ),
    )
}

github.com/spf13/afero compatibility

There is a compatibility shim for github.com/spf13/afero in github.com/twpayne/go-vfsafero. This allows you to use vfst to test existing code that uses afero.FS. See the documentation for an example.

github.com/src-d/go-billy compatibility

There is a compatibility shim for github.com/src-d/go-billy in github.com/twpayne/go-vfsbilly. This allows you to use vfst to test existing code that uses billy.Filesystem. See the documentation for an example.

Motivation

vfs was inspired by github.com/spf13/afero. So, why not use afero?

  • afero has several critical bugs in its in-memory mock filesystem implementation MemMapFs, to the point that it is unusable for non-trivial test cases. vfs does not attempt to implement an in-memory mock filesystem, and instead only provides a thin layer around the standard library's os and ioutil packages, and as such should have fewer bugs.

  • afero does not support creating or reading symbolic links, and its LstatIfPossible interface is clumsy to use as it is not part of the afero.Fs interface. vfs provides out-of-the-box support for symbolic links with all methods in the FS interface.

  • afero has been effectively abandoned by its author, and a "friendly fork" (github.com/absfs/afero) has not seen much activity. vfs, by providing much less functionality than afero, should be smaller and easier to maintain.

License

MIT

Documentation

Overview

Package vfs provides an abstraction of the os and ioutil packages that is easy to test.

Index

Constants

This section is empty.

Variables

View Source
var OSFS = &osfs{}

OSFS is the FS that calls os and ioutil functions directly.

View Source
var SkipDir = filepath.SkipDir

SkipDir is filepath.SkipDir.

Functions

func Contains added in v1.0.6

func Contains(fs Stater, p, prefix string) (bool, error)

Contains returns true if p is reachable by traversing through prefix. prefix must exist, but p may not. It is an expensive but accurate alternative to the deprecated filepath.HasPrefix.

func MkdirAll

func MkdirAll(fs MkdirStater, path string, perm os.FileMode) error

MkdirAll is equivalent to os.MkdirAll but operates on fs.

func Walk

func Walk(fs LstatReadDirer, path string, walkFn filepath.WalkFunc) error

Walk is the equivalent of filepath.Walk but operates on fs. Entries are returned in lexicographical order.

func WalkSlash added in v1.4.1

func WalkSlash(fs LstatReadDirer, path string, walkFn filepath.WalkFunc) error

WalkSlash is the equivalent of Walk but all paths are converted to use forward slashes with filepath.ToSlash.

Types

type FS

type FS interface {
	Chmod(name string, mode os.FileMode) error
	Chown(name string, uid, git int) error
	Chtimes(name string, atime, mtime time.Time) error
	Create(name string) (*os.File, error)
	Glob(pattern string) ([]string, error)
	Lchown(name string, uid, git int) error
	Lstat(name string) (os.FileInfo, error)
	Mkdir(name string, perm os.FileMode) error
	Open(name string) (*os.File, error)
	OpenFile(name string, flag int, perm os.FileMode) (*os.File, error)
	PathSeparator() rune
	RawPath(name string) (string, error)
	ReadDir(dirname string) ([]os.FileInfo, error)
	ReadFile(filename string) ([]byte, error)
	Readlink(name string) (string, error)
	Remove(name string) error
	RemoveAll(name string) error
	Rename(oldpath, newpath string) error
	Stat(name string) (os.FileInfo, error)
	Symlink(oldname, newname string) error
	Truncate(name string, size int64) error
	WriteFile(filename string, data []byte, perm os.FileMode) error
}

An FS is an abstraction over commonly-used functions in the os and ioutil packages.

type LstatReadDirer added in v1.0.4

type LstatReadDirer interface {
	Lstat(name string) (os.FileInfo, error)
	ReadDir(dirname string) ([]os.FileInfo, error)
}

A LstatReadDirer implements all the functionality needed by Walk.

type MkdirStater added in v1.0.4

type MkdirStater interface {
	Mkdir(name string, perm os.FileMode) error
	Stat(name string) (os.FileInfo, error)
}

A MkdirStater implements all the functionality needed by MkdirAll.

type PathFS

type PathFS struct {
	// contains filtered or unexported fields
}

A PathFS operates on an existing FS, but prefixes all names with a path. All names must be absolute paths, with the exception of symlinks, which may be relative.

func NewPathFS

func NewPathFS(fs FS, path string) *PathFS

NewPathFS returns a new *PathFS operating on fs and prefixing all names with path.

func (*PathFS) Chmod

func (p *PathFS) Chmod(name string, mode os.FileMode) error

Chmod implements os.Chmod.

func (*PathFS) Chown added in v0.1.5

func (p *PathFS) Chown(name string, uid, gid int) error

Chown implements os.Chown.

func (*PathFS) Chtimes added in v0.1.5

func (p *PathFS) Chtimes(name string, atime, mtime time.Time) error

Chtimes implements os.Chtimes.

func (*PathFS) Create added in v0.1.5

func (p *PathFS) Create(name string) (*os.File, error)

Create implements os.Create.

func (*PathFS) Glob added in v1.3.0

func (p *PathFS) Glob(pattern string) ([]string, error)

Glob implements filepath.Glob.

func (*PathFS) Join

func (p *PathFS) Join(op, name string) (string, error)

Join returns p's path joined with name.

func (*PathFS) Lchown added in v0.1.5

func (p *PathFS) Lchown(name string, uid, gid int) error

Lchown implements os.Lchown.

func (*PathFS) Lstat

func (p *PathFS) Lstat(name string) (os.FileInfo, error)

Lstat implements os.Lstat.

func (*PathFS) Mkdir

func (p *PathFS) Mkdir(name string, perm os.FileMode) error

Mkdir implements os.Mkdir.

func (*PathFS) Open added in v0.1.4

func (p *PathFS) Open(name string) (*os.File, error)

Open implements os.Open.

func (*PathFS) OpenFile added in v0.1.5

func (p *PathFS) OpenFile(name string, flag int, perm os.FileMode) (*os.File, error)

OpenFile implements os.OpenFile.

func (*PathFS) PathSeparator added in v1.4.0

func (p *PathFS) PathSeparator() rune

PathSeparator implements PathSeparator.

func (*PathFS) RawPath added in v1.3.3

func (p *PathFS) RawPath(path string) (string, error)

RawPath implements RawPath.

func (*PathFS) ReadDir

func (p *PathFS) ReadDir(dirname string) ([]os.FileInfo, error)

ReadDir implements ioutil.ReadDir.

func (*PathFS) ReadFile

func (p *PathFS) ReadFile(filename string) ([]byte, error)

ReadFile implements ioutil.ReadFile.

func (p *PathFS) Readlink(name string) (string, error)

Readlink implements os.Readlink.

func (*PathFS) Remove

func (p *PathFS) Remove(name string) error

Remove implements os.Remove.

func (*PathFS) RemoveAll

func (p *PathFS) RemoveAll(name string) error

RemoveAll implements os.RemoveAll.

func (*PathFS) Rename added in v0.1.3

func (p *PathFS) Rename(oldpath, newpath string) error

Rename implements os.Rename.

func (*PathFS) Stat

func (p *PathFS) Stat(name string) (os.FileInfo, error)

Stat implements os.Stat.

func (p *PathFS) Symlink(oldname, newname string) error

Symlink implements os.Symlink.

func (*PathFS) Truncate added in v0.1.5

func (p *PathFS) Truncate(name string, size int64) error

Truncate implements os.Truncate.

func (*PathFS) WriteFile

func (p *PathFS) WriteFile(filename string, data []byte, perm os.FileMode) error

WriteFile implements ioutil.WriteFile.

type ReadOnlyFS

type ReadOnlyFS struct {
	// contains filtered or unexported fields
}

A ReadOnlyFS operates on an existing FS, but any methods that modify the FS return an error.

func NewReadOnlyFS

func NewReadOnlyFS(fs FS) *ReadOnlyFS

NewReadOnlyFS returns a new *ReadOnlyFS operating on fs.

func (*ReadOnlyFS) Chmod

func (r *ReadOnlyFS) Chmod(name string, mode os.FileMode) error

Chmod implements os.Chmod.

func (*ReadOnlyFS) Chown added in v0.1.5

func (r *ReadOnlyFS) Chown(name string, uid, gid int) error

Chown implements os.Chown.

func (*ReadOnlyFS) Chtimes added in v0.1.5

func (r *ReadOnlyFS) Chtimes(name string, atime, mtime time.Time) error

Chtimes implements os.Chtimes.

func (*ReadOnlyFS) Create added in v0.1.5

func (r *ReadOnlyFS) Create(name string) (*os.File, error)

Create implements os.Create.

func (*ReadOnlyFS) Glob added in v1.3.0

func (r *ReadOnlyFS) Glob(pattern string) ([]string, error)

Glob implements filepath.Glob.

func (*ReadOnlyFS) Lchown added in v0.1.5

func (r *ReadOnlyFS) Lchown(name string, uid, gid int) error

Lchown implements os.Lchown.

func (*ReadOnlyFS) Lstat

func (r *ReadOnlyFS) Lstat(name string) (os.FileInfo, error)

Lstat implements os.Lstat.

func (*ReadOnlyFS) Mkdir

func (r *ReadOnlyFS) Mkdir(name string, perm os.FileMode) error

Mkdir implements os.Mkdir.

func (*ReadOnlyFS) Open added in v0.1.4

func (r *ReadOnlyFS) Open(name string) (*os.File, error)

Open implements os.Open.

func (*ReadOnlyFS) OpenFile added in v0.1.5

func (r *ReadOnlyFS) OpenFile(name string, flag int, perm os.FileMode) (*os.File, error)

OpenFile implements os.OpenFile.

func (*ReadOnlyFS) PathSeparator added in v1.4.0

func (r *ReadOnlyFS) PathSeparator() rune

PathSeparator implements PathSeparator.

func (*ReadOnlyFS) RawPath added in v1.3.4

func (r *ReadOnlyFS) RawPath(path string) (string, error)

RawPath implements RawPath.

func (*ReadOnlyFS) ReadDir

func (r *ReadOnlyFS) ReadDir(dirname string) ([]os.FileInfo, error)

ReadDir implements ioutil.ReadDir.

func (*ReadOnlyFS) ReadFile

func (r *ReadOnlyFS) ReadFile(filename string) ([]byte, error)

ReadFile implements ioutil.ReadFile.

func (r *ReadOnlyFS) Readlink(name string) (string, error)

Readlink implments os.Readlink.

func (*ReadOnlyFS) Remove

func (r *ReadOnlyFS) Remove(name string) error

Remove implements os.Remove.

func (*ReadOnlyFS) RemoveAll

func (r *ReadOnlyFS) RemoveAll(name string) error

RemoveAll implements os.RemoveAll.

func (*ReadOnlyFS) Rename added in v0.1.3

func (r *ReadOnlyFS) Rename(oldpath, newpath string) error

Rename implements os.Rename.

func (*ReadOnlyFS) Stat

func (r *ReadOnlyFS) Stat(name string) (os.FileInfo, error)

Stat implements os.Stat.

func (r *ReadOnlyFS) Symlink(oldname, newname string) error

Symlink implements os.Symlink.

func (*ReadOnlyFS) Truncate added in v0.1.5

func (r *ReadOnlyFS) Truncate(name string, size int64) error

Truncate implements os.Truncate.

func (*ReadOnlyFS) WriteFile

func (r *ReadOnlyFS) WriteFile(filename string, data []byte, perm os.FileMode) error

WriteFile implements ioutil.WriteFile.

type Stater added in v1.0.6

type Stater interface {
	Stat(string) (os.FileInfo, error)
}

A Stater implements Stat. It is assumed that the os.FileInfos returned by Stat are compatible with os.SameFile.

Directories

Path Synopsis
Package vfst provides helper functions for testing code that uses github.com/twpayne/go-vfs.
Package vfst provides helper functions for testing code that uses github.com/twpayne/go-vfs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL