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 ¶
- type Environment
- func (e *Environment) Calls() []invoke.Command
- func (e *Environment) Capabilities() invoke.Capabilities
- func (e *Environment) Close() error
- func (e *Environment) Download(ctx context.Context, remotePath, localPath string, ...) error
- func (e *Environment) FS() fs.FS
- func (e *Environment) Handle(name string, h Handler)
- func (e *Environment) LookPath(ctx context.Context, name string) (string, error)
- func (e *Environment) OS() invoke.TargetOS
- func (e *Environment) Start(ctx context.Context, cmd invoke.Command, stdio invoke.IO) (invoke.Process, error)
- func (e *Environment) Upload(ctx context.Context, localPath, remotePath string, ...) error
- type Handler
- type Option
- type Session
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 ¶
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 ¶
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 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.