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

cleanup

package
v0.4.0 Latest Latest
Warning

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

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

Documentation

Overview

Package cleanup tracks resources created by a test runner and removes them during scenario and runner teardown.

A Resource records its Kind, ID, and creating Actor. Deleters receive that actor information and are responsible for using the correct principal when removing the resource. A missing actor or resource ID is rejected at registration time.

Resources are deleted in ascending Kind.Order. Resources of the same kind are deleted in reverse registration order; different kinds with the same order are deterministic by kind name. Registering the same kind and ID more than once is idempotent and emits a warning. A resource deleted explicitly by a test should be removed with Deregister so teardown does not attempt it again.

Sweep is best effort: it attempts every pending resource, joins deletion errors, and logs failures with structured resource and attempt information. Retries are disabled by default. A suite can opt in through its YAML configuration:

defaults:

cleanup:
  max-attempts: 3

The value is the total number of attempts for one resource. Failed resources are requeued until that limit is reached; after the final failure they are removed from the active queue and the failure is returned. This prevents an endlessly failing deleter from creating an infinite teardown loop. Timestamps and retry state are included by slog's structured log output, including duplicate-registration and requeue-collision warnings.

A Registry is installed in the runner context with Install. Register and Sweep use that context integration. Register records a scenario-scoped resource, while RegisterRunner records a runner-scoped resource. The engine sweeps the two scopes independently after each scenario and when the runner finishes. A missing registry is a wiring error; an invalid or nil registry cannot be installed.

To add a resource type, define a Kind with an appropriate cleanup order, register each successfully created resource, and register a non-nil Deleter for the kind. The deleter may use any protocol required by that resource; cleanup does not assume every resource has a bearer-token REST delete endpoint.

Index

Constants

This section is empty.

Variables

View Source
var (
	KindSubscription = Kind{Name: "subscription", Order: 10}
	KindApplication  = Kind{Name: "application", Order: 20}
	KindAPIKey       = Kind{Name: "api-key", Order: 30}
	KindAPIProduct   = Kind{Name: "api-product", Order: 40}
	KindAPI          = Kind{Name: "api", Order: 50}
	// gateway-controller's own Mcp resource (the "/mcp-proxies" collection), distinct from
	// KindMCPServer below (platform-api's separate MCP server registration).
	KindMCPProxy = Kind{Name: "mcp-proxy", Order: 52}
	// gateway-controller's own Agent resource (the "/agents" collection). It deletes before the
	// control plane's imported AgentProxy copy, which platform-api only lets go once the
	// gateway has reported the Agent undeployed. Like an API it can name certificates, so it
	// also deletes before them.
	KindAgent      = Kind{Name: "agent", Order: 52}
	KindGraphQLAPI = Kind{Name: "graphql-api", Order: 53}
	KindMCPServer  = Kind{Name: "mcp-server", Order: 55}
	// An Agent proxy can hold its upstream credential as a {{ secret "handle" }}
	// placeholder, so it deletes before KindSecret.
	KindAgentProxy = Kind{Name: "agent-proxy", Order: 56}
	// A gateway subscription plan is referenced by its subscriptions and, by name, by the APIs
	// that enable it, so it deletes after both.
	KindSubscriptionPlan = Kind{Name: "subscription-plan", Order: 57}
	KindPolicy           = Kind{Name: "policy", Order: 60}
	KindSharedScope      = Kind{Name: "shared-scope", Order: 70}
	KindCertificate      = Kind{Name: "certificate", Order: 80}
	// LLMProxy and LLMProvider both delete before Secret: either can hold a credential as a
	// {{ secret "handle" }} placeholder, and platform-api refuses to delete a secret still
	// referenced by one (409 SECRET_IN_USE). LLMProxy also deletes before LLMProvider, since
	// a proxy references its own provider by id.
	KindLLMProxy    = Kind{Name: "llm-proxy", Order: 82}
	KindLLMProvider = Kind{Name: "llm-provider", Order: 84}
	KindSecret      = Kind{Name: "secret", Order: 85}
	// A provider references its template version by id, so the template version deletes
	// after every provider that could reference it.
	KindLLMProviderTemplate = Kind{Name: "llm-provider-template", Order: 86}
	// A provider or proxy deployment references its gateway by id, so gateway deletes after
	// both.
	KindGateway     = Kind{Name: "gateway", Order: 88}
	KindEnvironment = Kind{Name: "environment", Order: 95}
	KindProject     = Kind{Name: "project", Order: 100}
)

