Documentation
¶
Overview ¶
Package scenario reads LoadWave's YAML configuration and turns it into the two things the rest of the system needs: a wire-format test plan, and — for tests written declaratively rather than in Go — a set of runnable scenarios.
Index ¶
Constants ¶
const ( ExecutorConstantVUs = "constant-vus" ExecutorRampingVUs = "ramping-vus" )
Executor names accepted in configuration.
const ( VarVUID = "__vu" VarIteration = "__iteration" VarShard = "__shard" VarShards = "__shards" VarRandom = "__random" VarUUID = "__uuid" VarTimestamp = "__timestamp" VarUnixMilli = "__unixMilli" )
Built-in variable names, all prefixed so they cannot collide with a user's own declarations.
const DefaultScenarioName = "default"
DefaultScenarioName is the scenario synthesised for a bare --url run.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Name identifies the test in the dashboard and in result files.
Name string `yaml:"name,omitempty"`
// BaseURL is prefixed to every relative request path.
BaseURL string `yaml:"baseURL,omitempty"`
Load LoadConfig `yaml:"load"`
HTTP HTTPConfig `yaml:"http"`
Tags map[string]string `yaml:"tags,omitempty"`
Thresholds []Threshold `yaml:"thresholds,omitempty"`
// WorkersPerAgent is how many worker processes each agent should spawn.
// Zero lets each agent decide from its own core count.
WorkersPerAgent int `yaml:"workersPerAgent,omitempty"`
// BetweenRequests pauses after every request, whatever its outcome: a
// duration such as "1s", or a range such as "500ms-2s".
//
// This is the run's pacing floor, and it is why a scenario with no think
// time of its own does not loop as fast as the network allows — or, when
// its request fails instantly, as fast as the CPU allows. Empty applies
// one second. Set it to "0" for a throughput test, where flat out is the
// point.
//
// Individual steps override it, including down to none.
BetweenRequests string `yaml:"betweenRequests,omitempty"`
// Scenarios lists what to run. An entry with steps is a declarative
// scenario defined here; an entry with only a name and weight refers to
// a scenario compiled into the binary through the Go SDK. Leaving the
// list empty runs every scenario the binary has registered.
Scenarios []ScenarioConfig `yaml:"scenarios,omitempty"`
}
Config is a complete LoadWave test file.
func FromPlan ¶
func FromPlan(plan *loadwavev1.TestPlan) (*Config, error)
FromPlan recovers the configuration a plan was built from.
Workers use this to rebuild the HTTP settings and declarative scenarios. A plan with no embedded configuration — one assembled programmatically rather than from a file — yields a configuration carrying just the base URL, which is enough for a run whose scenarios are all compiled into the binary.
func Parse ¶
Parse reads a configuration from YAML.
Unknown fields are rejected rather than ignored. A silently misspelled key in a load test is a costly kind of bug: the run appears to work and quietly measures something other than what was asked for.
func (*Config) BetweenRequestsPause ¶
BetweenRequestsPause resolves the run's pacing, default included.
Every caller must go through this rather than reading the raw field. An empty field means "use the default", and treating it as the zero Pause reports — and applies — flat out, which is the opposite of what an unconfigured run should do.
func (*Config) BuildScenarios ¶
BuildScenarios compiles every declarative scenario in the configuration and registers it.
Scenarios that only reference compiled-in Go code are skipped, since they are already in the registry. A name that collides with a registered Go scenario is an error rather than an override: silently shadowing compiled code with YAML would be a genuinely confusing thing to debug.
func (*Config) HTTPOptions ¶
func (c *Config) HTTPOptions() loadwave.HTTPOptions
HTTPOptions renders the HTTP settings for the SDK's client factory.
type Duration ¶
Duration is a time.Duration that reads from YAML as "30s" or "5m".
func (Duration) MarshalYAML ¶
MarshalYAML implements yaml.InterfaceMarshaler.
func (*Duration) UnmarshalYAML ¶
UnmarshalYAML implements yaml.BytesUnmarshaler.
type HTTPConfig ¶
type HTTPConfig struct {
Timeout Duration `yaml:"timeout"`
Headers map[string]string `yaml:"headers,omitempty"`
UserAgent string `yaml:"userAgent"`
InsecureSkipTLSVerify bool `yaml:"insecureSkipTLSVerify"`
MaxIdleConnsPerHost int `yaml:"maxIdleConnsPerHost"`
DisableKeepAlives bool `yaml:"disableKeepAlives"`
DisableCompression bool `yaml:"disableCompression"`
FollowRedirects bool `yaml:"followRedirects"`
MaxRedirects int `yaml:"maxRedirects"`
IsolatePerVU bool `yaml:"isolatePerVU"`
DiscardBody bool `yaml:"discardBody"`
MaxBodyBytes int64 `yaml:"maxBodyBytes"`
Proxy string `yaml:"proxy"`
}
HTTPConfig mirrors the tunable parts of loadwave.HTTPOptions.
type LoadConfig ¶
type LoadConfig struct {
// Executor is "constant-vus" or "ramping-vus". Empty defaults to
// constant-vus.
Executor string `yaml:"executor"`
VUs int `yaml:"vus"`
Duration Duration `yaml:"duration"`
Stages []StageConfig `yaml:"stages,omitempty"`
// MaxIterationRate caps iterations started per second across the whole
// run. Zero leaves the VU count as the only control.
MaxIterationRate int `yaml:"maxIterationRate"`
// Iterations stops the run after this many iterations in total.
Iterations uint64 `yaml:"iterations"`
// GracefulStop is how long in-flight iterations get to finish.
GracefulStop Duration `yaml:"gracefulStop"`
}
LoadConfig describes the shape of the load over time.
type Path ¶
type Path struct {
// contains filtered or unexported fields
}
Path is a compiled accessor into a decoded JSON document.
This is deliberately not JSONPath. Declarative scenarios need to pull an id out of a response and put it in the next URL; supporting filters, wildcards and recursive descent would mean a query language to document, test and explain, in exchange for capabilities a load test almost never wants. What is supported is field access and array indexing, in either dotted or bracketed form:
id $.data.token items.0.sku items[0].sku
type ScenarioConfig ¶
type ScenarioConfig struct {
Name string `yaml:"name,omitempty"`
Weight int `yaml:"weight,omitempty"`
Description string `yaml:"description,omitempty"`
Vars map[string]string `yaml:"vars,omitempty"`
Steps []StepConfig `yaml:"steps,omitempty"`
}
ScenarioConfig is one entry in a configuration's scenario list.
An entry carrying steps defines the scenario here, declaratively. An entry with only a name refers to a scenario compiled into the binary through the Go SDK, and exists just to set its weight.
type StageConfig ¶
StageConfig is one leg of a ramping profile.
type StepConfig ¶
type StepConfig struct {
// Name labels the step's metrics. Defaults to the method and path with
// variable segments collapsed.
Name string `yaml:"name,omitempty"`
// Method and URL state the request explicitly. Alternatively use one of
// the shorthands below, which set both at once.
Method string `yaml:"method,omitempty"`
URL string `yaml:"url,omitempty"`
Get string `yaml:"get,omitempty"`
Post string `yaml:"post,omitempty"`
Put string `yaml:"put,omitempty"`
Patch string `yaml:"patch,omitempty"`
Delete string `yaml:"delete,omitempty"`
Head string `yaml:"head,omitempty"`
Headers map[string]string `yaml:"headers,omitempty"`
Query map[string]string `yaml:"query,omitempty"`
// At most one body form may be set.
JSON any `yaml:"json,omitempty"`
Form map[string]string `yaml:"form,omitempty"`
Body string `yaml:"body,omitempty"`
// Expect lists acceptable status codes. A response outside the list
// fails the step's check and ends the iteration.
Expect []int `yaml:"expect,omitempty"`
// Capture pulls values out of the JSON response into variables that
// later steps can interpolate with ${name}.
Capture map[string]string `yaml:"capture,omitempty"`
// Think pauses instead of making a request. Either a fixed duration
// ("2s") or a range ("1s-3s") drawn uniformly.
Think string `yaml:"think,omitempty"`
Timeout Duration `yaml:"timeout,omitempty"`
// BetweenRequests overrides the run's pacing for this step alone: a
// duration, a range, or "0" for no pause at all. Empty uses the run's
// setting.
BetweenRequests string `yaml:"betweenRequests,omitempty"`
}
StepConfig is one action in a declarative scenario: either an HTTP request or a pause.
func (StepConfig) ResolvedRequest ¶
func (s StepConfig) ResolvedRequest() (method, target string, err error)
ResolvedRequest returns the method and URL a step's explicit fields or shorthand resolve to, for callers outside this package that need to describe a step — such as the dashboard rendering one back into its builder form.
type Template ¶
type Template struct {
// contains filtered or unexported fields
}
Template is a string with ${name} placeholders, parsed once and rendered once per use.
Declarative steps render their URL, headers and body on every iteration — tens of thousands of times a second across a fleet — so the parse is done when the scenario is built rather than in the hot path, and a template with no placeholders costs nothing at all to render.
func MustParseTemplate ¶
MustParseTemplate is ParseTemplate for templates known good at build time.
func ParseTemplate ¶
ParseTemplate compiles a template string.
type Threshold ¶
type Threshold struct {
Metric string `yaml:"metric"`
Stat string `yaml:"stat"`
Op string `yaml:"op"`
Value float64 `yaml:"value"`
AbortOnFail bool `yaml:"abortOnFail"`
}
Threshold is a pass/fail assertion evaluated when the run ends.
type Vars ¶
type Vars struct {
// contains filtered or unexported fields
}
Vars holds one iteration's variables: those declared on the scenario, those captured from earlier responses, and a handful of built-ins.