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 ¶
- Variables
- func CaseBackpressure(t *testing.T)
- func CaseCommandCancellation(t *testing.T)
- func CaseCommandIdempotency(t *testing.T)
- func CaseCommandTimeout(t *testing.T)
- func CaseCrashExit(t *testing.T)
- func CaseDescribeStability(t *testing.T)
- func CaseDuplicateOutOfOrder(t *testing.T)
- func CaseHandshakeVersion(t *testing.T)
- func StatusCode(err error) status.Code
- type Case
- type ExecOutcome
- type FakeProcess
- func (p *FakeProcess) Env() map[string]string
- func (p *FakeProcess) Exit(err error)
- func (p *FakeProcess) Exited() bool
- func (p *FakeProcess) Kill() error
- func (p *FakeProcess) Killed() bool
- func (p *FakeProcess) Pid() int
- func (p *FakeProcess) Signal(sig os.Signal) error
- func (p *FakeProcess) Signals() []os.Signal
- func (p *FakeProcess) Stderr() io.ReadCloser
- func (p *FakeProcess) Stdout() io.ReadCloser
- func (p *FakeProcess) Wait() error
- func (p *FakeProcess) WriteStderr(line string)
- func (p *FakeProcess) WriteStdout(line string)
- type FakeRunner
- type FakeRunnerOption
- type Harness
- type HarnessOption
- type MockCore
- func (c *MockCore) Accepted() []*driver.DriverMessage
- func (c *MockCore) Describe(ctx context.Context) (*driver.DriverDescriptor, error)
- func (c *MockCore) Execute(ctx context.Context, req *driver.ExecuteRequest) (*driver.ExecuteResponse, error)
- func (c *MockCore) ExpectAccepted(want []*driver.DriverMessage) error
- func (c *MockCore) Health(ctx context.Context) (*driver.HealthResponse, error)
- func (c *MockCore) Initialize(ctx context.Context, req *driver.InitializeRequest) (*driver.InitializeResponse, error)
- func (c *MockCore) LastSequence(instanceID, deviceID string) uint64
- func (c *MockCore) RawCount() int
- func (c *MockCore) SimulateCrash()
- func (c *MockCore) StartWatch(ctx context.Context, req *driver.WatchRequest) error
- func (c *MockCore) StopWatch()
- func (c *MockCore) WaitForCommandTerminal(timeout time.Duration, commandID string) (driver.CommandState, bool)
- func (c *MockCore) WaitForMessage(timeout time.Duration, pred func(*driver.DriverMessage) bool) (*driver.DriverMessage, bool)
- func (c *MockCore) WatchErr() error
- type MockCoreOption
- type MockDriver
- func (d *MockDriver) CloseDevice(ctx context.Context, req *driver.CloseDeviceRequest) (*driver.CloseDeviceResponse, error)
- func (d *MockDriver) ConfigureInstance(ctx context.Context, req *driver.ConfigureInstanceRequest) (*driver.ConfigureInstanceResponse, error)
- func (d *MockDriver) Describe(ctx context.Context) (*driver.DriverDescriptor, error)
- func (d *MockDriver) Descriptor() driver.DriverDescriptor
- func (d *MockDriver) Discover(ctx context.Context, req *driver.DiscoverRequest, ...) error
- func (d *MockDriver) Execute(ctx context.Context, req *driver.ExecuteRequest) (*driver.ExecuteResponse, error)
- func (d *MockDriver) Health(ctx context.Context) (*driver.HealthResponse, error)
- func (d *MockDriver) History() []*driver.DriverMessage
- func (d *MockDriver) Initialize(ctx context.Context, req *driver.InitializeRequest) (*driver.InitializeResponse, error)
- func (d *MockDriver) NegotiatedVersion() uint32
- func (d *MockDriver) OpenDevice(ctx context.Context, req *driver.OpenDeviceRequest) (*driver.OpenDeviceResponse, error)
- func (d *MockDriver) Publish(instanceID, deviceID string, body driver.DriverMessageUnion) *driver.DriverMessage
- func (d *MockDriver) PublishRaw(msg *driver.DriverMessage)
- func (d *MockDriver) Shutdown(ctx context.Context, req *driver.ShutdownRequest) (*driver.ShutdownResponse, error)
- func (d *MockDriver) ShutdownNow()
- func (d *MockDriver) Watch(ctx context.Context, req *driver.WatchRequest, ...) error
- func (d *MockDriver) WatcherCount() int
- type MockDriverOption
- type Suite
Constants ¶
This section is empty.
Variables ¶
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 CaseCommandCancellation ¶
func CaseCommandIdempotency ¶
func CaseCommandTimeout ¶
func CaseCrashExit ¶
func CaseDescribeStability ¶
func CaseDuplicateOutOfOrder ¶
func CaseHandshakeVersion ¶
func StatusCode ¶
StatusCode extracts the code from an error that is (or wraps) a Status.
Types ¶
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) Killed ¶
func (p *FakeProcess) Killed() bool
Killed reports whether Kill was called.
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) 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 ¶
func (r *FakeRunner) Start(spec pluginhost.CommandSpec) (pluginhost.Process, error)
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) 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 ¶
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) Execute ¶
func (c *MockCore) Execute(ctx context.Context, req *driver.ExecuteRequest) (*driver.ExecuteResponse, error)
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) Initialize ¶
func (c *MockCore) Initialize(ctx context.Context, req *driver.InitializeRequest) (*driver.InitializeResponse, error)
Initialize performs the Core-side handshake.
func (*MockCore) LastSequence ¶
LastSequence reports the tracked sequence for a scope.
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 ¶
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.
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 (d *MockDriver) CloseDevice(ctx context.Context, req *driver.CloseDeviceRequest) (*driver.CloseDeviceResponse, error)
func (*MockDriver) ConfigureInstance ¶
func (d *MockDriver) ConfigureInstance(ctx context.Context, req *driver.ConfigureInstanceRequest) (*driver.ConfigureInstanceResponse, error)
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 (d *MockDriver) Discover(ctx context.Context, req *driver.DiscoverRequest, stream driver.DiscoveryWriter) error
func (*MockDriver) Execute ¶
func (d *MockDriver) Execute(ctx context.Context, req *driver.ExecuteRequest) (*driver.ExecuteResponse, error)
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 (d *MockDriver) Initialize(ctx context.Context, req *driver.InitializeRequest) (*driver.InitializeResponse, error)
func (*MockDriver) NegotiatedVersion ¶
func (d *MockDriver) NegotiatedVersion() uint32
NegotiatedVersion reports the version chosen during Initialize (0 before).
func (*MockDriver) OpenDevice ¶
func (d *MockDriver) OpenDevice(ctx context.Context, req *driver.OpenDeviceRequest) (*driver.OpenDeviceResponse, error)
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 (d *MockDriver) Shutdown(ctx context.Context, req *driver.ShutdownRequest) (*driver.ShutdownResponse, error)
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 (d *MockDriver) Watch(ctx context.Context, req *driver.WatchRequest, stream driver.DriverMessageWriter) error
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.