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

runtime

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2026 License: Apache-2.0 Imports: 49 Imported by: 0

Documentation

Overview

Package runtime manages networks, databases, containers, Compose stacks, readiness, and the lifecycle of resolved test blocks.

Index

Constants

View Source
const (
	KeyBlockName     = "blockName"
	KeyAdminUser     = "adminUsername"
	KeyAdminPass     = "adminPassword"
	KeyConsumerUser  = "consumerUsername"
	KeyConsumerPass  = "consumerPassword"
	KeyDeveloperUser = "developerUsername"
	KeyDeveloperPass = "developerPassword"
	KeyInstanceSet   = "instances"
)

Shared-scope keys published by the runtime.

View Source
const (
	EnvComposeCPULimit      = "APIP_CPU_LIMIT"
	EnvComposeMemoryLimitMB = "APIP_MEMORY_LIMIT_MB"
	EnvInstanceSuffix       = "INSTANCE"
)

EnvComposeCPULimit and EnvComposeMemoryLimitMB carry a compose component's declared resource limits into the stack's substitution env, for a service's own compose file to reference under its "deploy.resources.limits" (honoured by `docker compose up` without swarm mode). Set only when the definition declares a limit, so a compose file that does not reference them sees no behavior change.

View Source
const EnvComposeNetwork = "PG_NETWORK"

EnvComposeNetwork names the block network used by a compose stack.

Variables

This section is empty.

Functions

func AccessorKey

func AccessorKey(component, endpoint string) string

AccessorKey exposes the key format so a step helper can read an accessor.

func AwaitHealthy

func AwaitHealthy(ctx context.Context, inst *components.Instance, prober Prober) error

AwaitHealthy polls a component's declared health endpoint until it returns the expected status.

func CloseSharedLogs

func CloseSharedLogs()

CloseSharedLogs flushes and closes every shared component's log writer. Shared containers outlive all blocks and are reaped at process exit, so nothing else closes these files - the suite calls this once the run is over.

func EnsureParallelBudget

func EnsureParallelBudget(blocks, maxRunnersPerBlock int) (int, bool)

EnsureParallelBudget raises the test parallelism budget for nested block and runner tests.

func ParallelBudgetNotice

func ParallelBudgetNotice(from, to int) string

ParallelBudgetNotice describes an automatic test parallelism adjustment.

func Run

func Run(t *testing.T, resolved *topology.Resolved, deps Deps)

Run executes a resolved suite with parallel blocks and sequential scenarios per runner.

Types

type ComposeStack

type ComposeStack struct {
	Instance *components.Instance
	// contains filtered or unexported fields
}

ComposeStack is a running compose-backed component.

func LaunchCompose

func LaunchCompose(
	ctx context.Context, def *components.Definition, spec *components.ComposeSpec, opts Options,
) (*ComposeStack, error)

LaunchCompose starts a compose-backed component and presents it as one instance.

func (*ComposeStack) CopyFileFromContainer

func (c *ComposeStack) CopyFileFromContainer(ctx context.Context, service, path string) ([]byte, error)

CopyFileFromContainer reads one file out of a service's container.

Used to read a component's own persisted state directly - an embedded SQLite database, for instance - when no product API exposes it. This is a snapshot, not a live handle: the file is fully read before this call returns, so a caller holds a copy from one instant, not a connection to the container's own open file.

func (*ComposeStack) CoverageServices

func (c *ComposeStack) CoverageServices() []components.CoverageService

CoverageServices lists the services whose coverage artifacts a coverage run collects.

func (*ComposeStack) Exec

func (c *ComposeStack) Exec(ctx context.Context, service string, cmd []string) (string, error)

Exec runs a command inside one of the stack's services and returns its output.

func (*ComposeStack) Logs

func (c *ComposeStack) Logs(ctx context.Context) string

Logs returns each service's log output, concatenated and labelled.

func (*ComposeStack) PrimaryService

func (c *ComposeStack) PrimaryService() string

PrimaryService is the service whose ports back the component's endpoints.

func (*ComposeStack) RefreshPorts

func (c *ComposeStack) RefreshPorts(ctx context.Context) error

RefreshPorts re-reads every endpoint's host port and updates the component instance.

func (*ComposeStack) RestartService

func (c *ComposeStack) RestartService(ctx context.Context, service string) error

RestartService stops and starts one service, then refreshes its published ports.

func (*ComposeStack) ServiceContainerID

func (c *ComposeStack) ServiceContainerID(ctx context.Context, service string) (string, error)

ServiceContainerID resolves a running service's container ID.