Resource kinds ordered from earliest to latest cleanup.

Functions

func Install

func Install(ctx context.Context, r *Registry) error

Install attaches a registry to a runner context.

func Register

func Register(ctx context.Context, res Resource) error

Register records a resource using the registry in the context.

func RegisterRunner

func RegisterRunner(ctx context.Context, res Resource) error

RegisterRunner records a runner-scoped resource using the registry in the context.

func Sweep

func Sweep(ctx context.Context) error

Sweep runs the cleanup sweep for the registry in the context.

func SweepRunner

func SweepRunner(ctx context.Context) error

SweepRunner runs the runner-scoped cleanup sweep for the registry in the context.

Types

type Deleter

type Deleter func(ctx context.Context, res Resource) error

Deleter removes one resource as the actor that created it.

type Kind

type Kind struct {
	// Name identifies the kind in diagnostics.
	Name string
	// Order is ascending: lower is deleted FIRST. A resource that references another must
	// have a lower order than the thing it references.
	Order int
}

Kind identifies a resource type and its cleanup order.

type Registry

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

Registry tracks resources created by one test runner.

func NewRegistry

func NewRegistry(log *slog.Logger, maxAttempts ...int) *Registry

NewRegistry returns an empty registry. maxAttempts is optional; zero disables retries.

func Of

func Of(ctx context.Context) (*Registry, error)

Of returns the registry attached to a runner context.

func (*Registry) Count

func (r *Registry) Count() int

Count returns the number of registered resources.

func (*Registry) Deregister

func (r *Registry) Deregister(kind Kind, id string)

Deregister removes a resource that was deleted by the test.

func (*Registry) Pending

func (r *Registry) Pending() []Resource

Pending returns registered resources in cleanup order.

func (*Registry) Register

func (r *Registry) Register(res Resource) error

Register records a resource for cleanup.

func (*Registry) RegisterDeleter

func (r *Registry) RegisterDeleter(kind Kind, deleter Deleter) error

RegisterDeleter registers the function used to remove a resource kind.

func (*Registry) RegisterRunner

func (r *Registry) RegisterRunner(res Resource) error

RegisterRunner records a resource until the runner completes.

func (*Registry) RegisterScoped

func (r *Registry) RegisterScoped(scope Scope, res Resource) error

RegisterScoped records a resource for the selected lifecycle scope.

func (*Registry) Sweep

func (r *Registry) Sweep(ctx context.Context) error

Sweep deletes scenario-scoped resources and clears their registrations.

func (*Registry) SweepRunner

func (r *Registry) SweepRunner(ctx context.Context) error

SweepRunner deletes runner-scoped resources and clears their registrations.

type Resource

type Resource struct {
	Kind Kind
	ID   string

	// Actor is the reference of the principal that created this. Required.
	Actor string

	// Description is optional context for a leak warning — a name, a tenant.
	Description string
	// contains filtered or unexported fields
}

Resource describes a created resource and its creator.

func (Resource) String

func (r Resource) String() string

String renders the resource for a leak or cleanup-failure diagnostic.

type Scope

type Scope uint8

Scope determines how long a registered resource is retained.

const (
	// ScenarioScope retains a resource until the current scenario is swept.
	ScenarioScope Scope = iota
	// RunnerScope retains a resource until the owning runner is swept.
	RunnerScope
)

Jump to

Keyboard shortcuts

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