executor

package
v0.2.8 Latest Latest
Warning

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

Go to latest
Published: Feb 1, 2023 License: AGPL-3.0 Imports: 19 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultGracefulStopValue = 30 * time.Second //nolint:gochecknoglobals

DefaultGracefulStopValue is the graceful top value for all executors, unless it's manually changed by the gracefulStop in each one. TODO?: Discard? Or make this actually user-configurable somehow? hello #883...

Functions

func CancelReason

func CancelReason(ctx context.Context) error

CancelReason returns a reason the executor context was cancelled. This will return nil if ctx is not an executor context(ctx or any of its parents was never created by Context function).

func Context

func Context(ctx context.Context) context.Context

Context returns context.Context that can be cancelled by calling CancelExecutorContext. Use this to initialize context that will be passed to executors.

This allows executors to globally halt any executions that uses this context. Example use case is when a script calls test.abort().

Types

type BaseConfig

type BaseConfig struct {
	Name         string             `json:"-"` // set via the JS object key
	Type         string             `json:"executor"`
	StartTime    types.NullDuration `json:"startTime"`
	GracefulStop types.NullDuration `json:"gracefulStop"`
	Env          map[string]string  `json:"env"`
	Exec         null.String        `json:"exec"` // function name, externally validated
	Tags         map[string]string  `json:"tags"`
}

BaseConfig contains the common config fields for all executors

func NewBaseConfig

func NewBaseConfig(name, configType string) BaseConfig

NewBaseConfig returns a default base config with the default values

func (BaseConfig) GetEnv

func (bc BaseConfig) GetEnv() map[string]string

GetEnv returns any specific environment key=value pairs that are configured for the executor.

func (BaseConfig) GetExec

func (bc BaseConfig) GetExec() string

GetExec returns the configured custom exec value, if any.

func (BaseConfig) GetGracefulStop

func (bc BaseConfig) GetGracefulStop() time.Duration

GetGracefulStop returns how long k6 is supposed to wait for any still running iterations to finish executing at the end of the normal executor duration, before it actually kills them.

Of course, that doesn't count when the user manually interrupts the test, then iterations are immediately stopped.

func (BaseConfig) GetName

func (bc BaseConfig) GetName() string

GetName returns the name of the executor.

func (BaseConfig) GetStartTime

func (bc BaseConfig) GetStartTime() time.Duration

GetStartTime returns the starting time, relative to the beginning of the actual test, that this executor is supposed to execute.

func (BaseConfig) GetTags

func (bc BaseConfig) GetTags() map[string]string

GetTags returns any custom tags configured for the executor.

func (BaseConfig) GetType

func (bc BaseConfig) GetType() string

GetType returns the executor's type as a string ID.

func (BaseConfig) IsDistributable

func (bc BaseConfig) IsDistributable() bool

IsDistributable returns true since by default all executors could be run in a distributed manner.

func (BaseConfig) Validate

func (bc BaseConfig) Validate() (errors []error)

Validate checks some basic things like present name, type, and a positive start time

type BaseExecutor

type BaseExecutor struct {
	// contains filtered or unexported fields
}

BaseExecutor is a helper struct that contains common properties and methods between most executors. It is intended to be used as an anonymous struct inside of most of the executors, for the purpose of reducing boilerplate code.

func NewBaseExecutor

func NewBaseExecutor(config libWorker.ExecutorConfig, es *libWorker.ExecutionState, logger *logrus.Entry) *BaseExecutor

NewBaseExecutor returns an initialized BaseExecutor

func (*BaseExecutor) GetConfig

func (bs *BaseExecutor) GetConfig() libWorker.ExecutorConfig

GetConfig returns the configuration with which this executor was launched.

func (*BaseExecutor) GetLogger

func (bs *BaseExecutor) GetLogger() *logrus.Entry

GetLogger returns the executor logger entry.

func (*BaseExecutor) GetProgress

func (bs *BaseExecutor) GetProgress() *pb.ProgressBar

GetProgress just returns the progressbar pointer.

func (*BaseExecutor) Init

