#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" COMPOSE_FILE="${ROOT_DIR}/compose.ci.integration.yml" PROJECT_NAME="${COMPOSE_PROJECT_NAME:-plex-int-local}" export DEPLOYABLE_BACKEND_IMAGE="${DEPLOYABLE_BACKEND_IMAGE:-deployable-backend:local}" export DB_PASSWORD="${DB_PASSWORD:-plex_password}" export DB_URL="${DB_URL:-postgresql://plex_user:${DB_PASSWORD}@database:5432/plex_playlist}" cleanup() { docker compose -p "${PROJECT_NAME}" -f "${COMPOSE_FILE}" down -v --remove-orphans >/dev/null 2>&1 || true } trap cleanup EXIT echo "Running runtime integration checks against deployable backend image via compose" echo "DEPLOYABLE_BACKEND_IMAGE=${DEPLOYABLE_BACKEND_IMAGE}" docker compose -p "${PROJECT_NAME}" -f "${COMPOSE_FILE}" up -d database backend fetch_backend_endpoint() { endpoint_path="$1" output_file="$2" probe_tmp="$(mktemp)" if ! docker compose -p "${PROJECT_NAME}" -f "${COMPOSE_FILE}" exec -T backend python -c "$(printf '%s\n' \ 'import sys' \ 'import urllib.error' \ 'import urllib.request' \ 'endpoint_path = sys.argv[1]' \ 'url = f"http://127.0.0.1:8000{endpoint_path}"' \ 'try:' \ ' with urllib.request.urlopen(url, timeout=2) as response:' \ ' body = response.read().decode("utf-8", errors="replace")' \ ' print(response.status)' \ ' print(body)' \ 'except urllib.error.HTTPError as err:' \ ' body = err.read().decode("utf-8", errors="replace")' \ ' print(err.code)' \ ' print(body)' \ 'except Exception:' \ ' print("000")' \ ' print("")' )" "${endpoint_path}" >"${probe_tmp}" 2>/dev/null then : >"${output_file}" rm -f "${probe_tmp}" echo "000" return 0 fi http_code="$(head -n 1 "${probe_tmp}")" tail -n +2 "${probe_tmp}" >"${output_file}" rm -f "${probe_tmp}" echo "${http_code}" } backend_ready=false for i in $(seq 1 40); do backend_running_count="$(docker compose -p "${PROJECT_NAME}" -f "${COMPOSE_FILE}" ps --status running --services backend | wc -l)" if [ "${backend_running_count}" -eq 0 ]; then echo "❌ Backend container exited before becoming healthy" exit 1 fi health_code="$(fetch_backend_endpoint "/health" /tmp/blackbox-health.json)" if [ "${health_code}" = "200" ]; then backend_ready=true break fi sleep 2 done if [ "${backend_ready}" != "true" ]; then echo "❌ Backend did not become healthy" cat /tmp/blackbox-health.json 2>/dev/null || true exit 1 fi root_code="$(fetch_backend_endpoint "/" /tmp/blackbox-root.json)" if [ "${root_code}" != "200" ] || ! grep -q 'Plex Playlist Backend API' /tmp/blackbox-root.json; then echo "❌ Root endpoint validation failed" cat /tmp/blackbox-root.json 2>/dev/null || true exit 1 fi compatibility_code="$(fetch_backend_endpoint "/compatibility" /tmp/blackbox-compatibility.json)" if [ "${compatibility_code}" != "200" ] || ! grep -q '"ok":true' /tmp/blackbox-compatibility.json; then echo "❌ Compatibility endpoint validation failed" cat /tmp/blackbox-compatibility.json 2>/dev/null || true exit 1 fi echo "✅ Runtime integration checks passed"