testutil

package
v0.0.0-...-e0b90a1 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2026 License: Apache-2.0 Imports: 39 Imported by: 0

Documentation

Overview

Package testutil is the shared test harness: one isolated binary per test.

Everything here exists to make one promise cheap to keep: no test ever reaches the developer's real home directory, keychain or vendor account. Every command the harness builds is cut off from all three at once:

  • the configuration directory and HOME point into a temporary directory;
  • CLAUDE_CONFIG_DIR, CLAUDE_SECURESTORAGE_CONFIG_DIR, CLAUDE_CODE_OAUTH_TOKEN and CODEX_HOME are removed, so an inherited value cannot point the binary back at the real machine;
  • the endpoint overrides default to an unroutable loopback port, so a regression that fetched anyway fails loudly here rather than quietly reaching a vendor;
  • the keychain is either disabled outright or replaced by the fake security script, never /usr/bin/security.

Index

Constants

View Source
const (
	// LiveService is the keychain service a live session uses when no
	// configuration directory is set.
	LiveService = "Claude Code-credentials"

	// UnknownOrg is the organization directory name a login uses when the
	// exchange named none.
	UnknownOrg = "_unknown-org"

	// Acct is the account uuid every fixture account uses.
	Acct = "11111111-2222-3333-4444-555555555555"

	// Org is the organization uuid every fixture account uses.
	Org = "66666666-7777-8888-9999-000000000000"

	// Email is the email the fixture account is addressed by.
	Email = "owner@example.com"

	// TokenPath is the path the mock OAuth token endpoint is served under.
	TokenPath = "/v1/oauth/token"

	// UsagePath is the usage endpoint's path under the base URL.
	UsagePath = "/api/oauth/usage"

	// ProfilePath is the profile endpoint's path under the base URL.
	ProfilePath = "/api/oauth/profile"
)
View Source
const ClosedEndpoint = "http://127.0.0.1:9"

ClosedEndpoint is an unroutable base URL: port 9 on loopback, which nothing listens on. A test that means to talk to a server overrides the endpoint variables; a test that does not, cannot reach anything.

View Source
const KeychainAccount = "example"

KeychainAccount is the account attribute the fake keychain items carry.

It is also the USER every command runs with, so the account the binary's own reads match on is the same string the items are stored under and the dump-keychain listing advertises. A reader account that differed from the items' account would model a divergence it could never detect.

View Source
const TaggedBuild = false

TaggedBuild reports whether this binary was compiled with the testing build tag. The e2e guard asserts it, so a suite silently built without its seams fails loudly instead of reporting a cheerful zero failures.

Variables

This section is empty.

Functions

func CanonicalMigrationService

func CanonicalMigrationService(tb testing.TB, nsDir string) string

CanonicalMigrationService returns the same service name for the directory's canonical spelling.

A second name for one directory, and the reason discovery looks for both: a user handing a path through a symbolic link makes the session hash the spelling it was given, so the canonical spelling hashes differently. Under the temporary directory on macOS the two always differ, because /var is a link to /private/var.

func Capture

func Capture(cmd *exec.Cmd) (stdout, stderr *bytes.Buffer)

Capture attaches in-memory buffers to cmd's standard output and standard error and returns them. The standard library drains both pipes concurrently, so a child that fills one before finishing the other cannot deadlock the test - a pipe holds about 64 KiB before it blocks the writer.

func ExpiredAt

func ExpiredAt() int64

ExpiredAt returns an expiry far enough in the past to be expired under any margin.

func ExportSpelling

func ExportSpelling(dir string) string

ExportSpelling returns how a directory is spelled for naming purposes: NFC, no trailing slash.

func FrameDump

func FrameDump(content string, width, height int) string

FrameDump renders one frame of view content in the quoted format the terminal-frame goldens use: one line per terminal row, each row padded with spaces to the terminal's width, wrapped in double quotes, with backslashes and quotes escaped. Styling sequences are stripped first, so the dump describes what a viewer sees, never the escape-code stream.

Padding is by display width, because a cell grid is measured in cells: a double-width character fills two, and len or a rune count would pad such a row past the grid's edge.

func FreshAt

func FreshAt() int64

FreshAt returns an expiry far enough ahead to be fresh under the five-minute margin.

func Golden

func Golden(tb testing.TB, name string, got []byte)

Golden compares got against the named golden file byte for byte. One exact-byte comparison per table output is what proves the trailing padding and final newline a normalising comparator cannot see.

func GoldenPath

func GoldenPath(tb testing.TB, name string) string

