#!/bin/bash set -euo pipefail MODE="${1:-}" if [ -z "$MODE" ] || { [ "$MODE" != "demo" ] && [ "$MODE" != "prod" ] && [ "$MODE" != "production" ]; }; then echo "Usage: ./scripts/smoke-test.sh " >&2 exit 2 fi if [ "$MODE" = "production" ]; then MODE="prod" fi if ! command -v curl >/dev/null 2>&1; then echo "curl is required" >&2 exit 1 fi if ! command -v podman >/dev/null 2>&1; then echo "podman is required" >&2 exit 1 fi ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" if [ "$MODE" = "demo" ]; then ENV_FILE="$ROOT_DIR/compose/.env.demo" BACKEND_CONTAINER="likwid-demo-backend" FRONTEND_CONTAINER="likwid-demo-frontend" DB_CONTAINER="likwid-demo-db" else ENV_FILE="$ROOT_DIR/compose/.env.production" BACKEND_CONTAINER="likwid-prod-backend" FRONTEND_CONTAINER="likwid-prod-frontend" DB_CONTAINER="likwid-prod-db" fi if [ ! -f "$ENV_FILE" ]; then echo "Missing env file: $ENV_FILE" >&2 exit 1 fi set -a # shellcheck disable=SC1090 source <(sed 's/\r$//' "$ENV_FILE") set +a BACKEND_PORT="${BACKEND_PORT:-3000}" FRONTEND_PORT="${FRONTEND_PORT:-4321}" POSTGRES_USER="${POSTGRES_USER:-likwid}" POSTGRES_DB="${POSTGRES_DB:-likwid_prod}" if [ "$MODE" = "demo" ]; then BACKEND_PORT="${BACKEND_PORT:-3001}" FRONTEND_PORT="${FRONTEND_PORT:-4322}" POSTGRES_USER="${POSTGRES_USER:-likwid_demo}" POSTGRES_DB="${POSTGRES_DB:-likwid_demo}" fi BACKEND_HEALTH_URL="http://127.0.0.1:${BACKEND_PORT}/health" FRONTEND_URL="http://127.0.0.1:${FRONTEND_PORT}/" fail() { echo "FAIL: $1" >&2 exit 1 } ok() { echo "OK: $1" } echo "=== Likwid smoke test ($MODE) ===" echo "[1/4] Containers present" podman container exists "$BACKEND_CONTAINER" || fail "Missing container: $BACKEND_CONTAINER" podman container exists "$FRONTEND_CONTAINER" || fail "Missing container: $FRONTEND_CONTAINER" podman container exists "$DB_CONTAINER" || fail "Missing container: $DB_CONTAINER" backend_running="$(podman inspect -f '{{.State.Running}}' "$BACKEND_CONTAINER" 2>/dev/null || true)" frontend_running="$(podman inspect -f '{{.State.Running}}' "$FRONTEND_CONTAINER" 2>/dev/null || true)" db_running="$(podman inspect -f '{{.State.Running}}' "$DB_CONTAINER" 2>/dev/null || true)" [ "$backend_running" = "true" ] || fail "$BACKEND_CONTAINER is not running" [ "$frontend_running" = "true" ] || fail "$FRONTEND_CONTAINER is not running" [ "$db_running" = "true" ] || fail "$DB_CONTAINER is not running" ok "containers running" echo "[2/4] Backend health: $BACKEND_HEALTH_URL" health_json="$(curl -fsS "$BACKEND_HEALTH_URL")" || fail "backend health check failed" echo "$health_json" ok "backend /health" echo "[3/4] Frontend reachable: $FRONTEND_URL" http_code="$(curl -fsS -o /dev/null -w "%{http_code}" "$FRONTEND_URL" || true)" case "$http_code" in 2*|3*) ok "frontend HTTP $http_code";; *) fail "frontend not reachable (HTTP $http_code)";; esac echo "[4/4] Database reachable + migrations" podman exec "$DB_CONTAINER" pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB" >/dev/null || fail "pg_isready failed" migration_table_check="$(podman exec "$DB_CONTAINER" psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -tAc "SELECT to_regclass('_sqlx_migrations');" | tr -d '[:space:]')" if [ "$migration_table_check" != "_sqlx_migrations" ]; then fail "_sqlx_migrations table not found" fi failed_count="$(podman exec "$DB_CONTAINER" psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -tAc "SELECT COUNT(*) FROM _sqlx_migrations WHERE success = false;" | tr -d '[:space:]')" if [ "$failed_count" != "0" ]; then fail "found failed migrations: $failed_count" fi installed_count="$(podman exec "$DB_CONTAINER" psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -tAc "SELECT COUNT(*) FROM _sqlx_migrations;" | tr -d '[:space:]')" if [ -z "$installed_count" ] || [ "$installed_count" -lt 1 ]; then fail "no migrations recorded" fi ok "db reachable, migrations applied ($installed_count)" echo "=== Smoke test passed ==="