testguard

package
v1.2.9 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package testguard refuses to let a unit test reach a real host.

THE HURT. A unit test in the certify verb's first cut ran the REAL workloads on a bench and reached a real store, because the local-runner seam defaulted to the real thing when nothing injected a fake. Nobody wrote a hostname in the test: the test constructed production code, production code constructed its own default, and the default was an `exec.Command("ssh", …)`. The `net` class test reads test files for a real hostname and could not see this, because the host was never in the test's text -- it was in the default two packages away.

THE GUARD. Every seam in this tree that reaches a host calls RefuseHosts with the command line it is about to run. When NOVA_TEST_NO_HOST is 1 -- which `make test` sets, so every run of the suite carries it -- that call panics and names the command, so the defect is the test that constructed the real thing rather than a bench that was busy, a key that was missing or a flake nobody could reproduce. When the variable is unset the call is one atomic load and a return: no allocation, no lookup, nothing to pay on a production path that is about to spawn ssh anyway.

A TEST THAT WANTS A CHILD. A fake `ssh` written into t.TempDir() and put on PATH is not a host, and this package can see that for itself: a program that resolves INSIDE a temp directory (GOTMPDIR included) is a fake, a program that resolves to /usr/bin/ssh is the fleet. So the tests that already fake the seam that way -- and the tools they run as child processes, which inherit the variable -- keep working untouched. A test whose fake lives anywhere else says so out loud with `defer testguard.AllowHosts()()`.

Every seam this package guards is held by TestNoTestReachesAHostThroughAnUnfakedSeam in internal/ci, which reads the tree and refuses a seam that does not call it.

Index

Constants

View Source
const EnvNoHost = "NOVA_TEST_NO_HOST"

EnvNoHost is the variable that turns the guard on. `make test` sets it to "1" for every tier, and ci.yml reaches the same targets through make, so a test running anywhere on the CI path runs under the guard.

Variables

This section is empty.

Functions

func AllowHosts

func AllowHosts() func()

AllowHosts opens a scope in which a seam may run a child, and returns the function that closes it. The one honest use is a test that has installed its own fake on PATH:

defer testguard.AllowHosts()()

The scope is process-wide for its duration, so a test that opens one must not run in parallel with a test relying on the guard. That is a narrowing, written down rather than left to be discovered: the guard catches the UNFAKED seam, and a test that fakes a seam declares it.

func RefuseHosts

func RefuseHosts(program string, args ...string)

RefuseHosts is what every ssh/scp/rsync seam in this tree calls with the command line it is about to run. Under the guard, and outside an AllowHosts scope, it panics naming that command line; otherwise it returns immediately.

It panics rather than returning an error on purpose. An error would travel up a path that already handles "the bench was unreachable" and would be reported as exactly that -- an infrastructure story for a code defect. A panic names the test, the seam and the command in one stack, which is the cheapest possible read of the hurt above.

func Refusing

func Refusing() bool

Refusing reports whether the process-wide guard is armed.

func Reload

func Reload()

Reload re-reads the environment. Tests that set the variable with t.Setenv after start call it, and call it again on cleanup; nothing on a production path needs it.

Types

type Guard

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

Guard holds the state and seams for refusing host calls in tests.

func NewGuard

func NewGuard(armed bool) *Guard

NewGuard constructs an isolated guard with its armed state explicitly configured.

func (*Guard) AllowHosts

func (g *Guard) AllowHosts() func()

AllowHosts opens a scope in which a seam may run a child, and returns the function that closes it.

func (*Guard) RefuseHosts

func (g *Guard) RefuseHosts(program string, args ...string)

RefuseHosts is what every ssh/scp/rsync seam in this tree calls with the command line it is about to run. Under the guard, and outside an AllowHosts scope, it panics naming that command line; otherwise it returns immediately.

It panics rather than returning an error on purpose. An error would travel up a path that already handles "the bench was unreachable" and would be reported as exactly that -- an infrastructure story for a code defect. A panic names the test, the seam and the command in one stack, which is the cheapest possible read of the hurt above.

Jump to

Keyboard shortcuts

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