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).