tck

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package tck provides a tamper-resistant Transport Conformance Kit for the gomessaging framework. It randomizes service names, injects nonces into message payloads, and performs all broker validation directly — preventing implementations from passing the TCK by hardcoding responses.

Index

Constants

View Source
const ProtocolVersion = 1

ProtocolVersion is the current version of the TCK subprocess protocol.

Variables

This section is empty.

Functions

func ComputeExpectedBrokerState

func ComputeExpectedBrokerState(transportKey string, services map[string]spectest.ServiceConfig, mapper *NameMapper) spectest.BrokerState

ComputeExpectedBrokerState computes expected broker-level state from service intents using spec naming functions applied to runtime names.

func ComputeExpectedEndpoints

func ComputeExpectedEndpoints(transportKey string, services map[string]spectest.ServiceConfig, mapper *NameMapper) map[string][]spectest.ExpectedEndpoint

ComputeExpectedEndpoints computes expected topology endpoints from intents using spec naming functions applied to runtime (randomized) names. The result is keyed by template service name.

func ComputeProbeTarget

func ComputeProbeTarget(transportKey string, probe ProbeMessage, services map[string]spectest.ServiceConfig, mapper *NameMapper) spectest.ProbeTarget

ComputeProbeTarget derives a probe's raw broker target from the scenario context and randomized names. This replaces the static rawTarget field in tck.json.

func InjectNonce

func InjectNonce(payload json.RawMessage) (json.RawMessage, string)

InjectNonce adds a unique "_tckNonce" field to a JSON payload. Returns the modified payload and the nonce value.

func RunScenario

func RunScenario(t spectest.T, adapter Adapter, scenario Scenario)

RunScenario runs a single TCK scenario with randomized service names, nonce-injected payloads, and TCK-owned broker validation.

func RunTCK

func RunTCK(t spectest.T, fixturePath string, adapter Adapter)

RunTCK runs the full integration test suite. Each scenario shares the same adapter instance. For transports that need a fresh broker per scenario (e.g. NATS embedded server), use LoadScenarios + RunScenario directly.

Types

type Adapter

type Adapter interface {
	TransportKey() string
	BrokerConfig() BrokerConfig
	StartService(t spectest.T, serviceName string, intents []spectest.SetupIntent) *spectest.ServiceHandle
}

Adapter provides transport-specific service startup for the TCK. All broker access (querying state, raw publish/consume) is handled by the TCK itself — implementors only need to start services.

type BrokerClient

type BrokerClient interface {
	QueryState(t spectest.T) spectest.BrokerState
	PublishRaw(t spectest.T, target spectest.ProbeTarget, payload json.RawMessage, headers map[string]string) error
	CreateProbeConsumer(t spectest.T, target spectest.ProbeTarget) *spectest.ProbeConsumer
	// GetQueueMessages drains and returns messages currently in a named queue
	// (used to assert dead-lettering into the managed DLQ). Currently implemented
	// for AMQP only; the NATS client returns nil (no DLQ scenario runs on NATS).
	GetQueueMessages(t spectest.T, queueName string) []spectest.RawMessage
	Cleanup(t spectest.T)
}

BrokerClient provides direct broker access for TCK validation. Implementations are TCK-owned and not delegated to the adapter.

type BrokerConfig

type BrokerConfig struct {
	AMQPURL       string // e.g. amqp://guest:guest@localhost:5672
	ManagementURL string // e.g. http://guest:guest@localhost:15672
	NATSURL       string // e.g. nats://localhost:4222
}

BrokerConfig holds connection details for direct broker access.

type CloseServiceParams

type CloseServiceParams struct {
	ServiceName string `json:"serviceName"`
}

CloseServiceParams requests the adapter to close a single service.

type CoverageEntry

type CoverageEntry struct {
	IntentKey
	Scenarios []string
}

CoverageEntry records which scenarios exercise a particular intent.

type CoverageMatrix

type CoverageMatrix struct {
	Entries []CoverageEntry
	Missing []IntentKey
}

CoverageMatrix holds the full coverage analysis.

func ComputeCoverageMatrix

func ComputeCoverageMatrix(scenarios []Scenario) CoverageMatrix

ComputeCoverageMatrix scans all scenario intents and reports which of the 11 supported combinations are covered and which are missing.

type HelloParams

type HelloParams struct {
	ProtocolVersion int `json:"protocolVersion"`
}

HelloParams is sent as the first request to establish the protocol version.

type HelloResult

