Files
2026-05-07 00:58:53 +03:00

107 lines
4.5 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.
# integration
End-to-end test suite for the Galaxy platform. The suite drives `gateway`
from outside and verifies behaviour at the public boundary while
`backend` and `galaxy/game` run as Docker containers managed by the
test process via `testcontainers-go`.
For cross-cutting testing principles (unit vs integration boundaries,
why testcontainers tests pin no-op observability providers, why
infrastructure failures in this suite fail loudly instead of skipping)
see [`docs/TESTING.md`](../docs/TESTING.md). This README focuses on
the integration-specific runbook: prerequisites, entry points,
labels, and per-test fixtures.
## Prerequisites
- A reachable Docker daemon (`DOCKER_HOST` or the local socket).
- Go toolchain matching the workspace `go.work` directive.
- Network access for the first run (`postgres:16-alpine`,
`axllent/mailpit`, `redis:7-alpine` images are pulled). Subsequent
runs reuse the local image cache.
## Run
The recommended entry points are the Makefile targets:
```bash
make -C integration preclean # idempotent leftover cleanup
make -C integration integration # preclean + serial test run
make -C integration integration-step # preclean + one-test-at-a-time
```
`preclean` removes stale containers and locally-built images from
earlier runs; it never touches testcontainers-pulled service images
(`postgres:16-alpine`, `axllent/mailpit`, `redis:7-alpine`,
`testcontainers/ryuk`), so the cache stays warm. The cleanup keys
off labels:
- `org.testcontainers=true` — every container/network created by
`testcontainers-go` (our backend/gateway/game and the postgres /
redis / mailpit / ryuk service containers).
- `galaxy.backend=1` — engine instances spawned by backend's runtime
adapter directly on the host Docker daemon (see
`backend/internal/dockerclient/types.go`).
- `galaxy.test.kind=integration-image` — local builds of
`galaxy/{backend,gateway,game}:integration` produced by
`testenv/images.go`.
`integration` runs every test in the module sequentially
(`-p=1 -parallel=1`) — recommended default on a slow / shared Docker.
`integration-step` runs them one at a time with a fresh preclean
before each test and stops on the first failure; useful to isolate a
flake or build up to a full pass without losing context to subsequent
tests.
Direct `go test ./integration/...` still works but does not pre-clean
or serialise the suite; use it only on a hand-cleaned Docker.
The suite builds three Docker images on demand from the workspace
sources:
- `galaxy/backend:integration` (`backend/Dockerfile`),
- `galaxy/gateway:integration` (`gateway/Dockerfile`),
- `galaxy/game:integration` (`game/Dockerfile`).
Each image is built once per `go test` invocation, guarded by a
`sync.Once` inside `testenv`, and stamped with the
`galaxy.test.kind=integration-image` label so `preclean` can wipe it
on the next run. The first cold run is slow (~23 min on a
developer machine); subsequent runs reuse the layer cache.
## Skipping
Tests skip with a clear message when the Docker daemon is unreachable.
Subsuites that require a live engine container (`lobby_flow_test.go`)
also skip when the `galaxy/game` image cannot be built.
## Layout
- `testenv/` — fixtures: Postgres, Redis, mailpit, GeoLite2 mmdb,
image builders, backend/gateway runners, signed gRPC client (built
on top of the public `galaxy/gateway/authn` package, no duplicated
canonical-bytes code), mailpit HTTP client, `EnrollPilots` helper
for runtime-driven scenarios that need ≥10 members, platform
bootstrap.
- `*_test.go` — one file per cross-service scenario.
The runtime-driven tests (`runtime_lifecycle_test.go`,
`engine_command_proxy_test.go`) honour the engine's production
contract `len(races) >= 10`: each registers ten extra pilots with
synthetic `Player01..Player10` race names and matching emails, has
the owner invite each one, and has each pilot redeem the invite
before admin force-start. Cold runs add ~30 s for the ten extra
mailpit round-trips on top of the engine image build.
## Determinism
- Each test calls `Bootstrap(t)` to spin up a dedicated Postgres,
Redis, mailpit, backend and gateway. Cross-test contamination is not
possible.
- Tests do not call `t.Parallel()`. Docker resource pressure makes
parallel suites flaky on commodity hardware.
- Gateway anti-abuse and body-size limits are loosened for the bulk of
scenarios (so legitimate flows are not rate-limited mid-test) and
intentionally tightened in `gateway_edge_test.go` so each protective
mechanism can be observed firing.