errorfs

package
v2.0.2 Latest Latest
Warning

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

Go to latest
Published: Jan 22, 2025 License: BSD-3-Clause Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrInjected = LabelledError{

	Label: "ErrInjected",
	// contains filtered or unexported fields
}

ErrInjected is an error artificially injected for testing fs error paths.

Functions

func WrapFile

func WrapFile(f vfs.File, inj Injector) vfs.File

WrapFile wraps an existing vfs.File, returning a new vfs.File that shadows operations to the provided vfs.File. It uses the provided Injector for deciding when to inject errors. If an error is injected, the file propagates the error instead of shadowing the operation.

Types

type Counter

type Counter struct {
	Injector
	// contains filtered or unexported fields
}

Counter wraps an Injector, counting the number of errors injected. It may be used in tests to ensure that when an error is injected, the error is surfaced through the user interface.

func (*Counter) LastError

func (c *Counter) LastError() error

LastError returns the last non-nil error injected.

func (*Counter) Load

func (c *Counter) Load() uint64

Load returns the number of errors injected.

func (*Counter) MaybeError

func (c *Counter) MaybeError(op Op) error

MaybeError implements Injector.

func (*Counter) String

func (c *Counter) String() string

String implements fmt.Stringer.

type FS

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

FS implements vfs.FS, injecting errors into its operations.

func Wrap

func Wrap(fs vfs.FS, inj Injector) *FS

Wrap wraps an existing vfs.FS implementation, returning a new vfs.FS implementation that shadows operations to the provided FS. It uses the provided Injector for deciding when to inject errors. If an error is injected, FS propagates the error instead of shadowing the operation.

func (*FS) Create

func (fs *FS) Create(name string, category vfs.DiskWriteCategory) (vfs.File, error)

Create implements FS.Create.

func (*FS) GetDiskUsage

func (fs *FS) GetDiskUsage(path string) (vfs.DiskUsage, error)

GetDiskUsage implements FS.GetDiskUsage.

func (fs *FS) Link(oldname, newname string) error

Link implements FS.Link.

func (*FS) List

func (fs *FS) List(dir string) ([]string, error)

List implements FS.List.

func (*FS) Lock

func (fs *FS) Lock(name string) (io.Closer, error)

Lock implements FS.Lock.

func (*FS) MkdirAll

func (fs *FS) MkdirAll(dir string, perm os.FileMode) error

MkdirAll implements FS.MkdirAll.

func (*FS) Open

func (fs *FS) Open(name string, opts ...vfs.OpenOption) (vfs.File, error)

Open implements FS.Open.

func (*FS) OpenDir

func (fs *FS) OpenDir(name string) (vfs.File, error)

OpenDir implements FS.OpenDir.

func (*FS) OpenReadWrite

func (fs *FS) OpenReadWrite(
	name string, category vfs.DiskWriteCategory, opts ...vfs.OpenOption,
) (vfs.File, error)

OpenReadWrite implements FS.OpenReadWrite.

func (*FS) PathBase

func (fs *FS) PathBase(p string) string

PathBase implements FS.PathBase.

func (*FS) PathDir

func (fs *FS) PathDir(p string) string

PathDir implements FS.PathDir.

func (*FS) PathJoin

func (fs *FS) PathJoin(elem ...string) string

PathJoin implements FS.PathJoin.

func (*FS) Remove

func (fs *FS) Remove(name string) error

Remove implements FS.Remove.

func (*FS) RemoveAll

func (fs *FS) RemoveAll(fullname string) error

RemoveAll implements FS.RemoveAll.

func (*FS) Rename

func (fs *FS) Rename(oldname, newname string) error

Rename implements FS.Rename.

func (*FS) ReuseForWrite

func (fs *FS) ReuseForWrite(
	oldname, newname string, category vfs.DiskWriteCategory,
) (vfs.File, error)

ReuseForWrite implements FS.ReuseForWrite.

func (*FS) Stat

func (fs *FS) Stat(name string) (vfs.FileInfo, error)

Stat implements FS.Stat.

func (*FS) Unwrap

func (fs *FS) Unwrap() vfs.FS

Unwrap returns the FS implementation underlying fs. See pebble/vfs.Root.

type InjectIndex

type InjectIndex struct {
	*dsl.Index[Op]
}

InjectIndex implements Injector, injecting an error at a specific index.

func OnIndex

func OnIndex(index int32) *InjectIndex

OnIndex is a convenience function for constructing a dsl.OnIndex for use with an error-injecting filesystem.