type HelloResult struct {
	ProtocolVersion int          `json:"protocolVersion"`
	TransportKey    string       `json:"transportKey"`
	BrokerConfig    BrokerConfig `json:"brokerConfig"`
}

HelloResult is the response to hello, providing transport info and broker config.

type IntentKey

type IntentKey struct {
	Pattern   string
	Direction string
	Ephemeral bool
}

IntentKey identifies a unique pattern+direction+ephemeral combination.

func AllSupportedIntents

func AllSupportedIntents() []IntentKey

AllSupportedIntents returns the 11 known intent combinations that the TCK should exercise.

type NameMapper

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

NameMapper handles bidirectional mapping between template and runtime service names. Template names are the static names from tck.json (e.g. "orders"). Runtime names include a random suffix (e.g. "orders-a8f3b2c1").

func NewNameMapper

func NewNameMapper(templateNames []string) *NameMapper

NewNameMapper creates a NameMapper with a random 8-hex-char suffix for the given template names.

func (*NameMapper) MapIntents

func (m *NameMapper) MapIntents(intents []spectest.SetupIntent) []spectest.SetupIntent

MapIntents creates a copy of intents with TargetService mapped to runtime names. Other fields (Pattern, Direction, RoutingKey, Exchange) are unchanged.

func (*NameMapper) Runtime

func (m *NameMapper) Runtime(templateName string) string

Runtime returns the runtime name for a template name. Unknown names pass through unchanged.

func (*NameMapper) Suffix

func (m *NameMapper) Suffix() string

Suffix returns the random suffix used for this mapper.

func (*NameMapper) Template

func (m *NameMapper) Template(runtimeName string) string

Template returns the template name for a runtime name. Unknown names pass through unchanged.

type PhaseResult

type PhaseResult struct {
	Name     string        `json:"name"`
	Passed   bool          `json:"passed"`
	Duration time.Duration `json:"duration"`
	Errors   []string      `json:"errors,omitempty"`
}

PhaseResult records the outcome of a single TCK phase.

type ProbeMessage

type ProbeMessage struct {
	Direction        string            `json:"direction"` // "outbound" or "inbound"
	PublishVia       string            `json:"publishVia,omitempty"`
	ExpectReceivedBy string            `json:"expectReceivedBy,omitempty"`
	RoutingKey       string            `json:"routingKey"`
	Payload          json.RawMessage   `json:"payload"`
	CEAttributes     map[string]string `json:"ceAttributes"`
	PayloadMatch     json.RawMessage   `json:"payloadMatch,omitempty"`
}

ProbeMessage describes a cross-validation probe. Unlike spectest.ProbeMessage, this type omits rawTarget since it is computed at runtime.

type PublishParams

type PublishParams struct {
	ServiceName  string            `json:"serviceName"`
	PublisherKey string            `json:"publisherKey"`
	RoutingKey   string            `json:"routingKey"`
	Payload      json.RawMessage   `json:"payload"`
	Headers      map[string]string `json:"headers,omitempty"`
}

PublishParams requests the adapter to publish a message.

type RPCError

type RPCError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

RPCError describes a JSON-RPC error.

func (*RPCError) Error

func (e *RPCError) Error() string

type ReceivedMessageWire

type ReceivedMessageWire struct {
	RoutingKey   string                 `json:"routingKey"`
	Payload      json.RawMessage        `json:"payload"`
	Metadata     messaging.Metadata     `json:"metadata"`
	DeliveryInfo messaging.DeliveryInfo `json:"deliveryInfo"`
}

ReceivedMessageWire is the wire format of a received message.

type ReceivedParams

type ReceivedParams struct {
	ServiceName string `json:"serviceName"`
}

ReceivedParams requests the list of messages received by a service.

type ReceivedResult

type ReceivedResult struct {
	Messages []ReceivedMessageWire `json:"messages"`
}

ReceivedResult contains the messages received by a service.

type ReportSummary

type ReportSummary struct {
	Total  int `json:"total"`
	Passed int `json:"passed"`
	Failed int `json:"failed"`
}

ReportSummary holds aggregate counts.

type Request

type Request struct {
	ID     int             `json:"id"`
	Method string          `json:"method"`
	Params json.RawMessage `json:"params"`
}

Request is a JSON-RPC request sent from the TCK runner to the adapter (via stdin).

type Response

type Response struct {
	ID     int             `json:"id"`
	Result json.RawMessage `json:"result,omitempty"`
	Error  *RPCError       `json:"error,omitempty"`
}

