Documentation
¶
Overview ¶
Package terms parses a compact one-line chaos rule DSL into engine.RuleSpec / engine.Rule. It is the terse text form behind env-var and HTTP activation; because it decodes to RuleSpec, every parsed rule reuses engine.BuildRule validation. The engine.LintSpecs blast-radius check is opt-in — pass WithLint(engine.LintWarn) or WithLint(engine.LintReject) to Parse or Compile.
Grammar (v1 — single term per rule):
ruleset = rule { ";" rule }
rule = [ name ":" ] [ selector { "," selector } "=" ] term
selector = "kind(" KIND ")" | "name(" GLOB ")" | "attr(" key "=" value ")"
term = [ mode ] action [ "(" args ")" ]
mode = INT "*" (-> engine.Times) | FLOAT "%" (-> engine.Probability, seed 0)
action = latency | jitter | error | panic | conndrop | off
Action mapping:
latency(200ms) -> fault.Latency(200ms)
jitter(10ms,200ms) -> fault.Jittered(10ms,200ms)
error("boom") -> fault.Error(errors.New("boom"))
panic("kaboom") -> fault.Panic("kaboom")
conndrop -> fault.ConnDrop()
off -> rule present but inert (no faults)
Example:
rules, err := terms.Compile(`flaky: kind(http_client),name(/users/*)=2*latency(200ms)`)
Note for gofail users: there is no return(v). chaotic injects faults, it does not substitute return values, so gofail's return is renamed error here.
Limits: the DSL emits only the serializable RuleSpec subset — no MatchPredicate and no typed errors.
Staged faults: "term -> term -> ..." compiles to engine.WithStages. A leading "N*" sets a stage's match count; the final stage may omit the count to fire forever, e.g. 2*latency(200ms)->error("boom").
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Compile ¶
Compile is Parse followed by engine.BuildRule for each spec — the convenience path when you want rules to AddRule directly. Validation (unknown kinds, bad durations, out-of-range probabilities) is performed by BuildRule, so a structurally valid terms string can still fail here with a clear error. Options are forwarded to Parse, which is where linting happens.
Example ¶
package main
import (
"fmt"
"github.com/RomanAgaltsev/chaotic/source/terms"
)
func main() {
rules, err := terms.Compile(`flaky: kind(http_client),name(/users/*)=2*latency(200ms)`)
if err != nil {
panic(err)
}
fmt.Println(len(rules), rules[0].Name())
}
Output: 1 flaky
Types ¶
type Option ¶ added in v1.32.0
type Option func(*config)
Option configures Parse and Compile.
func WithLint ¶ added in v1.32.0
WithLint sets the blast-radius lint policy applied to the parsed specs. engine.LintWarn logs findings and installs anyway; engine.LintReject fails the parse when a finding is engine.SeverityHigh. Default: engine.LintOff.
Example ¶
package main
import (
"errors"
"fmt"
"github.com/RomanAgaltsev/chaotic/engine"
"github.com/RomanAgaltsev/chaotic/source/terms"
)
func main() {
// A terminal fault with no kind and no name scope matches every operation
// on every call — the hazard LintReject exists to stop.
_, err := terms.Compile(`wipeout: panic("boom")`, terms.WithLint(engine.LintReject))
fmt.Println(errors.Is(err, engine.ErrLintRejected))
}
Output: true