Documentation ¶
Overview ¶
Package coverage contains helpers for building compiler coverage reports.
Index ¶
- Constants
- Variables
- func OnCoverageRun(rm RunMessage, o ...Observer)
- type Bucket
- type Config
- type FuzzRunner
- type Maker
- type Observer
- type Option
- func AddInputs(paths ...string) Option
- func ObserveWith(o ...Observer) Option
- func Options(opts ...Option) Option
- func OptionsFromConfig(cfg *Config) Option
- func OverrideQuantities(qs QuantitySet) Option
- func SendStderrTo(w io.Writer) Option
- func UseBackendResolver(r backend.Resolver) Option
- func UseFuzzer(f fuzzer.SingleFuzzer) Option
- func UseStatDumper(d litmus.StatDumper) Option
- type Profile
- type ProfileKind
- type QuantitySet
- type RunContext
- type RunMessage
- type Runner
- type StandaloneRunner
Examples ¶
Constants ¶
const ( // DefaultCount is the default value for the Count quantity. DefaultCount = 1000 // DefaultNWorkers is the default value for the NWorkers quantity. DefaultNWorkers = 10 )
Variables ¶
var ( // ErrNoArch occurs when we try to run a lifted fuzzer for coverage and haven't a target architecture. ErrNoArch = errors.New("this runner needs an architecture set, but got none") // ErrNoFuzzer occurs when we try to run a lifted fuzzer for coverage but the fuzzer is nil. ErrNoFuzzer = errors.New("this runner needs a fuzzer, but got none") // ErrNoLifter occurs when we try to run a lifted fuzzer for coverage but the lifter is nil. ErrNoLifter = errors.New("this runner needs a lifter, but got none") // ErrNoStatDumper occurs when we try to run a lifted fuzzer for coverage but the statistic dumper is nil. ErrNoStatDumper = errors.New("this runner needs a lifter, but got none") // ErrNoInput occurs when we try to run a mutating fuzzer for coverage and haven't any input to feed it. ErrNoInput = errors.New("this runner needs input testcases, but got none") )
var ( // ErrNeedBackend occurs when we try to instantiate a runner for a known-fuzzer profile without a backend. ErrNeedBackend = errors.New("need backend information for this profile") // ErrNeedRunInfo occurs when we try to instantiate a runner for a standalone profile without run information. ErrNeedRunInfo = errors.New("need run information for this profile") // ErrUnsupportedProfileKind occurs when we try to instantiate a runner for an unsupported profile type. ErrUnsupportedProfileKind = errors.New("this profile kind can't be run yet") )
var ErrConfigNil = errors.New("supplied config is nil")
ErrConfigNil is produced when we supply a null pointer to OptionsFromConfig.
var ErrUnknownProfileKind = errors.New("unknown profile kind")
ErrUnknownProfileKind is an error that occurs if we try to unmarshal an unknown profile kind.
Functions ¶
func OnCoverageRun ¶
func OnCoverageRun(rm RunMessage, o ...Observer)
OnCoverageRun broadcasts run message rm to all observers o.
Types ¶
type Bucket ¶
type Bucket struct { // Name is the name of the bucket, in the form "[0-9]+(,[0-9]+)*". Name string // Size is the size of the bucket. Size int }
Bucket is the type of coverage buckets.
type Config ¶
type Config struct { // Paths contains the input and output pathsets for the coverage generator. Paths config.Pathset `toml:"paths"` // Quantities contains quantities for the coverage generator. Quantities QuantitySet `toml:"quantities"` // Profiles contains the list of coverage profiles to use. Profiles map[string]Profile `toml:"profiles"` }
Config gathers the configuration present in coverage generator config files.
func LoadConfigFromFile ¶
LoadConfigFromFile loads a coverage configuration from the filepath path.
type FuzzRunner ¶
type FuzzRunner struct { // TODO(@MattWindsor91): this overlaps with Env in director. // Fuzzer is the fuzzer this fuzz runner uses. Fuzzer fuzzer.SingleFuzzer // Lifter is the lifter this fuzz runner uses. Lifter backend.SingleLifter // StatDumper is the statistics dumper this fuzz runner uses between fuzzing and lifting. StatDumper litmus.StatDumper // Config is the configuration to pass to the fuzz runner. Config *fuzzer2.Config // Arch is the architecture that the lifting process should target. Arch id.ID // Runner should be the service runner to use when invoking the lifter. Runner service.Runner }
FuzzRunner is a coverage runner that uses the c4f fuzzer.
func (*FuzzRunner) Run ¶
func (f *FuzzRunner) Run(ctx context.Context, rc RunContext) error
type Maker ¶
type Maker struct {
// contains filtered or unexported fields
}
Maker contains state used by the coverage testbed maker.
type Observer ¶
type Observer interface { // OnCoverageRun announces that a coverage run is starting, stopping, or progressing. OnCoverageRun(rm RunMessage) }
Observer is the interface of types that can observe the progress of a coverage testbed generator.
type Option ¶
Option is the type of options to supply to the coverage testbed maker's constructor.
func ObserveWith ¶
ObserveWith adds each observer o into the observer list.
func OptionsFromConfig ¶
func OverrideQuantities ¶
func OverrideQuantities(qs QuantitySet) Option
OverrideQuantities overrides the maker's quantity set with qs.
func SendStderrTo ¶
SendStderrTo redirects stderr from commands to w.
func UseBackendResolver ¶
UseBackendResolver adds support for r as the source of backends.
func UseFuzzer ¶
func UseFuzzer(f fuzzer.SingleFuzzer) Option
UseFuzzer adds support for f as a 'known' fuzzer.
func UseStatDumper ¶
func UseStatDumper(d litmus.StatDumper) Option
UseStatDumper adds support for d as the statistics dumper.
type Profile ¶
type Profile struct { // Kind specifies the type of fuzzer profile this is. Kind ProfileKind `toml:"kind"` // Arch is the target architecture for the profile, if it uses one. Arch id.ID `toml:"arch"` // Backend directly feeds in the target backend for the profile, if it uses one. Backend *backend.Spec `toml:"backend"` // Run specifies, if this is a standalone profile, how to run the generator. Run *service.RunInfo `toml:"run"` // Fuzz specifies a fuzzer configuration to use if this is an known-fuzzer profile. Fuzz *fuzzer2.Config `toml:"fuzz"` // Runner specifies an overridden runner for the profile; this is basically useful only for testing. Runner Runner }
Profile tells the coverage generator how to set up a particular coverage profile.
type ProfileKind ¶
type ProfileKind uint8
ProfileKind is the enumeration of kinds of coverage profile.
const ( // Known is a profile kind that tells the coverage generator to run a mutating fuzzer known to it. // At time of writing, there is only one such fuzzer (c4f-fuzz). Known ProfileKind = iota // Standalone is a profile kind that tells the coverage generator to run an external, stand-alone fuzzer. Standalone // LastProfileKind represents the last profile kind. LastProfileKind = Standalone )
func (ProfileKind) MarshalText ¶
func (i ProfileKind) MarshalText() (text []byte, err error)
MarshalText marshals a profile kind to text by using its string representation.
func (ProfileKind) String ¶
func (i ProfileKind) String() string
func (*ProfileKind) UnmarshalText ¶
func (i *ProfileKind) UnmarshalText(text []byte) error
UnmarshalText tries to unmarshal a profile kind from text.
type QuantitySet ¶
type QuantitySet struct { // Count is the number of subjects to fuzz for each profile. Count int `toml:"count"` // Divisions specifies how to divide Count subjects into buckets. // Divisions behave recursively: each subsequent level of division gets applied to the first bucket in the // previous level. Divisions []int `toml:"divisions"` // NWorkers is the number of workers to spawn in the worker pool. NWorkers int }
QuantitySet contains the quantities tracked by the coverage generator.
func (*QuantitySet) Buckets ¶
func (q *QuantitySet) Buckets() []Bucket
Buckets calculates the set of buckets that should be constructed for the coverage setup. Buckets are allocated recursively according to the divisions set in the quantity set; each division carves the first bucket from the previous division into that many sub-buckets. Buckets always appear in reverse order, from highest outer bucket to lowest inner bucket.
Example ¶
ExampleQuantitySet_Buckets is a runnable example for QuantitySet.Buckets.
package main import ( "fmt" "github.com/c4-project/c4t/internal/coverage" ) func main() { qs := coverage.QuantitySet{Count: 1000, Divisions: []int{4, 5}} for _, b := range qs.Buckets() { fmt.Println(b) } }
Output: 4[250] 3[250] 2[250] 1_5[50] 1_4[50] 1_3[50] 1_2[50] 1_1[50]
Example (NoDivision) ¶
ExampleQuantitySet_Buckets is a runnable example for QuantitySet.Buckets where there is no division.
package main import ( "fmt" "github.com/c4-project/c4t/internal/coverage" ) func main() { qs := coverage.QuantitySet{Count: 1000, Divisions: []int{}} for _, b := range qs.Buckets() { fmt.Println(b) } }
Output: 1[1000]
Example (Uneven) ¶
ExampleQuantitySet_Buckets_uneven is a runnable example for QuantitySet.Buckets when there is uneven division.
package main import ( "fmt" "github.com/c4-project/c4t/internal/coverage" ) func main() { qs := coverage.QuantitySet{Count: 1000, Divisions: []int{3, 3}} for _, b := range qs.Buckets() { fmt.Println(b) } }
Output: 3[333] 2[333] 1_3[111] 1_2[111] 1_1[112]
func (*QuantitySet) Override ¶
func (q *QuantitySet) Override(other QuantitySet)
Override overrides this quantity set with the non-zero fields of other.
type RunContext ¶
type RunContext struct { // Seed is the seed to use to drive any random parts of the coverage runner. Seed int32 // BucketDir is the filepath to the bucket directory into which the coverage runner should output its recipe. BucketDir string // NumInBucket is the index of this single instance in its bucket. NumInBucket int // Input points to an input subject for the coverage runner, if any are available. Input *subject.Subject }
RunContext is the type of state provided to a coverage runner.
func (RunContext) ExpandArgs ¶
func (r RunContext) ExpandArgs(arg ...string) []string
ExpandArgs expands various special identifiers in args to parts of the runner context.
Example ¶
ExampleRunContext_ExpandArgs is a runnable example for RunContext.ExpandArgs.
package main import ( "fmt" "path/filepath" "github.com/c4-project/c4t/internal/coverage" "github.com/c4-project/c4t/internal/model/litmus" "github.com/c4-project/c4t/internal/subject" ) func main() { rc := coverage.RunContext{ Seed: 8675309, BucketDir: "bucket1,1", NumInBucket: 42, Input: subject.NewOrPanic(litmus.NewOrPanic("foo/bar.litmus")), } args := rc.ExpandArgs("-seed", "${seed}", "-o", "${outputDir}/${i}.c", "${input}") for _, arg := range args { fmt.Println(filepath.ToSlash(arg)) } }
Output: -seed 8675309 -o bucket1,1/42.c foo/bar.litmus
func (RunContext) LiftOutDir ¶
func (r RunContext) LiftOutDir() string
LiftOutDir is a suggested output directory for backend lifts in this runner context.
func (RunContext) OutLitmus ¶
func (r RunContext) OutLitmus() string
OutLitmus is a suggested filename for Litmus outputs of this runner context.
type RunMessage ¶
type RunMessage struct { observing.Batch // ProfileName contains the runner profile name on start and stop messages. ProfileName string // Profile contains the runner profile on start messages. Profile *Profile // Context contains the runner context on step messages. Context *RunContext }
RunMessage is the type of messages announcing coverage run progress.
func RunEnd ¶
func RunEnd(pname string) RunMessage
RunEnd announces that a coverage run is ending for the profile named pname.
func RunStart ¶
func RunStart(pname string, p Profile, nruns int) RunMessage
RunStart constructs a message stating that a coverage run of size nruns is starting using profile p (named pname).
func RunStep ¶
func RunStep(pname string, i int, rc RunContext) RunMessage
RunStep announces that a coverage run instance, number i, in profile pname and with runner context rc, is starting.
type Runner ¶
type Runner interface { // Run runs the Runner with context ctx and runner context rc. Run(ctx context.Context, rc RunContext) error }
Runner is the interface of things that can be run to generate coverage testbeds.
type StandaloneRunner ¶
type StandaloneRunner struct {
// contains filtered or unexported fields
}
StandaloneRunner is a coverage runner that runs a standalone binary.
func (*StandaloneRunner) Run ¶
func (s *StandaloneRunner) Run(ctx context.Context, rc RunContext) error
Run runs the standalone runner.