pluginharness

package
v0.2.5 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package pluginharness contains the conformance runner plus its mock Driver and mock Core. Everything runs over the in-process transport (sdk/go/transport) so the harness exercises the real handwritten wire encoding without needing gRPC or a serial port.

Index

Constants

This section is empty.

Variables

View Source
var ErrKilled = errors.New("fake plugin process killed")

ErrKilled is returned by FakeProcess.Wait when the host force-kills the process.

Functions

func CaseBackpressure

func CaseBackpressure(t *testing.T)

func CaseCommandCancellation

func CaseCommandCancellation(t *testing.T)

func CaseCommandIdempotency

func CaseCommandIdempotency(t *testing.T)

func CaseCommandTimeout

func CaseCommandTimeout(t *testing.T)

func CaseCrashExit

func CaseCrashExit(t *testing.T)

func CaseDescribeStability

func CaseDescribeStability(t *testing.T)

func CaseDuplicateOutOfOrder

func CaseDuplicateOutOfOrder(t *testing.T)

func CaseHandshakeVersion

func CaseHandshakeVersion(t *testing.T)

func StatusCode

func StatusCode(err error) status.Code

StatusCode extracts the code from an error that is (or wraps) a Status.

Types

type Case

type Case struct {
	Name string
	Run  func(t *testing.T)
}

Case is one conformance case.

type ExecOutcome

type ExecOutcome int

ExecOutcome controls what a delayed command does when its timer fires.

const (
	// ExecSucceed completes with SUCCEEDED unless the deadline already passed.
	ExecSucceed ExecOutcome = iota
	// ExecTimeout completes with TIMED_OUT even inside the deadline.
	ExecTimeout
)

type FakeProcess

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

FakeProcess is an in-memory pluginhost.Process that also connects to the real launch listener, so the host observes a real socket authentication.

func (*FakeProcess) Env

func (p *FakeProcess) Env() map[string]string

Env returns the environment the runner injected into the process.

func (*FakeProcess) Exit

func (p *FakeProcess) Exit(err error)

Exit makes the process terminate with err. It is idempotent.

func (*FakeProcess) Exited

func (p *FakeProcess) Exited() bool

Exited reports whether the process has terminated.

func (*FakeProcess) Kill

func (p *FakeProcess) Kill() error

Kill implements pluginhost.Process.

func (*FakeProcess) Killed

func (p *FakeProcess) Killed() bool

Killed reports whether Kill was called.

func (*FakeProcess) Pid

func (p *FakeProcess) Pid() int

Pid implements pluginhost.Process.

func (*FakeProcess) Signal

func (p *FakeProcess) Signal(sig os.Signal) error

Signal implements pluginhost.Process. By default a signal is treated as a graceful stop; tests can install a hook with WithOnSignal.

func (*FakeProcess) Signals

func (p *FakeProcess) Signals() []os.Signal

Signals returns the signals delivered to the process.

func (*FakeProcess) Stderr

func (p *FakeProcess) Stderr() io.ReadCloser

Stderr implements pluginhost.Process.

func (*FakeProcess) Stdout

func (p *FakeProcess) Stdout() io.ReadCloser

Stdout implements pluginhost.Process.

func (*FakeProcess) Wait

func (p *FakeProcess) Wait() error

Wait implements pluginhost.Process.

func (*FakeProcess) WriteStderr

func (p *FakeProcess) WriteStderr(line string)

WriteStderr appends one stderr line.

func (*FakeProcess) WriteStdout

func (p *FakeProcess) WriteStdout(line string)

WriteStdout appends one stdout line.

type FakeRunner

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

FakeRunner is an in-memory pluginhost.Runner used by the Supervisor tests. Although the process itself is in-memory, each fake process still dials the real launch listener with the injected credentials and serves a minimal Driver Protocol so the Supervisor's socket handshake, RPC health and RPC shutdown paths run end to end.

func NewFakeRunner

func NewFakeRunner(opts ...FakeRunnerOption) *FakeRunner

NewFakeRunner builds a runner that hands out fake processes. Each Start call creates a fresh process from the configured factory.

func (*FakeRunner) Start

Start implements pluginhost.Runner.

func (*FakeRunner) Started

func (r *FakeRunner) Started() []*FakeProcess

Started returns a copy of every process this runner has started.

func (*FakeRunner) StartedCount

func (r *FakeRunner) StartedCount() int

StartedCount returns how many Start calls have been issued.

