Initial Commit
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
## 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"`
|
||||
Reference in New Issue
Block a user