replay

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Jun 8, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package replay captures and replays HTTP request snapshots for regression tests.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnknownBoundary reports a replay boundary name outside the supported set.
	ErrUnknownBoundary = errors.New("unknown replay boundary")
	// ErrBoundaryConflict reports a boundary marked as both controlled and uncontrolled.
	ErrBoundaryConflict = errors.New("conflicting replay boundary")
	// ErrUncontrolledBoundaries reports a snapshot that still has nondeterministic boundaries.
	ErrUncontrolledBoundaries = errors.New("uncontrolled replay boundaries")
)

Functions

func Command

func Command(handler http.Handler) cli.Command

Command returns a command that replays a request snapshot through handler.

func NewRequest

func NewRequest(snapshot Snapshot) (*http.Request, error)

NewRequest builds a test request from snapshot.

func RequireDeterministic

func RequireDeterministic(snapshot Snapshot) error

RequireDeterministic verifies that a snapshot can be used as a stable regression test.

func Run

func Run(handler http.Handler, snapshot Snapshot) (*httptest.ResponseRecorder, error)

Run replays snapshot through handler and returns the response.

func ValidateBoundaries

func ValidateBoundaries(snapshot Snapshot) error

ValidateBoundaries verifies that replay boundary metadata uses known names and does not mark a boundary as both controlled and uncontrolled.

Types

type Boundary

type Boundary string

Boundary identifies an application dependency that can make replay nondeterministic.

const (
	// BoundaryClock identifies wall-clock time dependencies.
	BoundaryClock Boundary = "clock"
	// BoundaryRandomID identifies random identifier dependencies.
	BoundaryRandomID Boundary = "random_id"
	// BoundaryExternalHTTP identifies external HTTP dependencies.
	BoundaryExternalHTTP Boundary = "external_http"
	// BoundaryEmailDelivery identifies email delivery dependencies.
	BoundaryEmailDelivery Boundary = "email_delivery"
	// BoundaryFileWrites identifies file write dependencies.
	BoundaryFileWrites Boundary = "file_writes"
	// BoundaryDatabaseState identifies database state dependencies.
	BoundaryDatabaseState Boundary = "database_state"
	// BoundaryFeatureFlags identifies feature flag dependencies.
	BoundaryFeatureFlags Boundary = "feature_flags"
)

func NormalizeBoundaries

func NormalizeBoundaries(boundaries ...Boundary) []Boundary

NormalizeBoundaries trims empty boundary names and preserves first-seen order.

type BoundaryError

type BoundaryError struct {
	// Reason is one of ErrUnknownBoundary, ErrBoundaryConflict, or
	// ErrUncontrolledBoundaries.
	Reason error
	// Kind is "controlled" or "uncontrolled" for unknown-boundary errors.
	Kind string
	// Boundary is the boundary that failed validation.
	Boundary Boundary
	// Boundaries is the normalized boundary set for nondeterminism errors.
	Boundaries []Boundary
	// Expected is the supported boundary set for unknown-boundary errors.
	Expected []Boundary
}

BoundaryError describes invalid or nondeterministic replay boundary metadata.

func (*BoundaryError) Error

func (e *BoundaryError) Error() string

Error returns a human-readable boundary validation message.

func (*BoundaryError) Unwrap

func (e *BoundaryError) Unwrap() error

Unwrap returns the semantic boundary validation reason.

type ExpectedResponse

type ExpectedResponse struct {
	Status      int                 `json:"status"`
	Headers     map[string][]string `json:"headers,omitempty"`
	Body        []byte              `json:"body,omitempty"`
	BodyOmitted bool                `json:"body_omitted,omitempty"`
}

ExpectedResponse captures the response assertions used by generated replay tests.

func ExpectedResponseFrom

func ExpectedResponseFrom(response *httptest.ResponseRecorder) (ExpectedResponse, error)

ExpectedResponseFrom captures stable response fields from a replay result.

type Option

type Option func(*captureOptions)

Option configures request snapshot capture.

func WithApplicationVersion

func WithApplicationVersion(version string) Option

WithApplicationVersion includes the application version in captured snapshots.

func WithBodyLimit

func WithBodyLimit(limit int64) Option

WithBodyLimit captures the request body when it is no larger than limit bytes.

func WithClock

func WithClock(now func() time.Time) Option

WithClock configures the capture clock.

func WithControlledBoundaries

func WithControlledBoundaries(boundaries ...Boundary) Option

WithControlledBoundaries marks dependencies made deterministic for replay.

func WithEnvironment

func WithEnvironment(environment string) Option

WithEnvironment includes the application environment in captured snapshots.

func WithFeatureFlags

func WithFeatureFlags(flags map[string]string) Option

WithFeatureFlags includes scrubbed feature flag values in captured snapshots.

func WithHeaders

func WithHeaders(headers ...string) Option

WithHeaders configures the request headers captured into a snapshot.

func WithPrincipal

func WithPrincipal(ref PrincipalRef) Option

WithPrincipal includes an authenticated principal reference in captured snapshots.

func WithRedactor

func WithRedactor(redactor *scrub.Redactor) Option

WithRedactor configures the snapshot redactor.

func WithUncontrolledBoundaries

func WithUncontrolledBoundaries(boundaries ...Boundary) Option

WithUncontrolledBoundaries marks dependencies that may make replay nondeterministic.

type PrincipalRef

type PrincipalRef struct {
	Kind string `json:"kind,omitempty"`
	ID   string `json:"id"`
}

PrincipalRef identifies an authenticated principal without storing auth secrets.

type Snapshot

type Snapshot struct {
	Version                int                 `json:"version"`
	Method                 string              `json:"method"`
	Path                   string              `json:"path"`
	Query                  map[string][]string `json:"query,omitempty"`
	Headers                map[string][]string `json:"headers,omitempty"`
	RequestID              string              `json:"request_id,omitempty"`
	RoutePattern           string              `json:"route_pattern,omitempty"`
	RouteParams            map[string]string   `json:"route_params,omitempty"`
	ApplicationVersion     string              `json:"application_version,omitempty"`
	Environment            string              `json:"environment,omitempty"`
	FeatureFlags           map[string]string   `json:"feature_flags,omitempty"`
	ControlledBoundaries   []Boundary          `json:"controlled_boundaries,omitempty"`
	UncontrolledBoundaries []Boundary          `json:"uncontrolled_boundaries,omitempty"`
	Principal              *PrincipalRef       `json:"principal,omitempty"`
	CapturedAt             time.Time           `json:"captured_at"`
	Body                   []byte              `json:"body,omitempty"`
	BodyOmitted            bool                `json:"body_omitted"`
	ExpectedResponse       *ExpectedResponse   `json:"expected_response,omitempty"`
}

Snapshot captures enough request data to replay a handler request.

func Capture

func Capture(r *http.Request, opts ...Option) (Snapshot, error)

Capture creates a scrubbed request snapshot.

func DecodeSnapshot

func DecodeSnapshot(r io.Reader) (Snapshot, error)

DecodeSnapshot decodes one replay snapshot and rejects unknown fields.

Jump to

Keyboard shortcuts

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