func (*InjectIndex) MaybeError

func (ii *InjectIndex) MaybeError(op Op) error

MaybeError implements the Injector interface.

TODO(jackson): Remove this implementation and update callers to compose it with other injectors.

type Injector

type Injector interface {
	fmt.Stringer
	// MaybeError is invoked by an errorfs before an operation is executed. It
	// is passed an enum indicating the type of operation and a path of the
	// subject file or directory. If the operation takes two paths (eg,
	// Rename, Link), the original source path is provided.
	MaybeError(op Op) error
}

Injector injects errors into FS operations.

func Any

func Any(injectors ...Injector) Injector

Any returns an injector that injects an error if any of the provided injectors inject an error. The error returned by the first injector to return an error is used.

func ParseDSL

func ParseDSL(s string) (Injector, error)

ParseDSL parses the provided string using the default DSL parser.

func RandomLatency

func RandomLatency(pred Predicate, mean time.Duration, seed int64, limit time.Duration) Injector

RandomLatency constructs an Injector that does not inject errors but instead injects random latency into operations that match the provided predicate. The amount of latency injected follows an exponential distribution with the provided mean. Latency injected is derived from the provided seed and is deterministic with respect to each file's path.

If limit is nonzero, total latency injected over the lifetime of the Injector is capped to limit.

type InjectorFunc

type InjectorFunc func(Op) error

InjectorFunc implements the Injector interface for a function with MaybeError's signature.

func (InjectorFunc) MaybeError

func (f InjectorFunc) MaybeError(op Op) error

MaybeError implements the Injector interface.

func (InjectorFunc) String

func (f InjectorFunc) String() string

String implements fmt.Stringer.

type LabelledError

type LabelledError struct {
	Label string
	// contains filtered or unexported fields
}

LabelledError is an error that also implements Injector, unconditionally injecting itself. It implements String() by returning its label. It implements Error() by returning its underlying error.

func (LabelledError) If

func (le LabelledError) If(p Predicate) Injector

If returns an Injector that returns the receiver error if the provided predicate evalutes to true.

func (LabelledError) MaybeError

func (le LabelledError) MaybeError(op Op) error

MaybeError implements Injector.

func (LabelledError) String

func (le LabelledError) String() string

String implements fmt.Stringer.

type Op

type Op struct {
	// Kind describes the particular kind of operation being performed.
	Kind OpKind
	// Path is the path of the file of the file being operated on.
	Path string
	// Offset is the offset of an operation. It's set for OpFileReadAt and
	// OpFileWriteAt operations.
	Offset int64
}

Op describes a filesystem operation.

type OpKind

type OpKind int

OpKind is an enum describing the type of operation.

const (
	// OpCreate describes a create file operation.
	OpCreate OpKind = iota
	// OpLink describes a hardlink operation.
	OpLink
	// OpOpen describes a file open operation.
	OpOpen
	// OpOpenDir describes a directory open operation.
	OpOpenDir
	// OpRemove describes a remove file operation.
	OpRemove
	// OpRemoveAll describes a recursive remove operation.
	OpRemoveAll
	// OpRename describes a rename operation.
	OpRename
	// OpReuseForWrite describes a reuse for write operation.
	OpReuseForWrite
	// OpMkdirAll describes a make directory including parents operation.
	OpMkdirAll
	// OpLock describes a lock file operation.
	OpLock
	// OpList describes a list directory operation.
	OpList
	// OpFilePreallocate describes a file preallocate operation.
	OpFilePreallocate
	// OpStat describes a path-based stat operation.
	OpStat
	// OpGetDiskUsage describes a disk usage operation.
	OpGetDiskUsage
	// OpFileClose describes a close file operation.
	OpFileClose
	// OpFileRead describes a file read operation.
	OpFileRead
	// OpFileReadAt describes a file seek read operation.
	OpFileReadAt
	// OpFileWrite describes a file write operation.
	OpFileWrite
	// OpFileWriteAt describes a file seek write operation.
	OpFileWriteAt
	// OpFileStat describes a file stat operation.
	OpFileStat
	// OpFileSync describes a file sync operation.
	OpFileSync
	// OpFileSyncData describes a file sync operation.
	OpFileSyncData
	// OpFileSyncTo describes a file sync operation.
	OpFileSyncTo
	// OpFileFlush describes a file flush operation.
	OpFileFlush
)

func (OpKind) ReadOrWrite

func (o OpKind) ReadOrWrite() OpReadWrite

ReadOrWrite returns the operation's kind.

