Put the fedwiki chain (init, render, farm, caddy) behind a fedwiki compose profile symmetric with discourse's; the default composition is neither, selected via COMPOSE_PROFILES in test/.env, so a default stack no longer binds host 443. Guard every script and walkthrough on service presence: shared skipUnlessIntegrationEndpointReachable helper, seed-stack presence checks (also repairing its unsourced .env and container-native render invocation), generic root-owned testdata reclaim in teardown, discourse coverage in verify-stack-isolation, and fedwiki's 8090 base in the port probe. Update stack docs and finalize status bookkeeping for all three changes; archives the test-stack-integration-profiles change.
137 lines
6.5 KiB
Markdown
137 lines
6.5 KiB
Markdown
# Test Environment
|
|
|
|
This directory contains the Docker Compose setup and test data for local development.
|
|
|
|
> **LLM agents:** read [AGENTS.md](./AGENTS.md) first. All commands below
|
|
> are run from this `test/` directory. If you are working in a git
|
|
> worktree alongside other worktrees of this repo, you must run
|
|
> `./bootstrap-stack.sh` before `docker compose up` to avoid host port
|
|
> collisions. One exception: the FedWiki HTTPS proxy (Caddy on `443`) is a
|
|
> cross-stack singleton among stacks that compose it — see "Running multiple
|
|
> isolated stacks" below.
|
|
|
|
## Quick Start
|
|
|
|
```sh
|
|
cd test
|
|
./bootstrap-stack.sh
|
|
docker compose up -d
|
|
set -a; . .env; set +a
|
|
go run .. start --config mc-config.yaml
|
|
```
|
|
|
|
That composes the **core** stack: Postgres, Valkey, Keycloak, Temporal. Every
|
|
integration (FedWiki, Discourse) sits behind a compose profile and is off by
|
|
default, so the console boots without them.
|
|
|
|
To compose one, set the `COMPOSE_PROFILES` knob — either at bootstrap time:
|
|
|
|
```sh
|
|
COMPOSE_PROFILES=fedwiki ./bootstrap-stack.sh
|
|
```
|
|
|
|
or by editing that one line in the generated `test/.env` and re-running
|
|
`docker compose up -d`. Then uncomment that integration's `MC_*` block in the
|
|
same file so the app is configured for it, not merely running beside it. See
|
|
[`AGENTS.md`](AGENTS.md#which-integrations-the-stack-composes).
|
|
|
|
To run the Go test suite against its own pristine databases (not the app's),
|
|
use `make test` from the repo root. See
|
|
[`AGENTS.md`](AGENTS.md#running-the-go-test-suite).
|
|
|
|
## Running multiple isolated stacks (parallel worktrees)
|
|
|
|
`compose.yaml` accepts per-stack overrides via `.env`. The
|
|
`bootstrap-stack.sh` helper generates one with a deterministic, collision-free
|
|
port allocation derived from the worktree's directory name. Run the four
|
|
Quick Start commands above in worktree A and worktree B — the two stacks
|
|
coexist on disjoint host ports under separate `COMPOSE_PROJECT_NAME`
|
|
namespaces.
|
|
|
|
**Exception — the HTTPS farm is a singleton.** This applies only to stacks that
|
|
select the `fedwiki` profile; core-only stacks never contend for the port.
|
|
Browser access to FedWiki sites goes through a Caddy TLS proxy on host port
|
|
`443` (`wiki-security-social` sets Secure cookies, which browsers only store
|
|
over HTTPS). That port is fixed, not slot-allocated, so only one composing
|
|
stack can serve browser login at a time — a second such stack's `caddy`
|
|
container fails to bind `443` while the rest of its services come up normally.
|
|
A slot-allocated port wouldn't help anyway: better-auth scopes
|
|
cookies to the shared `*.localtest.me` domain (per-domain, not per-port —
|
|
RFC 6265), so parallel stacks would clobber each other's session cookies
|
|
regardless. Everything non-browser stays fully isolated: member-console's farm
|
|
**API** calls use plain HTTP over the slot-allocated `FEDWIKI_PORT` with a bearer
|
|
token (no cookies). True per-stack browser isolation needs a per-stack farm
|
|
domain — tracked in [`status/issues.md`](../status/issues.md).
|
|
|
|
To return a worktree to a clean state (containers + volumes + `.env` +
|
|
`secrets/` + `testdata/`):
|
|
|
|
```sh
|
|
./teardown-stack.sh
|
|
```
|
|
|
|
See [AGENTS.md](./AGENTS.md) for the full contract, including the Stripe
|
|
webhook constraint when running stacks in parallel.
|
|
|
|
## Services
|
|
|
|
URLs below are the single-stack defaults; after `bootstrap-stack.sh` the host
|
|
ports and `*.localhost` hostnames are per-stack (see the generated `.env`).
|
|
|
|
Core services, always composed:
|
|
|
|
| Service | URL | Credentials |
|
|
|---------|-----|-------------|
|
|
| Member Console | http://localhost:8081 | (via Keycloak) |
|
|
| Keycloak | http://keycloak.localhost:8080 | admin / admin |
|
|
| Temporal UI | http://localhost:8233 | (via Keycloak) |
|
|
| PostgreSQL | localhost:5432 | member_console / member_console |
|
|
| Valkey | localhost:6379 | — |
|
|
|
|
Integration services, composed only when their profile is selected:
|
|
|
|
| Service | Profile | URL | Credentials |
|
|
|---------|---------|-----|-------------|
|
|
| FedWiki (browser) | `fedwiki` | https://admin.localtest.me | (via Keycloak) |
|
|
| FedWiki API | `fedwiki` | http://admin.localtest.me | (bearer token, see the MC_FEDWIKI_* block in `.env`) |
|
|
| Discourse | `discourse` | http://discourse.localhost:9292 | (via Keycloak) |
|
|
|
|
> **All credentials above are throwaway test-only values** — never reuse any of them in a real deployment.
|
|
|
|
Browser access to FedWiki is HTTPS via the Caddy proxy (Caddy's internal CA — to
|
|
trust it for manual browsing, export the root once:
|
|
`docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt ./caddy-root.crt`).
|
|
See [AGENTS.md](./AGENTS.md) for the HTTPS/cert details.
|
|
|
|
## Test Data
|
|
|
|
The `testdata/` directory is named like that so that gopls can ignore it by default. It contains sample data for testing the Member Console, such as:
|
|
|
|
### Keycloak
|
|
|
|
Keycloak runs with `start-dev` (an ephemeral H2 database, no persistent volume). It does **not** import a realm file. Instead, the one-shot `keycloak-seed` service runs `seed/keycloak/seed-keycloak.sh` on every `docker compose up`, which — authenticating as the `master`-realm bootstrap admin — creates a dedicated **`test`** app realm and seeds its clients, roles, protocol mappers, client scopes, and test users over the Keycloak admin API (idempotent). App OIDC runs on `test`, not Keycloak's `master` admin realm, so the end-user account console works.
|
|
|
|
Seeded into the `test` realm:
|
|
- **Clients:** member-console, fedwiki, temporal-ui, temporal-authz (plus service accounts)
|
|
- **Users:** alice (operator), bob, carlos, diana — password `password`
|
|
|
|
To change the realm setup, edit `seed/keycloak/seed-keycloak.sh` — there is no realm export/import step. (An old `testdata/keycloak/master-realm.json` export remains on disk for reference but is untracked and unused by compose.)
|
|
|
|
### FedWiki
|
|
|
|
Everything in this section applies only when the `fedwiki` profile is selected.
|
|
|
|
FedWiki runtime data lives in `data/fedwiki/` (gitignored `status/` dirs). Seed data for owner files and access tokens is committed in `seed/fedwiki/`.
|
|
|
|
A `fedwiki-init` container automatically copies seed files into `data/fedwiki/` on `docker compose up` without overwriting existing files (`cp -rn`). This means:
|
|
- **Fresh clone:** seed data is copied in automatically, no manual steps needed.
|
|
- **Existing setup:** your local data is preserved.
|
|
|
|
To update seed data after making changes (e.g., new tokens or wiki sites):
|
|
|
|
```sh
|
|
# Copy the relevant files from data/fedwiki/ to seed/fedwiki/
|
|
cp data/fedwiki/<site>/status/owner.json seed/fedwiki/<site>/status/
|
|
cp data/fedwiki/<site>/status/user-access-tokens.json seed/fedwiki/<site>/status/
|
|
```
|