Documentation
¶
Overview ¶
Package match matches observed exchanges to the steps of a walkthrough's scenarios.
A document describes one HTTP exchange as two steps: the request, whose example has the request, and the response that follows with its participants reversed. The matcher aligns exchanges to request steps and standalone steps, and fills each response step from its request step's exchange. Steps involving a participant a capture cannot see, such as a person in a browser, are unobservable.
Each step has a rule: the defaults drawn from its example (method, path and status), then the document's own match, then the binding's, each replacing the fields it sets. Participants and method must agree for an exchange to be a candidate; path, status and headers raise the score.
Index ¶
- Constants
- func BodyMatches(predicates map[string]json.RawMessage, body json.RawMessage) bool
- func PathMatches(rule, path string) bool
- func Pointer(doc any, ptr string) (any, bool)
- func Prepare(w *pidl.Walkthrough, sc *pidl.WalkthroughScenario, b *pidl.Binding) ([]Step, []Warning)
- func ValueMatches(rule, value string) bool
- type Extra
- type Found
- type Instance
- type Kind
- type Options
- type Outcome
- type Rank
- type Report
- type Resolved
- type Resolver
- type Status
- type Step
- type StepResult
- type Strength
- type Tests
- type Warning
Constants ¶
const ( WeightPath = 3 WeightStatus = 2 WeightHeader = 2 WeightBody = 2 WeightSender = 1 )
Score weights. A match also earns matchBonus, so the alignment prefers matching an exchange to leaving it out.
const RoleTypeUser = "user"
RoleTypeUser is the role type of a person, whose steps a server's capture cannot see.
Variables ¶
This section is empty.
Functions ¶
func BodyMatches ¶
func BodyMatches(predicates map[string]json.RawMessage, body json.RawMessage) bool
BodyMatches reports whether a request body satisfies every predicate: a JSON pointer to the value the member must have, or to true when it must merely exist. Numbers compare by value. A body that is not JSON satisfies no predicate.
func PathMatches ¶
PathMatches reports whether path matches a rule's path: a regular expression when the rule starts with "^", otherwise a template whose segments in braces match any one non-empty segment. A trailing slash is ignored.
func Prepare ¶
func Prepare(w *pidl.Walkthrough, sc *pidl.WalkthroughScenario, b *pidl.Binding) ([]Step, []Warning)
Prepare classifies a scenario's steps and resolves each one's rule. b may be nil.
func ValueMatches ¶
ValueMatches reports whether a header value matches a rule's value: exact, a prefix when the rule ends with "*", or a regular expression when it starts with "^".
Types ¶
type Extra ¶
type Extra struct {
// Exchange is its position in the observation.
Exchange int
// AfterStep is the index of the scenario step it followed, or -1 when
// it came before the first matched step.
AfterStep int
}
Extra is an exchange that matched no step.
type Found ¶
type Found struct {
Instance
// Rank is the instance's rank among the candidates at its point.
Rank Rank
// RunnerUp is the next-best candidate scenario at that point, with its
// rank; empty when there was none.
RunnerUp string
RunnerUpRank Rank
}
Found is one scenario instance found in a capture.
type Instance ¶
type Instance struct {
Scenario string
Steps []StepResult
Extra []Extra
// Score is the alignment's total score, match bonuses included.
Score int
// Explained is the number of exchanges matched to steps.
Explained int
// Counts of step outcomes. Strong and Weak count matched steps.
Matched, Strong, Weak, NotSeen, Skipped, Unmatchable, Unobservable int
}
Instance is the outcome of aligning a run of exchanges to one scenario.
func Align ¶
Align assigns exchanges to the steps of one scenario instance. It keeps order, uses each exchange once and gives each step at most one exchange (more for a repeated step), maximizing the total score by dynamic programming over the two sequences; ties prefer the earlier exchange. Response steps take their request step's exchange. exchanges are the instance's exchanges, in order.
type Kind ¶
type Kind int
Kind classifies a step for matching.
const ( // KindRequest is a step whose example has a request. KindRequest Kind = iota // KindResponse is the response half of an earlier request step: the // nearest one going the other way between the same participants. KindResponse // KindStandalone is any other observable step; it matches only by an // explicit rule. KindStandalone // KindUnobservable is a step involving a participant a capture cannot see. KindUnobservable )
type Options ¶
type Options struct {
// Scenarios names the scenarios to look for, in order. When empty,
// every scenario that is not a fragment is a candidate at each point.
Scenarios []string
// From and To limit matching to exchanges in a time range. Exchanges
// without a time are kept.
From, To *time.Time
}
Options controls how a capture is split into scenario instances.
type Rank ¶
type Rank struct {
Net, Strong, Score int
}
Rank orders candidate instances: exchanges explained minus required steps not seen, then strong matches, then total score.
type Report ¶
type Report struct {
// Instances are the scenario instances found, in order.
Instances []Found
// Outside are the positions of exchanges in the window that fall in no
// instance.
Outside []int
// LeftOut is the number of exchanges outside the time window.
LeftOut int
// Warnings are notes for the document's or binding's author, each once,
// however many scenarios include the step.
Warnings []Warning
}
Report is the outcome of matching a capture to a walkthrough.
func Match ¶
func Match(w *pidl.Walkthrough, o *pidl.Observation, b *pidl.Binding, opts Options) (*Report, error)
Match splits an observation into the scenario instances it contains and aligns each. A capture usually holds more than one journey: an instance starts at the first exchange that matches a candidate's first matchable step, and runs until the exchange before the next one that matches the first matchable step of any candidate, so a new journey begins where a first step recurs. At each point the best-ranked candidate is taken. b may be nil.
type Resolved ¶
type Resolved struct {
// Index is the exchange's position in the observation.
Index int
// Exchange is the observed exchange.
Exchange *pidl.Exchange
// URL is the request URL after the binding's rewrites; Host and Path
// are its parts.
URL, Host, Path string
// From and To are participant IDs; empty when the binding cannot
// resolve them.
From, To string
}
Resolved is an exchange with its URL rewritten and its participants resolved through a binding.
type Resolver ¶
type Resolver struct {
// contains filtered or unexported fields
}
Resolver applies a binding's rewrites and label rules to exchanges.
func NewResolver ¶
NewResolver compiles a binding's regular expressions. b may be nil, in which case exchanges resolve by their labels alone.
type Status ¶
type Status string
Status is a step's result.
const ( // StatusMatched means an exchange was matched to the step. StatusMatched Status = "matched" // StatusNotSeen means a required step had no matching exchange. StatusNotSeen Status = "notSeen" // StatusSkipped means an optional step had no matching exchange. StatusSkipped Status = "skipped" // StatusUnmatchable means the step has no rule to match by. StatusUnmatchable Status = "unmatchable" // StatusUnobservable means the step involves a participant a capture // cannot see. StatusUnobservable Status = "unobservable" )
type Step ¶
type Step struct {
// Index is the step's position in the scenario's Steps.
Index int
// Step is the walkthrough step.
Step *pidl.WalkthroughStep
// Kind classifies the step.
Kind Kind
// Rule is the step's rule; meaningful when HasRule.
Rule pidl.StepMatch
// HasRule reports that the step can be matched: a request step, or a
// standalone step with a document or binding rule.
HasRule bool
// RuleSources names where the rule's fields came from, in the order
// they were applied: "example", "document", "binding <key>", "binding
// path <key>".
RuleSources []string
// PairedWith is the index of the request step a response step belongs
// to, and -1 for other kinds.
PairedWith int
}
Step is one step of a scenario, prepared for matching.
type StepResult ¶
type StepResult struct {
Step Step
Status Status
Strength Strength
// Exchanges are the positions, in the observation, of the exchanges
// matched to the step: one, several for a repeated step, and for a
// response step its request step's.
Exchanges []int
// Score is the match's score, before the match bonus.
Score int
}
StepResult is a step's outcome in one scenario instance.
type Tests ¶
type Tests struct {
// Participants and Method are the required tests.
Participants, Method Outcome
// SenderKnown reports that the exchange's sender resolved and agreed,
// not merely that it was unknown.
SenderKnown bool
// Path, Status, Headers and Body are the scored tests.
Path, Status, Headers, Body Outcome
}
Tests holds the outcome of testing an exchange against a step's rule.