Documentation
¶
Overview ¶
Package runtimetest provides Runtime, the canonical fake core.Runtime for the tagwright suite's wiring (Level 2) tests. It replaces the divergent hand-rolled fakeRuntime copies each tool grew, and their drift risk, with a single fake shaped for the one thing those tests exist to prove: that a failure on a runtime operation SURFACES rather than being silently swallowed.
To that end the fake carries three things a happy-path double does not:
- A fault knob on every operation (Faults). Set Faults.Exec, and the next Exec returns it; set Faults.List, and List does; and so on. A wiring test that never trips a knob is not testing the wiring, only the happy path, which the suite's audit found is where the fake tier misses every real bug. The knob is how a test injects the failure it then asserts surfaces.
- A scripted event channel (Emit, Fail, CloseWatch), so a test can drive the watch loop through a start/die/destroy sequence, a mid-stream error, or a clean end of stream, deterministically.
- A controllable fake Clock, so the debounce and the scheduler advance on the test's terms rather than the wall clock's.
It implements runtime.Runtime, runtime.Provisioner, and runtime.NetworkInspector, so it is a drop-in wherever a tool takes a core.Runtime. It is safe for concurrent use: a daemon under test drives it from its own goroutines while the test reads its recordings.
Index ¶
- type Clock
- type ExecResult
- type Faults
- type Runtime
- func (r *Runtime) Close() error
- func (r *Runtime) CloseWatch()
- func (r *Runtime) CreateContainer(_ context.Context, spec runtime.ContainerSpec) (string, error)
- func (r *Runtime) CreateNetwork(_ context.Context, spec runtime.NetworkSpec) (string, error)
- func (r *Runtime) CreateVolume(_ context.Context, spec runtime.VolumeSpec) (string, error)
- func (r *Runtime) Emit(ev runtime.Event)
- func (r *Runtime) Exec(_ context.Context, _ string, spec runtime.ExecSpec) (*runtime.ExecHandle, error)
- func (r *Runtime) ExecCommands() []string
- func (r *Runtime) Fail(err error)
- func (r *Runtime) Inspect(_ context.Context, id string) (runtime.Container, error)
- func (r *Runtime) Kill(context.Context, string, string) error
- func (r *Runtime) Leaked() []string
- func (r *Runtime) List(context.Context) ([]runtime.Container, error)
- func (r *Runtime) ListNetworks(context.Context) ([]runtime.Network, error)
- func (r *Runtime) PullImage(_ context.Context, ref string) error
- func (r *Runtime) Pulled() []string
- func (r *Runtime) RemoveContainer(_ context.Context, id string, _ bool) error
- func (r *Runtime) RemoveNetwork(_ context.Context, id string) error
- func (r *Runtime) RemoveVolume(_ context.Context, name string) error
- func (r *Runtime) Restart(context.Context, string) error
- func (r *Runtime) Start(context.Context, string) error
- func (r *Runtime) Stop(context.Context, string, int) error
- func (r *Runtime) Watch(context.Context) (<-chan runtime.Event, <-chan error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Clock ¶
type Clock struct {
// contains filtered or unexported fields
}
Clock is a controllable fake clock. Its Now method is the func(s a consumer takes as its clock (a ballast Scheduler's SetClock, for instance), so a test drives time forward on its own terms rather than the wall clock's.
Now auto-advances by a fixed step on every call. That single property is enough to make a poll loop like the scheduler's own fire deterministically: each read of "now" is a little later than the last, so a job whose next-fire time has passed comes due without the test having to interleave an explicit Advance between the scheduler's internal reads. Set the step to zero for a frozen clock the test advances only through Advance or Set.
func NewClock ¶
NewClock returns a Clock starting at start whose Now auto-advances by step on each call.
func (*Clock) Advance ¶
Advance moves the clock forward by d, on top of the auto-step, for a test that needs to jump time explicitly (past a debounce window, say).
func (*Clock) Now ¶
Now returns the current fake time, then advances it by the auto-step. It is the value to hand a consumer as its clock function.
type ExecResult ¶
type ExecResult struct {
Match string // substring matched against the exec command's last argument
Stdout string
Exit int
}
ExecResult is a canned exec outcome matched to a command by substring, the same shape ballast's original hand-rolled fake used: the last match on the command's final argument wins, its Stdout is returned to the reader, and a non-zero Exit makes the handle's Wait report a failure. A test that only needs a fault can leave ExecResults empty and set Faults.Exec instead.
type Faults ¶
type Faults struct {
List error
Inspect error
Exec error
Stop error
Start error
Kill error
Restart error
Close error
Watch error // delivered on Watch's error channel rather than returned
// Provisioner knobs.
PullImage error
CreateNetwork error
RemoveNetwork error
CreateVolume error
RemoveVolume error
CreateContainer error
RemoveContainer error
// NetworkInspector knob.
ListNetworks error
}
Faults holds one injectable error per operation. A non-nil entry makes the matching method return that error instead of its normal result, which is how a wiring test forces a failure and then asserts it surfaces. The zero Faults injects nothing, so a fake left at its defaults behaves as a happy path.
type Runtime ¶
type Runtime struct {
// Containers is what List returns and what Inspect matches against, by ID
// then Name. Networks is what ListNetworks returns, on top of any network
// created through the Provisioner surface.
Containers []runtime.Container
Networks []runtime.Network
// ExecResults are consulted, in order, by Exec. Faults is the per-op error
// injection surface. Both are safe to set before or between calls.
ExecResults []ExecResult
Faults Faults
// Clock is the fake clock the test threads into the code under test (for a
// ballast daemon, into the scheduler). New installs a fresh one.
Clock *Clock
// contains filtered or unexported fields
}
Runtime is the canonical fake. Construct it with New. Populate Containers (returned by List, matched by Inspect), Networks (returned by ListNetworks), ExecResults, and Faults directly; they are plain fields guarded by the fake's mutex on every access.
func New ¶
func New() *Runtime
New builds a Runtime with an installed fake Clock and buffered event and error channels ready for Watch. The buffers let a test Emit a burst of events before the watch loop is even running without blocking.
func (*Runtime) CloseWatch ¶
func (r *Runtime) CloseWatch()
CloseWatch ends the event stream, so a watch loop selecting on it returns as it would when the socket closes. Safe to call once; a second call is a no-op.
func (*Runtime) CreateContainer ¶
func (*Runtime) CreateNetwork ¶
func (*Runtime) CreateVolume ¶
func (*Runtime) Emit ¶
Emit queues a lifecycle event for the watch loop to observe. It never blocks past the channel buffer in practice; a full buffer is a test that scripted more events than it drained.
func (*Runtime) Exec ¶
func (r *Runtime) Exec(_ context.Context, _ string, spec runtime.ExecSpec) (*runtime.ExecHandle, error)
Exec records the command, honors Faults.Exec, drains any stdin (mimicking the real adapter closing the write side after copying a dump in), then returns a handle whose Stdout and exit code come from the first matching ExecResult.
func (*Runtime) ExecCommands ¶
ExecCommands returns the last argument of every Exec call, in order, so a test can assert which dump or quiesce commands ran.
func (*Runtime) Fail ¶
Fail delivers a terminal error on Watch's error channel, the way a real adapter reports the socket dropping. It does not close the event stream.
func (*Runtime) Inspect ¶
Inspect returns the container whose ID or Name matches id, or Faults.Inspect if set, or a not-found error.
func (*Runtime) Leaked ¶
Leaked reports every throwaway object created through the Provisioner surface that was not later removed, the teardown-completeness check a verify-style test asserts is empty.