Documentation
¶
Overview ¶
Package dsl is the core Plax functionality.
Historical background: Here "dsl" means "domain-specific language".
Index ¶
- Variables
- func As(src interface{}, dst interface{}) error
- func Canon(x interface{}) interface{}
- func CopyBindings(bs map[string]interface{}) map[string]interface{}
- func FindInclude(ctx *Ctx, filename string) ([]byte, error)
- func FirstRune(s string) (rune, bool)
- func HappyTerminalPhase(name string) bool
- func Include(ctx *Ctx, x interface{}, at []string) (interface{}, error)
- func IncludeMap(ctx *Ctx, k string, v interface{}, at []string) (map[string]interface{}, error)
- func IncludeYAML(ctx *Ctx, bs []byte) ([]byte, error)
- func JSExec(ctx *Ctx, src string, env map[string]interface{}) (interface{}, error)
- func JSON(x interface{}) string
- func MaybeParseJSON(x interface{}) interface{}
- func MaybeSerialize(x interface{}) (string, error)
- func ReadIncluded(ctx *Ctx, filename string) (interface{}, error)
- func Redact(r *regexp.Regexp, s string) string
- func RegexpMatch(pat string, target interface{}) ([]match.Bindings, error)
- func SrcDir(level int) string
- func TestIdFromPathname(s string) string
- func TrimEOL(s string) string
- func Wait(ctx *Ctx, durationString string) error
- func WantsRedaction(p string) bool
- type Bindings
- func (b *Bindings) Bind(ctx *Ctx, x interface{}) (interface{}, error)
- func (bs *Bindings) Clean(ctx *Ctx, clear bool)
- func (b *Bindings) Copy() (*Bindings, error)
- func (bs *Bindings) SerialSub(ctx *Ctx, serialization string, payload interface{}) (string, error)
- func (bs *Bindings) Set(value string) error
- func (bs *Bindings) SetKeyValue(key string, value interface{})
- func (bs *Bindings) SetString(value string) error
- func (bs *Bindings) String() string
- func (bs *Bindings) StringSub(ctx *Ctx, s string) (string, error)
- func (bs *Bindings) Sub(ctx *Ctx, s string) (string, error)
- func (b *Bindings) SubX(ctx *Ctx, src interface{}, dst *interface{}) error
- type Broken
- type Chan
- type ChanKind
- type ChanMaker
- type ChanOpts
- type ChanRegistry
- type Close
- type Ctx
- func (c *Ctx) AddRedaction(pat string) error
- func (ctx *Ctx) BindingsRedactions(bs Bindings) error
- func (c *Ctx) Inddf(format string, args ...interface{})
- func (c *Ctx) Indf(format string, args ...interface{})
- func (c *Ctx) Logdf(format string, args ...interface{})
- func (c *Ctx) Logf(format string, args ...interface{})
- func (c *Ctx) Redactf(format string, args ...interface{})
- func (c *Ctx) SetLogLevel(level string) error
- func (c *Ctx) Warnf(format string, args ...interface{})
- func (c *Ctx) WithCancel() (*Ctx, func())
- func (c *Ctx) WithTimeout(d time.Duration) (*Ctx, func())
- type DocSpec
- type Errors
- type Exec
- type Failure
- type GoLogger
- type Ingest
- type Kill
- type Logger
- type MockChan
- func (c *MockChan) Close(ctx *Ctx) error
- func (c *MockChan) DocSpec() *DocSpec
- func (c *MockChan) Kill(ctx *Ctx) error
- func (c *MockChan) Kind() ChanKind
- func (c *MockChan) Open(ctx *Ctx) error
- func (c *MockChan) Pub(ctx *Ctx, m Msg) error
- func (c *MockChan) Read(ctx *Ctx, in *bufio.Reader) error
- func (c *MockChan) Recv(ctx *Ctx) chan Msg
- func (c *MockChan) Sub(ctx *Ctx, topic string) error
- func (c *MockChan) To(ctx *Ctx, m Msg) error
- type Mother
- func (c *Mother) Close(ctx *Ctx) error
- func (c *Mother) DocSpec() *DocSpec
- func (c *Mother) Kill(ctx *Ctx) error
- func (c *Mother) Kind() ChanKind
- func (c *Mother) Open(ctx *Ctx) error
- func (c *Mother) Pub(ctx *Ctx, m Msg) error
- func (c *Mother) Recv(ctx *Ctx) chan Msg
- func (c *Mother) Sub(ctx *Ctx, topic string) error
- func (c *Mother) To(ctx *Ctx, m Msg) error
- type MotherMakeRequest
- type MotherRequest
- type MotherResponse
- type Msg
- type Phase
- type Process
- type Pub
- type Reconnect
- type Recv
- type Redactions
- type Retries
- type Serialization
- type Spec
- type Step
- type Sub
- type Test
- func (t *Test) Bind(ctx *Ctx, x interface{}) (interface{}, error)
- func (t *Test) Close(ctx *Ctx) error
- func (t *Test) Init(ctx *Ctx) error
- func (t *Test) InitChans(ctx *Ctx) error
- func (t *Test) Run(ctx *Ctx) *Errors
- func (t *Test) RunFrom(ctx *Ctx, from string) error
- func (t *Test) Tick(ctx *Ctx) time.Duration
- func (t *Test) Validate(ctx *Ctx) []error
- func (t *Test) Wanted(ctx *Ctx, lowestPriority int, labels []string, tests []string) bool
Constants ¶
This section is empty.
Variables ¶
var ( // DefaultSerialization is of course the default Serialization // (for pub and recv operation). DefaultSerialization = serJSON // Serializations is a dictionary of supported Serializations. Serializations = map[string]Serialization{ string(serJSON): serJSON, string(serString): serString, } )
var DebugDocScan = false
var ( // DefaultChanBufferSize is a default buffer size any Chan can // choose to consider. DefaultChanBufferSize = 1024 )
var DefaultInitialPhase = "phase1"
var (
DefaultMaxSteps = 100
)
var HappyTerminalPhases = []string{"", "happy", "done"}
HappyTerminalPhases is the set of phase names that indicate that the test has completed successfully.
var TheChanRegistry = make(ChanRegistry)
TheChanRegistry is the global, well-known registry of supported Chan types.
Functions ¶
func Canon ¶
func Canon(x interface{}) interface{}
Canon constructs a canonical (via JSON) representation.
func CopyBindings ¶
func FindInclude ¶
FindInclude searches the include directories for the file
func HappyTerminalPhase ¶
HappyTerminalPhase reports whether the given phase name represents a happy terminal phase.
func Include ¶
Include looks for '#include', 'include:' or 'includes:' to find YAML files to include in the input data at the given location.
'include: FILENAME' will read FILENAME, which should be YAML representation of a map. That map is added to the map that contained the 'include: FILENAME' property. The FILENAME is relative to the given directory 'dir'.
'#include<FILENAME>' will replace that value with the thing represented by FILENAME in YAML. Unlike cpp, the FILENAME is relative to the given directory 'dir'.
func IncludeMap ¶
IncludeMap includes the filename (v) at (at)
func IncludeYAML ¶
IncludeYAML surrounds Include() with YAML (un)marshaling.
Intended to be used right after reading bytes that represent YAML.
func MaybeParseJSON ¶
func MaybeParseJSON(x interface{}) interface{}
func MaybeSerialize ¶
func ReadIncluded ¶
ReadIncluded is a utility function that's convenient for Include().
func Redact ¶ added in v0.8.2
Redact might replace part of s with <redacted> depending on the given Regexp.
If the Regexp has no groups, all substrings that match the Regexp are redacted.
For each named group with a name starting with "redact", that group is redacted (for all matches).
If there are groups but none has a name starting with "redact", then the first matching (non-captured) group is redacted.
func RegexpMatch ¶
RegexpMatch compiles the given pattern (as Go regular expression, matches the target against that pattern, and returns the results as a list of match.Bindings.
A matched named group becomes a binding. If the name starts with an uppercase rune, then the binding variable starts with '?'. Otherwise, the variable starts with '?*'
func TestIdFromPathname ¶
func TrimEOL ¶
TrimEOL is a utility function that removes the last (if any) newline character(s).
This function does not trim more than one newline.
func WantsRedaction ¶ added in v0.8.1
WantsRedaction reports whether the parameter's value should be redacted.
Currently if a parameter starts with "X_" after ignoring special characters, then the parameter's value should be redacted.
Types ¶
type Bindings ¶
func NewBindings ¶
func NewBindings() *Bindings
func (*Bindings) Set ¶
Set the parameter key=value pair assuming the value is either JSON-serialized or not.
If we can't deserialize the value, we use the literal string (for backwards compatibility).
func (*Bindings) SetKeyValue ¶
SetKeyValue to set the binding key to the given (native) value.
type Broken ¶
type Broken struct {
Err error
}
Broken is an error that represents a test that is broken (and not simpling failing).
type Chan ¶
type Chan interface {
// Open starts up the Chan.
Open(ctx *Ctx) error
// Chose shuts down this Chan.
Close(ctx *Ctx) error
// Kill ungracefully closes an underlying connection (if any).
//
// Useful for testing MQTT LWT.
Kill(ctx *Ctx) error
// Kind returns this Chan's type.
Kind() ChanKind
// Sub, when required, initials a subscription.
//
// Use the Recv method to obtain messages that arrive via any
// subscription.
Sub(ctx *Ctx, topic string) error
// Recv returns a channel of messages.
Recv(ctx *Ctx) chan Msg
// Pub, when supported, publishes a message on this Chan.
Pub(ctx *Ctx, m Msg) error
// To is a utility to send a message to the channel returned
// by Recv.
To(ctx *Ctx, m Msg) error
DocSpec() *DocSpec
}
Chan can send and receive messages.
func NewMockChan ¶
type ChanKind ¶
type ChanKind string
ChanKind is something like 'mqtt', 'kds', etc.
Support for a Chan registers itself in ChanRegistry.
type ChanOpts ¶
type ChanOpts interface{}
ChanOpts represents generic data that is give to a Chan constructor.
type ChanRegistry ¶
ChanRegistry maps a ChanKind to a constructor for that type of Chan.
type Close ¶ added in v0.8.26
type Close struct {
Chan string
// contains filtered or unexported fields
}
type Ctx ¶
type Ctx struct {
context.Context
Logger
IncludeDirs []string
Dir string
LogLevel string
*Redactions
}
Ctx includes a context.Context, logging specifications, and some directories for various file inclusions.
func (*Ctx) AddRedaction ¶ added in v0.8.1
AddRedaction compiles the given string as a regular expression and installs that regexp as a desired redaction in logging output.
func (*Ctx) BindingsRedactions ¶ added in v0.8.10
bindingRedactions adds redaction patterns for values of binding variables that start with X_ if redact is true
func (*Ctx) Inddf ¶
Inddf emits a log line starting with a '|' when ctx.LogLevel is 'debug';
The second 'd' is for "debug".
func (*Ctx) Logdf ¶
Logdf emits a log line starting with a '>' when ctx.LogLevel is 'debug';
The second 'd' is for "debug".
func (*Ctx) SetLogLevel ¶
SetLogLevel sets the dsl.Ctx LogLevel.
func (*Ctx) WithCancel ¶
WithCancel builds a new dsl.Ctx with a cancel function.
type DocSpec ¶
type Errors ¶
Errors collects errors from the main test as well as from final phase executions.
type Failure ¶
type Failure struct {
Err error
}
Failure is an error that does not represent something that's broken.
type Ingest ¶
type Logger ¶
type Logger interface {
Printf(format string, args ...interface{})
}
Logger is an interface that allows for pluggable loggers.
Used in the Plax Lambda.
type MockChan ¶
type MockChan struct {
// contains filtered or unexported fields
}
MockChan is a channel type that just emits what it receives.
This channel type is mostly used for testing. A message published to a mock channel is simply emitted as is (for test to receive).
type Mother ¶
type Mother struct {
// contains filtered or unexported fields
}
Mother is the mother of all (other) channels.
Mother ('mother') can make channels, and Mother is itself a Channel.
type MotherMakeRequest ¶
type MotherMakeRequest struct {
// Name is the requested name for the channel to be created.
Name string `json:"name"`
// Type is something like 'mqtt', 'httpclient', or 'sqs' (the
// types that are registered with a (or The) ChannelRegistry).
Type ChanKind `json:"type"`
// Config is the configuration (if any) for the requested channel.
Config interface{} `json:"config,omitempty"`
}
MotherMakeRequest is the structure for a request to make a new channel.
type MotherRequest ¶
type MotherRequest struct {
Make *MotherMakeRequest `json:"make"`
}
MotherRequest is the structure for a request to Mother.
Every MotherRequest will get exactly one MotherResponse.
type MotherResponse ¶
type MotherResponse struct {
// Request is the request the provoked this response.
Request *MotherRequest `json:"request"`
// Success reports whether the request succeeded.
Success bool `json:"success"`
// Error, if not zero, is an error message for a failed
// request.
Error string `json:"error,omitempty"`
}
MotherResponse is the structure of the generic response to a request.
type Phase ¶
type Phase struct {
// Doc is an optional documentation string.
Doc string `yaml:",omitempty"`
// Steps is a sequence of Steps, which are attempted in order.
//
// Each Step is subject to bindings substitution.
Steps []*Step
}
Phase is a list of Steps.
type Process ¶
type Process struct {
// Name is an opaque string used is reports about this
// Process.
Name string `json:"name" yaml:"name"`
// Command is the name of the program.
//
// Subject to expansion.
Command string `json:"command" yaml:"command"`
// Args is the list of command-line arguments for the program.
//
// Subject to expansion.
Args []string `json:"args" yaml:"args"`
Stdout chan string `json:"-"`
Stderr chan string `json:"-"`
Stdin chan string `json:"-"`
ExitCode chan int `json:"-"`
// contains filtered or unexported fields
}
Process represents an external process run from a test.
func (*Process) Start ¶
Start starts the program, which runs in the background (until the test is complete).
Stderr and stdout are logged via ctx.Logf.
func (*Process) Substitute ¶
Substitute the bindings into the Process
type Pub ¶
type Pub struct {
Chan string
Topic string
// Schema is an optional URI for a JSON Schema that's used to
// validate outgoing messages.
Schema string `json:",omitempty" yaml:",omitempty"`
Payload interface{}
// Serialization specifies how a string Payload should be
// deserialized (if at all).
//
// Legal values: 'json', 'text'. Default is 'json'.
//
// If given a non-string, that value is always used as is.
//
// If given a string, if serialization is 'json' or not
// specified, then the string is parsed as JSON. If the
// serialization is 'text', then the string is used as is.
Serialization string `json:",omitempty" yaml:",omitempty"`
Run string `json:",omitempty" yaml:",omitempty"`
// contains filtered or unexported fields
}
type Recv ¶
type Recv struct {
Chan string
Topic string
// Pattern is a Sheens pattern
// https://github.com/Comcast/sheens/blob/main/README.md#pattern-matching
// for matching incoming messages.
//
// Use a pattern for matching JSON-serialized messages.
//
// Also see Regexp.
Pattern interface{}
// Regexp, which is an alternative to Pattern, gives a (Go)
// regular expression used to match incoming messages.
//
// A named group match becomes a bound variable.
Regexp string
Timeout time.Duration
// Target is an optional switch to specify what part of the
// incoming message is considered for matching.
//
// By default, only the payload is matched. If Target is
// "message", then matching is performed against
//
// {"Topic":TOPIC,"Payload":PAYLOAD}
//
// which allows matching based on the topic of in-bound
// messages.
Target string
// ClearBindings will remove all bindings for variables that
// do not start with '?!' before executing this step.
ClearBindings bool
// Guard is optional Javascript (!) that should return a
// boolean to indicate whether this Recv has been satisfied.
//
// The code is executed in a function body, and the code
// should 'return' a boolean.
//
// The following variables are bound in the global
// environment:
//
// bindingss: the set (array) of bindings returned by match()
//
// elapsed: the elapsed time in milliseconds since the last step
//
// msg: the receved message ({"topic":TOPIC,"payload":PAYLOAD})
//
// print: a function that prints its arguments to stdout.
//
Guard string `json:",omitempty" yaml:",omitempty"`
Run string `json:",omitempty" yaml:",omitempty"`
// Schema is an optional URI for a JSON Schema that's used to
// validate incoming messages before other processing.
Schema string `json:",omitempty" yaml:",omitempty"`
// Max attempts to receive a message; optionally for a specific topic
Attempts int `json:",omitempty" yaml:",omitempty`
// contains filtered or unexported fields
}
type Redactions ¶ added in v0.8.19
type Redactions struct {
// Redact enables or disables redactions.
//
// The sketchy field name is for backwards compatibility.
Redact bool
// Pattens maps strings representing regular expressions to
// Repexps.
Patterns map[string]*regexp.Regexp
// RWMutex makes this gear safe for concurrent use.
sync.RWMutex
}
Redactions is set of patterns that can be redacted by the Redactf method.
func NewRedactions ¶ added in v0.8.19
func NewRedactions() *Redactions
NewRedactions makes a disabled Redactions.
func (*Redactions) Add ¶ added in v0.8.19
func (r *Redactions) Add(pat string) error
Add compiles the given string as a regular expression and installs that regexp as a desired redaction.
func (*Redactions) Redactf ¶ added in v0.8.19
func (r *Redactions) Redactf(format string, args ...interface{}) string
Redactf calls fmt.Sprintf and then redacts the result.
type Retries ¶
type Retries struct {
// N is the maximum number of retries.
N int
// Delay is the initial delay before the first retry.
Delay time.Duration
// DelayFactor is multiplied by the last delay to return the
// next delay.
DelayFactor float64
}
Retries represents a specification for how to retry a failed test.
func NewRetries ¶
func NewRetries() *Retries
NewRetries returns the default Retries specification. N is 0.
type Serialization ¶
type Serialization string
Serialization is a enum of possible (de)serializations.
func NewSerialization ¶
func NewSerialization(name string) (*Serialization, error)
func (*Serialization) Deserialize ¶
func (s *Serialization) Deserialize(str string) (interface{}, error)
Deserialize attempts to deserialize the given string.
func (*Serialization) Serialize ¶
func (s *Serialization) Serialize(x interface{}) (string, error)
Serialize attempts to render the given argument.
func (*Serialization) UnmarshalYAML ¶
func (s *Serialization) UnmarshalYAML(value *yaml.Node) error
type Spec ¶
type Spec struct {
// InitialPhase is the starting phase, which defaults to
// DefaultInitialPhase.
InitialPhase string
// FinalPhases is an option list of phases to execute after
// the execution starting at InitialPhase terminates.
FinalPhases []string
// Phases maps phase names to Phases.
//
// Each Phase is subject to bindings substitution.
Phases map[string]*Phase
}
Spec represents a set of named test Phases.
type Step ¶
type Step struct {
// Doc is an optional documentation string.
Doc string `yaml:",omitempty"`
// Fails indicates that this Step is expected to fail, which
// currently means returning an error from exec.
Fails bool `yaml:",omitempty"`
// Skip will make the test execution skip this step.
Skip bool `yaml:",omitempty"`
Pub *Pub `yaml:",omitempty"`
Sub *Sub `yaml:",omitempty"`
Recv *Recv `yaml:",omitempty"`
Kill *Kill `yaml:",omitempty"`
Reconnect *Reconnect `yaml:",omitempty"`
Close *Close `yaml:",omitempty"`
Run string `yaml:",omitempty"`
// Wait is wait time in milliseconds as a string.
Wait string `yaml:",omitempty"`
Goto string `yaml:",omitempty"`
Branch string `yaml:",omitempty"`
Ingest *Ingest `yaml:",omitempty"`
}
Step represents a single action.
type Sub ¶
type Test ¶
type Test struct {
// Id usually comes from the filename that defines the test.
Id string `json:",omitempty" yaml:",omitempty"`
// Name is the test specification name
Name string `json:",omitempty" yaml:",omitempty"`
// Doc is an optional documentation string.
Doc string `json:",omitempty" yaml:",omitempty"`
// Labels is an optional set of labels (e.g., "cpe", "app").
Labels []string `json:",omitempty" yaml:",omitempty"`
// Priority 0 is the highest priority.
Priority int
// Spec is the test specification.
//
// Parts of the Spec are subject to bindings substitution.
Spec *Spec
// State is arbitrary state the Javascript code can use.
State map[string]interface{}
// Bindings is the first set of bindings returned by the last
// pattern match (if any).
Bindings Bindings
// Chans is the map of Chan names to Chans.
Chans map[string]Chan
// T is the time the last Step executed.
T time.Time
// Optional seed for random number generator.
//
// Effectively defaults to the current time in UNIX
// nanoseconds
Seed int64
// MaxSteps, when not zero, is the maximum number of steps to
// execute.
//
// Can act as a circuit breaker for infinite loops due to
// branches.
MaxSteps int
// Libraries is a list of filenames that should contain
// Javascript. This source is loaded into each Javascript
// environment.
//
// Warning: These files are loaded for each Javascript
// invocation (because re-using the Javascript environment is
// not a safe thing to do -- and I don't think I can "seal"
// one environment and extend it per-invocation).
Libraries []string
// Negative indicates that a reported failure (but not error)
// should be interpreted as a success.
Negative bool
// Dir is the base directory for reading relative pathnames
// (for libraries, includes, and ##FILENAMEs).
Dir string
// Retries is an optional retry specification.
//
// This data isn't actually used in the code here. Instead,
// this data is here to make it easy for a test to specify its
// own retry policy (if any). Actual implementation provided
// by invoke.Run().
Retries *Retries
// Registry is the channel (type) registry for this test.
//
// Defaults to TheChanRegistry.
Registry ChanRegistry
// contains filtered or unexported fields
}
Test is the top-level type for a complete test.
func (*Test) Run ¶
Run initializes the Mother channel, runs the test, and runs final phases (if any).