CI ran `cargo test --workspace` with no `--include-ignored`, so it executed 927 tests and skipped 237 — every DB-backed integration test is `#[ignore = "needs DATABASE_URL..."]`, which covers ALL of api.rs, ALL of authz.rs, and the entire CLI journey suite. The isolation and RBAC tests existed but never ran (AUDIT.md F-Q-014, logged and never remediated). CI provides Postgres, so it can run them. Three things had to be right for that to go green: - **`--all-targets`, not a bare workspace run.** `-- --include-ignored` un-ignores not just `#[ignore]` tests but also ` ```ignore ` DOCTESTS, which are illustrative pseudocode that does not compile. `--all-targets` runs lib/bins/ integration tests but excludes doctests (the same reason clippy uses it); a separate `--doc` step runs the doctests without the flag. Structural, so a future pseudocode doctest can't silently break CI either. - **The CLI journeys are their own step.** They spawn a real picloud whose dispatcher/orchestrator claim loops are global by design; run concurrently with the manager-core suites on the shared database they would claim those suites' outbox and workflow rows. Sequential steps keep the live server off the DB while the other suites use it. The step also rebuilds `-p picloud` first (the harness execs the prebuilt binary) and sets the dev-mode env the server needs. - **A higher `max_connections`.** `#[sqlx::test]` pools are lazy, but mass-parallel test startup briefly opens many at once (each test creates its own throwaway database); on a many-core box that transient spike exceeded the default 100 and Postgres answered "sorry, too many clients already". Steady-state peak is only ~26; 500 absorbs the spike with room to spare. Serving the app needs nothing like this many. (This is the local compose ceiling; a small CI runner's default 100 has ample headroom for its lower parallelism.) Also fixes the test the CI gap had let rot: api.rs asserted `v["schema"] == 66` with a hand-bump comment, and since nothing ran it, it sat broken from migration 0066 to 0073. It now asserts `/version` surfaces the live constants (`migrations::latest_version()`, `SDK_VERSION`) — the wiring — while value drift stays caught by schema_snapshot + check-versioning. A constant hand-synced to another constant is a chore, not a test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
89 lines
3.3 KiB
YAML
89 lines
3.3 KiB
YAML
# Default PiCloud stack. Runs the full system end-to-end behind a single
|
|
# Caddy entrypoint, suitable for local development and for verifying that
|
|
# the wiring still works after architectural changes.
|
|
#
|
|
# Caddy is exposed on host port ${PICLOUD_HOST_PORT:-8000} (defaults to
|
|
# 8000 because host port 80 commonly needs sudo on Linux and port 8080 is
|
|
# already in use on this dev machine).
|
|
#
|
|
# For real production deployment, layer the production overrides on top:
|
|
# docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
|
|
|
name: picloud
|
|
|
|
services:
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
# The default ceiling of 100 is not enough to RUN THE TEST SUITE. libtest runs
|
|
# ~nproc tests concurrently, and every `#[sqlx::test]` opens its own pool
|
|
# against its own throwaway database — on a 16-core box that alone exceeds 100,
|
|
# and Postgres answers with "sorry, too many clients already". The DB-backed
|
|
# tests were all `#[ignore]`d and CI never passed `--include-ignored`, so this
|
|
# ceiling was never actually exercised; it surfaced the moment CI started
|
|
# running them. Serving the app needs nothing like this many.
|
|
command: postgres -c max_connections=500
|
|
environment:
|
|
POSTGRES_DB: ${POSTGRES_DB:-picloud}
|
|
POSTGRES_USER: ${POSTGRES_USER:-picloud}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-picloud}
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
ports:
|
|
# Exposed in dev so you can poke at the DB with psql. Configurable
|
|
# because the conventional 5432 is often already in use locally;
|
|
# the prod overlay removes this mapping entirely.
|
|
- "127.0.0.1:${PICLOUD_POSTGRES_HOST_PORT:-15432}:5432"
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-picloud} -d ${POSTGRES_DB:-picloud}"]
|
|
interval: 5s
|
|
timeout: 3s
|
|
retries: 10
|
|
|
|
picloud:
|
|
build:
|
|
context: .
|
|
dockerfile: docker/orchestrator.Dockerfile
|
|
environment:
|
|
PICLOUD_BIND: 0.0.0.0:8080
|
|
DATABASE_URL: postgres://${POSTGRES_USER:-picloud}:${POSTGRES_PASSWORD:-picloud}@postgres:5432/${POSTGRES_DB:-picloud}
|
|
RUST_LOG: ${RUST_LOG:-info}
|
|
PICLOUD_PUBLIC_BASE_URL: ${PICLOUD_PUBLIC_BASE_URL:-http://localhost:8000}
|
|
# Bootstrap admin (Phase 3a). Read once on first start to seed the
|
|
# admin_users table; ignored on subsequent boots if the table is
|
|
# non-empty. No defaults on purpose — leaving these unset in prod
|
|
# is a foot-gun. For dev, .env.example documents sensible values.
|
|
PICLOUD_ADMIN_USERNAME: ${PICLOUD_ADMIN_USERNAME:?set PICLOUD_ADMIN_USERNAME (see .env.example)}
|
|
PICLOUD_ADMIN_PASSWORD: ${PICLOUD_ADMIN_PASSWORD:?set PICLOUD_ADMIN_PASSWORD (see .env.example)}
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
expose:
|
|
- "8080"
|
|
|
|
dashboard:
|
|
build:
|
|
context: ./dashboard
|
|
dockerfile: ../docker/dashboard.Dockerfile
|
|
expose:
|
|
- "80"
|
|
|
|
caddy:
|
|
image: caddy:2-alpine
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${PICLOUD_HOST_PORT:-8000}:80"
|
|
volumes:
|
|
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
|
|
- caddy_data:/data
|
|
- caddy_config:/config
|
|
depends_on:
|
|
picloud:
|
|
condition: service_started
|
|
dashboard:
|
|
condition: service_started
|
|
|
|
volumes:
|
|
postgres_data:
|
|
caddy_data:
|
|
caddy_config:
|