engine

package
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package engine implements OpenMock's pure parse -> match -> render core.

The engine has no I/O and makes no assumption that it runs inside a server: it does not bind ports, does not know about HTTP, and depends on nothing beyond an OpenMock document and a normalized request. That is what lets it be imported standalone by an embedding host (see the "embedding host" role in openmock-dev/openmock's docs/serving.md) as well as driven by this module's own server and cmd/openmock packages.

Use Parse to load and validate a document (spec §3, §3.6) and New to create an Engine that resolves normalized Requests against it (spec §8). Parse refuses any document spec §3.6 requires an implementation to refuse; Resolve maintains the per-operation call counters the calls facet reads (spec §6.3) and renders synthetic unrouted/unmatched responses per spec §10.

This package passes every case in openmock-dev/openmock's conformance corpus (vendored under engine/testdata/conformance; see conformance_test.go) covering HTTP, gRPC, GraphQL, and WebSocket mocks: routing, first-match-wins scenario selection, all v0.2 matchers (equality, exists, RE2 pattern), the calls facet, templating (including whole-value typed injection and literal escaping), conformance-mode faker, and document validation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CallType

type CallType string

CallType is a gRPC operation's declared call shape (spec §5.4).

const (
	CallUnary           CallType = "unary"
	CallServerStreaming CallType = "server-streaming"
)

type CallsFacet

type CallsFacet struct {
	Min *int
	Max *int
}

CallsFacet matches the operation's call counter against an inclusive range (spec §6.3). A nil bound is unconstrained on that side.

type CloseSpec

type CloseSpec struct {
	Code   int
	Reason string
}

CloseSpec is a WebSocket response's close directive (spec §7.5).

type Document

type Document struct {
	OpenMock string
	Info     *Info
	Servers  []*Server
}

Document is a parsed and validated OpenMock document (spec §3). Use Parse to obtain one; the zero value is not usable.

func Parse

func Parse(data []byte) (*Document, error)

Parse parses and validates an OpenMock document (spec §3). A document that violates any requirement of spec §3.6 is refused: Parse returns a non-nil error and no Document — never a partially usable one.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine resolves normalized requests against a parsed Document, maintaining the per-operation call counters the calls facet reads (spec §6.3). The zero value is not usable; use New.

An Engine is safe for concurrent use: a serving adapter may call Resolve (and Reset) from many goroutines at once. The call counters are the only mutable state, and mu guards them — a plain map increment would both race and, worse, trigger Go's fatal "concurrent map writes" panic under real load.

func New

func New(doc *Document) *Engine

New creates an Engine for doc, with fresh call counters.

func (*Engine) Reset

func (e *Engine) Reset()

Reset clears the call counters, as if no request had been resolved yet. It is the engine-side "reset state" capability of docs/serving.md §0 — what a standalone server projects as POST /reset and a test framework calls between tests. Spec §6.3 keeps counters monotonic during a run and leaves the run boundary to the embedder; Reset is how an embedder ends one run and starts the next. Safe for concurrent use with Resolve.

func (*Engine) Resolve

func (e *Engine) Resolve(req *Request) map[string]any

Resolve routes req, advances the matched operation's call counter, selects the first matching scenario, and renders its response (spec §8). The result is ready to marshal as the protocol's normalized response (see conformance/README.md's expected.json shapes). An unrouted or unmatched request yields the synthetic response of spec §10. Resolve never mutates req.

func (*Engine) Routes

func (e *Engine) Routes(req *Request) bool

Routes reports whether req routes to an operation (spec §8 step 1): a target server is selected and one of its operations matches the request's address. It has no side effects — in particular it never advances a call counter — so a transport can use it to admit or refuse a connection without consuming a call. A WebSocket server uses it to refuse an unroutable path at establishment (spec §5.9) rather than accepting the connection first.

type FacetValue

type FacetValue struct {
	Kind       FacetValueKind
	Str        string
	Pattern    *regexp.Regexp
	PatternSrc string
}

FacetValue is a scalar facet value: a literal string to compare by canonical-string equality, or an exists/pattern matcher (spec §6.1).

type FacetValueKind

type FacetValueKind int

FacetValueKind discriminates the shape of a FacetValue.

const (
	FacetString FacetValueKind = iota
	FacetExistsTrue
	FacetExistsFalse
	FacetPattern
)

type HeaderTemplate

type HeaderTemplate struct {
	Values []string // len 1 for a plain string value
	IsList bool     // true when the document declared a YAML sequence
}

HeaderTemplate is a response header's value: one templated string, or a list of them emitted as separate field lines in order (spec §4.6, §7).

type Info

type Info struct {
	Title       string
	Version     string
	Description string
}

Info is the document's optional, non-normative metadata (spec §3.2).

type Operation

type Operation struct {
	// HTTP, WebSocket
	Method string // HTTP only
	Path   string // HTTP, WebSocket

	// gRPC
	Service string
	RPC     string
	Type    CallType

	// GraphQL
	OperationType string
	OperationName string

	Summary   string
	Scenarios []*Scenario
	// contains filtered or unexported fields
}

Operation is one addressable route and its scenarios (spec §5). Which fields are populated depends on the owning Server's Type.

type PayloadFacet

type PayloadFacet struct {
	Scalar *string
	Map    map[string]FacetValue // dotted path -> value
}

PayloadFacet is the body/message facet's map-or-scalar form (spec §6.1).

type QueryElement

type QueryElement struct {
	IsPattern  bool
	Str        string
	Pattern    *regexp.Regexp
	PatternSrc string
}

QueryElement is one position within a query facet's element list.

type QueryFacetValue

type QueryFacetValue struct {
	Exists   *bool
	Elements []QueryElement
}

QueryFacetValue is one key's value under the query facet: either a whole-facet exists assertion, or an exact positional list of elements (spec §4.6, §6.1).

type Request

type Request struct {
	Protocol string
	Server   string

	// HTTP, WebSocket
	Method  string
	Path    string
	Params  map[string]string
	Query   map[string][]string
	Headers map[string]string // keys lowercased; repeated values already joined with ", "

	// HTTP
	Body any

	// gRPC
	Service  string
	RPC      string
	Metadata map[string]string // keys lowercased; repeated values already joined with ", "
	Message  any

	// GraphQL
	OperationType string
	OperationName string
	Variables     any

	// WebSocket
	Connection string
}

Request is a normalized incoming request (spec §4). Which fields apply depends on Protocol. Params is not part of the wire request: routing derives it from the matched path template (spec §5.2) on an internal copy — Resolve never mutates the Request it is given, and any Params value the caller sets is ignored.

func (*Request) UnmarshalJSON

func (r *Request) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes a normalized request per conformance/README.md's request.json shape, normalizing repeated wire values per spec §4.6: headers/metadata join with ", "; query stays a list.

type Response

type Response struct {
	// HTTP
	Status  int
	Headers map[string]HeaderTemplate
	Body    any

	// gRPC
	GRPCStatus string
	Error      string
	Metadata   map[string]string
	Trailers   map[string]string
	Message    any

	Messages []any

	// GraphQL
	Data any

	Errors     []any
	Extensions any

	// WebSocket
	WSMessages []any

	Close *CloseSpec

	Delay int
	// contains filtered or unexported fields
}

Response is the template for a scenario's answer (spec §7). Which fields apply depends on the owning Server's Type (and, for gRPC, the Operation's Type).

type Scenario

type Scenario struct {
	Name     string
	Summary  string
	When     *When
	Response *Response
}

Scenario maps a matched request to a response (spec §6).

type Server

type Server struct {
	Name          string
	Type          ServerType
	Port          *int
	DescriptorSet string
	Schema        string
	Operations    []*Operation
}

Server is a named group of operations of one protocol (spec §3.3).

type ServerType

type ServerType string

ServerType is a server's protocol (spec §3.3).

const (
	ServerHTTP      ServerType = "http"
	ServerGRPC      ServerType = "grpc"
	ServerGraphQL   ServerType = "graphql"
	ServerWebSocket ServerType = "websocket"
)

type When

type When struct {
	Params    map[string]FacetValue
	Query     map[string]QueryFacetValue
	Headers   map[string]FacetValue
	Body      *PayloadFacet
	Metadata  map[string]FacetValue
	Message   *PayloadFacet
	Variables map[string]FacetValue
	Calls     *CallsFacet
}

When declares the facets a request must satisfy for its Scenario to match (spec §6.1). A nil field means that facet is unconstrained.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL