faults

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package faults injects failures into the emulator's responses.

It exists so a test can prove its own error handling: a retry loop is only tested by a request that actually fails, and against a real cloud a failure is something you wait for rather than ask for.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Rule

type Rule struct {
	// Method is an HTTP method, or empty for any.
	Method string

	// Path matches the escaped path. A trailing * makes it a prefix, so
	// "/storage/v1/*" covers a whole service.
	Path string

	// Status is the HTTP status to answer with. Zero means 503.
	Status int

	// Code is the canonical error code. Zero is derived from Status.
	Code gerr.Code

	// Message is the error text. Empty gets a default naming the rule.
	Message string

	// Latency delays the response. It runs on the injected clock, so under a
	// FakeClock the request waits until a test advances time.
	Latency time.Duration

	// Count is how many matching requests to fail. Zero means every one.
	Count int

	// Rate is the fraction of matching requests to fail, 0..1. Zero means every
	// one. It is applied deterministically — a rate of 0.2 fails exactly one in
	// every five matching requests, in a fixed pattern — so a fault composes
	// with time travel into a reproducible test rather than a coin flip.
	Rate float64
}

Rule decides which requests fail and how. A zero Method or Path matches anything, so the empty Rule matches every request.

func (Rule) Err

func (r Rule) Err() error

Err renders the rule as the error the transport writes over REST.

func (Rule) FailsRequest

func (r Rule) FailsRequest() bool

FailsRequest reports whether a matched rule ends the request with an error. A latency-only rule — a delay with no error asked for — does not: it slows a request that then succeeds normally. Every other rule (an explicit status, or the bare rule with neither latency nor status) fails the request.

type Set

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

Set is the live list of rules. It is safe for concurrent use: rules are added from a test goroutine while requests are being served.

func New

func New() *Set

New returns an empty Set, which fails nothing.

func (*Set) Add

func (s *Set) Add(r Rule) *Set

Add arms a rule and returns the Set, so calls can be chained.

func (*Set) Clear

func (s *Set) Clear()

Clear disarms every rule.

func (*Set) Len

func (s *Set) Len() int

Len reports how many rules are still armed, so a test can assert one fired as often as it expected.

func (*Set) Match

func (s *Set) Match(method, path string) (Rule, bool)

Match returns the first rule claiming a request, consuming one of its firings. Exhausted rules are dropped, so a Count of 1 fails once and then lets the retry through.

func (*Set) Rules

func (s *Set) Rules() []Rule

Rules returns a snapshot of the armed rules, for a status view. Order is arm order, which is match order.

func (*Set) UnaryServerInterceptor

func (s *Set) UnaryServerInterceptor(clk clock.Clock) grpc.UnaryServerInterceptor

UnaryServerInterceptor applies the same rules to unary gRPC calls that the REST path applies to HTTP requests, so a single Set faults both protocols. The match is on the full method (/pkg.Service/Method), the latency runs on the injected clock, and the failure is a real gRPC status — the rule's canonical code, which gerr numbers the same as grpc/codes — not an HTTP status smuggled over gRPC. Streaming RPCs are not intercepted.

Jump to

Keyboard shortcuts

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