Documentation
¶
Overview ¶
Package mutate implements the test-kills-mutant falsifier described by docs/specs/falsifiable-packet-v0.md. An impact packet row of kind test claims that a test file covers a changed Go file; this package mutates the changed file's top-level declarations, runs the claimed tests against each mutant on an exported copy of the revision, and requires at least one mutant to die. A surviving population falsifies the claim that the test proves anything.
Index ¶
- func HostSandbox() (string, error)
- func PassthroughEnvironment(names []string) []string
- type Export
- func (exported *Export) Close()
- func (exported *Export) Dir() string
- func (exported *Export) Judge(ctx context.Context, request Request) (Report, error)
- func (exported *Export) JudgeGroup(ctx context.Context, changed string, lines []LineSpan, tests []string) (map[string]Report, error)
- func (exported *Export) Run(ctx context.Context, timeout time.Duration, dir string, environment []string, ...) (string, bool, error)
- func (exported *Export) Scratch() string
- func (exported *Export) Unsandboxed() string
- type LineSpan
- type Report
- type Request
- type Survivor
- type Verdict
- type Witness
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func HostSandbox ¶
HostSandbox names the sandbox the runner would use on this host, or says why the host cannot run cited tests.
func PassthroughEnvironment ¶
PassthroughEnvironment copies the named host variables that are set.
Types ¶
type Export ¶
type Export struct {
// contains filtered or unexported fields
}
Export is one exported revision that judges many claims on one copy. The runner restores the changed file after every mutant, so no claim ever sees another's mutation, and every claim shares the export's build cache.
func Open ¶
Open exports request.Revision once; only Root, Git, Revision, and CacheDir are read. A host without a sandbox opens nothing and every later Judge reports Unsupported. Close removes the copy.
func (*Export) Close ¶
func (exported *Export) Close()
Close removes the exported copy. It is safe to call more than once.
func (*Export) Dir ¶
Dir is the directory holding the exported revision. The runner that mutates a file there must restore it after every mutant.
func (*Export) Judge ¶
Judge falsifies one claim on the exported copy. Root, Git, and Revision may be left empty; when given they must match the export.
func (*Export) JudgeGroup ¶
func (exported *Export) JudgeGroup(ctx context.Context, changed string, lines []LineSpan, tests []string) (map[string]Report, error)
JudgeGroup falsifies every claim that one of tests covers changed, on the exported copy, with one go test per package per mutant instead of one per claim. The mutants depend on changed and lines alone, so each is written once and every package's live claims run together with -json output, from which each claim's own functions decide its verdict exactly as Judge would: a function that fails after building kills, every function passing is a survivor, a package that did not build is uncompilable. A claim is decided at its first kill and leaves later runs; the mutant loop continues while any claim is undecided. A function the package run left without an outcome (the binary died in another test, the output was cut) is re-run alone under its claim's own pattern, so no claim inherits another's crash. Budget: every claim in a run is charged the run's wall time; a claim whose charge reaches the row budget before a run is BUDGET_EXCEEDED at that mutant; a package run's go test timeout is the per-run share times the claims in it, capped at the row budget, so a group is never slower per test than a claim alone. Reports are keyed by test path; a repeated path is judged once.
func (*Export) Run ¶
func (exported *Export) Run(ctx context.Context, timeout time.Duration, dir string, environment []string, argv ...string) (string, bool, error)
Run executes argv inside the host sandbox from dir with exactly environment, after emptying the scratch directory, and kills the run's process group afterwards whatever happened. It reports the bounded combined output, whether the per-run timeout (not the caller's context) ended the run, and the command's error.
func (*Export) Scratch ¶
Scratch is the one directory the sandbox lets a run write, emptied before every Run; a sibling runner points the interpreter's temporary files at it.
func (*Export) Unsandboxed ¶
Unsandboxed is non-empty when the host has no sandbox, and says why; a sibling runner reports Unsupported with it and runs nothing.
type LineSpan ¶
type LineSpan struct {
Start, End int
}
LineSpan is one inclusive 1-based line range of the changed file.
type Report ¶
type Report struct {
Verdict Verdict
Mutants int
Killed int
Survived int
// Uncompilable counts mutants that never built, which are neither killed
// nor survivors: the test was never asked about them.
Uncompilable int
Skipped int
Operators []string
Elapsed time.Duration
Detail string
// Witness identifies the first behavioural kill when the runner could
// attribute it to one named test. It is nil for every non-kill and for an
// unattributed package failure.
Witness *Witness
// Survivors lists every mutant that built and passed the tests, in plan
// order; it is complete only for a Complete run.
Survivors []Survivor
}
Report is the falsifier's answer. Detail is one deterministic human-readable line: it carries no timings and no temporary paths.
type Request ¶
type Request struct {
Root string
Git string
Revision string
ChangedPath string
TestPath string
// Lines, when set, confines mutation to sites whose line falls inside
// one of the spans (1-based, inclusive), so a claim about a change is
// judged on the change and not on the rest of the file.
Lines []LineSpan
MaxMutants int
Budget time.Duration
// Complete runs every mutant instead of stopping at the first kill.
Complete bool
// CacheDir, when set, is the absolute GOCACHE every run in this request
// writes. Callers share it across requests of one invocation and remove
// it; it must never be the host's own build cache.
CacheDir string
}
Request names one claim to falsify. Root is never modified: all work happens on an export of Revision under the system temporary directory.
type Survivor ¶ added in v0.7.0
Survivor is one mutant the tests let live: its operator, the 1-based line of the changed file it was applied at, and its zero-based, end-exclusive byte span in the original changed-file blob.
type Verdict ¶
type Verdict string
Verdict is the falsifier's judgement about the claim. Every judgement about the code under test travels here; error is reserved for caller mistakes and infrastructure failure.
const ( // Killed reports that at least one mutant died: the falsifier passes. Killed Verdict = "KILLED" // Survived reports that every mutant lived: the falsifier fails. Survived Verdict = "SURVIVED" // NoMutants reports that the changed file held nothing mutable. NoMutants Verdict = "NO_MUTANTS" // BudgetExceeded reports that time ran out before any mutant was killed. BudgetExceeded Verdict = "BUDGET_EXCEEDED" // Unsupported reports that the claim could not be judged at all. Unsupported Verdict = "UNSUPPORTED" )