Documentation
¶
Overview ¶
Package testutil holds test-only helpers shared across the CLI test surface. These helpers are intentionally NOT under a `_test.go` file because they need to be imported by tests in other packages — _test.go files are only visible to their own package's tests.
Production code must not import this package. The drift policy `PolicyTestUtilNotImportedFromProduction` under internal/policies/ (M-0118/AC-7) is the chokepoint.
Index ¶
- func AiwfBinary(t *testing.T) string
- func BuildBinary(t *testing.T, tmp string, extraArgs ...string) string
- func CaptureRun(t *testing.T, fn func() int) (rc int, stdout, stderr string)
- func CaptureStderr(t *testing.T, fn func()) []byte
- func CaptureStdout(t *testing.T, fn func()) []byte
- func ExitedWithCode(err error, code int) bool
- func ExtractRow(haystack, prefix string) string
- func MustExec(t *testing.T, workdir, name string, args ...string)
- func ReadFileT(t *testing.T, path string) string
- func RunBin(t *testing.T, workdir, extraPath string, env []string, args ...string) (string, error)
- func RunBinStdin(t *testing.T, workdir, extraPath string, stdin io.Reader, args ...string) (string, error)
- func RunBinary(bin string, args ...string) (string, error)
- func RunBinaryAt(workdir, bin string, args ...string) (string, error)
- func RunGit(workdir string, args ...string) (string, error)
- func SetupGitRepoWithUpstream(t *testing.T, email string) string
- func SkipIfShortOrUnsupported(t *testing.T)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AiwfBinary ¶
AiwfBinary returns the absolute path to a built `aiwf` binary, compiling on the first call. The binary lives in a per-process temp dir so concurrent `go test` runs don't fight over it.
macOS Sonoma 14.8.x has a syspolicyd crash on unsigned Mach-O headers (G-0128). Ad-hoc-signing the binary post-build routes around it.
func BuildBinary ¶
BuildBinary compiles ./cmd/aiwf into tmp/aiwf with the given extra `go build` args (typically `-ldflags=…`) and returns the path. Use when AiwfBinary's cached default-build won't do (e.g., the ldflags-stamped-Version test path needs a per-invocation build).
Builds happen from the repo root so the relative package path resolves regardless of which package the test runs in. The same G-0128 codesigning fix applies as AiwfBinary.
func CaptureRun ¶
CaptureRun redirects os.Stdout and os.Stderr around fn, returning the exit code and both captured streams. Used by tests that need both — typically `aiwf upgrade` where success/failure surface across both streams.
func CaptureStderr ¶
CaptureStderr is the os.Stderr sibling of CaptureStdout. Used by tests that assert on verb-level error messages — verbs write usage errors to stderr while findings/data go to stdout, so separate capture is needed.
func CaptureStdout ¶
CaptureStdout replaces os.Stdout with a pipe for the duration of fn and returns whatever was written. Used by tests that drive verbs in-process (the verbs write to os.Stdout directly so the dispatcher tests need this to assert against output).
Tests calling CaptureStdout cannot run under t.Parallel — os.Stdout is a process-level fd shared by every goroutine. The cmd/aiwf and internal/cli/integration test packages' setup_test.go skip-lists document which tests stay serial because they call CaptureStdout.
Why this lives in a shared testutil package (M-0118/AC-7): the pre-M-0118 codebase had two parallel copies of this function — at cmd/aiwf/helpers_test.go and internal/cli/initcmd/helpers_test.go — because _test.go files cannot cross package boundaries. Sharing the implementation here is the only way to keep one canonical definition.
func ExitedWithCode ¶
ExitedWithCode reports whether err is an *exec.ExitError with the given exit code. Used to tolerate non-zero exit codes that are documented contract (e.g., `aiwf doctor` returns 1 ExitFindings when aiwf.yaml is missing — that's expected, not a test failure).
func ExtractRow ¶
ExtractRow returns the first line of haystack whose prefix (after trimming leading whitespace) matches prefix. Empty if not found. Used by tests that parse line-oriented output like `aiwf doctor`.
func MustExec ¶
MustExec runs name with args in workdir; failure t.Fatals. The caller's location is reported via t.Helper().
func ReadFileT ¶
ReadFileT reads the file at path and returns its contents as a string; t.Fatals on error. Trivial wrapper around os.ReadFile that keeps test bodies free of repeated error-check boilerplate.
func RunBin ¶
RunBin runs the built binary with args in workdir, prepending extraPath onto PATH. Returns combined stdout+stderr and exit error. The binary is built once per test process via AiwfBinary's sync.Once.
func RunBinStdin ¶
func RunBinStdin(t *testing.T, workdir, extraPath string, stdin io.Reader, args ...string) (string, error)
RunBinStdin is the stdin-bearing variant of RunBin: pipes the supplied reader to the binary's stdin so tests can exercise `--body-file -` and similar shorthands. Otherwise identical to RunBin (env, working dir, combined stdout+stderr).
func RunBinary ¶
RunBinary invokes bin with args and returns combined stdout+stderr. Combined output is what a user sees, so the assertions read the same bytes the user would. Sibling of RunBin but doesn't add env vars — the caller controls the environment.
func RunBinaryAt ¶
RunBinaryAt is the workdir-bearing variant of RunBinary. Used by tests where the binary needs to run inside a specific repo (e.g. after init).
func RunGit ¶
RunGit invokes git in workdir and returns combined output. The command runs with a fixed deterministic identity (GIT_AUTHOR_* env vars) so tests don't depend on the developer's git config.
func SetupGitRepoWithUpstream ¶
SetupGitRepoWithUpstream creates a fresh git repo with a bare origin set up as its upstream, then pushes an empty seed commit so the working repo has a tracked branch. Returns the absolute path of the working repo. Tests that exercise provenance audit scopes (`@{u}..HEAD` ranges) need an upstream configured.
func SkipIfShortOrUnsupported ¶
SkipIfShortOrUnsupported gates binary integration tests: requires `go` on PATH, skipped under `-short`, skipped on Windows (aiwf is unix-only).
Types ¶
This section is empty.