func (bs *BaseExecutor) Init(_ context.Context) error

Init doesn't do anything for most executors, since initialization of all planned VUs is handled by the executor.

type ConstantArrivalRate

type ConstantArrivalRate struct {
	*BaseExecutor
	// contains filtered or unexported fields
}

ConstantArrivalRate tries to execute a specific number of iterations for a specific period.

func (*ConstantArrivalRate) Init

func (car *ConstantArrivalRate) Init(ctx context.Context) error

Init values needed for the execution

func (ConstantArrivalRate) Run

func (car ConstantArrivalRate) Run(parentCtx context.Context, out chan<- workerMetrics.SampleContainer, workerInfo *libWorker.WorkerInfo) (err error)

Run executes a constant number of iterations per second.

TODO: Split this up and make an independent component that can be reused between the constant and ramping arrival rate executors - that way we can keep the complexity in one well-architected part (with short methods and few lambdas :D), while having both config frontends still be present for maximum UX benefits. Basically, keep the progress bars and scheduling (i.e. at what time should iteration X begin) different, but keep everything else the same. This will allow us to implement https://github.com/k6io/k6/issues/1386 and things like all of the TODOs below in one place only.

type ConstantArrivalRateConfig

type ConstantArrivalRateConfig struct {
	BaseConfig
	Rate     null.Int           `json:"rate"`
	TimeUnit types.NullDuration `json:"timeUnit"`
	Duration types.NullDuration `json:"duration"`

	// Initialize `PreAllocatedVUs` number of VUs, and if more than that are needed,
	// they will be dynamically allocated, until `MaxVUs` is reached, which is an
	// absolutely hard limit on the number of VUs the executor will use
	PreAllocatedVUs null.Int `json:"preAllocatedVUs"`
	MaxVUs          null.Int `json:"maxVUs"`
}

ConstantArrivalRateConfig stores config for the constant arrival-rate executor

func NewConstantArrivalRateConfig

func NewConstantArrivalRateConfig(name string) *ConstantArrivalRateConfig

NewConstantArrivalRateConfig returns a ConstantArrivalRateConfig with default values

func (ConstantArrivalRateConfig) GetDescription

func (carc ConstantArrivalRateConfig) GetDescription(et *libWorker.ExecutionTuple) string

GetDescription returns a human-readable description of the executor options

func (ConstantArrivalRateConfig) GetExecutionRequirements

func (carc ConstantArrivalRateConfig) GetExecutionRequirements(et *libWorker.ExecutionTuple) []libWorker.ExecutionStep

GetExecutionRequirements returns the number of required VUs to run the executor for its whole duration (disregarding any startTime), including the maximum waiting time for any iterations to gracefully stop. This is used by the execution scheduler in its VU reservation calculations, so it knows how many VUs to pre-initialize.

func (ConstantArrivalRateConfig) GetMaxExecutorVUs

func (config ConstantArrivalRateConfig) GetMaxExecutorVUs() int64

func (ConstantArrivalRateConfig) GetMaxVUs

GetMaxVUs is just a helper method that returns the scaled max VUs.

func (ConstantArrivalRateConfig) GetPreAllocatedVUs

func (carc ConstantArrivalRateConfig) GetPreAllocatedVUs(et *libWorker.ExecutionTuple) int64

GetPreAllocatedVUs is just a helper method that returns the scaled pre-allocated VUs.

func (ConstantArrivalRateConfig) HasWork

HasWork reports whether there is any work to be done for the given execution segment.

func (ConstantArrivalRateConfig) NewExecutor

NewExecutor creates a new ConstantArrivalRate executor

func (ConstantArrivalRateConfig) ScaleOptions

func (config ConstantArrivalRateConfig) ScaleOptions(subFraction float64) libWorker.ExecutorConfig

func (ConstantArrivalRateConfig) Validate

func (carc ConstantArrivalRateConfig) Validate() []error

Validate makes sure all options are configured and valid

type ConstantVUs

type ConstantVUs struct {
	*BaseExecutor
	// contains filtered or unexported fields
}