func (*ComposeStack) Services

func (c *ComposeStack) Services() []string

Services lists the compose services this stack runs.

func (*ComposeStack) StageDir

func (c *ComposeStack) StageDir() string

StageDir is where the stack's files were materialized, for diagnosing a config problem.

func (*ComposeStack) StartService

func (c *ComposeStack) StartService(ctx context.Context, service string) error

StartService starts a stopped service and refreshes its published ports.

func (*ComposeStack) Stop

func (c *ComposeStack) Stop(ctx context.Context) error

Stop tears down the stack and removes its staging directory.

func (*ComposeStack) StopService

func (c *ComposeStack) StopService(ctx context.Context, service string) error

StopService stops one service while leaving the rest of the stack running.

type Container

type Container struct {
	Instance *components.Instance
	// contains filtered or unexported fields
}

Container is a started component: its Instance for addressing, plus the handle needed to stop it and read its logs.

func Launch

func Launch(ctx context.Context, def *components.Definition, opts Options) (*Container, error)

Launch starts one instance and waits for its container-level readiness strategy.

func LaunchShared

func LaunchShared(
	ctx context.Context, def *components.Definition, opts Options,
) (*Container, error)

LaunchShared starts a shared component once and returns the existing container thereafter.

func (*Container) AttachTo

func (c *Container) AttachTo(ctx context.Context, nw *Network, alias string) error

AttachTo connects a shared container to a block network under its alias.

func (*Container) DetachFrom

func (c *Container) DetachFrom(ctx context.Context, nw *Network) error

DetachFrom disconnects a shared container from a block network.

func (*Container) Exec

func (c *Container) Exec(ctx context.Context, cmd []string) (string, error)

Exec runs a command inside the container and returns its combined output.

func (*Container) Logs

func (c *Container) Logs(ctx context.Context) (string, error)

Logs returns the container's log output, for diagnosing a boot or health failure.

func (*Container) Stop

func (c *Container) Stop(ctx context.Context) error

Stop terminates the container. It is safe to call repeatedly.

type Credentials

type Credentials struct {
	User     string
	Password string
}

Credentials are one block's database credentials.

func NewCredentials

func NewCredentials() (Credentials, error)

NewCredentials generates credentials for a block.

type DatabaseOptions

type DatabaseOptions struct {
	// Network is the block's private network. Required when any server is needed.
	Network *Network

	// RepoRoot resolves the repo-relative schema paths a component registers.
	RepoRoot string

	// Requests is each component's storage need.
	Requests []Request

	// LogWriter, when non-nil, receives each started server's output for the block that
	// owns it. A database server belongs to exactly one block, so the block's own writer
	// is its correct destination.
	LogWriter *logcapture.Writer
}

DatabaseOptions configures database provisioning.

type Deps

type Deps struct {
	// RepoRoot resolves repo-relative paths.
	RepoRoot string

	// Steps constructs runner-isolated step definitions.
	Steps StepFactory

	// FeatureRoot resolves the feature paths in the suite file.
	FeatureRoot string

	// Logger receives engine diagnostics.
	Logger *slog.Logger

	// CleanupDeleters registers how to delete each resource kind. Called per runner, so
	// each gets a registry wired with the suite's deleters.
	CleanupDeleters func(*cleanup.Registry, *Topology)

	// Coverage, when non-nil, makes every block harvest its containers' coverage
	// counters at teardown. Nil in a default run — the suite decides, because only it
	// knows whether the images are instrumented.
	Coverage *coverage.Sink

	// Logs, when non-nil, makes every block stream its containers' combined stdout/stderr
	// into one file for the block's whole lifetime. Nil in a default run — the suite
	// decides whether container output is being collected at all.
	Logs *logcapture.Sink
}

Deps are what the engine needs from the suite.

type HTTPProber

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

HTTPProber probes over HTTP with normal TLS certificate and hostname verification.

func NewHTTPProber

func NewHTTPProber(perAttempt time.Duration) *HTTPProber

NewHTTPProber returns a prober with a per-attempt timeout and normal TLS verification.

func (*HTTPProber) Probe

func (p *HTTPProber) Probe(ctx context.Context, url string) (int, error)

Probe implements Prober.

type InstanceKey

type InstanceKey string

InstanceKey identifies one instance of one component within a block.

func KeyFor

func KeyFor(component string, ordinal int) InstanceKey

KeyFor builds the instance key for a component ordinal.

type Network

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

Network is a block's private Docker network.

func NewNetwork

func NewNetwork(ctx context.Context, block string) (*Network, error)

NewNetwork creates a network for a block.

