Documentation
¶
Overview ¶
Package nodes implements every flow node type, one file each, and registers them with their parameter specs (Specs). The specs are the single source for the validator's parameter checks and for the generated node reference.
A node only describes its work. Whatever needs the scheduler, the network, the clock or the workspace goes through State.Runtime, which the engine implements; this package never imports the engine.
Index ¶
- Variables
- func Extract(x model.Extraction, resp *Response, jar []httpx.StoredCookie) (any, error)
- func Failed(node, check, message string, warn bool, emit Emitter) diag.List
- func ParseDelay(text string) (lo, hi time.Duration, err error)
- func Reference() []byte
- type Emitter
- type FuzzSubject
- type HTTPCall
- type HTTPResult
- type Lane
- type LaneOptions
- type LaneResult
- type Masker
- type MutableRequest
- type Outcome
- type Param
- type ParamKind
- type Phase
- type RequestCall
- type Response
- type Runner
- type Runtime
- type SchemaCheck
- type SchemaViolation
- type Spec
- type State
- type Status
- type Vars
Constants ¶
This section is empty.
Variables ¶
var ErrFileName = errors.New("not a plain file name")
ErrFileName is wrapped by Runtime.WriteFile when a name is not a plain file name (FLW-RUN-017).
Functions ¶
func Extract ¶
func Extract(x model.Extraction, resp *Response, jar []httpx.StoredCookie) (any, error)
Extract reads one value from a response (or the cookie jar). It is shared by set values read from a response and a request version's extract: block.
func Failed ¶
Failed reports a failed assertion: a warning through emit when warn is set, otherwise an error diagnostic. Shared with a version's assert: list.
func ParseDelay ¶
ParseDelay reads "2s" or "lo..hi" (lo ≤ hi); shared with validate.
Types ¶
type Emitter ¶
type Emitter interface {
Log(node, message string)
Warn(d diag.Diagnostic)
Digest(node, format, text string)
}
Emitter receives what nodes report while running. Implementations must be safe for concurrent use: nodes in different lanes call it at once.
type FuzzSubject ¶
type FuzzSubject struct {
Body any // the good body, decoded JSON with numbers as json.Number
Schema map[string]any // the stored request-body schema, nil when none is kept
}
FuzzSubject is a request ready to be sent with bad bodies.
type HTTPCall ¶
HTTPCall is an ad-hoc HTTP call (fetch, webhook, digest webhook). A string Body is sent as text; any other non-nil value as JSON.
type HTTPResult ¶
HTTPResult is an ad-hoc call's response (nil when it failed).
type Lane ¶
type Lane struct {
Label string // "[3]", "b1", "then"
Nodes []model.Node
OwnVars bool // writes stay in the lane (batch iterations)
OwnNodes bool // nodes.<id> stay in the lane (batch, run_till)
Item any
Index int
HasItem bool // item and index are in scope
}
Lane is one node list a container runs.
type LaneOptions ¶
type LaneOptions struct {
Concurrency int // lanes in flight; capped by the run-wide limit
Wait string // "all" (default), "any" or "first-success"
LaneJars bool // give lanes their own cookie jars per http.cookies
}
LaneOptions say how lanes run.
type LaneResult ¶
type LaneResult struct {
Status Status
Vars map[string]any
Nodes map[string]any
Diags diag.List
First bool
}
LaneResult is one lane's outcome. Vars and Nodes are the lane's own layers (empty unless the lane had them). First marks the lane that settled a wait of any or first-success.
type MutableRequest ¶
type MutableRequest struct {
Mu sync.Mutex
Method *string
URL *string
Headers map[string]string
Query map[string]string
Body *any // replaces the whole body
BodyPaths map[string]any // dot paths into a JSON body
Cookies map[string]string
}
MutableRequest collects what pre-hook set nodes change. The engine applies it on top of the rendered request, so overrides win. Mu guards every field: set nodes in parallel hook branches write concurrently.
type Outcome ¶
type Outcome struct {
Outputs map[string]any
Diags diag.List
Status Status
// Outcomes are the names of the outcomes a request ended with (success, failure, the ones its version
// names); empty for a step that is not a request, whose outcome follows its status.
Outcomes []string
}
Outcome is what a node produced: Outputs become nodes.<id> (written once). An empty Status means failed when Diags has errors, else passed.
type Param ¶
type Param struct {
Name string
Kind ParamKind
Required bool
Enum []string
Min, Max int64 // ParamInt bounds; 0 and 0 mean unbounded
Doc string
}
Param describes one node parameter.
type ParamKind ¶
type ParamKind int
ParamKind is what a node parameter holds.
const ( ParamString ParamKind = iota + 1 // a literal string (a set target, a var name) ParamText // a {{…}} template ParamExpr // a bare expression (check, until) ParamDuration // a duration literal: 500ms, 2s ParamInt ParamBool ParamEnum ParamName // a plain file name (names.Valid) ParamAny // any value; strings inside are templates ParamMap // a mapping of names to templates )
Parameter kinds.
type RequestCall ¶
type RequestCall struct {
Ref model.Ref
Version string
Overlay string // a flowi overlay of the request's collection, "" for none
// Open, Over and Close are the node's connection use (see model.RequestCall).
Open, Over string
Close bool
Hooks model.HookControl
With map[string]any
Headers map[string]string
// Outcomes are the step's own outcomes, in place of the version's (see model.RequestCall).
Outcomes []model.Outcome
// Body, when set, is sent in place of the request's own body (a fuzz case). A string is sent as text and
// anything else as JSON.
Body *any
}
RequestCall is a saved request to run from a request node.
type Response ¶
type Response struct {
Status int
Header http.Header
Body any // parsed JSON, or the text
Text string // the body as text (for regex extraction)
Time time.Duration
}
Response is the response as nodes see it.
type Runtime ¶
type Runtime interface {
// Lanes runs node lists (parallel branches, batch or run_till
// iterations) under the run's concurrency and branch-error policies.
// Results are in lane order.
Lanes(ctx context.Context, lanes []Lane, o LaneOptions) []LaneResult
Request(ctx context.Context, c RequestCall) Outcome
Subflow(ctx context.Context, ref model.Ref, inputs map[string]any) Outcome
HTTP(ctx context.Context, c HTTPCall) HTTPResult
// Background sends c without waiting (webhook wait: false); failures
// become FLW-RUN-016 warnings.
Background(node string, c HTTPCall)
Sleep(ctx context.Context, d time.Duration) error
// StopRun ends the run: running steps finish, no step that has not
// started will (a stop node). Stopped reports it, for loops.
StopRun()
Stopped() bool
Now() time.Time
RandomDuration(lo, hi time.Duration) time.Duration // seeded by the run
// Report is the report so far of the whole run ("run") or of a
// finished node, by id, as seen from the calling node.
Report(of string) (report.Run, bool)
// WriteFile writes under the run's data directory ("saved" or
// "digests"). name is one or more "/"-separated segments, each a
// plain file name; anything else wraps ErrFileName.
WriteFile(dir, name string, data []byte, appendTo bool) (string, error)
// CheckSchema checks what an earlier request step received against the
// response schema kept for its request.
CheckSchema(step string) SchemaCheck
// FuzzSubject prepares a request step for fuzzing: its body as it would be sent, and the request-body schema
// kept for it. An error says why the request cannot be fuzzed (it has no JSON body).
FuzzSubject(ctx context.Context, c RequestCall) (FuzzSubject, error)
}
Runtime is what the engine does for nodes: everything that needs the scheduler, the network, the clock or the workspace. Nodes describe the work; they never start goroutines or open connections themselves.
type SchemaCheck ¶
type SchemaCheck struct {
Found bool
Request string // the request's path, for messages
Status int
Violations []SchemaViolation
}
SchemaCheck is the result of checking a step's response against its kept schema. Found is false when no schema is kept (or the step has no response).
type SchemaViolation ¶
SchemaViolation is one place a body does not match its schema.
type Spec ¶
type Spec struct {
Type model.NodeType
Group string // Call, Data, Check, Control, Output
Summary string
Params []Param
// MapForm means every key that is not a Param is "<var>: template".
MapForm bool
// Typed lists the keys the codec reads into typed fields (request,
// flow, with, body, branches, …); they are not Params.
Typed []string
Run Runner
}
Spec describes a node type: its catalogue entry, parameters and runner.
type State ¶
type State struct {
Phase Phase
Path string // the node instance's path, e.g. users[2]/create
Vars *Vars // vars.<name>
Request *MutableRequest // overrides for the request; nil outside pre-hooks
Response *Response // nil before the response
Cookies []httpx.StoredCookie // the run's cookie jar, for extract from: cookie
// Scope returns the template scope for the current state (vars,
// request, response, env, secrets, …); it is rebuilt by the engine on
// each call so nodes always see the latest values.
Scope func() template.Scope
Emit Emitter
Masker Masker
// Secret registers a value derived from a secret (a template result
// that read secret.*), so it is masked wherever it appears later. Nil
// means nothing is registered.
Secret func(v any)
// Runtime does what nodes cannot do alone; nil only in contexts
// that need none of it.
Runtime Runtime
}
State is what a node can read and change.
type Vars ¶
type Vars struct {
// contains filtered or unexported fields
}
Vars is a layered variable store: writes go to the own layer, reads fall back to the parent's. It is safe for concurrent use; mu guards own.