testutil

package
v0.1.0 Latest Latest
Warning

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

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

Documentation

Overview

Package testutil provides reusable integration-test fixtures.

The Garage fixture (this file) brings up an ephemeral, single-node Garage S3 server in a container. It is the S3 target used by integration tests across all phases. Garage is pinned to a known-good tag (see GarageImage); as of that version Garage has no S3 Object Lock and no bucket versioning (see decisions.md #8), so tests must not depend on those features.

Index

Constants

View Source
const FixtureRequiredVar = "OPENCLOUD_FIXTURE_REQUIRED"

FixtureRequiredVar turns a skipped OpenCloud test into a failed one. The CI job that brings the fixture up sets it; nothing else should.

View Source
const FixtureWebClientID = "web"

FixtureWebClientID is the OpenCloud web client the extension runs inside; its tokens carry `aud: web` (decisions.md #21).

View Source
const GarageImage = "dxflrs/garage:v2.4.1"

GarageImage is the pinned Garage image. Single-node auto-config (--single-node / --default-bucket) requires >= v2.3.0 (see phase-0 spikes). docker-compose.dev.yml names the same image (internal/buildinfo's TestGarageIsTheSameEverywhere); Renovate bumps both (renovate.json).

Variables

This section is empty.

Functions

func DepsUnder

func DepsUnder(deps map[string]bool, roots ...string) []string

DepsUnder returns, sorted, the import paths in deps that are one of roots or sit below one of them. A root names a package or module path without a trailing slash: "github.com/aws" matches "github.com/aws/smithy-go" but not "github.com/awsome".

func FixtureAccessToken

func FixtureAccessToken(t *testing.T, client *http.Client, base, user, password string) string

FixtureAccessToken logs user in at the fixture's IdP (base, e.g. https://localhost:9200) and returns an access token for the web client. client must trust the fixture's certificate.

func FixtureGap

func FixtureGap(t *testing.T, format string, args ...any)

FixtureGap stops a test that started, reached the fixture, and found it incomplete — a Space that is not there, a file seed.sh did not write. Same rule as OpenCloudEnv: a gap is a skip locally and a failure where the fixture was promised.

func FixtureRequired

func FixtureRequired() bool

FixtureRequired reports whether a missing fixture must fail the run.

func ModuleDeps

func ModuleDeps(t testing.TB, pkg string) []string

ModuleDeps returns, sorted, the modules whose packages a package's binary links, without versions: the module of every package `go list -deps` reports, the standard library excluded (it has no module). The package's own module is included.

A pinned module list notices what a package list is too noisy to watch: a dependency upgrade that brings in a new module, or stops needing one. Like PackageDeps it skips the test without a go toolchain.

func OpenCloudEnv

func OpenCloudEnv(t *testing.T, names ...string) []string

OpenCloudEnv returns the named fixture variables in order, stopping the test if any of them is empty.

addr, id, secret := testutil.OpenCloudEnv(t,
	"CS3_GATEWAY_ADDR", "CS3_SERVICE_ACCOUNT_ID", "CS3_SERVICE_ACCOUNT_SECRET")

func PackageDeps

func PackageDeps(t testing.TB, pkg string) map[string]bool

PackageDeps returns the full transitive dependency set of a package as `go list -deps` reports it: what the package's binary links, test files excluded. pkg is anything `go list` accepts, usually a relative directory.

Tests that audit what a binary is built from use it (the admin tool must not link the decrypt path; the decrypt tool must not link an S3 client). It skips the test when no go toolchain is on PATH, since then the question cannot be asked.

Types

type FakeClock

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

FakeClock is a deterministic clock for tests. It satisfies the Clock interface used across the packages (Now() time.Time) without importing any of them, avoiding an import cycle between testutil and its consumers.

It is safe for concurrent use: background workers read it while tests advance it.

func NewFakeClock

func NewFakeClock(start time.Time) *FakeClock

NewFakeClock returns a FakeClock pinned to start.

func (*FakeClock) Advance

func (c *FakeClock) Advance(d time.Duration)

Advance moves the fake clock forward by d.

func (*FakeClock) Now

func (c *FakeClock) Now() time.Time

Now returns the current fake time.

func (*FakeClock) Set

func (c *FakeClock) Set(t time.Time)

Set pins the fake clock to t.

type Garage

type Garage struct {

	// Endpoint is the S3 API base URL, e.g. http://127.0.0.1:49xxx.
	Endpoint string
	// Region is the region Garage advertises ("garage").
	Region string
	// AccessKeyID / SecretAccessKey are the seeded default S3 credentials.
	AccessKeyID     string
	SecretAccessKey string
	// Bucket is the pre-created default bucket.
	Bucket string
	// contains filtered or unexported fields
}

Garage is a running ephemeral Garage instance and the connection details a path-style SigV4 S3 client needs to talk to it.

func StartGarage

func StartGarage(ctx context.Context, t *testing.T) *Garage

StartGarage brings up a clean, ephemeral Garage container with a default bucket and access key already provisioned. It registers cleanup via t.Cleanup, so callers do not terminate it themselves.

Data lives in the container's /tmp (no volumes), so every StartGarage yields a pristine store. Intended for use behind the `integration` build tag.

func (*Garage) CreateKey

func (g *Garage) CreateKey(ctx context.Context, t *testing.T, name string, grants ...Grant) Key

CreateKey creates a named Garage access key and grants it exactly the given permissions on the fixture's bucket. Passing no grants yields a key with access to nothing, which is a useful control.

func (*Garage) S3Client

func (g *Garage) S3Client(ctx context.Context, t *testing.T) *s3.Client

S3Client returns an AWS SDK v2 S3 client configured for this Garage instance: the seeded owner credentials, the Garage region, the container endpoint, and path-style addressing (Garage does not support virtual-host style by default).

func (*Garage) S3ClientFor

func (g *Garage) S3ClientFor(ctx context.Context, t *testing.T, key Key) *s3.Client

S3ClientFor is S3Client for an arbitrary key, so a test can exercise what a specific set of Garage grants actually permits.

type Grant

type Grant string

Grant is one of Garage's bucket permissions.

Garage has exactly these three and nothing finer (`garage bucket allow --help` on the pinned image). Two consequences drive the credential split in phase 7, and both are asserted by TestGarageGrantMatrix rather than taken from Garage's documentation:

  • GrantOwner is about administering the *bucket* — deleting it, changing its website configuration. It is not what lets a key delete an object; that is GrantWrite. So "the maintenance key is the owner key" buys nothing.
  • There is no grant that permits writing without also permitting deleting, and none that permits writing without reading. So a key that can add a backup can also destroy every backup it can see.
const (
	GrantRead  Grant = "--read"
	GrantWrite Grant = "--write"
	GrantOwner Grant = "--owner"
)

type Key

type Key struct {
	AccessKeyID     string
	SecretAccessKey string
}

Key is one Garage access key pair.

Jump to

Keyboard shortcuts

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