plan

package
Version: v0.0.0-...-0d16973 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 10, 2021 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package plan contains the Plan type, as well as various parts of plans that don't warrant their own packages.

Index

Examples

Constants

View Source
const UseDateSeed int64 = -1

UseDateSeed is a value for the header constructor's seed parameter that ensures its RNG will be seeded by run date.

Variables

View Source
var (
	// ErrVersionMismatch occurs when the version of a plan loaded into part of a tester doesn't equal CurrentVer.
	ErrVersionMismatch = errors.New("bad plan version")

	// ErrForbiddenStage occurs when a plan has confirmation of a stage that should not be confirmed.
	ErrForbiddenStage = errors.New("expected stage to be absent")

	// ErrMissingStage occurs when a plan is missing confirmation of a stage on which something depends.
	ErrMissingStage = errors.New("expected stage to be present")
)
View Source
var ErrNil = errors.New("plan nil")

ErrNil is an error that can be returned if a tester stage gets a nil plan.

Functions

func Read

func Read(r io.Reader, p *Plan) error

Read reads uncompressed plan information from r into p.

func ReadCompressed

func ReadCompressed(r io.Reader, p *Plan) error

ReadCompressed reads compressed plan information from r into p.

func ReadFile

func ReadFile(path string, p *Plan) error

ReadFile reads plan information from the file named by path into p.

func ReadMagic

func ReadMagic(r io.ReadSeeker, p *Plan) error

ReadMagic is ReadCompressed if r starts with the gzip magic number, and Read otherwise. As we seek backwards after reading the magic number, r must be a ReadSeeker.

Types

type Map

type Map map[id.ID]Plan

Map is shorthand for a map from machine IDs to plans.

type Metadata

type Metadata struct {
	// Creation marks the time at which the plan was created.
	Creation time.Time `json:"created,omitempty"`

	// Seed is a pseudo-randomly generated integer that should be used to drive randomiser input.
	Seed int64 `json:"seed"`

	// Version is a version identifier of the form YYYYMMDD, used to check whether the plan format has changed.
	Version Version `json:"version,omitempty"`

	// Stages contains a record of every stage that has been completed in the plan's development.
	Stages []stage.Record `json:"stages"`
}

Metadata is a grouping of plan metadata.

func MockMetadata

func MockMetadata() Metadata

func NewMetadata

func NewMetadata(seed int64) *Metadata

NewMetadata produces metadata with a seed and creation time initialised from the current time. If seed is set to anything other than UseDateSeed, the seed will be set from the creation time.

func (*Metadata) CheckVersion

func (m *Metadata) CheckVersion() error

CheckVersion checks to see if this metadata's plan version is compatible with this tool's version. It returns ErrVersionMismatch if not.

func (*Metadata) ConfirmStage

func (m *Metadata) ConfirmStage(s stage.Stage, ts timing.Span)

ConfirmStage adds a stage confirmation for s, spanning timespan ts, to this metadata.

func (*Metadata) ForbidStage

func (m *Metadata) ForbidStage(stages ...stage.Stage) error

ForbidStage checks to make sure that this metadata has not had any given stage marked completed at least once. It returns ErrForbiddenStage if not.

Example

ExampleMetadata_ForbidStage is a testable example for Metadata.ForbidStage.

package main

import (
	"fmt"
	"time"

	"github.com/c4-project/c4t/internal/timing"

	"github.com/c4-project/c4t/internal/plan"
	"github.com/c4-project/c4t/internal/plan/stage"
)

func main() {
	m := plan.NewMetadata(plan.UseDateSeed)
	fmt.Println("starts without plan stage?:", m.ForbidStage(stage.Plan) == nil)
	m.ConfirmStage(stage.Plan, timing.SpanFromInstant(time.Now()))
	fmt.Println("ends without plan stage?:", m.ForbidStage(stage.Plan) == nil)

}
Output:

starts without plan stage?: true
ends without plan stage?: false

func (*Metadata) Rand

func (m *Metadata) Rand() *rand.Rand

Rand creates a random number generator using this Metadata's seed.

func (*Metadata) RequireStage

func (m *Metadata) RequireStage(stages ...stage.Stage) error

RequireStage checks to see if this metadata has had each given stage marked completed at least once. It returns ErrMissingStage if not.

Example

ExampleMetadata_RequireStage is a testable example for Metadata.RequireStage.

package main

import (
	"fmt"
	"time"

	"github.com/c4-project/c4t/internal/timing"

	"github.com/c4-project/c4t/internal/plan"
	"github.com/c4-project/c4t/internal/plan/stage"
)