ConstantVUs maintains a constant number of VUs running for the specified duration.

func (ConstantVUs) Run

func (clv ConstantVUs) Run(parentCtx context.Context, out chan<- workerMetrics.SampleContainer, workerInfo *libWorker.WorkerInfo) (err error)

Run constantly loops through as many iterations as possible on a fixed number of VUs for the specified duration.

type ConstantVUsConfig

type ConstantVUsConfig struct {
	BaseConfig
	VUs      null.Int           `json:"vus"`
	Duration types.NullDuration `json:"duration"`
}

ConstantVUsConfig stores VUs and duration

func NewConstantVUsConfig

func NewConstantVUsConfig(name string) ConstantVUsConfig

NewConstantVUsConfig returns a ConstantVUsConfig with default values

func (ConstantVUsConfig) GetDescription

func (clvc ConstantVUsConfig) GetDescription(et *libWorker.ExecutionTuple) string

GetDescription returns a human-readable description of the executor options

func (ConstantVUsConfig) GetExecutionRequirements

func (clvc ConstantVUsConfig) GetExecutionRequirements(et *libWorker.ExecutionTuple) []libWorker.ExecutionStep

GetExecutionRequirements returns the number of required VUs to run the executor for its whole duration (disregarding any startTime), including the maximum waiting time for any iterations to gracefully stop. This is used by the execution scheduler in its VU reservation calculations, so it knows how many VUs to pre-initialize.

func (ConstantVUsConfig) GetMaxExecutorVUs

func (clvc ConstantVUsConfig) GetMaxExecutorVUs() int64

func (ConstantVUsConfig) GetVUs

GetVUs returns the scaled VUs for the executor.

func (ConstantVUsConfig) HasWork

func (clvc ConstantVUsConfig) HasWork(et *libWorker.ExecutionTuple) bool

HasWork reports whether there is any work to be done for the given execution segment.

func (ConstantVUsConfig) NewExecutor

func (clvc ConstantVUsConfig) NewExecutor(es *libWorker.ExecutionState, logger *logrus.Entry) (libWorker.Executor, error)

NewExecutor creates a new ConstantVUs executor

func (ConstantVUsConfig) ScaleOptions

func (clvc ConstantVUsConfig) ScaleOptions(subFraction float64) libWorker.ExecutorConfig

func (ConstantVUsConfig) Validate

func (clvc ConstantVUsConfig) Validate() []error

Validate makes sure all options are configured and valid

type PerVUIterations

type PerVUIterations struct {
	*BaseExecutor
	// contains filtered or unexported fields
}

PerVUIterations executes a specific number of iterations with each VU.

func (PerVUIterations) Run

func (pvi PerVUIterations) Run(parentCtx context.Context, out chan<- workerMetrics.SampleContainer, workerInfo *libWorker.WorkerInfo) (err error)

Run executes a specific number of iterations with each configured VU.

type PerVUIterationsConfig

type PerVUIterationsConfig struct {
	BaseConfig
	VUs         null.Int           `json:"vus"`
	Iterations  null.Int           `json:"iterations"`
	MaxDuration types.NullDuration `json:"maxDuration"`
}

PerVUIterationsConfig stores the number of VUs iterations, as well as maxDuration settings

func NewPerVUIterationsConfig

func NewPerVUIterationsConfig(name string) PerVUIterationsConfig

NewPerVUIterationsConfig returns a PerVUIterationsConfig with default values

func (PerVUIterationsConfig) GetDescription

func (pvic PerVUIterationsConfig) GetDescription(et *libWorker.ExecutionTuple) string

GetDescription returns a human-readable description of the executor options

func (PerVUIterationsConfig) GetExecutionRequirements

func (pvic PerVUIterationsConfig) GetExecutionRequirements(et *libWorker.ExecutionTuple) []libWorker.ExecutionStep

GetExecutionRequirements returns the number of required VUs to run the executor for its whole duration (disregarding any startTime), including the maximum waiting time for any iterations to gracefully stop. This is used by the execution scheduler in its VU reservation calculations, so it knows how many VUs to pre-initialize.