Response is a JSON-RPC response sent from the adapter to the TCK runner (via fd 3).

type Scenario

type Scenario struct {
	Name          string                            `json:"name"`
	Transports    []string                          `json:"transports,omitempty"`
	Services      map[string]spectest.ServiceConfig `json:"services"`
	Messages      []spectest.MessageSpec            `json:"messages"`
	ProbeMessages []ProbeMessage                    `json:"probeMessages,omitempty"`
}

Scenario describes a multi-service integration test scenario. Unlike spectest.TCKScenario, this type does not include expectedEndpoints, broker state, or rawTarget — those are computed at runtime.

func LoadScenarios

func LoadScenarios(t spectest.T, fixturePath string) []Scenario

LoadScenarios loads TCK scenarios from a fixture file.

func LoadScenariosFile

func LoadScenariosFile(fixturePath string) ([]Scenario, error)

LoadScenariosFile loads TCK scenarios from a fixture file, returning an error instead of calling t.Fatal. This is used by the standalone tck-runner binary.

type ScenarioReport

type ScenarioReport struct {
	Name     string        `json:"name"`
	Passed   bool          `json:"passed"`
	Duration time.Duration `json:"duration"`
	Services []string      `json:"services"`
	Patterns []string      `json:"patterns"`
	Phases   []PhaseResult `json:"phases"`
}

ScenarioReport records the outcome of a single TCK scenario.

func RunScenarioWithReport

func RunScenarioWithReport(t spectest.T, adapter Adapter, scenario Scenario) ScenarioReport

RunScenarioWithReport runs a single scenario and returns a structured report with per-phase timing and error capture.

type ShutdownParams

type ShutdownParams struct{}

ShutdownParams requests the adapter to exit cleanly.

type StartServiceParams

type StartServiceParams struct {
	ServiceName string                 `json:"serviceName"`
	Intents     []spectest.SetupIntent `json:"intents"`
}

StartServiceParams requests the adapter to start a service with the given intents.

type StartServiceResult

type StartServiceResult struct {
	PublisherKeys []string           `json:"publisherKeys"`
	Topology      messaging.Topology `json:"topology"`
}

StartServiceResult is the response after starting a service.

type SubprocessAdapter

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

SubprocessAdapter implements Adapter by spawning an external process and communicating via a newline-delimited JSON-RPC protocol. Requests are sent on stdin; responses are read from fd 3. stdout/stderr are forwarded to t.Log.

func NewSubprocessAdapter

func NewSubprocessAdapter(t spectest.T, command string, args ...string) *SubprocessAdapter

NewSubprocessAdapter starts the adapter process, performs the hello handshake, and returns a ready-to-use Adapter.

func (*SubprocessAdapter) BrokerConfig

func (a *SubprocessAdapter) BrokerConfig() BrokerConfig

func (*SubprocessAdapter) StartService

func (a *SubprocessAdapter) StartService(t spectest.T, serviceName string, intents []spectest.SetupIntent) *spectest.ServiceHandle

func (*SubprocessAdapter) TransportKey

func (a *SubprocessAdapter) TransportKey() string

type TCKReport

type TCKReport struct {
	TransportKey string           `json:"transportKey"`
	Timestamp    time.Time        `json:"timestamp"`
	Scenarios    []ScenarioReport `json:"scenarios"`
	Coverage     CoverageMatrix   `json:"coverage"`
	Summary      ReportSummary    `json:"summary"`
}

TCKReport is the top-level conformance report.

func RunTCKWithReport

func RunTCKWithReport(t spectest.T, fixturePath string, adapter Adapter) *TCKReport

RunTCKWithReport runs all scenarios and produces a full conformance report.

func (*TCKReport) GenerateJSON

func (r *TCKReport) GenerateJSON() ([]byte, error)

GenerateJSON marshals the report to indented JSON.

func (*TCKReport) GenerateMarkdown

func (r *TCKReport) GenerateMarkdown() string

GenerateMarkdown renders the report as a Markdown document.

Directories

Path Synopsis
Package adapterutil provides a reusable adapter-side protocol handler for the TCK subprocess protocol.
Package adapterutil provides a reusable adapter-side protocol handler for the TCK subprocess protocol.
cmd
tck-runner command
Binary tck-runner is the standalone Transport Conformance Kit runner.
Binary tck-runner is the standalone Transport Conformance Kit runner.

Jump to

Keyboard shortcuts

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