enginetest

package
v0.3.13 Latest Latest
Warning

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

Go to latest
Published: May 14, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package enginetest provides reusable contract-test machinery for the interfaces declared in sdk/engine — engine.Engine and engine.Host today, more if the engine package grows.

Modeled on net/http/httptest, testing/iotest, and gocloud.dev/blob/drivertest: a single sibling package next to its subject covers every contract-checking surface the parent package exposes. The Go convention is one xxxtest sub-package per parent package, not one per interface — see the stdlib examples linked above. Importable from any concrete implementation's *_test files; contains exclusively test-support code; nothing in here should be referenced from non-test production paths.

What lives here

  • RunSuite — the standard contract every engine.Engine implementation should pass. New engines add a one-liner:

    func TestEngineContract(t *testing.T) { enginetest.RunSuite(t, func() (engine.Engine, enginetest.Capabilities) { return newMyEngine(), enginetest.Capabilities{} }) }

  • HostSuite — the standard contract every engine.Host implementation should pass. Hosts (NoopHost, vessel sandboxHost, OTel-instrumented HostFuncs, third-party hosts) add a one-liner:

    func TestMyHost_Contract(t *testing.T) { enginetest.HostSuite(t, func() engine.Host { return newMyHost() }) }

  • MockHost — a minimal Host implementation that records every interaction, lets tests inject interrupts / user replies, and exposes the captured envelopes / usage / checkpoints for assertion. Engines may use it directly in their own tests instead of re-implementing the full Host surface.

What does NOT live here

This package does not enumerate engine- or host-specific behaviours (graph-edge ordering, script-language semantics, vessel sandbox-specific bus routing, …). It only asserts what every implementation of the targeted interface is contractually obliged to do. Implementation-specific tests live next to the implementation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HostSuite added in v0.3.4

func HostSuite(t *testing.T, f HostFactory, caps ...HostCapabilities)

HostSuite runs every applicable contract subtest against hosts produced by f. Each subtest builds a fresh host so failures isolate cleanly.

func RunSuite

func RunSuite(t *testing.T, f Factory)

RunSuite runs every contract test that applies to the engine produced by f. Engines should call this from their own *_test.go:

func TestEngineContract(t *testing.T) {
    enginetest.RunSuite(t, func() (engine.Engine, enginetest.Capabilities) {
        return graph.NewEngine(), enginetest.Capabilities{SupportsResume: true}
    })
}

Each subtest constructs a fresh engine, so failures isolate cleanly. The whole suite must pass for an implementation to be considered engine.Engine-compliant.

Types

type Capabilities

type Capabilities struct {
	// SupportsResume is true when the engine implements Run.ResumeFrom
	// (i.e. given a non-nil ResumeFrom whose ExecID matches Run.ID it
	// resumes the run rather than returning errdefs.NotAvailable).
	//
	// Engines that implement engine.Resumer with stricter CanResume
	// admission rules (e.g. graph runner requires cp.Step to be a
	// real node id) MAY surface errdefs.Validation when the suite's
	// minimal test checkpoint fails admission; the suite accepts
	// that as a valid SupportsResume=true outcome since the engine
	// honestly rejected an unworkable resume request.
	SupportsResume bool
}

Capabilities lets an engine declare which optional behaviours it implements. The contract suite uses this to skip resume-specific subtests when the engine has SupportsResume == false (those subtests instead assert the engine returns NotAvailable).

type Factory

type Factory func() (engine.Engine, Capabilities)

Factory builds a fresh engine and reports its capabilities. The suite calls Factory once per subtest so subtests do not share engine state.

Engines that take no construction arguments can wrap a constructor:

enginetest.RunSuite(t, enginetest.NewFactory(graph.NewEngine))

or implement Factory directly when the construction needs more setup.

func NewFactory

func NewFactory(ctor func() engine.Engine) Factory

NewFactory adapts a parameterless constructor into a Factory that reports zero capabilities. Use Factory directly when you need to declare SupportsResume.

type HostCapabilities added in v0.3.4

type HostCapabilities struct {
	// SkipAskUserNotAvailable is true when the host is expected
	// to SUCCEED on AskUser (a real UI host with a configured
	// UserPrompter). The suite then asserts the call returns a
	// non-zero reply rather than allowing NotAvailable.
	SkipAskUserNotAvailable bool

	// SkipPublishConcurrency is true when the host's Publish
	// implementation is intentionally serial (e.g. a writer-locked
	// log shipper that must preserve order). The suite then runs
	// the Publish concurrency probe sequentially so the test
	// reflects the real serial-only contract.
	SkipPublishConcurrency bool

	// AcceptsBudgetExceeded, when true, indicates the host's
	// ReportUsage MAY return an errdefs.BudgetExceeded error for
	// the suite's zero-usage probe (= unusual but legal for hosts
	// pre-configured with a zero budget). When false (default),
	// the suite asserts ReportUsage(0-usage) returns nil.
	AcceptsBudgetExceeded bool
}

HostCapabilities lets a host opt out of subtests that don't apply. Most hosts pass the zero value (= every subtest runs).

type HostFactory added in v0.3.4

type HostFactory func() engine.Host

HostFactory builds a fresh engine.Host for each subtest. The suite invokes it once per case so subtests do not share host state.

type MockHost

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

MockHost is a fully-featured engine.Host for tests. It records every interaction and lets the test inject cooperative interrupts and user replies.

All methods are safe for concurrent use; any number of goroutines inside the engine may call them while the test inspects state.

Zero value is NOT ready to use. Call NewMockHost which pre-allocates the channels.

func NewMockHost

func NewMockHost() *MockHost

NewMockHost returns a ready-to-use MockHost. The interrupt channel is buffered so MockHost.Interrupt never blocks the test goroutine when the engine has not yet reached its select on Interrupts().

func (*MockHost) AskUser

AskUser records the prompt and returns the configured reply, or a NotAvailable error when no reply has been set.

func (*MockHost) Checkpoint

func (h *MockHost) Checkpoint(_ context.Context, cp engine.Checkpoint) error

Checkpoint records cp and returns the configured checkpointErr.

func (*MockHost) Checkpoints

func (h *MockHost) Checkpoints() []engine.Checkpoint

Checkpoints returns a copy of every checkpoint the engine submitted.

func (*MockHost) Envelopes

func (h *MockHost) Envelopes() []event.Envelope

Envelopes returns a copy of every envelope received so far.

func (*MockHost) Interrupt

func (h *MockHost) Interrupt(cause engine.Cause, detail string)

Interrupt queues an interrupt for the engine. Non-blocking: if the buffer is full the call drops the new signal silently — tests that care should call only once or assert via MockHost.Envelopes that the engine has reached its select.

func (*MockHost) Interrupts

func (h *MockHost) Interrupts() <-chan engine.Interrupt

Interrupts returns the cooperative-interrupt channel.

func (*MockHost) Prompts

func (h *MockHost) Prompts() []engine.UserPrompt

Prompts returns a copy of every UserPrompt the engine submitted.

func (*MockHost) Publish

func (h *MockHost) Publish(_ context.Context, env event.Envelope) error

Publish records the envelope and returns the configured publishErr (default nil).

func (*MockHost) ReportUsage

func (h *MockHost) ReportUsage(_ context.Context, usage model.TokenUsage) error

ReportUsage records the usage delta. Multiple calls are kept in order so tests can assert per-call totals; sum them with MockHost.TotalUsage when only the total matters.

func (*MockHost) SetCheckpointError

func (h *MockHost) SetCheckpointError(err error)

SetCheckpointError configures all subsequent Checkpoint calls to return err. Pass nil to clear.

func (*MockHost) SetPublishError

func (h *MockHost) SetPublishError(err error)

SetPublishError configures all subsequent Publish calls to return err. Pass nil to clear.

func (*MockHost) SetUserReply

func (h *MockHost) SetUserReply(reply *engine.UserReply)

SetUserReply configures what AskUser returns. Pass nil to revert to the NotAvailable default.

func (*MockHost) TotalUsage

func (h *MockHost) TotalUsage() model.TokenUsage

TotalUsage sums every recorded usage report.

func (*MockHost) Usages

func (h *MockHost) Usages() []model.TokenUsage

Usages returns a copy of every usage report.

Jump to

Keyboard shortcuts

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