GoldenPath returns the golden file for name under testdata/golden.

func GoldenTrimmed

func GoldenTrimmed(tb testing.TB, name string, got []byte)

GoldenTrimmed compares got against the named golden file under the snapshot normalisation: CRLF becomes LF and trailing whitespace at end of file is removed, on both sides. Interior trailing padding stays, so seven of the table oracles - whose stored bodies lack the final row's right padding - compare equal to the padded output a real run emits.

func HoldLock

func HoldLock(tb testing.TB, path string) *os.File

HoldLock takes the exclusive lock on path and holds it until the returned file is closed; the test's cleanup closes it as a backstop.

flock locks belong to the open file description, so a second open of the same path - even in the same process - is a genuine second holder, which is what makes "the second waits" assertions mean anything.

func InodeOf

func InodeOf(tb testing.TB, path string) (dev, ino uint64)

InodeOf returns a file's (device, inode) pair, for proving a replacement was atomic.

func ItemFileName

func ItemFileName(service string) string

ItemFileName returns the name fold the fake security applies to an account or a service. The fold has to match the tr -c 'A-Za-z0-9._-' '_' inside the installed script; the two change together.

func LockIsHeld

func LockIsHeld(path string) bool

LockIsHeld reports whether some other holder owns the exclusive lock on path. It opens the file and tries a non-blocking flock, which is exactly what the binary does. False when the file does not exist yet, so a caller can poll this from the moment it starts a child.

func MigrationService

func MigrationService(nsDir string) string

MigrationService returns the keychain service a live session would migrate nsDir to.

func ModeOf

func ModeOf(tb testing.TB, path string) uint32

ModeOf returns a file's permission bits.

func NowMS

func NowMS() int64

NowMS returns the current time in milliseconds since the epoch.

func ReadGolden

func ReadGolden(tb testing.TB, name string) []byte

ReadGolden returns one golden file's bytes.

func RepoRoot

func RepoRoot(tb testing.TB) string

RepoRoot returns the repository root directory.

func SchemaError

func SchemaError(name string, document []byte) error

SchemaError validates document against the named embedded schema (draft 2020-12) and returns the validation error, or nil when the document conforms. name is the schema's file name, such as "status.v1.json". Schema validation proves shape, not byte order.

func ScriptCmds

func ScriptCmds() map[string]ScriptCmd

ScriptCmds returns the in-process commands registered by every family, as a fresh map the caller may hand to testscript.Params.Cmds.

func ScriptCommands

func ScriptCommands() map[string]func()

ScriptCommands returns the helper programs the e2e harness registers beside the binary under test. Each runs inside the re-executed test binary, whose working directory is the script's own, so every path argument is script-relative or absolute.

func ScriptSetup

func ScriptSetup(env *testscript.Env) error

ScriptSetup prepares one script's isolated world: an owned config/home/bin tree beside the extracted script files, the fake executables installed with their knobs wired, every endpoint override closed, and the identity pinned. The binary under test is already on PATH, registered by the same TestMain that passes this to the runner.

func SendSIGTERM

func SendSIGTERM(tb testing.TB, pid int)

SendSIGTERM sends SIGTERM to one process id, asking the operating system to do what a user's kill would.

func Sha8

func Sha8(raw string) string

Sha8 returns hex(sha256(nfc(raw)))[0:8], the way a live session names a keychain item.

func StripANSI

func StripANSI(text string) string

StripANSI returns one block of output with its terminal escape sequences removed.

Log formatters style field names and separators even when standard error is a pipe, so a test that reads field=value out of a log line has to strip the escapes first: the = itself is wrapped in them, and the sequences contain digits, so neither a literal "field=" search nor "skip to the first digit" survives them.

func ValidateSchema

func ValidateSchema(tb testing.TB, name string, document []byte)

ValidateSchema fails the test when document does not conform to the named embedded schema.

func WaitUntil

func WaitUntil(budget time.Duration, ready func() bool) bool

WaitUntil polls ready every 20 ms until it returns true or budget elapses. It reports whether the condition was ever observed, so the caller decides what a timeout means. Polling rather than sleeping a fixed interval is what keeps tests fast in the common case and honest in the slow one.

Types

type Fixture

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

Fixture is a temporary store, a fake home, and the environment that points one process at both and at nothing else.

func New

func New(tb testing.TB) *Fixture

New builds an isolated store with the keychain disabled outright and every endpoint closed.

func (*Fixture) AllowWrite

func (f *Fixture) AllowWrite(service string) *Fixture

