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
- func DepsUnder(deps map[string]bool, roots ...string) []string
- func FixtureAccessToken(t *testing.T, client *http.Client, base, user, password string) string
- func FixtureGap(t *testing.T, format string, args ...any)
- func FixtureRequired() bool
- func ModuleDeps(t testing.TB, pkg string) []string
- func OpenCloudEnv(t *testing.T, names ...string) []string
- func PackageDeps(t testing.TB, pkg string) map[string]bool
- type FakeClock
- type Garage
- type Grant
- type Key
Constants ¶
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.
const FixtureWebClientID = "web"
FixtureWebClientID is the OpenCloud web client the extension runs inside; its tokens carry `aud: web` (decisions.md #21).
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
NewFakeClock returns a FakeClock pinned to start.
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 ¶
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 ¶
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.
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.