fake

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package fake is a scriptable, contract-verified test double for invoke.Environment.

The fake simulates a small POSIX-ish target: a virtual filesystem, a minimal shell and builtin vocabulary, and full transfer semantics between the real host filesystem and the virtual one. It passes the same invoketest contract suite the real providers pass, so tests written against it exercise contract-accurate lifecycle, error, and stream behavior — not a mock that can be programmed into impossible states.

Consumer-registered handlers take precedence over the builtin vocabulary; commands that are neither registered nor builtin fail with invoke.ErrNotFound, exactly as a missing binary does on a real target.

What the shell runs

invoke.Shell scripts are interpreted, not executed, and the interpreter covers a subset: sequencing with ; and &&, single and double quotes, $NAME and ${NAME} expansion, $(command) substitution, redirection to /dev/null (flush or spaced) and between the two output streams, cd, and exit.

A script reaching outside that subset is refused — wrapping invoke.ErrNotSupported, before any process exists — rather than run wrongly. Pipelines, || lists, redirection to a file, input redirection, backquotes, newline-separated commands, background commands, comments, globs, backslash escapes, arithmetic expansion, the ${ operator forms, and the special and positional parameters ($?, $1, $$) are all refused by name. The alternative was worse than useless: an unrecognized character is just another character to a tokenizer, so a pipeline used to become arguments to the first command and `false || echo rescued` exited 1 having printed nothing, where every real target exits 0 having printed. A test asserting that is not merely unverified — it asserts the opposite of the truth.

The builtin vocabulary

The builtins are a vocabulary rather than an implementation: they cover the forms the contract suite and ordinary shell-outs use, and a form outside them — a test operator beyond the set below, most utility flags — fails loudly on standard error rather than being answered falsely. What the fake answers without a handler:

  • sh -c, running the script through this same interpreter
  • echo (no flags) and printf (%s and %% conversions, the common backslash escapes)
  • cat, reading standard input; file arguments are ignored
  • test, with the one-argument form, an optional leading !, and the unary -e, -d, -f, -L, -n, -z, and -t; test and cd do not follow symbolic links
  • true, false, sleep SECONDS, pwd, and uname (which reports Linux, matching Environment.OS)
  • find PATH -maxdepth 0 -perm MODE, and dd if=/dev/zero with optional bs= and count=
  • mkdir [-p], touch, and rm [-r|-f|-rf], each with the failure modes a real target has

Inside scripts, cd (to $HOME with no argument) and exit (numeric statuses only) are the shell's own. Anything else — ls, cp, grep, env, chmod — is an unknown command: invoke.ErrNotFound from Start, the shell's exit 127 from a script. Register your own with Environment.Handle, which overrides any builtin of the same name and is reachable everywhere the name can be written. A script needing more than the subset belongs in a handler, or on a real target.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Environment

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

Environment is a simulated execution target.

func New

func New(opts ...Option) *Environment

New returns a fresh simulated target with an empty /tmp, a small base environment, and no recorded calls.

func (*Environment) Calls

func (e *Environment) Calls() []invoke.Command

Calls returns the commands started so far, in order. Probe and cleanup commands issued by test helpers appear too: the record is honest.

func (*Environment) Capabilities

func (e *Environment) Capabilities() invoke.Capabilities

Capabilities reports the simulated target's features: signal delivery and symlink-preserving transfers work; TTY allocation is not simulated.

func (*Environment) Close

func (e *Environment) Close() error

Close marks the fake closed and terminates simulated processes still running. It is idempotent.

func (*Environment) Download

func (e *Environment) Download(ctx context.Context, remotePath, localPath string, opts ...invoke.TransferOption) error

Download copies a virtual file or tree out to the real host filesystem, atomically per file via temp-and-rename.

func (*Environment) FS

func (e *Environment) FS() fs.FS

FS returns a read-only io/fs.FS view of the fake target's filesystem, for asserting on target state with standard tooling (fs.ReadFile, fs.WalkDir, fstest.TestFS). Paths are unrooted io/fs paths: the target's /tmp/app.txt is "tmp/app.txt", and "." is the root.

The view is live — it reflects mutations as commands and transfers make them — and implements fs.ReadLinkFS, so symlinks are inspectable.

func (*Environment) Handle

func (e *Environment) Handle(name string, h Handler)

Handle registers a handler for commands whose Path equals name, overriding any builtin of the same name. A handler is reachable everywhere the name can be written: started directly, invoked from a invoke.Shell script or a $(...) substitution, and through the path LookPath reports for it. Calls records commands given to Start; a script's internal invocations belong to the script.

func (*Environment) LookPath

func (e *Environment) LookPath(ctx context.Context, name string) (string, error)

LookPath resolves name against the fake's handlers and builtins. The answer is itself resolvable: what LookPath reports, Start accepts.

func (*Environment) OS

func (e *Environment) OS() invoke.TargetOS

OS reports the simulated target's operating system.

func (*Environment) Start

func (e *Environment) Start(ctx context.Context, cmd invoke.Command, stdio invoke.IO) (invoke.Process, error)

Start launches a simulated process for cmd.

func (*Environment) Upload

func (e *Environment) Upload(ctx context.Context, localPath, remotePath string, opts ...invoke.TransferOption) error

Upload copies a real host file or tree into the fake target's virtual filesystem, with the full transfer semantics providers share: per-file atomicity (nothing commits unless the source was read completely), modes preserved or forced umask-proof, symlink policies with containment, special files erroring by name, and real progress totals.

type Handler

type Handler func(ctx context.Context, cmd invoke.Command, s *Session) int

Handler simulates one command: it reads and writes the session streams and returns the exit code. Honoring ctx cancellation keeps a scripted command responsive to the lifecycle machinery, which handles the resulting classification (cancellation, Close, signals) itself.

type Option

type Option func(*Environment)

Option configures the fake at construction.

func WithEnv

func WithEnv(pairs ...string) Option

WithEnv adds KEY=VALUE pairs to the fake target's base environment.

type Session

type Session struct {
	// Stdin is the invocation's standard input (never nil; empty when
	// the caller wired none).
	Stdin io.Reader

	// Stdout and Stderr are the invocation's output streams (never
	// nil; discarding when the caller wired none).
	Stdout io.Writer
	Stderr io.Writer

	// Dir is the working directory the command was started with.
	Dir string

	// Env is the resolved environment: the fake's base environment with
	// the command's overlay applied, in "KEY=VALUE" form.
	Env []string
}

Session is the execution state a Handler runs with.

Jump to

Keyboard shortcuts

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