AllowWrite registers service as a service the fake will let a write reach. The stand-in refuses any other service: a write is the one operation where a test that forgot to say which item must not silently succeed.

func (*Fixture) Apply

func (f *Fixture) Apply(cmd *exec.Cmd) *exec.Cmd

Apply sets cmd's environment to this fixture's isolated environment.

func (*Fixture) AssertKeychainReadOnly

func (f *Fixture) AssertKeychainReadOnly()

AssertKeychainReadOnly fails the test when any security subcommand other than the three read-only ones was issued - which would mean a keychain write path exists where none should.

func (*Fixture) BinDir

func (f *Fixture) BinDir() string

BinDir returns the owned directory the fake executables are installed into.

func (*Fixture) Blob

func (f *Fixture) Blob(access, refresh string, expiresAtMS int64) string

Blob returns a credential document in the live store's shape, carrying the fixture identity.

func (*Fixture) CodexBin

func (f *Fixture) CodexBin() string

CodexBin returns where the fake codex is installed.

func (*Fixture) CodexEndpoints

func (f *Fixture) CodexEndpoints(baseURL string) *Fixture

CodexEndpoints points the token and usage endpoints at a mock server.

func (*Fixture) CodexHome

func (f *Fixture) CodexHome(name string) string

CodexHome returns a named home directory inside the fixture, created on demand. The only such home a test may name: a test that wants the fallback path puts its file under Home instead, which is inside the fixture too.

func (*Fixture) CodexLogPath

func (f *Fixture) CodexLogPath() string

CodexLogPath returns where the fake codex records its argv, environment and working directory once a test wires the script's log knob to it.

func (*Fixture) ConfigDir

func (f *Fixture) ConfigDir() string

ConfigDir returns the configuration directory the command under test is pointed at.

func (*Fixture) ConfigDirRecord

func (f *Fixture) ConfigDirRecord(acct, org, service string) map[string]any

ConfigDirRecord returns a read-only registry record naming one keychain service.

func (*Fixture) ConfigFile

func (f *Fixture) ConfigFile() string

ConfigFile returns the registry file path.

func (*Fixture) CredentialsPath

func (f *Fixture) CredentialsPath(acct, org string) string

CredentialsPath returns one account's credential file path.

func (*Fixture) Dump

func (f *Fixture) Dump(services ...string) *Fixture

Dump sets what dump-keychain lists, in security(1)'s own format.

func (*Fixture) Endpoints

func (f *Fixture) Endpoints(baseURL string) *Fixture

Endpoints points the usage, token, authorize and profile endpoints at a mock server.

func (*Fixture) Environ

func (f *Fixture) Environ() []string

Environ returns the isolated environment: the process environment with every scrubbed variable removed, then this fixture's own settings. Removals run first, so an inherited value loses to the fixture rather than to the scrub list.

func (*Fixture) Fault

func (f *Fixture) Fault(names string) *Fixture

Fault turns on fault injection.

func (*Fixture) Home

func (f *Fixture) Home() string

Home returns the fake HOME.

func (*Fixture) IdentifiedBlob

func (f *Fixture) IdentifiedBlob(access, refresh string, expiresAtMS int64, acct string, org any) string

IdentifiedBlob returns a credential document naming a specific account and organization. org may be a string, or nil when the credential names no organization.

func (*Fixture) ItemsDir

func (f *Fixture) ItemsDir() string

ItemsDir returns where the fake keychain items live.

func (*Fixture) KeychainAccounts

func (f *Fixture) KeychainAccounts() []string

KeychainAccounts returns every account directory the fake keychain has items under, sorted.

func (*Fixture) KeychainDumpPath

func (f *Fixture) KeychainDumpPath() string

KeychainDumpPath returns where the fake dump-keychain output lives.

func (*Fixture) KeychainItem

func (f *Fixture) KeychainItem(service, blob string) *Fixture

KeychainItem gives the fake keychain one readable item.

func (*Fixture) KeychainItemPath

func (f *Fixture) KeychainItemPath(service string) string

KeychainItemPath returns the file one item's password is stored in, under this fixture's own account.

func (*Fixture) KeychainItemPathFor

func (f *Fixture) KeychainItemPathFor(account, service string) string

KeychainItemPathFor returns the file one item's password would be stored in under account.

A generic password is identified by its account and its service, so this is what a write with the wrong account creates and what a read with the right one will never serve.

func (*Fixture) KeychainItems

func (f *Fixture) KeychainItems() []KeychainItemEntry

KeychainItems returns every item file the fake keychain holds, sorted.

The whole keychain rather than one item, for the tests whose claim is that nothing was added, changed or removed - a claim that has to see a sibling under another account to be worth making.

