Files
missions/docker-compose.test.yml
T
Oleksandr Bezdieniezhnykh 6b2c2d998e [AZ-577] [AZ-578] [AZ-579] [AZ-580] Implement E2E test batch 2
Adds 26 blackbox tests (FT-P-01..18, FT-N-01..08) covering full AC
matrices for Vehicles/Missions/Waypoints/Health/Errors. Three
spec-vs-code carry-forwards documented in batch_02_report.md and
pinned with [Trait("carry_forward", ...)].

Shared scaffolding: ApiDtos.cs, AssertProblemEnvelopeAsync helper,
Seeds.cs, StubSchema.cs, CascadeF3/F4 fixtures, PostgresStopStart
fixture (gated by COMPOSE_RESTART_ENABLED). Removes the 4 placeholder
Sanity.cs files (now superseded). docker-compose.test.yml gains the
expected_results volume mount + FIXTURE_SQL_DIR for the consumer.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 08:28:37 +03:00

148 lines
6.3 KiB
YAML

## Test compose stack for the missions service.
## Naming: post-rename target. Project entrypoint is Azaion.Missions.csproj.
## B5 (namespace), B6 (domain), B7 (drop GPS-Denied), B8 (HTTP routes), B9
## (DB migration), B12 (default-vehicle rule) have all landed locally.
## Cross-repo work pending: B4 (Gitea repo rename + suite .gitmodules + git mv),
## B10 (suite compose service block), B11 (autopilot/ui consumer cutover).
## Documented in _docs/02_document/tests/environment.md.
##
## Post-2026-05-14 drift re-verification: JWT model is ECDSA-SHA256 with JWKS
## fetched from the `admin` service. Tests provide a `jwks-mock` container that
## stands in for `admin` -- it holds a fixed ECDSA P-256 keypair, serves the
## public key as JWKS over HTTPS at `https://jwks-mock/.well-known/jwks.json`,
## and signs test tokens on demand at `https://jwks-mock/sign`. The consumer
## fetches signed tokens from the mock; missions validates them against the
## mock's JWKS. The private key never leaves the mock container.
services:
postgres-test:
image: postgres:16-alpine
container_name: missions-postgres-test
environment:
POSTGRES_DB: azaion
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres-test
ports:
- "5433:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d azaion"]
interval: 1s
timeout: 1s
retries: 30
networks:
- e2e-net
tmpfs:
## Ephemeral PG data; recreated per `docker compose down -v`.
- /var/lib/postgresql/data
jwks-mock:
## Build context populated by Step 6 (Implement Tests). The mock is a tiny
## ASP.NET Core / Python / Node app that:
## - Holds a fixed ECDSA P-256 keypair (in-memory; never exported).
## - Serves `GET /.well-known/jwks.json` over HTTPS with `Cache-Control:
## public, max-age=60` (60s instead of admin's 3600s so tests can observe
## rotation within a single 15-minute CI window).
## - Serves `POST /sign` over HTTPS accepting a claims JSON body and
## returning a signed JWT (ECDSA-SHA256) for test consumption.
## - Supports `POST /rotate-key` to generate a new keypair with a new
## `kid`; the prior public key stays in the JWKS for `OldKeyGraceSeconds`
## to verify the rotation transition (used by NFT-RES-07).
## - Self-signs its TLS certificate; the `missions` container trusts the
## mock's CA via a mounted volume at /etc/ssl/certs/jwks-mock-ca.crt.
## - Image tag: `azaion/jwks-mock:test`. Until built, run-tests.sh prints
## a clear "jwks-mock not yet built" message.
build:
context: tests/Azaion.Missions.JwksMock
dockerfile: Dockerfile
container_name: missions-jwks-mock
environment:
JWT_ISSUER: https://admin-test.azaion.local
JWT_AUDIENCE: azaion-edge
OLD_KEY_GRACE_SECONDS: 5
healthcheck:
test: ["CMD-SHELL", "wget -q --no-check-certificate -O - https://127.0.0.1:8443/.well-known/jwks.json || exit 1"]
interval: 2s
timeout: 1s
retries: 30
networks:
- e2e-net
missions:
build:
context: .
container_name: missions-sut
environment:
DATABASE_URL: postgresql://postgres:postgres-test@postgres-test:5432/azaion
JWT_ISSUER: https://admin-test.azaion.local
JWT_AUDIENCE: azaion-edge
JWT_JWKS_URL: https://jwks-mock:8443/.well-known/jwks.json
## Shorten the JWKS cache so NFT-RES-07 + NFT-SEC-11 can observe rotation
## within the 15-minute CI wall-clock budget. Production leaves both
## unset and inherits the library defaults (12h / 5min).
JWT_JWKS_AUTO_REFRESH_INTERVAL_SECONDS: "30"
JWT_JWKS_REFRESH_INTERVAL_SECONDS: "10"
ASPNETCORE_URLS: http://+:8080
ASPNETCORE_ENVIRONMENT: Test
## CORS: Test environment (NOT Production) -- empty allow-list falls back
## to permissive with a PermissiveDefaultWarning log line (per
## CorsConfigurationValidator). Production-gate scenarios (E9 lock test)
## set ASPNETCORE_ENVIRONMENT=Production and assert startup THROWS.
## The jwks-mock CA cert is mounted so missions can validate the mock's
## TLS cert when fetching JWKS over HTTPS. The container ENTRYPOINT runs
## update-ca-certificates on startup so the mounted CA is trusted by the
## OS bundle that .NET HttpClient reads from.
volumes:
- ./tests/jwks-mock-ca.crt:/usr/local/share/ca-certificates/jwks-mock-ca.crt:ro
ports:
- "5002:8080"
depends_on:
postgres-test:
condition: service_healthy
jwks-mock:
condition: service_healthy
healthcheck:
## Per AC-7.1, /health is anonymous. Container is "healthy" once /health returns 200.
test: ["CMD-SHELL", "wget -q -O - http://127.0.0.1:8080/health || exit 1"]
interval: 2s
timeout: 1s
retries: 30
networks:
- e2e-net
e2e-consumer:
## Build context placeholder -- populated by Step 6 (Implement Tests) when the
## test csproj is created. Until then, run-tests.sh detects the absence and
## prints a clear "test project not yet created" message.
build:
context: tests/Azaion.Missions.E2E.Tests
dockerfile: Dockerfile
container_name: missions-e2e
environment:
MISSIONS_BASE_URL: http://missions:8080
DB_SIDE_CHANNEL: Host=postgres-test;Port=5432;Database=azaion;Username=postgres;Password=postgres-test
## Consumer fetches test tokens from jwks-mock instead of minting locally:
## the private key never leaves the mock container, so tests can't
## accidentally sign with a key that doesn't match the mock's published JWKS.
JWKS_MOCK_SIGN_URL: https://jwks-mock:8443/sign
JWT_ISSUER: https://admin-test.azaion.local
JWT_AUDIENCE: azaion-edge
## Fixtures consumed by FixtureSql.Load (cascade_F3 / F4 in batch 2,
## NFT-* fixtures in subsequent batches). Mounted read-only below.
FIXTURE_SQL_DIR: /app/fixtures
depends_on:
missions:
condition: service_healthy
jwks-mock:
condition: service_healthy
volumes:
- ./test-results:/app/results
- ./tests/jwks-mock-ca.crt:/usr/local/share/ca-certificates/jwks-mock-ca.crt:ro
- ./_docs/00_problem/input_data/expected_results:/app/fixtures:ro
networks:
- e2e-net
profiles:
- test
networks:
e2e-net:
name: missions-e2e-net