chaotic

module
v1.8.0 Latest Latest
Warning

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

Go to latest
Published: Jun 4, 2026 License: MIT

README

chaotic

test codecov Go Reference Go Report Card Release

In-process Go chaos library. Wrap your integration boundaries — http.RoundTripper, net/http middleware, database/sql driver, gRPC interceptors — and inject latency, errors, panics, and connection drops on demand. When no rules are configured the wrappers are near-zero-cost passthroughs; chaotic is safe to leave linked everywhere.

Status

v1, test-only mode. Production-mode hooks (HTTP admin endpoint, file-watcher rule source, observers) are forward-compatible additions planned for v2.

Install

go get github.com/ag4r/chaotic
go get github.com/ag4r/chaotic/adapter/grpc   # only if you need gRPC chaos

Quick example

package main

import (
	"io"
	"net/http"
	"time"

	chaoshttp "github.com/ag4r/chaotic/adapter/http"
	"github.com/ag4r/chaotic/chaostest"
	"github.com/ag4r/chaotic/engine"
	"github.com/ag4r/chaotic/fault"
)

func TestRetriesOnTransientError(t *testing.T) {
	eng := chaostest.New(t)
	eng.AddRule(engine.NewRule(
		engine.MatchKind(engine.OpHTTPClient),
		engine.MatchName("/users/*"),
		engine.Times(2),
		engine.WithFaults(fault.Latency(200*time.Millisecond), fault.Error(io.ErrUnexpectedEOF)),
	).Named("transient-failure"))

	client := &http.Client{Transport: chaoshttp.WrapTransport(http.DefaultTransport, eng)}
	// ... call code under test that uses `client` and is supposed to retry ...

	chaostest.AssertHits(t, eng, "transient-failure", 2)
	chaostest.AssertEventsExhausted(t, eng)
}

Modules

This repo contains two Go modules:

  • github.com/ag4r/chaotic — engine, faults, and the HTTP / HTTP server / SQL adapters. Stdlib only.
  • github.com/ag4r/chaotic/adapter/grpc — gRPC interceptors. Depends on google.golang.org/grpc.

A go.work file at the repo root makes the workspace resolve both modules during development. Run tests with:

go test ./...                 # main module
go -C adapter/grpc test ./... # gRPC submodule

Observers

Attach an Observer with engine.WithObserver to receive an event each time a named rule fires or is skipped:

type Observer interface {
	RuleFired(ruleName string, op Op, action Action)
	RuleSkipped(ruleName string, op Op, reason string)
}

An observer may additionally implement RichObserver to receive per-fault detail the base interface cannot carry. The engine type-asserts for it once, at construction, and calls FaultInjected after a fault's Apply returns without error (latency and jittered faults, plus any custom no-op fault). Faults that short-circuit the call — error, panic, connection drop — do not produce a FaultEvent.

type RichObserver interface {
	Observer
	FaultInjected(ctx context.Context, ev FaultEvent)
}

type FaultEvent struct {
	Rule      string
	Op        Op
	FaultKind fault.Kind
	Latency   time.Duration // exact for Latency; the max bound for Jittered; 0 otherwise
}

Ready-made observers live in their own submodules so the core stays dependency-free:

  • observer/slog — structured logs of fires and skips.
  • observer/prometheuschaotic_rule_fires_total{rule}, chaotic_rule_skips_total{rule,reason}, and the chaotic_fault_latency_seconds{rule} histogram (a RichObserver). Label values are truncated to 64 characters to bound series cardinality.
  • observer/otel — OpenTelemetry fire/skip counters, plus (as a RichObserver) a chaotic.fault_injected event on the span active in the call's context.
Op.Attrs key conventions

Op.Attrs is a map[string]string. Adapters populate it with stable, low-cardinality keys so observer labels stay consistent. Match on these with engine.MatchAttr:

Adapter Op.Kind Op.Name Op.Method Op.Attrs keys
HTTP client OpHTTPClient request path HTTP method host
HTTP server OpHTTPServer request path HTTP method remote
SQL OpSQL statement class statement class query
gRPC client OpGRPCClient full method unary / stream
gRPC server OpGRPCServer full method unary / stream

Keep custom attribute values low-cardinality: they become metric labels and unbounded values (raw SQL text, user IDs) blow up an observer's memory.

Directories

Path Synopsis
adapter
http
Package http wraps an http.RoundTripper so outbound client calls are subject to chaos.
Package http wraps an http.RoundTripper so outbound client calls are subject to chaos.
httpsrv
Package httpsrv provides net/http middleware that subjects inbound requests to chaos.
Package httpsrv provides net/http middleware that subjects inbound requests to chaos.
sql
Package sql wraps a database/sql driver so calls are subject to chaos.
Package sql wraps a database/sql driver so calls are subject to chaos.
Package chaos provides explicit injection points: chaos.Point(ctx, name) consults the engine bound to ctx and returns a fault error (or nil) at a place no adapter wraps - between two pure functions, inside a goroutine, at a state-machine transition.
Package chaos provides explicit injection points: chaos.Point(ctx, name) consults the engine bound to ctx and returns a fault error (or nil) at a place no adapter wraps - between two pure functions, inside a goroutine, at a state-machine transition.
Package chaostest provides testing.TB integration helpers for chaotic.
Package chaostest provides testing.TB integration helpers for chaotic.
golden
Package golden records a chaos fault fire-sequence from one test run and replays it deterministically in another, to turn a flaky CI failure into a reproducible local one.
Package golden records a chaos fault fire-sequence from one test run and replays it deterministically in another, to turn a flaky CI failure into a reproducible local one.
quick
Package quick provides opinionated one-line shortcuts for the most common chaos test setups.
Package quick provides opinionated one-line shortcuts for the most common chaos test setups.
Package engine holds the rules and decision logic that adapters consult on every wrapped operation.
Package engine holds the rules and decision logic that adapters consult on every wrapped operation.
examples
chaos-point command
Command chaos-point demonstrates an explicit injection point guarding a post-commit hook.
Command chaos-point demonstrates an explicit injection point guarding a post-commit hook.
circuit-breaker command
Command circuit-breaker shows a circuit breaker opening after chaos injects repeated failures, after which calls short-circuit instead of calling the failing dependency.
Command circuit-breaker shows a circuit breaker opening after chaos injects repeated failures, after which calls short-circuit instead of calling the failing dependency.
db-conn-pool command
Command db-conn-pool shows database/sql discarding a poisoned connection and transparently retrying on a fresh one when chaos injects a connection drop.
Command db-conn-pool shows database/sql discarding a poisoned connection and transparently retrying on a fresh one when chaos injects a connection drop.
prod-safety-rails command
Command prod-safety-rails shows the production bounds that keep chaos from becoming the outage: a failure budget, a max-concurrent cap, a production guard, and a kill switch.
Command prod-safety-rails shows the production bounds that keep chaos from becoming the outage: a failure budget, a max-concurrent cap, a production guard, and a kill switch.
retry-http command
Command retry-http demonstrates a retry loop recovering from a transient fault injected into an http.Client's transport.
Command retry-http demonstrates a retry loop recovering from a transient fault injected into an http.Client's transport.
Package fault defines the fault primitives that rules execute when they fire.
Package fault defines the fault primitives that rules execute when they fire.
internal
sqlclass
Package sqlclass classifies SQL strings into a leading verb and a best-effort primary table name.
Package sqlclass classifies SQL strings into a leading verb and a best-effort primary table name.

Jump to

Keyboard shortcuts

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