func (*Fixture) LockPath

func (f *Fixture) LockPath(acct, org string) string

LockPath returns one account's namespace lock file path.

func (*Fixture) Lookup

func (f *Fixture) Lookup(key string) (string, bool)

Lookup returns the value this fixture would set for key.

func (*Fixture) NamespaceDir

func (f *Fixture) NamespaceDir(acct, org string) string

NamespaceDir returns one account's namespace directory.

func (*Fixture) NamespaceEntries

func (f *Fixture) NamespaceEntries(acct, org string) []string

NamespaceEntries returns everything in a namespace directory, sorted by name. An unreadable namespace is reported as empty, which is what a caller asserting nothing was left behind wants anyway.

func (*Fixture) OwnedRecord

func (f *Fixture) OwnedRecord(acct, org string) map[string]any

OwnedRecord returns an owned registry record for a namespace this store holds.

func (*Fixture) Root

func (f *Fixture) Root() string

Root returns the fixture's own root directory, which everything the fixture creates lives under.

func (*Fixture) Scratch

func (f *Fixture) Scratch(name string) string

Scratch returns a path inside the fixture, for resume files and the like.

func (*Fixture) SecurityBin

func (f *Fixture) SecurityBin() string

SecurityBin returns where the fake security(1) is installed.

func (*Fixture) SecurityLog

func (f *Fixture) SecurityLog() []string

SecurityLog returns every argv line the fake security has recorded so far.

func (*Fixture) SecurityLogPath

func (f *Fixture) SecurityLogPath() string

SecurityLogPath returns where the fake security logs one line per invocation.

func (*Fixture) SecurityWrite

func (f *Fixture) SecurityWrite(line string) Output

SecurityWrite runs the fake security the way the write transport does: argv -i, with one command line on standard input.

func (*Fixture) Set

func (f *Fixture) Set(key, value string) *Fixture

Set records one environment variable for every command this fixture builds, replacing any earlier value for the same key.

func (*Fixture) Unset

func (f *Fixture) Unset(key string) *Fixture

Unset removes one environment variable from the fixture's own settings, leaving the scrub of inherited values in place.

func (*Fixture) WithCodex

func (f *Fixture) WithCodex() *Fixture

WithCodex installs the fake codex executable and wires it into every spawn, so a login child runs the stand-in instead of a real binary.

func (*Fixture) WithKeychain

func (f *Fixture) WithKeychain() *Fixture

WithKeychain installs the fake security(1) and switches the keychain on.

The script's own knobs keep their original names, because the script is installed verbatim; the harness sets them.

func (*Fixture) WriteCredentials

func (f *Fixture) WriteCredentials(acct, org, blob string) string

WriteCredentials writes .credentials.json into a namespace, mode 0600 inside 0700 directories, and returns the file's path.

func (*Fixture) WriteRegistry

func (f *Fixture) WriteRegistry(accounts []any) *Fixture

WriteRegistry writes a registry holding exactly these accounts.

func (*Fixture) WriteRegistryDocument

func (f *Fixture) WriteRegistryDocument(document any) *Fixture

WriteRegistryDocument writes a whole registry document, for the cases that need a member the builders do not set.

type KeychainItemEntry

type KeychainItemEntry struct {
	// Name is "<account>/<file>".
	Name string
	// Data is the item file's bytes.
	Data []byte
}

KeychainItemEntry is one item file the fake keychain holds.

type Output

type Output struct {
	// Code is the exit status code, or -1 when a signal ended the process.
	Code int
	// Signaled reports whether a signal ended the process instead of an
	// exit.
	Signaled bool
	// Stdout is standard output, as text.
	Stdout string
	// Stderr is standard error, as text.
	Stderr string
}

Output is everything a finished child said.

func Finish

func Finish(tb testing.TB, cmd *exec.Cmd, stdout, stderr *bytes.Buffer) Output

Finish waits for a started cmd and returns what it said, with both pipes fully drained.

func Run

func Run(tb testing.TB, cmd *exec.Cmd) Output

Run starts cmd with captured pipes, waits for it, and returns what it said.

func (Output) ExitCode

func (o Output) ExitCode(tb testing.TB) int

ExitCode returns the exit code, insisting there was one. A process ended by a signal fails the test, because for the binary under test that means signal handling did not run.

type ScriptCmd

type ScriptCmd = func(ts *testscript.TestScript, neg bool, args []string)

ScriptCmd is an in-process testscript command whose resources live for one script run.

Jump to

Keyboard shortcuts

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