func main() {
	m := plan.NewMetadata(plan.UseDateSeed)
	fmt.Println("starts with plan stage?:", m.RequireStage(stage.Plan) == nil)
	m.ConfirmStage(stage.Plan, timing.SpanFromInstant(time.Now()))
	fmt.Println("ends with plan stage?:", m.RequireStage(stage.Plan) == nil)

}
Output:

starts with plan stage?: false
ends with plan stage?: true

type Plan

type Plan struct {
	// Metadata contains the metadata for this plan.
	Metadata Metadata `json:"metadata"`

	// Machine represents the machine targeted by this plan.
	Machine machine.Named `json:"machine"`

	// Backend represents the backend targeted by this plan.
	Backend *backend2.NamedSpec `json:"backend,omitempty"`

	// Compilers represents the compilers to be targeted by this plan.
	Compilers compiler.InstanceMap `json:"compilers"`

	// Corpus contains each test corpus entry chosen for this plan.
	Corpus corpus.Corpus `json:"corpus"`

	// Mutation contains configuration specific to mutation testing.
	// If nil or marked disabled, no mutation testing is occurring.
	//
	// Note that the type of this field may change to an expanded form at some point.
	Mutation *mutation.Config `json:"mutation"`
}

Plan represents a test plan. A plan covers an entire campaign of testing.

func Mock

func Mock() *Plan

Mock makes a valid, but mocked-up, plan.

func (*Plan) Arches

func (p *Plan) Arches() []id.ID

Arches gets a list of all architectures targeted by compilers in the machine plan m. These architectures are in order of their string equivalents.

func (*Plan) Check

func (p *Plan) Check() error

Check checks various basic properties on a plan.

func (*Plan) CompilerIDs

func (p *Plan) CompilerIDs() ([]id.ID, error)

CompilerIDs gets a sorted slice of all compiler IDs mentioned in this machine plan. It fails if any of the IDs are invalid.

Example

ExamplePlan_CompilerIDs is a runnable example for Plan.CompilerIDs.

package main

import (
	"fmt"

	"github.com/c4-project/c4t/internal/model/service/compiler"

	"github.com/c4-project/c4t/internal/id"

	"github.com/c4-project/c4t/internal/plan"
)

func main() {
	p := plan.Plan{Compilers: compiler.InstanceMap{
		id.FromString("gcc.ppc"):   {Compiler: compiler.Compiler{Arch: id.ArchPPC}},
		id.FromString("clang.ppc"): {Compiler: compiler.Compiler{Arch: id.ArchPPC}},
		id.FromString("gcc"):       {Compiler: compiler.Compiler{Arch: id.ArchArm}},
		id.FromString("clang"):     {Compiler: compiler.Compiler{Arch: id.ArchArm}},
	}}
	cids, _ := p.CompilerIDs()
	for _, c := range cids {
		fmt.Println(c)
	}

}
Output:

clang
clang.ppc
gcc
gcc.ppc

func (*Plan) IsMutationTest

func (p *Plan) IsMutationTest() bool

IsMutationTest gets whether this plan is defining a mutation test.

This is shorthand for checking if the plan has an enabled mutation configuration.

func (*Plan) MaxNumRecipes

func (p *Plan) MaxNumRecipes() int

MaxNumRecipes counts the upper bound on the number of recipes that need producing for this plan. The actual number of recipes may be lower if there is sharing between architectures (which, at time of writing, is not yet implemented).

Example

ExamplePlan_MaxNumRecipes is a testable example for MaxNumRecipes.

package main

import (
	"fmt"

	"github.com/c4-project/c4t/internal/model/service/compiler"
	"github.com/c4-project/c4t/internal/plan"
	"github.com/c4-project/c4t/internal/subject/corpus"
)

func main() {
	p := plan.Plan{
		Compilers: compiler.InstanceMap{
			id.FromString("gcc1"): compiler.MockX86Gcc(),
			id.FromString("gcc2"): compiler.MockX86Gcc(), // same architecture
			id.FromString("gcc3"): compiler.MockPower9GCCOpt(),
		},
		Corpus: corpus.New("foo", "bar", "baz"),
	}
	fmt.Println(p.MaxNumRecipes())

}
Output:

6

func (*Plan) Mutant

func (p *Plan) Mutant() mutation.Mutant

Mutant gets the currently selected mutant ID according to this plan, or 0 if mutation is disabled.

This assumes that the plan is being repeatedly refreshed with the appropriate mutant ID.

func (*Plan) NumExpCompilations

func (p *Plan) NumExpCompilations() int

NumExpCompilations counts the expected amount of compilations that will be produced on this plan. It does not actually count the number of compilations present in the plan.