type FakeRunnerOption

type FakeRunnerOption func(*FakeRunner)

FakeRunnerOption configures a FakeRunner.

func WithAutoHandshake

func WithAutoHandshake(v bool) FakeRunnerOption

WithAutoHandshake controls whether each fake process emits the expected handshake line on stdout after Start.

func WithCrashAfterHandshake

func WithCrashAfterHandshake() FakeRunnerOption

WithCrashAfterHandshake makes each fake process exit with a crash right after its handshake, exercising crash detection and the restart budget.

func WithOnSignal

func WithOnSignal(fn func(os.Signal)) FakeRunnerOption

WithOnSignal installs a Signal hook on each fake process.

type Harness

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

Harness wires one MockDriver and one MockCore together over an in-process transport and runs the protocol dispatcher. It is the standard fixture for conformance cases.

func NewHarness

func NewHarness(t *testing.T, driverOpts []MockDriverOption, coreOpts []MockCoreOption, opts ...HarnessOption) *Harness

NewHarness starts a fresh mock stack. Call Close to tear it down.

func (*Harness) Close

func (h *Harness) Close()

Close tears the harness down and waits for the server loop to exit.

func (*Harness) Core

func (h *Harness) Core() *MockCore

Core exposes the mock Core.

func (*Harness) Driver

func (h *Harness) Driver() *MockDriver

Driver exposes the mock Driver for direct staging of publishes.

func (*Harness) Initialize

func (h *Harness) Initialize(ctx context.Context) *driver.InitializeResponse

Initialize performs the handshake and requires success.

func (*Harness) StartWatch

func (h *Harness) StartWatch(ctx context.Context, req *driver.WatchRequest) error

StartWatch opens a Watch stream and waits until the mock Driver has actually registered the session, removing the publish/registration race between the client call and the server handler.

type HarnessOption

type HarnessOption func(*Harness)

HarnessOption tunes a Harness.

func WithPipeCapacity

func WithPipeCapacity(n int) HarnessOption

WithPipeCapacity sets the transport queue size (small values exercise backpressure).

type MockCore

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

MockCore is the Core-side counterpart of MockDriver. It drives a real DriverClient over the in-process transport, dedupes incoming DriverMessage frames with a SequenceTracker, and records the accepted stream for assertions. It also owns both transport ends so tests can simulate a plugin crash.

func NewMockCore

func NewMockCore(cli driver.DriverClient, coreEnd, peerEnd transport.Transport, opts ...MockCoreOption) *MockCore

NewMockCore wraps a DriverClient plus both pipe ends.

func (*MockCore) Accepted

func (c *MockCore) Accepted() []*driver.DriverMessage

Accepted returns a copy of deduped messages in receive order.

func (*MockCore) Describe

func (c *MockCore) Describe(ctx context.Context) (*driver.DriverDescriptor, error)

Describe fetches the plugin descriptor.

func (*MockCore) Execute

Execute forwards a command.

func (*MockCore) ExpectAccepted

func (c *MockCore) ExpectAccepted(want []*driver.DriverMessage) error

ExpectAccepted returns an error if the accepted set does not match the expected per-(instance, device) sequence list exactly.

func (*MockCore) Health

func (c *MockCore) Health(ctx context.Context) (*driver.HealthResponse, error)

Health forwards a health probe.

func (*MockCore) Initialize

Initialize performs the Core-side handshake.

func (*MockCore) LastSequence

func (c *MockCore) LastSequence(instanceID, deviceID string) uint64

LastSequence reports the tracked sequence for a scope.

func (*MockCore) RawCount

func (c *MockCore) RawCount() int

RawCount is the number of frames observed (before dedup).

func (*MockCore) SimulateCrash

func (c *MockCore) SimulateCrash()

SimulateCrash tears down both transport ends, equivalent to the plugin process dying and the host dropping the channel. Pending calls and streams must then fail with an error rather than hang.

func (*MockCore) StartWatch

func (c *MockCore) StartWatch(ctx context.Context, req *driver.WatchRequest) error

StartWatch opens a Watch stream and consumes frames in the background, applying the (instance, device, sequence) dedup contract. Frames that Core would drop are counted in RawCount but not recorded.

func (*MockCore) StopWatch

func (c *MockCore) StopWatch()

StopWatch cancels the background consumer and waits for it to exit.

func (*MockCore) WaitForCommandTerminal