func (PerVUIterationsConfig) GetIterations

func (pvic PerVUIterationsConfig) GetIterations() int64

GetIterations returns the UNSCALED iteration count for the executor. It's important to note that scaling per-VU iteration executor affects only the number of VUs. If we also scaled the iterations, scaling would have quadratic effects instead of just linear.

func (PerVUIterationsConfig) GetMaxExecutorVUs

func (pvic PerVUIterationsConfig) GetMaxExecutorVUs() int64

func (PerVUIterationsConfig) GetVUs

GetVUs returns the scaled VUs for the executor.

func (PerVUIterationsConfig) HasWork

HasWork reports whether there is any work to be done for the given execution segment.

func (PerVUIterationsConfig) NewExecutor

func (pvic PerVUIterationsConfig) NewExecutor(
	es *libWorker.ExecutionState, logger *logrus.Entry,
) (libWorker.Executor, error)

NewExecutor creates a new PerVUIterations executor

func (PerVUIterationsConfig) ScaleOptions

func (pvic PerVUIterationsConfig) ScaleOptions(subFraction float64) libWorker.ExecutorConfig

func (PerVUIterationsConfig) Validate

func (pvic PerVUIterationsConfig) Validate() []error

Validate makes sure all options are configured and valid

type RampingArrivalRate

type RampingArrivalRate struct {
	*BaseExecutor
	// contains filtered or unexported fields
}

RampingArrivalRate tries to execute a specific number of iterations for a specific period. TODO: combine with the ConstantArrivalRate?

func (*RampingArrivalRate) Init

func (varr *RampingArrivalRate) Init(ctx context.Context) error

Init values needed for the execution

func (RampingArrivalRate) Run

func (varr RampingArrivalRate) Run(parentCtx context.Context, out chan<- workerMetrics.SampleContainer, workerInfo *libWorker.WorkerInfo) (err error)

Run executes a variable number of iterations per second.

TODO: Split this up and make an independent component that can be reused between the constant and ramping arrival rate executors - that way we can keep the complexity in one well-architected part (with short methods and few lambdas :D), while having both config frontends still be present for maximum UX benefits. Basically, keep the progress bars and scheduling (i.e. at what time should iteration X begin) different, but keep everyhing else the same. This will allow us to implement https://github.com/k6io/k6/issues/1386 and things like all of the TODOs below in one place only.

type RampingArrivalRateConfig

type RampingArrivalRateConfig struct {
	BaseConfig
	StartRate null.Int           `json:"startRate"`
	TimeUnit  types.NullDuration `json:"timeUnit"`
	Stages    []Stage            `json:"stages"`

	// Initialize `PreAllocatedVUs` number of VUs, and if more than that are needed,
	// they will be dynamically allocated, until `MaxVUs` is reached, which is an
	// absolutely hard limit on the number of VUs the executor will use
	PreAllocatedVUs null.Int `json:"preAllocatedVUs"`
	MaxVUs          null.Int `json:"maxVUs"`
}

RampingArrivalRateConfig stores config for the ramping (i.e. variable) arrival-rate executor.

func NewRampingArrivalRateConfig

func NewRampingArrivalRateConfig(name string) *RampingArrivalRateConfig

NewRampingArrivalRateConfig returns a RampingArrivalRateConfig with default values

func (RampingArrivalRateConfig) GetDescription

func (varc RampingArrivalRateConfig) GetDescription(et *libWorker.ExecutionTuple) string

GetDescription returns a human-readable description of the executor options

func (RampingArrivalRateConfig) GetExecutionRequirements

func (varc RampingArrivalRateConfig) GetExecutionRequirements(et *libWorker.ExecutionTuple) []libWorker.ExecutionStep

GetExecutionRequirements returns the number of required VUs to run the executor for its whole duration (disregarding any startTime), including the maximum waiting time for any iterations to gracefully stop. This is used by the execution scheduler in its VU reservation calculations, so it knows how many VUs to pre-initialize.