func (*Network) Block

func (n *Network) Block() string

Block is the label of the block that owns this network.

func (*Network) Name

func (n *Network) Name() string

Name is the docker network name, which containers join and which appears in diagnostics.

func (*Network) Remove

func (n *Network) Remove(ctx context.Context) error

Remove tears down the network. It is safe to call repeatedly.

type Options

type Options struct {
	// Network is the block's private network. Required.
	Network *Network

	// Ordinal and Replicas position this instance among its component's replicas.
	Ordinal  int
	Replicas int

	// Env is merged over the definition's static Env. This is where a resolved DSN
	// and any wiring-derived values arrive.
	Env map[string]string

	// ConfigContent is the assembled configuration file. When non-nil it is copied to
	// the definition's ConfigInjection.ContainerPath before start, because the
	// products read configuration once at boot.
	ConfigContent []byte

	// Files are extra host files to copy in, resolved to absolute paths already.
	Files []components.FileMount

	// RepoRoot resolves the relative paths in the definition's Files.
	RepoRoot string

	// StartTimeout overrides defaultStartTimeout.
	StartTimeout time.Duration

	// Arch overrides the detected architecture, for testing image substitution.
	Arch string

	// StableHostPorts publishes endpoints on explicitly selected host ports. It is required
	// for components that may be attached to multiple networks during their lifetime.
	StableHostPorts bool

	// LogWriter, when non-nil, receives this container's stdout/stderr for the whole
	// container lifetime, tagged with the component's name. Nil in a default run — the
	// suite decides whether container output is being collected at all.
	LogWriter *logcapture.Writer

	// SharedLogs, when non-nil, is the run-scoped sink LaunchShared writes a shared
	// component's output to. A shared component outlives every block, so LogWriter — which
	// belongs to one block — is the wrong destination for it.
	SharedLogs *logcapture.Sink
}

Options contains the resolved values used to start one component instance.

type Phase

type Phase int

Phase is one stage of bringing a component up. The phases are ordered and each is a strictly stronger claim than the last.

const (
	// PhaseStarted means the container is running and its declared ports are listening.
	PhaseStarted Phase = iota

	// PhaseHealthy means the component returned its declared ready status.
	PhaseHealthy

	// PhaseSchemaApplied means the component's storage and schema are ready.
	PhaseSchemaApplied
)

func (Phase) String

func (p Phase) String() string

String renders the phase for diagnostics.

type Plan

type Plan struct {
	// Servers is one entry per non-embedded engine used in the block, sorted by type
	// for determinism.
	Servers []Server

	// Stores is every logical database, sorted by ID.
	Stores map[StoreID]*Store

	// Assignments maps each component instance to the store it connects to.
	Assignments map[InstanceKey]StoreID
}

Plan is the resolved storage layout of one block.

func BuildPlan

func BuildPlan(requests []Request) (*Plan, error)

BuildPlan resolves a block's storage requests into a plan.

BuildPlan allocates one store per owning component instance, resolves shared stores, and selects one server per non-embedded engine.

func (*Plan) NeedsServer

func (p *Plan) NeedsServer(t components.DBType) bool

NeedsServer reports whether the block must run a container for this engine.

func (*Plan) Store

func (p *Plan) Store(id StoreID) (*Store, bool)

Store returns a store by ID.

func (*Plan) StoreFor

func (p *Plan) StoreFor(component string, ordinal int) (*Store, bool)

StoreFor returns the store a component instance connects to.

func (*Plan) StoreIDs

func (p *Plan) StoreIDs() []StoreID

StoreIDs returns every store ID, sorted, for deterministic iteration.

type Prober

type Prober interface {
	// Probe returns the observed status, or an error if the attempt could not be made
	// at all (connection refused during warm-up, for instance).
	Probe(ctx context.Context, url string) (int, error)
}

Prober performs one health attempt. Injectable so the gate's timing and classification logic can be tested without containers.

type Provisioned

type Provisioned struct {
	// Servers are the started database containers, keyed by engine, so the block can
	// stop them at teardown.
	Servers map[components.DBType]*Container

	// Env is the environment to merge into each component instance, keyed by instance.
	// Already rendered through each component's own naming convention.
	Env map[InstanceKey]map[string]string

	// Credentials are the block's generated credentials, exposed for diagnostics and
	// for steps that must connect to a store directly.
	Credentials Credentials

	// Plan is the layout that was provisioned.
	Plan *Plan
}

Provisioned is the outcome of provisioning one block's storage: the server containers that were started, and the environment each component instance needs in order to reach its store.

func Provision