func (c *MockCore) WaitForCommandTerminal(timeout time.Duration, commandID string) (driver.CommandState, bool)

WaitForCommandTerminal waits for a terminal CommandProgress of the given command and returns its state.

func (*MockCore) WaitForMessage

func (c *MockCore) WaitForMessage(timeout time.Duration, pred func(*driver.DriverMessage) bool) (*driver.DriverMessage, bool)

WaitForMessage blocks until a deduped message satisfies pred or the timeout expires. It reports (found, true) on success.

func (*MockCore) WatchErr

func (c *MockCore) WatchErr() error

WatchErr is the terminal Watch error once the stream ends.

type MockCoreOption

type MockCoreOption func(*MockCore)

MockCoreOption tunes a MockCore.

func WithRecvDelay

func WithRecvDelay(d time.Duration) MockCoreOption

WithRecvDelay simulates a slow consumer: each accepted frame is delayed, which lets tests exercise transport backpressure.

type MockDriver

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

MockDriver is a deterministic in-memory DriverServer for conformance testing. It publishes all six DriverMessage variants to matching Watch sessions and implements idempotent Execute plus cancellation.

func NewMockDriver

func NewMockDriver(opts ...MockDriverOption) *MockDriver

NewMockDriver returns a configured mock Driver with a stable descriptor.

func (*MockDriver) CloseDevice

func (*MockDriver) ConfigureInstance

func (*MockDriver) Describe

func (d *MockDriver) Describe(ctx context.Context) (*driver.DriverDescriptor, error)

func (*MockDriver) Descriptor

func (d *MockDriver) Descriptor() driver.DriverDescriptor

Descriptor returns the stable descriptor (for expectations).

func (*MockDriver) Discover

func (*MockDriver) Execute

func (*MockDriver) Health

func (d *MockDriver) Health(ctx context.Context) (*driver.HealthResponse, error)

func (*MockDriver) History

func (d *MockDriver) History() []*driver.DriverMessage

History returns a copy of all published messages (for replay assertions).

func (*MockDriver) Initialize

func (*MockDriver) NegotiatedVersion

func (d *MockDriver) NegotiatedVersion() uint32

NegotiatedVersion reports the version chosen during Initialize (0 before).

func (*MockDriver) OpenDevice

func (*MockDriver) Publish

func (d *MockDriver) Publish(instanceID, deviceID string, body driver.DriverMessageUnion) *driver.DriverMessage

Publish stages and emits one DriverMessage with a fresh sequence and returns it.

func (*MockDriver) PublishRaw

func (d *MockDriver) PublishRaw(msg *driver.DriverMessage)

PublishRaw stages a pre-built frame without assigning a fresh sequence, used to inject duplicates and out-of-order frames.

func (*MockDriver) Shutdown

func (*MockDriver) ShutdownNow

func (d *MockDriver) ShutdownNow()

ShutdownNow marks the mock as stopped: Initialize fails and Watch streams are refused at the application layer (separate from transport crash).

func (*MockDriver) Watch

func (*MockDriver) WatcherCount

func (d *MockDriver) WatcherCount() int

WatcherCount returns the number of currently registered Watch sessions.

type MockDriverOption

type MockDriverOption func(*MockDriver)

MockDriverOption tunes a MockDriver.

func WithExecDelay

func WithExecDelay(d time.Duration, outcome ExecOutcome) MockDriverOption

WithExecDelay makes Execute return ACCEPTED and complete after delay.

func WithReplay

func WithReplay(enabled bool) MockDriverOption

WithReplay enables Watch replay from resume_from_sequence.

func WithWatchBuffer

func WithWatchBuffer(n int) MockDriverOption

WithWatchBuffer sets the per-session publish buffer used in backpressure tests.

func WithWatchError

func WithWatchError(err error) MockDriverOption

WithWatchError makes Watch fail immediately (crash/fault injection).

type Suite

type Suite struct{}

Suite is the ordered conformance suite defined by docs/architecture/plugin-system.md §12: handshake/version negotiation, descriptor stability, duplicate/out-of-order/backpressure, command idempotency/timeout/cancellation, and crash exit at the mock level.

func (Suite) Cases

func (Suite) Cases() []Case

Cases returns the suite cases. Each case builds its own Harness so tests stay independent.

func (Suite) Run

func (s Suite) Run(t *testing.T)

Run executes every case as a subtest.

Jump to

Keyboard shortcuts

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