Help us shape the future of Go! Take the 2026 Go Developer Survey

exectest

package
v1.9.3 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 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