exectest

package
v1.9.4 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package exectest is the conformance suite every exec.Executor must pass.

The rungs of the isolation ladder are meant to be interchangeable: the same handler, the same payload, and the same declared inputs must behave the same way whether the handler runs in-process or in a pod. One shared table-driven suite is how that stays true, and it is what lets a new rung land without redesigning the ones before it.

Rungs differ in what they can enforce — in-process cannot kill a handler that ignores its deadline — so a rung declares its Capabilities and the suite asserts the enforcement cases only against rungs that claim them.

Index

Constants

View Source
const (
	JobOK    = "exectest.ok"
	JobError = "exectest.error"
	JobPanic = "exectest.panic"
	JobSlow  = "exectest.slow"
	JobEcho  = "exectest.echo"
)

Job names the suite installs. Every executor under test must be able to run all of them.

Artifact-carrying fixtures (writing outputs, reading staged inputs) arrive in Phase 2 alongside the suite cases that exercise them. Adding them now would ship handlers no case runs.

Variables

View Source
var ErrIntentional = errors.New("intentional failure")

ErrIntentional is what JobError returns, so tests can match it exactly.

Functions

func CheckCapabilities

func CheckCapabilities(name string, level exec.Level, caps Capabilities) error

CheckCapabilities reports whether the capabilities a rung claims are consistent with the isolation it advertises, returning nil when they are.

Without this check Capabilities is an escape hatch: a rung that reports LevelProcess but sets Enforces false skips DeadlineEnforced — the only test proving it can stop a handler that ignores cancellation, which is the property the whole isolation ladder exists to provide — and still passes the suite clean. An executor may run handlers where it cannot kill them, or it may claim LevelProcess; it may not do both.

RunSuite calls this. It is exported so a rung's own tests can assert the same consistency without running the full suite.

func HandlerNames

func HandlerNames() []string

HandlerNames returns the fixture job names, which is what a fingerprint is derived from.

func Handlers

func Handlers() []job.Registrable

Handlers returns the fixture handler set. Registering these is all an executor needs to be run through the suite.

func RunSuite

func RunSuite(t *testing.T, name string, newExecutor func(*testing.T) exec.Executor, caps Capabilities)

RunSuite runs the conformance suite against one executor implementation.

newExecutor is called per subtest so each case gets a clean executor. The returned executor must already have the fixture Handlers registered.

Types

type Capabilities

type Capabilities struct {
	// Enforces means the rung can stop a handler that ignores its
	// deadline. Only out-of-process rungs can.
	Enforces bool

	// ReportsUsage means the rung measures CPU time and peak memory
	// rather than only wall time.
	ReportsUsage bool

	// IsolatesPanic means a panicking handler does not take the caller
	// down, so the rung reports it as a failed attempt rather than
	// relying on the worker's recover middleware.
	IsolatesPanic bool
}

Capabilities describes what a rung can actually do, so the suite asserts enforcement only against rungs that provide it.

It describes variation, not an opt-out. RunSuite cross-checks it against the executor's own Level: anything claiming LevelProcess or above must enforce deadlines and isolate panics, and saying otherwise fails the suite rather than skipping the tests that prove it.

type EchoPayload

type EchoPayload struct {
	Value string `json:"value"`
	Want  int    `json:"want"`
}

EchoPayload is the payload JobEcho round-trips. Want, when non-zero, is the byte length the handler asserts Value has, which is how the suite proves a large payload crossed the boundary without truncation.

type SlowPayload

type SlowPayload struct {
	SleepMillis int `json:"sleep_millis"`

	// IgnoreCtx makes the handler deaf to cancellation entirely, standing
	// in for a native library that has stopped honouring it. Only a rung
	// that can kill the process will stop this one.
	IgnoreCtx bool `json:"ignore_ctx"`

	// SwallowCancel only matters when IgnoreCtx is false. A cooperative
	// handler normally returns ctx.Err() once its context is done; setting
	// this makes it catch that and return nil instead, the shape of a
	// handler whose own cleanup swallows context.Canceled. The shim then
	// reports StatusOK in its Result frame despite the deadline having
	// fired, which is exactly the case that must not fool the executor
	// into reporting success — the executor's own timedOut bookkeeping,
	// not the frame's contents, has to be what decides the Status.
	SwallowCancel bool `json:"swallow_cancel"`
}

SlowPayload controls how long JobSlow sleeps.

Jump to

Keyboard shortcuts

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