Documentation
¶
Index ¶
- Constants
- Variables
- func Chain(middlewares ...Middleware) func(Scenario) Scenario
- func ListenAsWorker(ctx context.Context, addr string, scenario Scenario) error
- func SetSeed(seed int64)
- func SkipIfShort(t TB)
- func ToRunEvent(result Result, passed bool, startedAt time.Time) fabricmetrics.RunEvent
- func ToRunEventProto(result Result, passed bool, startedAt time.Time) *fabricv1.RunEvent
- func UserError(err error) error
- func ValidateConfig(cfg Config) error
- type AbortConfig
- type AdaptiveConfig
- type Config
- type Extractor
- type FabricEmitHook
- type FabricRunEmit
- type Feeder
- type HTTPScenarioConfig
- type LatencyStats
- type Middleware
- func WithBulkhead(maxConcurrent int) Middleware
- func WithCircuitBreaker(threshold float64, window, timeout time.Duration) Middleware
- func WithErrorRate(rate float64) Middleware
- func WithJitter(min, max time.Duration, rate float64) Middleware
- func WithLatency(d time.Duration, rate float64) Middleware
- func WithRetry(n int, backoff time.Duration) Middleware
- func WithStatusCode(code int, rate float64) Middleware
- func WithTimeout(d time.Duration) Middleware
- type Phase
- type PhaseType
- type Reporter
- type ReportingConfig
- type Result
- type ResultHook
- type SaturationPolicy
- type Scenario
- type Snapshot
- type Step
- type StressConfig
- type StressResult
- type TB
- type Test
- type ThresholdOutcome
- type ThresholdViolationError
- type Thresholds
Constants ¶
const ( // SaturationPolicyDrop preserves the configured arrival rate by discarding // arrivals that cannot start immediately. SaturationPolicyDrop = engine.SaturationPolicyDrop // SaturationPolicyBlock waits for capacity, applying backpressure to the // scheduler. This preserves the behavior of earlier Pulse versions. SaturationPolicyBlock = engine.SaturationPolicyBlock )
const ( // PhaseTypeConstant represents a constant arrival-rate phase. PhaseTypeConstant = model.PhaseTypeConstant // PhaseTypeRamp represents a linear ramp between two arrival rates. PhaseTypeRamp = model.PhaseTypeRamp // PhaseTypeStep represents discrete steps between two arrival rates. PhaseTypeStep = model.PhaseTypeStep // PhaseTypeSpike represents a temporary spike from a base rate to a peak rate. PhaseTypeSpike = model.PhaseTypeSpike )
Variables ¶
var ( ErrInjected = errors.New("pulse: injected fault") // ErrBulkheadFull is returned by WithBulkhead when the concurrency // limit is reached and the context expires before a slot opens. ErrBulkheadFull = errors.New("pulse: bulkhead full") )
ErrInjected is returned by WithErrorRate when a fault is injected.
var ErrAborted = engine.ErrAborted
ErrAborted is returned (joined into the run error) when an AbortConfig limit is breached and the run is stopped early. Detect it with errors.Is.
var ErrCircuitOpen = errors.New("pulse: circuit open")
ErrCircuitOpen is returned when the circuit breaker is open and requests are being rejected to simulate cascading failures.
var ErrUser = metrics.ErrUser
ErrUser marks an error as originating from scenario/user code rather than the target, so the run counts it under the "user_error" category instead of "unknown_error". Detect it with errors.Is; wrap with UserError.
Functions ¶
func Chain ¶ added in v0.3.3
func Chain(middlewares ...Middleware) func(Scenario) Scenario
Chain applies middlewares to a Scenario in order. The first middleware is the outermost wrapper.
func ListenAsWorker ¶ added in v0.5.0
ListenAsWorker starts a distributed worker server on addr that accepts RunRequests from a coordinator and executes scenario at the directed rate. It blocks until ctx is cancelled. Use in library mode alongside RunContext with Config.Workers set on the coordinator side.
func SetSeed ¶ added in v0.4.0
func SetSeed(seed int64)
SetSeed sets a deterministic seed for the random source used by built-in middlewares (WithErrorRate, WithJitter, WithLatency, WithStatusCode).
After SetSeed is called all middleware RNG calls share a single mutex-serialised source derived from seed. This guarantees that two runs with the same seed and the same sequential call order produce identical injected-fault patterns. Because OS scheduling can vary which goroutine draws which random value under concurrency, exact replay is best-effort.
func SkipIfShort ¶ added in v0.3.2
func SkipIfShort(t TB)
SkipIfShort skips the test if -short flag is set.
func ToRunEvent ¶ added in v0.3.1
ToRunEvent converts a Pulse Result into a fabric metrics.RunEvent, making it compatible with other Algoryn ecosystem tools. The startedAt parameter should be the time the run began. If zero, time.Now() minus result.Duration is used as a best-effort approximation. Snapshot.Service is empty; use ToFabricRunEmit when you need a service name on the snapshot.
func ToRunEventProto ¶ added in v0.3.7
ToRunEventProto converts a Pulse Result into fabric.v1.RunEvent (binary contract). Timestamps are set from startedAt / endedAt via Fabric conversion helpers (timestamppb).
func UserError ¶ added in v0.7.0
UserError wraps err so a run counts it under the "user_error" category. It returns nil when err is nil. The result unwraps to both ErrUser and err, so errors.Is matches either. Use it inside a scenario for failures that are the test's responsibility (bad fixtures, business-rule violations, client-side validation) rather than transport or server errors:
scenario := func(ctx context.Context) (int, error) {
order, err := buildOrder(feeder.Next())
if err != nil {
return 0, pulse.UserError(err) // counted as user_error, not unknown_error
}
return client.Post(ctx, url, order)
}
func ValidateConfig ¶ added in v0.4.0
ValidateConfig validates the Config fields of a Test: phases, saturation policy, concurrency limits, reporting interval, and thresholds. It is called by validateTest and is also available to external packages (such as config.Load) that build a pulse.Config from another representation and want early error reporting before constructing a full Test.
Types ¶
type AbortConfig ¶ added in v0.7.0
type AbortConfig = engine.AbortConfig
AbortConfig stops a run early (fail-fast) when a reporting interval breaches a configured error-rate or P99-latency limit. When triggered, RunContext returns a result for the partial run wrapped with ErrAborted. Requires Reporting.Interval > 0.
type AdaptiveConfig ¶ added in v0.5.0
type AdaptiveConfig = engine.AdaptiveConfig
AdaptiveConfig enables real-time RPS auto-tuning for PhaseTypeConstant phases. On each reporting interval the engine adjusts the arrival rate up or down based on observed error rate and P99 latency thresholds. Requires Reporting.Interval > 0.
type Config ¶
type Config struct {
Phases []Phase
MaxConcurrency int
// Seed pins the random source used by built-in middlewares (WithErrorRate,
// WithJitter, WithLatency, WithStatusCode) so that injected-fault patterns
// are reproducible across runs. Two runs with the same Seed, the same
// Config, and the same scenario execution order produce identical fault
// patterns. OS scheduling variation means exact replay is best-effort.
// Seed is applied only when SetSeed has not already been called; set it
// to nil to leave the random source unseeded (the default).
Seed *int64
// SaturationPolicy defaults to SaturationPolicyDrop.
SaturationPolicy SaturationPolicy
Thresholds Thresholds
Reporting ReportingConfig
// Service is optional metadata for Fabric MetricSnapshot.Service and RunCompleted payloads.
Service string
// Workers is an optional list of distributed worker addresses ("host:port").
// When non-empty, RunContext fans out the test to all workers via HTTP and
// merges their results. Workers must be started with ListenAsWorker.
// For single-node runs (the default), leave Workers nil or empty.
Workers []string
// WorkerWeights optionally assigns a relative capacity to each worker, in the
// same order as Workers. Arrival rate and concurrency are split
// proportionally (e.g. {2,1} sends a 2:1 share to the first worker). When
// empty or mismatched in length, workers are weighted equally.
WorkerWeights []int
// DistributedHTTPScenario, when non-nil, is forwarded to workers in the
// RunRequest so CLI workers can build the HTTP scenario from config.
// Populated by config.Load() from the YAML target section.
// Library users with pre-registered scenarios should leave this nil.
DistributedHTTPScenario *HTTPScenarioConfig
// DashboardAddr, when non-empty, starts an HTTP dashboard server at the
// given address (e.g. ":9090") that streams live metrics via SSE.
// Open http://localhost:9090 in a browser while the run is active.
DashboardAddr string
OnResult ResultHook // optional; nil means no-op
OnFabricEmit FabricEmitHook // optional; protobuf RunEvent + RunCompleted Event
// OnSnapshot is called at the end of each reporting interval with the
// metrics observed during that window. It is invoked from a background
// goroutine and must not block. Only active when Reporting.Interval > 0.
OnSnapshot func(snapshot Snapshot)
// Adaptive, when non-zero, enables real-time RPS auto-tuning for
// PhaseTypeConstant phases based on observed error rate and P99 latency.
// Requires Reporting.Interval > 0.
Adaptive AdaptiveConfig
// Abort, when non-zero, stops the run early (fail-fast) when a reporting
// interval breaches a configured error-rate or P99-latency limit. The run
// error is wrapped with ErrAborted. Requires Reporting.Interval > 0.
Abort AbortConfig
// Stress, when non-zero, enables ramp-to-failure capacity discovery. The run
// stops when a failure threshold is breached and Result.Stress is populated.
// Requires Reporting.Interval > 0, is mutually exclusive with Adaptive, and is
// not supported in distributed mode (Workers).
Stress StressConfig
// Percentiles lists additional latency percentiles (values in (0,100), e.g.
// 99.9) to compute for the final result, in addition to the always-reported
// P50/P90/P95/P99. Reported in Result.ExtraPercentiles keyed by label
// ("p99.9"). Out-of-range values are rejected by validation.
Percentiles []float64
// Reporters is an optional list of metric exporters called on each snapshot
// interval and once after the run completes. Requires Reporting.Interval > 0
// for OnSnapshot to fire; OnResult is always called.
Reporters []Reporter
}
Config holds execution configuration for a test. Config holds execution configuration for a test.
type Extractor ¶ added in v0.7.0
type Extractor[T any] struct { // contains filtered or unexported fields }
Extractor is a thread-safe value container for passing data extracted from one scenario step to subsequent steps (e.g. an auth token from a login response used in all following requests).
Declare one extractor per value to correlate, share it across steps via closure, and call Set inside the producing step and Get or MustGet in the consuming steps.
func (*Extractor[T]) Get ¶ added in v0.7.0
Get returns the stored value and true, or the zero value and false if Set has not been called yet.
type FabricEmitHook ¶ added in v0.3.7
FabricEmitHook is invoked after threshold evaluation with protobuf contracts for the Fabric stack. run carries fabric.v1.MetricSnapshot; completed is EVENT_TYPE_RUN_COMPLETED for tools like Beacon.
type FabricRunEmit ¶ added in v0.3.7
FabricRunEmit bundles the protobuf shapes Pulse emits for downstream Algoryn tools. RunEvent carries the full MetricSnapshot; RunCompleted is the fabric.v1.Event envelope (EVENT_TYPE_RUN_COMPLETED) for consumers such as Beacon.
func ToFabricRunEmit ¶ added in v0.3.7
ToFabricRunEmit builds a matched pair: full RunEvent proto and a RunCompleted fabric Event sharing the same run id. RunCompleted uses timestamppb.Now() for the envelope timestamp.
type Feeder ¶ added in v0.6.0
type Feeder[T any] struct { // contains filtered or unexported fields }
Feeder supplies values to concurrent scenario invocations in a thread-safe, allocation-free manner. Use NewFeeder for a fixed dataset that cycles round-robin, or NewFeederFunc for generated or random values.
func NewFeeder ¶ added in v0.6.0
NewFeeder returns a Feeder that cycles through items in order, wrapping around when the end is reached. Safe for concurrent use. Panics if items is empty.
func NewFeederFunc ¶ added in v0.6.0
NewFeederFunc returns a Feeder that calls fn on every Next call. fn must be safe for concurrent use. Panics if fn is nil.
type HTTPScenarioConfig ¶ added in v0.5.0
type HTTPScenarioConfig struct {
URL string
Method string
Headers map[string]string
Body string
// Checks, when set, are response assertions forwarded to CLI workers so a
// distributed run evaluates the same checks as a local run.
Checks *transport.Checks
}
HTTPScenarioConfig holds the HTTP target parameters for distributed workers. When set alongside Config.Workers, the coordinator forwards these to each worker so they can build the HTTP scenario without a local config file. This is populated automatically by config.Load(); library users with custom scenarios (pre-registered in workers via ListenAsWorker) should leave it nil.
type LatencyStats ¶
type LatencyStats struct {
Min time.Duration
Mean time.Duration
P50 time.Duration
P90 time.Duration
P95 time.Duration
P99 time.Duration
Max time.Duration
}
LatencyStats contains aggregate latency data.
type Middleware ¶ added in v0.3.3
Middleware wraps a Scenario to add behavior before or after execution.
func WithBulkhead ¶ added in v0.3.5
func WithBulkhead(maxConcurrent int) Middleware
WithBulkhead returns a Middleware that limits the number of concurrent executions of a scenario.
func WithCircuitBreaker ¶ added in v0.3.6
func WithCircuitBreaker(threshold float64, window, timeout time.Duration) Middleware
WithCircuitBreaker returns a Middleware that simulates cascading failures by opening a circuit when the error rate within a time window exceeds the threshold.
When the circuit opens it stays open for timeout; after that it transitions to half-open and allows exactly one probe request through. If the probe succeeds the circuit closes; if it fails the circuit re-opens and the timeout resets. Concurrent arrivals in half-open state are rejected with ErrCircuitOpen until the probe resolves.
func WithErrorRate ¶ added in v0.3.3
func WithErrorRate(rate float64) Middleware
WithErrorRate returns a Middleware that causes a percentage of requests to fail without calling the underlying Scenario.
func WithJitter ¶ added in v0.3.4
func WithJitter(min, max time.Duration, rate float64) Middleware
WithJitter returns a Middleware that adds random latency between min and max to a percentage of requests.
func WithLatency ¶ added in v0.3.3
func WithLatency(d time.Duration, rate float64) Middleware
WithLatency returns a Middleware that adds artificial latency to a percentage of requests.
func WithRetry ¶ added in v0.3.5
func WithRetry(n int, backoff time.Duration) Middleware
WithRetry returns a Middleware that retries a failed scenario up to n times with a fixed backoff between attempts.
Retries are skipped immediately when the context is already canceled or expired after a failed attempt, returning the context error. This prevents spurious retries when a deadline fires mid-run.
func WithStatusCode ¶ added in v0.3.4
func WithStatusCode(code int, rate float64) Middleware
WithStatusCode returns a Middleware that forces a specific HTTP status code to be returned for a percentage of requests, without calling the underlying Scenario.
func WithTimeout ¶ added in v0.3.4
func WithTimeout(d time.Duration) Middleware
WithTimeout returns a Middleware that enforces a maximum duration for each scenario execution.
type Phase ¶
type Phase struct {
Type PhaseType
Duration time.Duration
ArrivalRate int
// From and To are the arrival rates (per second) at the start and end of a ramp or step phase.
From int
To int
// Steps is the number of discrete rate levels for PhaseTypeStep.
Steps int
// SpikeAt is when the spike starts; 0 means immediately.
SpikeAt time.Duration
// SpikeDuration is how long the spike lasts.
SpikeDuration time.Duration
}
Phase defines the minimal execution shape for the MVP.
func (Phase) IsConstant ¶
IsConstant reports whether p is a constant arrival-rate phase.
type Reporter ¶ added in v0.5.0
type Reporter interface {
// OnSnapshot is called at the end of each reporting interval with the
// metrics observed during that window. Called from a background goroutine;
// must not block.
OnSnapshot(snapshot Snapshot)
// OnResult is called once after the run completes with the full aggregated
// result and whether all configured thresholds passed.
OnResult(result Result, passed bool)
}
Reporter receives metrics during and after a test run. Register reporters via Config.Reporters to export live and final metrics to external systems (Prometheus, InfluxDB, Datadog, …) without modifying core pulse logic.
type ReportingConfig ¶ added in v0.4.0
type ReportingConfig struct {
// Interval enables temporal snapshots when greater than zero.
Interval time.Duration
}
ReportingConfig controls optional interval snapshots.
type Result ¶
type Result struct {
Total int64
Failed int64
Duration time.Duration
RPS float64
Scheduled int64
Started int64
Dropped int64
DroppedRate float64
Completed int64
MaxActive int64
Latency LatencyStats
// TTFB holds time-to-first-byte statistics for HTTP scenarios. Zero-valued
// when the transport did not report a first-byte time.
TTFB LatencyStats
// BytesIn and BytesOut are the total response and request bytes observed
// across the run. Throughput is BytesIn / Duration (and BytesOut / Duration).
BytesIn int64
BytesOut int64
// Stress reports the ramp-to-failure outcome when Config.Stress is enabled;
// nil otherwise.
Stress *StressResult
StatusCounts map[int]int64
ErrorCounts map[string]int64
ThresholdOutcomes []ThresholdOutcome `json:"-"`
Snapshots []Snapshot
// ExtraPercentiles holds additional latency percentiles requested via
// Config.Percentiles, keyed by label (e.g. "p99.9"). Nil when none were
// requested.
ExtraPercentiles map[string]time.Duration
}
Result contains the aggregated outcome of a test run.
func Run ¶
Run validates the test definition and executes it through the engine. Use RunContext when the caller needs cancellation or a global timeout.
func RunContext ¶ added in v0.4.0
RunContext validates the test definition and executes it through the engine. The context controls scheduling and in-flight scenario executions. When test.Config.Workers is non-empty, the run is distributed across those workers; otherwise it executes locally.
type ResultHook ¶
ResultHook is an optional callback invoked after a test run completes. result contains the full aggregated metrics. passed is true when execution completed and all configured thresholds were met.
type SaturationPolicy ¶ added in v0.4.0
type SaturationPolicy = engine.SaturationPolicy
SaturationPolicy controls what happens when all execution slots are in use.
type Scenario ¶
Scenario is the user-defined workload executed by Pulse. The int is an HTTP or application status code; use 0 when not applicable.
func Apply ¶ added in v0.3.3
func Apply(scenario Scenario, middlewares ...Middleware) Scenario
Apply wraps a Scenario with the given middlewares.
type Snapshot ¶ added in v0.4.0
type Snapshot struct {
StartedAt time.Time
Duration time.Duration
Total int64
Failed int64
RPS float64
Scheduled int64
Started int64
Dropped int64
DroppedRate float64
Completed int64
MaxActive int64
Latency LatencyStats
TTFB LatencyStats
BytesIn int64
BytesOut int64
StatusCounts map[int]int64
ErrorCounts map[string]int64
}
Snapshot contains metrics observed during one reporting interval.
type StressConfig ¶ added in v0.7.0
type StressConfig = engine.StressConfig
StressConfig enables ramp-to-failure capacity discovery: the arrival rate climbs from the first phase's rate by StepRPS every healthy interval until the target's error rate or P99 latency breaches a failure threshold. The run then stops normally (no error) with Result.Stress reporting the sustained capacity. Requires Reporting.Interval > 0 and is mutually exclusive with Adaptive.
type StressResult ¶ added in v0.7.0
type StressResult = metrics.StressResult
StressResult reports the outcome of a ramp-to-failure run (see StressConfig). It is nil on Result for non-stress runs.
type TB ¶ added in v0.3.2
type TB interface {
Helper()
Fatalf(format string, args ...any)
Logf(format string, args ...any)
Skip(args ...any)
}
TB is the minimal testing interface required by Pulse helpers.
type ThresholdOutcome ¶
ThresholdOutcome records whether a configured threshold passed for a run.
type ThresholdViolationError ¶
ThresholdViolationError is returned when a configured threshold is exceeded. Description matches the corresponding ThresholdOutcome description (e.g. "mean_latency < 200ms").
func (*ThresholdViolationError) Error ¶
func (e *ThresholdViolationError) Error() string
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
mockserver
command
|
|
|
pulse
command
|
|
|
Package dashboard provides a live HTTP dashboard that streams Pulse metrics to a browser in real time using Server-Sent Events (SSE).
|
Package dashboard provides a live HTTP dashboard that streams Pulse metrics to a browser in real time using Server-Sent Events (SSE). |
|
Package distributed contains the wire types and HTTP transport used for distributed Pulse runs.
|
Package distributed contains the wire types and HTTP transport used for distributed Pulse runs. |
|
coordinator
Package coordinator implements the Pulse distributed coordinator.
|
Package coordinator implements the Pulse distributed coordinator. |
|
merger
Package merger combines multiple WorkerResult values from distributed workers into a single metrics.Result.
|
Package merger combines multiple WorkerResult values from distributed workers into a single metrics.Result. |
|
worker
Package worker implements the Pulse distributed worker HTTP server.
|
Package worker implements the Pulse distributed worker HTTP server. |
|
Package har imports HTTP Archive (HAR) files as Pulse scenarios.
|
Package har imports HTTP Archive (HAR) files as Pulse scenarios. |
|
reqmetrics
Package reqmetrics carries per-request transport observations (time-to-first- byte and byte counts) from the transport layer up to the engine through the request context.
|
Package reqmetrics carries per-request transport observations (time-to-first- byte and byte counts) from the transport layer up to the engine through the request context. |
|
ssrf
Package ssrf provides an opt-in policy that rejects HTTP requests to private, link-local, and cloud-metadata IP ranges before they leave the process.
|
Package ssrf provides an opt-in policy that rejects HTTP requests to private, link-local, and cloud-metadata IP ranges before they leave the process. |
|
Package reporter provides plug-in metric exporters for Pulse test runs.
|
Package reporter provides plug-in metric exporters for Pulse test runs. |