Documentation
¶
Overview ¶
Package runtime manages networks, databases, containers, Compose stacks, readiness, and the lifecycle of resolved test blocks.
Index ¶
- Constants
- func AccessorKey(component, endpoint string) string
- func AwaitHealthy(ctx context.Context, inst *components.Instance, prober Prober) error
- func CloseSharedLogs()
- func EnsureParallelBudget(blocks, maxRunnersPerBlock int) (int, bool)
- func ParallelBudgetNotice(from, to int) string
- func Run(t *testing.T, resolved *topology.Resolved, deps Deps)
- type ComposeStack
- func (c *ComposeStack) CopyFileFromContainer(ctx context.Context, service, path string) ([]byte, error)
- func (c *ComposeStack) CoverageServices() []components.CoverageService
- func (c *ComposeStack) Exec(ctx context.Context, service string, cmd []string) (string, error)
- func (c *ComposeStack) Logs(ctx context.Context) string
- func (c *ComposeStack) PrimaryService() string
- func (c *ComposeStack) RefreshPorts(ctx context.Context) error
- func (c *ComposeStack) RestartService(ctx context.Context, service string) error
- func (c *ComposeStack) ServiceContainerID(ctx context.Context, service string) (string, error)
- func (c *ComposeStack) Services() []string
- func (c *ComposeStack) StageDir() string
- func (c *ComposeStack) StartService(ctx context.Context, service string) error
- func (c *ComposeStack) Stop(ctx context.Context) error
- func (c *ComposeStack) StopService(ctx context.Context, service string) error
- type Container
- func (c *Container) AttachTo(ctx context.Context, nw *Network, alias string) error
- func (c *Container) DetachFrom(ctx context.Context, nw *Network) error
- func (c *Container) Exec(ctx context.Context, cmd []string) (string, error)
- func (c *Container) Logs(ctx context.Context) (string, error)
- func (c *Container) Stop(ctx context.Context) error
- type Credentials
- type DatabaseOptions
- type Deps
- type HTTPProber
- type InstanceKey
- type Network
- type Options
- type Phase
- type Plan
- type Prober
- type Provisioned
- type Request
- type Server
- type StepFactory
- type StepRegistrar
- type Store
- type StoreID
- type Topology
- func (t *Topology) CollectCoverage(ctx context.Context, sink *coverage.Sink) error
- func (t *Topology) Component(name string) (*components.Instance, error)
- func (t *Topology) ComponentVersion(name string) (string, error)
- func (t *Topology) OpenComponentDB(ctx context.Context, component, embeddedService string) (*sql.DB, func() error, error)
- func (t *Topology) ServiceControl(name string) (*ComposeStack, string, error)
- func (t *Topology) Teardown(ctx context.Context) error
- func (t *Topology) URL(component, endpoint string) (string, error)
- func (t *Topology) URLAt(component string, ordinal int, endpoint string) (string, error)
Constants ¶
const ( KeyBlockName = "blockName" KeyAdminUser = "adminUsername" KeyAdminPass = "adminPassword" KeyConsumerUser = "consumerUsername" KeyConsumerPass = "consumerPassword" KeyDeveloperUser = "developerUsername" KeyDeveloperPass = "developerPassword" KeyInstanceSet = "instances" )
Shared-scope keys published by the runtime.
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.
const EnvComposeNetwork = "PG_NETWORK"
EnvComposeNetwork names the block network used by a compose stack.
Variables ¶
This section is empty.
Functions ¶
func AccessorKey ¶
AccessorKey exposes the key format so a step helper can read an accessor.
func AwaitHealthy ¶
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 ¶
EnsureParallelBudget raises the test parallelism budget for nested block and runner tests.
func ParallelBudgetNotice ¶
ParallelBudgetNotice describes an automatic test parallelism adjustment.
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 ¶
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 ¶
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 ¶
AttachTo connects a shared container to a block network under its alias.
func (*Container) DetachFrom ¶
DetachFrom disconnects a shared container from a block network.
type Credentials ¶
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.
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 ¶
NewNetwork creates a network for a block.
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
// 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.
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 ¶
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.
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.
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 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 *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 ¶
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 ¶
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.