Documentation
¶
Overview ¶
Package gatedlaboratory runs a file's mutants from one compilation.
It is the two halves put together. internal/schemata turns a file and its mutants into one instrumented file that selects a mutant at run time, and internal/gobuildrunner compiles a package's tests once and runs that binary. Each is useless alone: compiling once only helps when the compiled thing stops changing between mutants, and instrumenting only helps if something compiles it once.
What it removes is measured: the fixed cost of starting `go test`, 750-950 ms per mutant whatever the suite does. See docs/experiments/test-invocation.md.
Index ¶
- type GatedLaboratory
- func (l *GatedLaboratory) FellBack() int
- func (l *GatedLaboratory) Gated() int
- func (l *GatedLaboratory) Test(repository ditto.Repository, file *gomutatedfile.GoMutatedFile) future.Future[result.Result[string]]
- func (l *GatedLaboratory) TestAll(repository ditto.Repository, files []*gomutatedfile.GoMutatedFile) []future.Future[result.Result[string]]
- type Runner
- type TemporaryDirectory
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type GatedLaboratory ¶
type GatedLaboratory struct {
// contains filtered or unexported fields
}
GatedLaboratory instruments a file once, compiles once, and selects a mutant per run. Anything it cannot gate goes to the laboratory it delegates to, which is the path ditto has always taken.
func New ¶
func New(delegate ditto.Laboratory, temporaryDirectory TemporaryDirectory) *GatedLaboratory
func NewWithRunner ¶
func NewWithRunner(delegate ditto.Laboratory, temporaryDirectory TemporaryDirectory, runner Runner) *GatedLaboratory
NewWithRunner is the seam the tests use, so the laboratory's decisions can be checked without a Go toolchain compiling anything.
func (*GatedLaboratory) FellBack ¶
func (l *GatedLaboratory) FellBack() int
func (*GatedLaboratory) Gated ¶
func (l *GatedLaboratory) Gated() int
Gated and FellBack are exact counters: how many mutants ran from the shared compilation, and how many kept their own. They are what this is judged on, because wall clock on a working machine varies by more than half and these do not vary at all.
func (*GatedLaboratory) Test ¶
func (l *GatedLaboratory) Test( repository ditto.Repository, file *gomutatedfile.GoMutatedFile, ) future.Future[result.Result[string]]
Test keeps the one-mutant-at-a-time contract, and takes the old path. A single mutant cannot repay a compilation.
func (*GatedLaboratory) TestAll ¶
func (l *GatedLaboratory) TestAll( repository ditto.Repository, files []*gomutatedfile.GoMutatedFile, ) []future.Future[result.Result[string]]
TestAll runs every mutant of one file, gating the ones it can.
type Runner ¶
type Runner interface {
Select(mutant int)
Built() bool
Test(repository ditto.TemporaryRepository) result.Result[string]
}
Runner is the seam over building and running, so the laboratory can be tested without a toolchain.
type TemporaryDirectory ¶
type TemporaryDirectory interface {
New() string
}