func (*RampingArrivalRateConfig) GetMaxExecutorVUs

func (varc *RampingArrivalRateConfig) GetMaxExecutorVUs() int64

func (RampingArrivalRateConfig) GetMaxVUs

GetMaxVUs is just a helper method that returns the scaled max VUs.

func (RampingArrivalRateConfig) GetPreAllocatedVUs

func (varc RampingArrivalRateConfig) GetPreAllocatedVUs(et *libWorker.ExecutionTuple) int64

GetPreAllocatedVUs is just a helper method that returns the scaled pre-allocated VUs.

func (RampingArrivalRateConfig) HasWork

HasWork reports whether there is any work to be done for the given execution segment.

func (RampingArrivalRateConfig) NewExecutor

NewExecutor creates a new RampingArrivalRate executor

func (*RampingArrivalRateConfig) ScaleOptions

func (varc *RampingArrivalRateConfig) ScaleOptions(subFraction float64) libWorker.ExecutorConfig

func (*RampingArrivalRateConfig) Validate

func (varc *RampingArrivalRateConfig) Validate() []error

Validate makes sure all options are configured and valid

type RampingVUs

type RampingVUs struct {
	*BaseExecutor
	// contains filtered or unexported fields
}

RampingVUs handles the old "stages" execution configuration - it loops iterations with a variable number of VUs for the sum of all of the specified stages' duration.

func (*RampingVUs) Init

func (vlv *RampingVUs) Init(_ context.Context) error

Init initializes the rampingVUs executor by precalculating the raw and graceful steps.

func (*RampingVUs) Run

func (vlv *RampingVUs) Run(ctx context.Context, _ chan<- workerMetrics.SampleContainer, workerInfo *libWorker.WorkerInfo) error

Run constantly loops through as many iterations as possible on a variable number of VUs for the specified stages.

type RampingVUsConfig

type RampingVUsConfig struct {
	BaseConfig
	StartVUs         null.Int           `json:"startVUs"`
	Stages           []Stage            `json:"stages"`
	GracefulRampDown types.NullDuration `json:"gracefulRampDown"`
}

RampingVUsConfig stores the configuration for the stages executor

func NewRampingVUsConfig

func NewRampingVUsConfig(name string) RampingVUsConfig

NewRampingVUsConfig returns a RampingVUsConfig with its default values

func (RampingVUsConfig) GetDescription

func (vlvc RampingVUsConfig) GetDescription(et *libWorker.ExecutionTuple) string

GetDescription returns a human-readable description of the executor options

func (RampingVUsConfig) GetExecutionRequirements

func (vlvc RampingVUsConfig) GetExecutionRequirements(et *libWorker.ExecutionTuple) []libWorker.ExecutionStep

GetExecutionRequirements very dynamically reserves exactly the number of required VUs for this executor at every moment of the test.

If gracefulRampDown is specified, it will also be taken into account, and the number of needed VUs to handle that will also be reserved. See the documentation of reserveVUsForGracefulRampDowns() for more details.

