#!/usr/bin/env bash # Manages the persistent shared Postgres that the whole test suite points at via # CM_TEST_DATABASE_URL (wired up in .cargo/config.toml). One long-lived server # means cm-testkit takes its `_container: None` branch and NEVER starts a # per-test testcontainer — so a killed/panicking/orphaned `cargo test` has no # container to leak. `--restart unless-stopped` keeps it up across Docker # restarts so direct `cargo test` always has a server to connect to. # # Usage: scripts/test-server.sh {up|down|status|clean} # up start the server if not already running (idempotent) # down remove the server # status show its state # clean drop leftover test_ databases (reclaim space without a restart) set -euo pipefail CONTAINER="${CM_TEST_PG_CONTAINER:-clawmates-test-pg}" PORT="${CM_TEST_PG_PORT:-54331}" case "${1:-up}" in up) if docker ps --format '{{.Names}}' | grep -qx "$CONTAINER"; then echo "$CONTAINER already up on :$PORT" exit 0 fi docker rm -f "$CONTAINER" >/dev/null 2>&1 || true # --shm-size: Docker defaults /dev/shm to 64MB. Postgres allocates parallel # query segments there, and the suite runs many tests at once against many # databases, so the default is exhausted mid-run — surfacing as # `could not resize shared memory segment ... No space left on device` # during MIGRATIONS, which reads like a schema fault and is not one. # # Space exhaustion has a second cause with the same symptom: cm-testkit # creates a database per test and drops none, so they accumulate across # runs (779 of them, once). `$0 clean` sweeps those. docker run -d --name "$CONTAINER" --restart unless-stopped \ --shm-size=1g \ -e POSTGRES_PASSWORD=postgres \ -e POSTGRES_DB=postgres \ -p "${PORT}:5432" \ postgres:16-alpine \ -c fsync=off -c full_page_writes=off -c max_connections=300 >/dev/null until docker exec "$CONTAINER" pg_isready -U postgres -q >/dev/null 2>&1; do sleep 0.5 done echo "$CONTAINER up on :$PORT" ;; down) docker rm -f "$CONTAINER" >/dev/null 2>&1 || true echo "$CONTAINER removed" ;; status) docker ps -a --filter "name=^/${CONTAINER}$" \ --format '{{.Names}} | {{.Status}} | {{.Ports}}' || true ;; clean) # Drop every transient test database to reclaim space (cm-testkit creates # test_ per test and does not drop them). Safe to run anytime. docker exec "$CONTAINER" psql -U postgres -tAc \ "SELECT datname FROM pg_database WHERE datname LIKE 'test\_%'" \ | while IFS= read -r db; do [ -n "$db" ] && docker exec "$CONTAINER" dropdb -U postgres --force "$db" || true done echo "dropped leftover test_* databases" ;; *) echo "usage: $0 {up|down|status|clean}" >&2 exit 2 ;; esac