Documentation
¶
Index ¶
- Constants
- func HarnessSource(packageName string) []byte
- type CoverageQuery
- type Fingerprinter
- type Loader
- type Options
- type PackageOutcome
- type Range
- type Record
- func (r *Record) AlwaysRunTests() []string
- func (r *Record) DurationOf(tests []string) time.Duration
- func (r *Record) Encode() ([]byte, error)
- func (r *Record) Knows(absPath string) bool
- func (r *Record) LineCoverage(absPath string) map[int]int
- func (r *Record) ProfileOf(name string) (lines int, duration time.Duration, ok bool)
- func (r *Record) TestNames() []string
- func (r *Record) TestsCovering(absPath string, lines []int) []string
- func (r *Record) Usable() bool
- type Stats
- type TestCoverage
Constants ¶
const ( CollectionSingleProcess = "single-process" CollectionPerProcess = "per-process" CollectionSalvaged = "salvaged" CollectionReused = "reused" )
Collection modes, reported per package so tests and stats can tell whether the fast path actually ran — an agreement test that silently fell back to per-process collection would prove nothing.
const ( EnvTestList = "ASSAY_TEST_LIST" EnvCounterDir = "ASSAY_COUNTER_DIR" )
EnvTestList and EnvCounterDir form the harness contract. With either unset the injected TestMain is a plain os.Exit(m.Run()), which is what keeps -test.list and the per-test salvage path working against the same binary.
const HarnessFileName = "assay_harness_test.go"
HarnessFileName is the file injected into the test package through -overlay. It never touches the source tree; the overlay makes the compiler see a test file that does not exist on disk.
Variables ¶
This section is empty.
Functions ¶
func HarnessSource ¶
HarnessSource renders the injected TestMain for a package.
The protocol is exact and every line of it was verified empirically:
- a sentinel m.Run with -test.run=^$ comes first, because the coverage machinery finalizes lazily and ClearCounters fails with "covermode=<invalid>" before the first m.Run;
- the snapshot taken right after the sentinel holds exactly the package's init-time execution, which the collector merges into every test's ranges for parity with per-process profiles;
- test.gocoverdir points at a throwaway directory so the binary's exit-time emission is contained instead of warning on stderr;
- the progress line is printed after the snapshot, so a line's presence means the window it names is complete on disk.
Types ¶
type CoverageQuery ¶
type CoverageQuery struct {
// contains filtered or unexported fields
}
CoverageQuery answers the question the index exists to answer — which tests execute this line — with one implementation and one staleness rule.
It exists because two callers grew their own copies and diverged: mutation's scope checked that a record was indexed at the base commit, `assay explain` did not, and so explain would happily report coverage measured against source that is not the source being asked about. Whatever consults the index goes through here, and the guard applies to everyone.
The memoization is not optional at mutation scale: resolving a file to its package walks the directory table and finding the affected test packages is a graph traversal, and both were being redone for every mutation site in a file.
func NewCoverageQuery ¶
func NewCoverageQuery(g *graph.Graph, loader *Loader, commit string) *CoverageQuery
func (*CoverageQuery) TestsCovering ¶
TestsCovering returns the tests with known coverage of any of the lines, grouped by the test package that owns them. The second result reports whether any candidate record was usable at this query's commit — it separates "the index says nothing covers this" from "there is no index to ask".
type Fingerprinter ¶
type Fingerprinter struct {
// contains filtered or unexported fields
}
func NewFingerprinter ¶
func (*Fingerprinter) For ¶
func (f *Fingerprinter) For(importPath string) cache.Fingerprint
type Options ¶
type Options struct {
Root string
Commit string
Graph *graph.Graph
TreeDigests map[string]string
Store *cache.Store
Tags []string
Jobs int
Timeout time.Duration
Env []string
Packages []string
Progress func(pkg string, done, total int)
// Legacy runs each test in its own process instead of one harness process per
// package. Much slower, and the only way to cross-check the harness path.
Legacy bool
}
type PackageOutcome ¶
type PackageOutcome struct {
Package string
Tests int
AlwaysRun int
Reused bool
Degraded string
Mode string
// Fallback records why the harness path was abandoned for this package. A
// silent fallback costs a failed compile plus a full per-process run on
// every rebuild, which must not be a mystery slowdown.
Fallback string
Err error
}
type Record ¶
type Record struct {
Version int
Package string
IndexedAt string
Files []string
Tests []TestCoverage
Degraded string
// contains filtered or unexported fields
}
func (*Record) AlwaysRunTests ¶
func (*Record) LineCoverage ¶
LineCoverage reports, for one file, every covered line and how many distinct attributable tests execute it. Always-run tests carry no ranges, so their unknown attribution can never dress a line as covered.
func (*Record) ProfileOf ¶
ProfileOf reports a test's coverage breadth — how many distinct lines it executes across the workspace — and its indexed duration. Breadth is the focus signal survivor advice ranks by: among the tests that already execute a mutated line, the one covering the fewest lines is the one whose assertions sit closest to that line. Overlapping ranges are merged per file so a line counts once no matter how many blocks report it.