Example

ExamplePlan_NumExpCompilations is a testable example for NumExpCompilations.

package main

import (
	"fmt"

	"github.com/c4-project/c4t/internal/model/service/compiler"
	"github.com/c4-project/c4t/internal/plan"
	"github.com/c4-project/c4t/internal/subject/corpus"
)

func main() {
	p := plan.Plan{
		Compilers: compiler.InstanceMap{
			id.FromString("gcc1"): compiler.MockX86Gcc(),
			id.FromString("gcc2"): compiler.MockX86Gcc(),
			id.FromString("gcc3"): compiler.MockPower9GCCOpt(),
		},
		Corpus: corpus.New("foo", "bar", "baz"),
	}
	fmt.Println(p.NumExpCompilations())

}
Output:

9

func (*Plan) RunStage

func (p *Plan) RunStage(ctx context.Context, r Runner) (*Plan, error)

RunStage runs r with ctx and this plan. If r is a StageRunner, we marks s as completed on the resulting plan, using wall clock.

func (*Plan) SetMutant

func (p *Plan) SetMutant(m mutation.Mutant)

SetMutant sets the current mutant ID to m, provided that mutation testing is active.

Example

ExamplePlan_SetMutant is a runnable example for Plan.SetMutant.

package main

import (
	"fmt"

	"github.com/c4-project/c4t/internal/mutation"

	"github.com/c4-project/c4t/internal/plan"
)

func main() {
	p := plan.Mock()
	fmt.Printf("plan mutant: %s (is mutation test: %v)\n", p.Mutant(), p.IsMutationTest())
	p.SetMutant(mutation.Mutant{Name: mutation.Name{Operator: "XYZ", Variant: 1}, Index: 42})
	fmt.Printf("plan mutant: %s (is mutation test: %v)\n", p.Mutant(), p.IsMutationTest())
	p.Mutation = &mutation.Config{Enabled: true}
	fmt.Printf("plan mutant: %s (is mutation test: %v)\n", p.Mutant(), p.IsMutationTest())
	p.SetMutant(mutation.Mutant{Name: mutation.Name{Operator: "XYZ", Variant: 1}, Index: 42})
	fmt.Printf("plan mutant: %s (is mutation test: %v)\n", p.Mutant(), p.IsMutationTest())

}
Output:

plan mutant: 0 (is mutation test: false)
plan mutant: 0 (is mutation test: false)
plan mutant: 0 (is mutation test: true)
plan mutant: XYZ1:42 (is mutation test: true)

func (*Plan) Write

func (p *Plan) Write(w io.Writer, flags WriteFlag) error

Write dumps plan p to w.

func (*Plan) WriteFile

func (p *Plan) WriteFile(path string, flags WriteFlag) error

WriteFile dumps plan p to the file named by path.

type Runner

type Runner interface {
	// Stage returns the stage that this runner implements.
	Stage() stage.Stage

	// Run runs this type's processing stage on the plan pointed to by p.
	// It also takes a context, which can be used to cancel the process.
	// It returns an updated plan (which may or may not be p edited in-place), or an error.
	Run(ctx context.Context, p *Plan) (*Plan, error)

	// Closer captures that some stages have resources that need to be freed after use.
	io.Closer
}

Runner is the interface of parts of the tester that transform plans.

type Version

type Version uint32

Version is the type of plan version numbers.

const CurrentVer Version = 2021_02_19

CurrentVer is the current plan version. It changes when the interface between various bits of the tester (generally manifested within the plan version) changes.

func (Version) IsCurrent

func (v Version) IsCurrent() bool

IsCurrent is true if, and only if, v is compatible with the current version.

type WriteFlag

type WriteFlag uint8

WriteFlag is the type of writing flags for use in

const (
	// Ext is the file extension, if any, that should be used for plan files.
	Ext = ".json"
	// ExtCompress is the file extension, if any, that should be used for compressed plan files.
	ExtCompress = Ext + ".gz"

	// WriteNone is the absence of write flags.
	WriteNone WriteFlag = 0
	// WriteHuman should be passed to plan writers to request human-readable indentation.
	WriteHuman WriteFlag = 1 << iota
	// WriteCompress should be passed to plan writers to request compression.
	WriteCompress
)

Directories

Path Synopsis
Package analysis handles analysing a Corpus and filing its subjects into categorised sub-corpora.
Package analysis handles analysing a Corpus and filing its subjects into categorised sub-corpora.
Package stage contains plan metadata describing which stages of a test cycle have occurred.
Package stage contains plan metadata describing which stages of a test cycle have occurred.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL