Documentation
¶
Overview ¶
Package agenttest provides deterministic consumer-side fixtures and reusable conformance suites for the Agent Framework's public execution boundaries. It exercises public Definition, Execution, DeploymentResolver, and TreeCommitter contracts without simulating private Engine state or Process lifecycle ownership. Each suite covers the behavior its contract states in prose and no compiler checks; it never asserts one implementation arrangement.
Example (MemoryCommitter) ¶
package main
import (
"fmt"
"github.com/Tangerg/scope/agent"
)
func main() {
committer := agent.NewMemoryTreeCommitter()
var contract agent.TreeCommitter = committer
fmt.Printf("%T\n", contract)
}
Output: *agent.MemoryTreeCommitter
Index ¶
- Variables
- func RunDefinitionConformance(t *testing.T, config DefinitionConformanceConfig)
- func RunDeploymentResolverConformance(t *testing.T, config DeploymentResolverConformanceConfig)
- func RunTreeCommitterConformance(t *testing.T, factory func() TreeCommitterConformanceDriver)
- type DefinitionConformanceConfig
- type DeploymentResolverConformanceConfig
- type ExecutionConformanceCase
- type ObservationRecorder
- func (o *ObservationRecorder) AwaitEvent(ctx context.Context, predicate func(agent.Event) bool) (agent.Event, error)
- func (o *ObservationRecorder) Deltas() []agent.Delta
- func (o *ObservationRecorder) Events() []agent.Event
- func (o *ObservationRecorder) OnDelta(_ context.Context, delta agent.Delta)
- func (o *ObservationRecorder) OnEvent(_ context.Context, event agent.Event)
- type RejectedStepConformanceCase
- type ScriptedCall
- type ScriptedDispatcher
- func (s *ScriptedDispatcher) Dispatch(ctx context.Context, request agent.EffectRequest, emit agent.DeltaEmitter) (agent.Settlement, error)
- func (s *ScriptedDispatcher) Policy(effect agent.Effect) agent.EffectPolicy
- func (s *ScriptedDispatcher) Remaining() int
- func (s *ScriptedDispatcher) Requests() []agent.EffectRequest
- type ScriptedDispatcherConfig
- type TreeCommitterConformanceDriver
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidDispatchScript = errors.New("agenttest: invalid dispatch script") ErrUnexpectedDispatch = errors.New("agenttest: unexpected dispatch") ErrEffectMismatch = errors.New("agenttest: effect does not match script") )
var ErrInvalidEventPredicate = errors.New("agenttest: invalid event predicate")
Functions ¶
func RunDefinitionConformance ¶
func RunDefinitionConformance(t *testing.T, config DefinitionConformanceConfig)
RunDefinitionConformance verifies descriptor stability, concurrent Start isolation, exact Snapshot/Restore, byte-equivalent Step results, and stable rejection classifications for the supplied representative cases.
All configured Signals are validated before the Definition runs. Restore and Step inherit the test context; each Step receives a child context canceled when that call returns. RestoredCases and the fresh Signal batches must describe successful Steps; RejectedCases describe domain violations and assert the exact Failure the Definition persists for them. Cancellation paths remain ordinary tests owned by the Definition implementation.
func RunDeploymentResolverConformance ¶ added in v0.36.0
func RunDeploymentResolverConformance(t *testing.T, config DeploymentResolverConformanceConfig)
RunDeploymentResolverConformance verifies the behavior a DeploymentResolver promises but no compiler checks: exact reference matching, rejection of a reference that only shares a name, rejection of unknown references, and lookups that stay independent of their order, repetition, and concurrency.
Boundedness, absence of remote input/output, and absence of Process re-entry cannot be observed from outside an implementation and remain the implementation's own tests. Run this suite under -race so the concurrency case can report a data race.
func RunTreeCommitterConformance ¶ added in v0.32.0
func RunTreeCommitterConformance( t *testing.T, factory func() TreeCommitterConformanceDriver, )
RunTreeCommitterConformance injects failures on both sides of storage commits because a lost response must not cause duplicate dispatch or false publication. Scenarios cover Unknown resolution, child publication, input consumption, budget preservation, subtree cancellation recovery, and tree-local child signal and cancel controls, whose parent receipt and recipient state are checked through LoadTree.
Each factory call must return an empty isolated store so prior head ownership cannot mask a missing compare-and-swap or idempotency check:
agenttest.RunTreeCommitterConformance(t, func() agenttest.TreeCommitterConformanceDriver {
return agent.NewMemoryTreeCommitter()
})
Runtime operations inherit the test context; storage calls detach its cancellation, and cleanup may outlive it to join owned work. Shutdown scenarios release an injected storage gate independently of caller cancellation and verify the authoritative head on both sides of the cut. Hosts must also fault-inject their real transport to prove its own storage deadline and that shutdown interrupts blocked I/O.
Types ¶
type DefinitionConformanceConfig ¶
type DefinitionConformanceConfig struct {
Definition agent.Definition
Input agent.Payload
InitialSignals []agent.Signal
// FollowingSignals exercises the original instance and each restored copy
// through a representative multi-Step suffix.
FollowingSignals [][]agent.Signal
RestoredCases []ExecutionConformanceCase
RejectedCases []RejectedStepConformanceCase
}
DefinitionConformanceConfig supplies representative cases, not a proof that arbitrary Definition code never reads hidden input or performs I/O.
type DeploymentResolverConformanceConfig ¶ added in v0.36.0
type DeploymentResolverConformanceConfig struct {
Resolver agent.DeploymentResolver
// Resolvable lists every Deployment the resolver must return for that
// Deployment's own reference. At least one is required. The suite derives
// its name-collision probes from these, so a resolver that falls back by
// name is detected without the caller constructing the collision.
Resolvable []agent.Deployment
// Unresolvable lists references the resolver must reject. It may be empty;
// the derived collision probes already exercise rejection.
Unresolvable []agent.DeploymentRef
}
type ObservationRecorder ¶
type ObservationRecorder struct {
// contains filtered or unexported fields
}
ObservationRecorder is a concurrency-safe EventListener and DeltaListener. Its zero value is ready for use.
func (*ObservationRecorder) AwaitEvent ¶
func (o *ObservationRecorder) AwaitEvent( ctx context.Context, predicate func(agent.Event) bool, ) (agent.Event, error)
AwaitEvent returns the first recorded Event accepted by predicate. It waits for later events until ctx ends and never polls Process state.
func (*ObservationRecorder) Deltas ¶
func (o *ObservationRecorder) Deltas() []agent.Delta
Deltas returns recorded increments in delivery order.
func (*ObservationRecorder) Events ¶
func (o *ObservationRecorder) Events() []agent.Event
Events returns recorded events in publication order.
type RejectedStepConformanceCase ¶ added in v0.36.0
type RejectedStepConformanceCase struct {
Name string
// State is an exact state previously produced by the Definition.
State agent.ExecutionState
Signals []agent.Signal
// FailureKind and FailureCode are the exact persisted classification.
FailureKind agent.FailureKind
FailureCode string
}
RejectedStepConformanceCase requires a stable domain classification instead of the generic execution.step.failed fallback.
type ScriptedCall ¶ added in v0.41.0
type ScriptedCall struct {
ExpectedEffect *agent.Effect
// Deltas are emitted in declaration order before the final outcome.
Deltas []json.RawMessage
SettlementStatus agent.SettlementStatus
SettlementPayload json.RawMessage
// Error makes Dispatch return an indeterminate external error.
Error error
}
ScriptedCall describes one expected Dispatcher call and its deterministic stream and settlement outcome. ExpectedEffect is optional; when present, the complete immutable Effect must match. Error may follow emitted Deltas and is mutually exclusive with SettlementStatus and SettlementPayload.
type ScriptedDispatcher ¶
type ScriptedDispatcher struct {
// contains filtered or unexported fields
}
ScriptedDispatcher is a concurrency-safe finite Dispatcher fixture. It records every request that reaches script consumption and fails calls made beyond or contrary to the configured script.
func NewScriptedDispatcher ¶
func NewScriptedDispatcher(config ScriptedDispatcherConfig) (*ScriptedDispatcher, error)
NewScriptedDispatcher copies the script so callers cannot change expectations while dispatch is running.
func (*ScriptedDispatcher) Dispatch ¶
func (s *ScriptedDispatcher) Dispatch( ctx context.Context, request agent.EffectRequest, emit agent.DeltaEmitter, ) (agent.Settlement, error)
func (*ScriptedDispatcher) Policy ¶ added in v0.44.0
func (s *ScriptedDispatcher) Policy(effect agent.Effect) agent.EffectPolicy
func (*ScriptedDispatcher) Remaining ¶
func (s *ScriptedDispatcher) Remaining() int
func (*ScriptedDispatcher) Requests ¶
func (s *ScriptedDispatcher) Requests() []agent.EffectRequest
Requests returns consumed Dispatch requests in actual call order, including requests that mismatch or exceed the script.
type ScriptedDispatcherConfig ¶
type ScriptedDispatcherConfig struct {
ReplayPolicy agent.ReplayPolicy
// Calls are consumed in actual Dispatch order.
Calls []ScriptedCall
}
type TreeCommitterConformanceDriver ¶ added in v0.32.0
type TreeCommitterConformanceDriver interface {
// TreeCommitter must share storage with LoadTree so the suite can verify
// acknowledged writes through an independent read.
agent.TreeCommitter
// LoadTree must not activate the tree, because observation cannot take
// ownership from the writer being tested.
LoadTree(ctx context.Context, rootID agent.ProcessID) (agent.TreeSnapshot, bool, error)
}
TreeCommitterConformanceDriver separates commits from reads so the suite can detect acknowledgments that did not install the claimed authoritative head.
Source Files
¶
- definition_conformance.go
- deployment_resolver_conformance.go
- dispatcher.go
- doc.go
- observation.go
- signal_durability_conformance.go
- tree_child_control_conformance.go
- tree_commit_cycle_conformance.go
- tree_durability_child_conformance.go
- tree_durability_conformance.go
- tree_durability_crash_conformance.go
- tree_durability_resolution_conformance.go
- tree_shutdown_conformance.go