Co-authored-by: Cursor <cursoragent@cursor.com>
6.4 KiB
Test Environment
Platform
Three execution contexts — all use native Docker for the host CPU (no Rosetta / QEMU emulation).
| Context | Host CPU | Docker platform | How tests/builds run |
|---|---|---|---|
| Local dev | Apple Silicon Mac (darwin/arm64, e.g. M1) |
linux/arm64 |
scripts/run-tests.sh sets DOCKER_DEFAULT_PLATFORM=linux/arm64; compose builds follow the host |
| CI unit tests | Woodpecker platform: arm64 agent (colocated Jetson) |
linux/arm64 |
.woodpecker/01-test.yml — dotnet test in sdk image (arm64-only by suite convention) |
| CI image build | Woodpecker platform: arm64 or amd64 agent |
matches agent | .woodpecker/02-build-push.yml matrix — same Dockerfile, tags {branch}-arm / {branch}-amd64 |
Mac M1 rule: do not pin platform: linux/amd64 in compose files or Dockerfiles. That forces Rosetta/QEMU emulation and logs warnings such as The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8).
amd64 agent rule: the remote Woodpecker amd64 agent builds production images natively. Deploy (suite/_infra/deploy/satellite-provider/) pulls ${BRANCH}-amd64 — built only on the amd64 agent, not cross-compiled from arm64.
| Surface | Behavior |
|---|---|
scripts/run-tests.sh |
On darwin/arm64, exports DOCKER_DEFAULT_PLATFORM=linux/arm64 before every docker run / docker compose |
docker-compose.tests.yml |
No platform: override — images match the host (arm64 on Mac, amd64 on an amd64 Linux dev box) |
docker-compose.yml (dev / perf) |
Same — no arch pin |
| API + integration Dockerfiles | Multi-arch sdk:10.0 / aspnet:10.0; build stage installs Debian protobuf-compiler + PROTOBUF_PROTOC=/usr/bin/protoc on arm64 (bundled Grpc.Tools linux_arm64/protoc segfaults; harmless on amd64) |
Suite CI/agent reference: suite/_infra/ci/README.md § Agent pools and § Build-push step.
Infrastructure
| Component | Technology | Configuration |
|---|---|---|
| System Under Test | SatelliteProvider.Api (Docker container) | ASPNETCORE_ENVIRONMENT=Development |
| Database | PostgreSQL 16 (Docker container) | Fresh DB per test run (migrations auto-applied) |
| Test Runner | Custom console app (SatelliteProvider.IntegrationTests) | Docker container on same network |
| Orchestration | docker-compose.tests.yml | Waits for API health before starting tests |
| Perf orchestration | docker-compose.yml + docker-compose.perf.yml | See containerization.md — host port 5433 conflict playbook |
Network Topology
[Test Runner] --HTTP--> [API :8080] --TCP--> [PostgreSQL :5432]
|
+--HTTPS--> [Google Maps] (external, real)
External Dependencies
| Dependency | Strategy | Notes |
|---|---|---|
| Google Maps tile server | Real (live) | Integration tests use real downloads; requires GOOGLE_MAPS_API_KEY |
| PostgreSQL | Real (containerized) | Fresh database each run via migrations |
| File system | Real (Docker volume) | ./tiles, ./ready, ./logs mounted |
Environment Variables
| Variable | Value | Purpose |
|---|---|---|
| API_URL | http://api:8080 | Test runner → API connection |
| ASPNETCORE_ENVIRONMENT | Development | API config mode |
| ConnectionStrings__DefaultConnection | Host=postgres;Port=5432;... | DB connection |
| MapConfig__ApiKey | (from host env) | Google Maps auth |
| GOOGLE_MAPS_API_KEY | (from .env or shell env) |
Google Maps tile downloads (AZ-487 onward — required for any integration mode) |
| JWT_SECRET | (from .env or shell env; ≥ 32 bytes) |
HS256 signing key shared by API + test runner (AZ-487); fail-fast at startup if missing |
| JWT_ISSUER | (from .env or shell env) |
Expected iss claim (AZ-494); fail-fast at startup if missing. DEV-ONLY local value: DEV-ONLY-iss-admin-azaion-local |
| JWT_AUDIENCE | (from .env or shell env) |
Expected aud claim (AZ-494); fail-fast at startup if missing. DEV-ONLY local value: DEV-ONLY-aud-satellite-provider |
| INTEGRATION_TEST_DB_RESET | enabled (default) / skip (set by --keep-state) |
AZ-493 reset hook; enabled truncates test-table rows on runner start, skip preserves them for debugging |
Test Execution
Decision: Docker (no hardware dependencies detected)
Hardware dependencies found: None
Canonical entry point: ./scripts/run-tests.sh (Step 0: format check; Step 1: unit tests; Step 2: integration tests via Compose).
Manual integration command (matches run-tests.sh Step 2):
docker compose -f docker-compose.tests.yml up --build --abort-on-container-exit --exit-code-from integration-tests
docker-compose.tests.yml is self-contained (postgres + api + integration-tests on an internal Docker network). Postgres is not published to the host — intentional when host port 5433 is occupied by a sibling stack.
Performance tests (Step 15 / scripts/run-performance-tests.sh): start the API with the perf overlay when host port 5433 is occupied — docker compose -f docker-compose.yml -f docker-compose.perf.yml up -d --build. Details: containerization.md. PT-10 (DeliverRouteTiles gRPC stream) runs via dotnet SatelliteProvider.IntegrationTests --run-pt10 inside the script; host-side default API_URL=https://localhost:18980 with TLS trust via ./certs/api.crt (PERF_CA_CERT override). Harness knobs:
| Variable | Default | Purpose |
|---|---|---|
PERF_REPEAT_COUNT |
20 | Cold iterations for PT-07/PT-08/PT-10 distribution |
PERF_UAV_BATCH_SIZE |
10 | Items per PT-08 upload batch |
PERF_PT10_SLOW_MS |
50 | Delay between gRPC stream events on the slow-consumer sub-check (PT-10) |
PERF_JWT_TOKEN |
(minted in-script) | Pre-minted Bearer token; skips --mint-only when set |
PERF_CA_CERT |
$PROJECT_ROOT/certs/api.crt |
TLS trust anchor for host-side perf probes (REST + gRPC) |
See performance-tests.md § PT-10 for pass thresholds.
| Property | Value |
|---|---|
| Execution mode | Sequential (one test at a time) |
| Timeout per test | 15 minutes (HttpClient timeout) |
| Polling interval | 2–3 seconds |
| Max poll attempts | 120–360 (depends on test) |
| Startup wait | 30 retries × 2s = 60s max |