Documentation
¶
Overview ¶
Package fault defines the fault primitives that rules execute when they fire. Each fault implements Apply(ctx); a non-nil error short-circuits the adapter's Action.Before chain and is delivered to the caller in the adapter's native error model.
Index ¶
- Variables
- type Fault
- func ConnDrop() Fault
- func Error(err error) Fault
- func HTTPStatus(code int, body ...string) Fault
- func HeaderInject(key, value string) Fault
- func HeaderStrip(key string) Fault
- func Jittered(min, max time.Duration) Fault
- func JitteredSeed(min, max time.Duration, seed int64) Fault
- func Latency(d time.Duration) Fault
- func Panic(v any) Fault
- type HTTPStatusError
- type HeaderFault
- type Kind
- type Kinded
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrConnDrop = errors.New("chaotic: connection drop")
ErrConnDrop is the sentinel returned by ConnDrop's Apply. Each adapter detects this sentinel via errors.Is and substitutes its native connection-drop error (driver.ErrBadConn, status.Unavailable, etc.).
Functions ¶
This section is empty.
Types ¶
type Fault ¶
Fault is one chaos primitive. Apply may sleep, return an error, or panic. A return of nil means the fault completed without affecting the call.
func ConnDrop ¶
func ConnDrop() Fault
ConnDrop returns ErrConnDrop. Each adapter detects this sentinel and substitutes its native connection-drop error.
Example ¶
package main
import (
"context"
"errors"
"fmt"
"github.com/ag4r/chaotic/fault"
)
func main() {
// ConnDrop returns a sentinel each adapter maps to its native
// connection-drop error (driver.ErrBadConn, codes.Unavailable, ...).
f := fault.ConnDrop()
err := f.Apply(context.Background())
fmt.Println(errors.Is(err, fault.ErrConnDrop))
}
Output: true
func Error ¶
Error returns err verbatim from Apply. The adapter is responsible for wrapping it into its native error model (e.g., &url.Error{Op: "chaos"} for http). A nil err makes Apply a no-op.
Example ¶
package main
import (
"context"
"errors"
"fmt"
"github.com/ag4r/chaotic/fault"
)
func main() {
f := fault.Error(errors.New("upstream unavailable"))
fmt.Println(f.Apply(context.Background()))
}
Output: upstream unavailable
func HTTPStatus ¶ added in v1.7.0
HTTPStatus returns a fault that makes the HTTP adapters render the given status code: adapter/httpsrv writes it, adapter/http synthesizes a response carrying it. Body is optional. When omitted the adapter uses http.StatusText.
Example ¶
package main
import (
"context"
"errors"
"fmt"
"github.com/ag4r/chaotic/fault"
)
func main() {
// HTTPStatus carries a status code on a sentinel the HTTP adapters render.
err := fault.HTTPStatus(503, "overloaded").Apply(context.Background())
var hse *fault.HTTPStatusError
errors.As(err, &hse)
fmt.Println(hse.StatusCode(), hse.Body)
}
Output: 503 overloaded
func HeaderInject ¶ added in v1.7.0
HeaderInject returns a fault that sets header key to value on the headers flowing toward the code under test.
func HeaderStrip ¶ added in v1.7.0
HeaderStrip returns a fault that deletes header key from the headers flowing toward the code under test.
Example ¶
package main
import (
"context"
"errors"
"fmt"
"github.com/ag4r/chaotic/fault"
)
func main() {
// HeaderStrip yields a sentinel describing a header deletion; the adapters
// apply it to the headers flowing toward the code under test.
err := fault.HeaderStrip("X-Trace-Id").Apply(context.Background())
var hf *fault.HeaderFault
errors.As(err, &hf)
fmt.Println(hf.Strip, hf.Key)
}
Output: true X-Trace-Id
func Jittered ¶
Jittered sleeps for a uniformly random duration in [min, max]. Negative or zero values are treated as "no sleep". If max <= min, sleeps for min.
func JitteredSeed ¶ added in v1.4.0
JitteredSeed is like Jittered but draws from a seeded PCG source, so the sequence of sleep durations is reproducible across runs with the same seed. Use it when a chaos test must be deterministically replayable. The draw is mutex-guarded. The fault is safe for concurrent use.
Example ¶
package main
import (
"context"
"time"
"github.com/ag4r/chaotic/fault"
)
func main() {
// JitteredSeed draws sleep durations from a seeded source, so a chaos test
// replays the same delays across runs. No Output: the delays are time-based
// and intentionally not printed.
f := fault.JitteredSeed(10*time.Millisecond, 50*time.Millisecond, 42)
_ = f.Apply(context.Background())
}
Output:
func Latency ¶
Latency sleeps for d. Returns ctx.Err() if the context is canceled first. A non-positive d returns immediately.
Example (ContextCancellation) ¶
package main
import (
"context"
"fmt"
"time"
"github.com/ag4r/chaotic/fault"
)
func main() {
// A canceled context makes a latency fault return immediately with the
// context error instead of sleeping.
ctx, cancel := context.WithCancel(context.Background())
cancel()
f := fault.Latency(time.Hour)
fmt.Println(f.Apply(ctx))
}
Output: context canceled
func Panic ¶
Panic calls panic(v) from Apply. The panic propagates through the action, through the adapter, out to the caller. Recovery is the caller's responsibility.
Example ¶
package main
import (
"context"
"fmt"
"github.com/ag4r/chaotic/fault"
)
func main() {
f := fault.Panic("boom")
defer func() {
fmt.Println("recovered:", recover())
}()
_ = f.Apply(context.Background())
}
Output: recovered: boom
type HTTPStatusError ¶ added in v1.7.0
type HTTPStatusError struct {
Code int
Body string // empty => the adapter substitutes http.StatusText(Code)
}
HTTPStatusError is the sentinel an HTTPStatus fault returns. The HTTP adapters detect it via errors.As and render the status instead of the generic 500. The fault package stays free of net/http: this carries only the code and an optional body string.
func (*HTTPStatusError) Error ¶ added in v1.7.0
func (e *HTTPStatusError) Error() string
func (*HTTPStatusError) StatusCode ¶ added in v1.7.0
func (e *HTTPStatusError) StatusCode() int
StatusCode reports the HTTP status code the fault should render.
type HeaderFault ¶ added in v1.7.0
type HeaderFault struct {
Strip bool // true => delete Key, false => set Key to Value
Key string
Value string
}
HeaderFault is the sentinel a header fault returns. Adapters detect it via errors.As, apply the mutation to the headers flowing toward the code under test (request headers on the server, response headers on the client), then let the wrapped call proceed - it does NOT abort the call.
Because the engine fires at most one rule per Op and rule's fault chain short-circuits on the first sentinel, only one header fault applies per rule (a preceding Latency is fine, it returns nil and continues). To mutate several headers, use several rules, or wait for a future batch helper.
func (*HeaderFault) Error ¶ added in v1.7.0
func (*HeaderFault) Error() string