Files
2026-05-27 23:29:53 +01:00

89 lines
4.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## ADDED Requirements
### Requirement: Garage v2 image policy
The `@suaveplan/testing-integration-garage-s3` plugin SHALL pin to `dxflrs/garage:v2.0.0` (name + minor version). A follow-up operational change tracked at `docs/superpowers/specs/2026-04-25-test-suite-audit.md §5` will pin to `sha256:<digest>`.
#### Scenario: Image tag pinned
- **WHEN** the container factory is invoked without injection
- **THEN** the resulting container uses image `dxflrs/garage:v2.0.0`
### Requirement: Dual-port exposure
The fixture SHALL expose two TCP ports from the container: the S3 API port on container port `3900` and the admin port on container port `3902`. Both MUST be mapped to host ports and recorded in `config.s3Endpoint` and `config.adminEndpoint`.
#### Scenario: Both endpoints recorded
- **WHEN** the container has started
- **THEN** `config.s3Endpoint` and `config.adminEndpoint` are populated with reachable host URLs
### Requirement: Env-bridge contract
The plugin SHALL declare and forward exactly four environment variables: `GARAGE_S3_ENDPOINT`, `GARAGE_S3_ACCESS_KEY_ID`, `GARAGE_S3_SECRET_ACCESS_KEY`, `GARAGE_S3_BUCKET`. When ALL four are set on the parent process at construction time, the fixture MUST enter env-bridge passthrough mode.
#### Scenario: env() returns the full four-key set
- **WHEN** the fixture has started
- **THEN** `fixture.env()` returns a record with exactly the four declared keys
### Requirement: Seven-step initialisation sequence
In container mode `start()` SHALL execute the following sequence against the admin port, in order, before declaring the fixture healthy:
1. `status` — read cluster status to discover the node id
2. `layout assign` — assign capacity to the discovered node
3. `layout apply` — commit the layout version
4. `bucket create` — create the configured bucket
5. `key create` — create an access/secret key pair
6. `bucket allow` — grant the key full permissions on the bucket
7. `key info` — read back the key to confirm and capture the secret
Any step failure MUST abort the sequence and reject `start()` with a coded error naming the failing step.
#### Scenario: Successful seven-step init
- **WHEN** `start()` is invoked against a fresh container
- **THEN** all seven admin operations execute in the order above before `start()` resolves
#### Scenario: Layout-apply failure aborts
- **WHEN** the third step (`layout apply`) fails
- **THEN** `start()` rejects with `code === "INTEGRATION.GARAGE_S3.LAYOUT_APPLY_FAILED"` AND steps 4–7 are not attempted
### Requirement: Healthcheck contract — admin port
`isHealthy()` SHALL probe the admin port (3902) with an HTTP request and resolve `true` only when the admin endpoint responds. The S3 port (3900) alone is NOT sufficient evidence of health.
#### Scenario: Admin port is the source of truth
- **WHEN** the S3 port is open but the admin port has not yet started
- **THEN** `isHealthy()` resolves `false`
### Requirement: Configurable timeouts
The fixture options SHALL accept `healthIntervalMs?: number` and `healthTimeoutMs?: number` overrides forwarded to `HealthPoller`. Defaults follow `HealthPoller`'s defaults (500 ms / 120 s).
#### Scenario: Override applied
- **WHEN** the fixture is constructed with `{ healthTimeoutMs: 30000 }`
- **THEN** `HealthPoller` rejects after 30 s when the container never becomes healthy
### Requirement: Injectable factories
The fixture constructor SHALL accept optional `containerFactory`, `execFn`, and `fetchFn` parameters for the container, admin-CLI exec, and admin-port HTTP calls respectively. Defaults invoke testcontainers, the container's exec API, and the global `fetch`.
#### Scenario: Injected execFn drives the seven-step sequence
- **WHEN** `execFn` is replaced with a stub that records every command
- **THEN** the recorded commands match the seven-step order
### Requirement: Error-code prefix
Errors thrown from the plugin SHALL carry codes matching `^INTEGRATION\.GARAGE_S3\.[A-Z_]+$`. At minimum the package SHALL define: `START_FAILED`, `STOP_FAILED`, `STATUS_FAILED`, `LAYOUT_ASSIGN_FAILED`, `LAYOUT_APPLY_FAILED`, `BUCKET_CREATE_FAILED`, `KEY_CREATE_FAILED`, `BUCKET_ALLOW_FAILED`, `KEY_INFO_FAILED`.
#### Scenario: Each step has its own coded error
- **WHEN** `bucket create` fails
- **THEN** the rejection's `code === "INTEGRATION.GARAGE_S3.BUCKET_CREATE_FAILED"` AND `context.step === "bucket-create"`