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
- func CanonicalMigrationService(tb testing.TB, nsDir string) string
- func Capture(cmd *exec.Cmd) (stdout, stderr *bytes.Buffer)
- func ExpiredAt() int64
- func ExportSpelling(dir string) string
- func FrameDump(content string, width, height int) string
- func FreshAt() int64
- func Golden(tb testing.TB, name string, got []byte)
- func GoldenPath(tb testing.TB, name string) string
- func GoldenTrimmed(tb testing.TB, name string, got []byte)
- func HoldLock(tb testing.TB, path string) *os.File
- func InodeOf(tb testing.TB, path string) (dev, ino uint64)
- func ItemFileName(service string) string
- func LockIsHeld(path string) bool
- func MigrationService(nsDir string) string
- func ModeOf(tb testing.TB, path string) uint32
- func NowMS() int64
- func ReadGolden(tb testing.TB, name string) []byte
- func RepoRoot(tb testing.TB) string
- func SchemaError(name string, document []byte) error
- func ScriptCmds() map[string]ScriptCmd
- func ScriptCommands() map[string]func()
- func ScriptSetup(env *testscript.Env) error
- func SendSIGTERM(tb testing.TB, pid int)
- func Sha8(raw string) string
- func StripANSI(text string) string
- func ValidateSchema(tb testing.TB, name string, document []byte)
- func WaitUntil(budget time.Duration, ready func() bool) bool
- type Fixture
- func (f *Fixture) AllowWrite(service string) *Fixture
- func (f *Fixture) Apply(cmd *exec.Cmd) *exec.Cmd
- func (f *Fixture) AssertKeychainReadOnly()
- func (f *Fixture) BinDir() string
- func (f *Fixture) Blob(access, refresh string, expiresAtMS int64) string
- func (f *Fixture) CodexBin() string
- func (f *Fixture) CodexEndpoints(baseURL string) *Fixture
- func (f *Fixture) CodexHome(name string) string
- func (f *Fixture) CodexLogPath() string
- func (f *Fixture) ConfigDir() string
- func (f *Fixture) ConfigDirRecord(acct, org, service string) map[string]any
- func (f *Fixture) ConfigFile() string
- func (f *Fixture) CredentialsPath(acct, org string) string
- func (f *Fixture) Dump(services ...string) *Fixture
- func (f *Fixture) Endpoints(baseURL string) *Fixture
- func (f *Fixture) Environ() []string
- func (f *Fixture) Fault(names string) *Fixture
- func (f *Fixture) Home() string
- func (f *Fixture) IdentifiedBlob(access, refresh string, expiresAtMS int64, acct string, org any) string
- func (f *Fixture) ItemsDir() string
- func (f *Fixture) KeychainAccounts() []string
- func (f *Fixture) KeychainDumpPath() string
- func (f *Fixture) KeychainItem(service, blob string) *Fixture
- func (f *Fixture) KeychainItemPath(service string) string
- func (f *Fixture) KeychainItemPathFor(account, service string) string
- func (f *Fixture) KeychainItems() []KeychainItemEntry
- func (f *Fixture) LockPath(acct, org string) string
- func (f *Fixture) Lookup(key string) (string, bool)
- func (f *Fixture) NamespaceDir(acct, org string) string
- func (f *Fixture) NamespaceEntries(acct, org string) []string
- func (f *Fixture) OwnedRecord(acct, org string) map[string]any
- func (f *Fixture) Root() string
- func (f *Fixture) Scratch(name string) string
- func (f *Fixture) SecurityBin() string
- func (f *Fixture) SecurityLog() []string
- func (f *Fixture) SecurityLogPath() string
- func (f *Fixture) SecurityWrite(line string) Output
- func (f *Fixture) Set(key, value string) *Fixture
- func (f *Fixture) Unset(key string) *Fixture
- func (f *Fixture) WithCodex() *Fixture
- func (f *Fixture) WithKeychain() *Fixture
- func (f *Fixture) WriteCredentials(acct, org, blob string) string
- func (f *Fixture) WriteRegistry(accounts []any) *Fixture
- func (f *Fixture) WriteRegistryDocument(document any) *Fixture
- type KeychainItemEntry
- type Output
- type ScriptCmd
Constants ¶
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" )
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.
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.
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 ¶
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 ¶
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 ¶
ExportSpelling returns how a directory is spelled for naming purposes: NFC, no trailing slash.
func FrameDump ¶
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 ¶
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 ¶
GoldenPath returns the golden file for name under testdata/golden.
func GoldenTrimmed ¶
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 ¶
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 ItemFileName ¶
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 ¶
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 ¶
MigrationService returns the keychain service a live session would migrate nsDir to.
func ReadGolden ¶
ReadGolden returns one golden file's bytes.
func SchemaError ¶
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 ¶
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 ¶
SendSIGTERM sends SIGTERM to one process id, asking the operating system to do what a user's kill would.
func StripANSI ¶
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 ¶
ValidateSchema fails the test when document does not conform to the named embedded schema.
func WaitUntil ¶
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 ¶
New builds an isolated store with the keychain disabled outright and every endpoint closed.
func (*Fixture) AllowWrite ¶
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) 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 ¶
BinDir returns the owned directory the fake executables are installed into.
func (*Fixture) Blob ¶
Blob returns a credential document in the live store's shape, carrying the fixture identity.
func (*Fixture) CodexEndpoints ¶
CodexEndpoints points the token and usage endpoints at a mock server.
func (*Fixture) CodexHome ¶
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 ¶
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 ¶
ConfigDir returns the configuration directory the command under test is pointed at.
func (*Fixture) ConfigDirRecord ¶
ConfigDirRecord returns a read-only registry record naming one keychain service.
func (*Fixture) ConfigFile ¶
ConfigFile returns the registry file path.
func (*Fixture) CredentialsPath ¶
CredentialsPath returns one account's credential file path.
func (*Fixture) Endpoints ¶
Endpoints points the usage, token, authorize and profile endpoints at a mock server.
func (*Fixture) Environ ¶
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) 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) KeychainAccounts ¶
KeychainAccounts returns every account directory the fake keychain has items under, sorted.
func (*Fixture) KeychainDumpPath ¶
KeychainDumpPath returns where the fake dump-keychain output lives.
func (*Fixture) KeychainItem ¶
KeychainItem gives the fake keychain one readable item.
func (*Fixture) KeychainItemPath ¶
KeychainItemPath returns the file one item's password is stored in, under this fixture's own account.
func (*Fixture) KeychainItemPathFor ¶
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) NamespaceDir ¶
NamespaceDir returns one account's namespace directory.
func (*Fixture) NamespaceEntries ¶
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 ¶
OwnedRecord returns an owned registry record for a namespace this store holds.
func (*Fixture) Root ¶
Root returns the fixture's own root directory, which everything the fixture creates lives under.
func (*Fixture) SecurityBin ¶
SecurityBin returns where the fake security(1) is installed.
func (*Fixture) SecurityLog ¶
SecurityLog returns every argv line the fake security has recorded so far.
func (*Fixture) SecurityLogPath ¶
SecurityLogPath returns where the fake security logs one line per invocation.
func (*Fixture) SecurityWrite ¶
SecurityWrite runs the fake security the way the write transport does: argv -i, with one command line on standard input.
func (*Fixture) Set ¶
Set records one environment variable for every command this fixture builds, replacing any earlier value for the same key.
func (*Fixture) Unset ¶
Unset removes one environment variable from the fixture's own settings, leaving the scrub of inherited values in place.
func (*Fixture) WithCodex ¶
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 ¶
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 ¶
WriteCredentials writes .credentials.json into a namespace, mode 0600 inside 0700 directories, and returns the file's path.
func (*Fixture) WriteRegistry ¶
WriteRegistry writes a registry holding exactly these accounts.
func (*Fixture) WriteRegistryDocument ¶
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 ¶
Finish waits for a started cmd and returns what it said, with both pipes fully drained.
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.
Source Files
¶
- buildtag_release.go
- codex.go
- codex_doctor_script.go
- codex_fixture.go
- codex_invariance_script.go
- codex_login_script.go
- codex_refresh_script.go
- codex_status_script.go
- doctor_script.go
- document.go
- fixture.go
- framedump.go
- golden.go
- import_script.go
- isolate_script.go
- keychain.go
- lock.go
- login_script.go
- proc.go
- schema.go
- script.go
- script_cmds.go
- status_script.go
- status_script_refresh.go
- swap_attribution_script.go
- swap_cleanup_script.go
- swap_live_containment_script.go
- swap_lock_timing_script.go
- swap_orgs_script.go
- swap_script.go
- swap_status_occupant_script.go
- testutil.go
- undo_script.go