type OpReadWrite

type OpReadWrite int

OpReadWrite is an enum describing whether an operation is a read or write operation.

const (
	// OpIsRead describes read operations.
	OpIsRead OpReadWrite = iota
	// OpIsWrite describes write operations.
	OpIsWrite
)

func (OpReadWrite) String

func (kind OpReadWrite) String() string

String implements fmt.Stringer.

type Parser

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

A Parser parses the error-injecting DSL. It may be extended to include additional errors through AddError.

func NewParser

func NewParser() *Parser

NewParser constructs a new parser for an encoding of a lisp-like DSL describing error injectors.

Errors: - ErrInjected is the only error currently supported by the DSL.

Injectors:

  • <ERROR>: An error by itself is an injector that injects an error every time.
  • (<ERROR> <PREDICATE>) is an injector that injects an error only when the operation satisfies the predicate.

Predicates:

  • Reads is a constant predicate that evalutes to true iff the operation is a read operation (eg, Open, Read, ReadAt, Stat)
  • Writes is a constant predicate that evaluates to true iff the operation is a write operation (eg, Create, Rename, Write, WriteAt, etc).
  • (PathMatch <STRING>) is a predicate that evalutes to true iff the operation's file path matches the provided shell pattern.
  • (OnIndex <INTEGER>) is a predicate that evaluates to true only on the n-th invocation.
  • (And <PREDICATE> [PREDICATE]...) is a predicate that evaluates to true iff all the provided predicates evaluate to true. And short circuits on the first predicate to evaluate to false.
  • (Or <PREDICATE> [PREDICATE]...) is a predicate that evaluates to true iff at least one of the provided predicates evaluates to true. Or short circuits on the first predicate to evaluate to true.
  • (Not <PREDICATE>) is a predicate that evaluates to true iff its provided predicates evaluates to false.
  • (Randomly <FLOAT> [INTEGER]) is a predicate that pseudorandomly evaluates to true. The probability of evaluating to true is determined by the required float argument (must be ≤1). The optional second parameter is a pseudorandom seed, for adjusting the deterministic randomness.
  • Operation-specific: (OpFileReadAt <INTEGER>) is a predicate that evaluates to true iff an operation is a file ReadAt call with an offset that's exactly equal.

Example: (ErrInjected (And (PathMatch "*.sst") (OnIndex 5))) is a rule set that will inject an error on the 5-th I/O operation involving an sstable.

func (*Parser) AddError

func (p *Parser) AddError(le LabelledError)

AddError defines a new error that may be used within the DSL parsed by Parse and will inject the provided error.

func (*Parser) Parse

func (p *Parser) Parse(s string) (Injector, error)

Parse parses the error injection DSL, returning the parsed injector.

type Predicate

type Predicate = dsl.Predicate[Op]

Predicate encodes conditional logic that determines whether to inject an error.

var (
	// Reads is a predicate that returns true iff an operation is a read
	// operation.
	Reads Predicate = opKindPred{/* contains filtered or unexported fields */}
	// Writes is a predicate that returns true iff an operation is a write
	// operation.
	Writes Predicate = opKindPred{/* contains filtered or unexported fields */}
)

func And

func And(operands ...Predicate) Predicate

And returns a predicate that evaluates to true if all of the operands evaluate to true.

func PathMatch

func PathMatch(pattern string) Predicate

PathMatch returns a predicate that returns true if an operation's file path matches the provided pattern according to filepath.Match.

func Randomly

func Randomly(p float64, seed int64) Predicate

Randomly constructs a new predicate that pseudorandomly evaluates to true with probability p using randomness determinstically derived from seed.

The predicate is deterministic with respect to file paths: its behavior for a particular file is deterministic regardless of intervening evaluations for operations on other files. This can be used to ensure determinism despite nondeterministic concurrency if the concurrency is constrained to separate files.

type Toggle

type Toggle struct {
	Injector
	// contains filtered or unexported fields
}

Toggle wraps an Injector. By default, Toggle injects nothing. When toggled on through its On method, it begins injecting errors when the contained injector injects them. It may be returned to its original state through Off.

func (*Toggle) MaybeError

func (t *Toggle) MaybeError(op Op) error

MaybeError implements Injector.

func (*Toggle) Off

func (t *Toggle) Off()

Off disables error injection.

func (*Toggle) On

func (t *Toggle) On()

On enables error injection.

func (*Toggle) String

func (t *Toggle) String() string

String implements fmt.Stringer.

Jump to

Keyboard shortcuts

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