On the other hand, gracefulStop is handled here. To facilitate it, we'll ensure that the last execution step will have 0 VUs and will be at time offset (sum(stages.Duration)+gracefulStop). Any steps that would've been added after it will be ignored. Thus:

  • gracefulStop can be less than gracefulRampDown and can cut the graceful ramp-down periods of the last VUs short.
  • gracefulRampDown can be more than gracefulStop:
  • If the user manually ramped down VUs at the end of the test (i.e. the last stage's target is 0), then this will have no effect.
  • If the last stage's target is more than 0, the VUs at the end of the executor's life will have more time to finish their last iterations.

func (RampingVUsConfig) GetGracefulRampDown

func (vlvc RampingVUsConfig) GetGracefulRampDown() time.Duration

GetGracefulRampDown is just a helper method that returns the graceful ramp-down period as a standard Go time.Duration value...

func (RampingVUsConfig) GetMaxExecutorVUs

func (vlvc RampingVUsConfig) GetMaxExecutorVUs() int64

func (RampingVUsConfig) GetStartVUs

func (vlvc RampingVUsConfig) GetStartVUs(et *libWorker.ExecutionTuple) int64

GetStartVUs is just a helper method that returns the scaled starting VUs.

func (RampingVUsConfig) HasWork

func (vlvc RampingVUsConfig) HasWork(et *libWorker.ExecutionTuple) bool

HasWork reports whether there is any work to be done for the given execution segment.

func (RampingVUsConfig) NewExecutor

func (vlvc RampingVUsConfig) NewExecutor(es *libWorker.ExecutionState, logger *logrus.Entry) (libWorker.Executor, error)

NewExecutor creates a new RampingVUs executor

func (RampingVUsConfig) ScaleOptions

func (vlvc RampingVUsConfig) ScaleOptions(subFraction float64) libWorker.ExecutorConfig

func (RampingVUsConfig) Validate

func (vlvc RampingVUsConfig) Validate() []error

Validate makes sure all options are configured and valid

type SharedIterations

type SharedIterations struct {
	*BaseExecutor
	// contains filtered or unexported fields
}

SharedIterations executes a specific total number of iterations, which are all shared by the configured VUs.

func (*SharedIterations) Init

func (si *SharedIterations) Init(ctx context.Context) error

Init values needed for the execution

func (SharedIterations) Run

func (si SharedIterations) Run(parentCtx context.Context, out chan<- workerMetrics.SampleContainer, workerInfo *libWorker.WorkerInfo) (err error)

Run executes a specific total number of iterations, which are all shared by the configured VUs.

type SharedIterationsConfig

type SharedIterationsConfig struct {
	BaseConfig
	VUs         null.Int           `json:"vus"`
	Iterations  null.Int           `json:"iterations"`
	MaxDuration types.NullDuration `json:"maxDuration"`
}

SharedIterationsConfig stores the number of VUs iterations, as well as maxDuration settings

func NewSharedIterationsConfig

func NewSharedIterationsConfig(name string) SharedIterationsConfig

NewSharedIterationsConfig returns a SharedIterationsConfig with default values

func (SharedIterationsConfig) GetDescription

func (sic SharedIterationsConfig) GetDescription(et *libWorker.ExecutionTuple) string

GetDescription returns a human-readable description of the executor options

func (SharedIterationsConfig) GetExecutionRequirements

func (sic SharedIterationsConfig) GetExecutionRequirements(et *libWorker.ExecutionTuple) []libWorker.ExecutionStep

GetExecutionRequirements returns the number of required VUs to run the executor for its whole duration (disregarding any startTime), including the maximum waiting time for any iterations to gracefully stop. This is used by the execution scheduler in its VU reservation calculations, so it knows how many VUs to pre-initialize.

func (SharedIterationsConfig) GetIterations

func (sic SharedIterationsConfig) GetIterations(et *libWorker.ExecutionTuple) int64

GetIterations returns the scaled iteration count for the executor.

func (SharedIterationsConfig) GetMaxExecutorVUs

func (sic SharedIterationsConfig) GetMaxExecutorVUs() int64

func (SharedIterationsConfig) GetVUs

GetVUs returns the scaled VUs for the executor.

func (SharedIterationsConfig) HasWork

HasWork reports whether there is any work to be done for the given execution segment.

func (SharedIterationsConfig) NewExecutor

func (sic SharedIterationsConfig) NewExecutor(
	es *libWorker.ExecutionState, logger *logrus.Entry,
) (libWorker.Executor, error)

NewExecutor creates a new SharedIterations executor

func (SharedIterationsConfig) ScaleOptions

func (sic SharedIterationsConfig) ScaleOptions(subFraction float64) libWorker.ExecutorConfig

func (SharedIterationsConfig) Validate

func (sic SharedIterationsConfig) Validate() []error

Validate makes sure all options are configured and valid

type Stage

type Stage struct {
	Duration types.NullDuration `json:"duration"`
	Target   null.Int           `json:"target"` // TODO: maybe rename this to endVUs? something else?

}

Stage contains

Jump to

Keyboard shortcuts

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