func Provision(ctx context.Context, opts DatabaseOptions) (*Provisioned, error)

Provision starts the databases required by a block and returns their component environment.

func (*Provisioned) Stop

func (p *Provisioned) Stop(ctx context.Context) error

Stop tears down every server this provisioning started.

type Request

type Request struct {
	Def      *components.Definition
	Type     components.DBType
	Image    components.ImageRef
	Replicas int
}

Request describes one component's storage need within a block.

type Server

type Server struct {
	// Type is the engine.
	Type components.DBType
	// Image is the selected server image. An empty value uses the runtime default.
	Image components.ImageRef
	// Stores are the logical databases to create on it.
	Stores []StoreID
}

Server is one database container a block must run.

type StepFactory

type StepFactory func(topo *Topology) (StepRegistrar, error)

StepFactory constructs isolated runner step bindings for a running topology.

type StepRegistrar

type StepRegistrar func(sc *godog.ScenarioContext)

StepRegistrar wires a suite's step definitions to its current runner.

type Store

type Store struct {
	ID StoreID

	// Type is the engine backing this store.
	Type components.DBType

	// Database is the generated physical name.
	Database string

	// Owner is the component whose schema this store carries.
	Owner string

	// OwnerOrdinal distinguishes stores when the owner has replicas.
	OwnerOrdinal int

	// Schema is the DDL the framework must apply, in order. Empty when the owner
	// migrates itself or the engine needs no schema.
	Schema []string

	// Embedded is true when the engine lives inside the owning component's container
	// and so needs no server of its own.
	Embedded bool
}

Store is one logical database the framework will provision.

type StoreID

type StoreID string

StoreID identifies one logical database within a block.

func KeyStore

func KeyStore(component string, ordinal int) StoreID

KeyStore is the store ID owned by a component ordinal.

type Topology

type Topology struct {
	// Block is the resolved declaration this came from.
	Block *topology.ResolvedBlock

	// PropagationTimeout bounds asynchronous propagation waits for steps using this topology.
	PropagationTimeout time.Duration

	// Instances are the running components, addressable by name.
	Instances *components.Set

	// Admin are the fixed administrative credentials supplied by the test overlays.
	Admin actor.Credentials

	// Shared is the block's shared scope, already populated.
	Shared *tcontext.Shared

	// Storage is what the database layer provisioned.
	Storage *Provisioned
	// contains filtered or unexported fields
}

Topology is one block's running infrastructure.

func BootBlock

func BootBlock(
	ctx context.Context, block *topology.ResolvedBlock, repoRoot string, logWriter *logcapture.Writer,
	sharedLogs *logcapture.Sink,
) (*Topology, error)

BootBlock starts the block's storage and components in dependency order. logWriter, when non-nil, receives every launched component's stdout/stderr for the block's whole lifetime, into one combined file.

func (*Topology) CollectCoverage

func (t *Topology) CollectCoverage(ctx context.Context, sink *coverage.Sink) error

CollectCoverage stops coverage-enabled services and copies their artifacts to the sink.

func (*Topology) Component

func (t *Topology) Component(name string) (*components.Instance, error)

Component returns a running instance by component name.

func (*Topology) ComponentVersion

func (t *Topology) ComponentVersion(name string) (string, error)

ComponentVersion returns the effective version resolved for a component in this block.

func (*Topology) OpenComponentDB

func (t *Topology) OpenComponentDB(ctx context.Context, component, embeddedService string) (*sql.DB, func() error, error)

OpenComponentDB opens a direct connection to the SQL store a component owns, for a step that must assert on what is actually persisted rather than on what a product API chooses to return.

embeddedService names the compose service holding the store when the engine is embedded (SQLite lives inside the owning application's own container, not a database server this block started) - see Store.Embedded. It is ignored for Postgres/SQLServer, which are reached over the network instead. The caller must call the returned close function when done; for an embedded store this also removes the local copy of the database file made to read it.

func (*Topology) ServiceControl

func (t *Topology) ServiceControl(name string) (*ComposeStack, string, error)

ServiceControl resolves a compose service or component to its controlling stack.

func (*Topology) Teardown

func (t *Topology) Teardown(ctx context.Context) error

Teardown stops all block resources in reverse order.

func (*Topology) URL

func (t *Topology) URL(component, endpoint string) (string, error)

URL returns a named endpoint address on a component.

func (*Topology) URLAt

func (t *Topology) URLAt(component string, ordinal int, endpoint string) (string, error)

URLAt returns an endpoint address on a specific component replica.

Jump to

Keyboard shortcuts

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