#!/usr/bin/env bash # Migration Test: Verify alembic upgrade head works on an empty database. # Also verifies alembic downgrade base works. # # Usage: bash scripts/test_migrations.sh [DATABASE_URL] # If DATABASE_URL not provided, uses DATABASE_URL env var. # # Exit codes: # 0 = all migrations pass # 1 = upgrade failed # 2 = downgrade failed # 3 = data integrity check failed set -euo pipefail DB_URL="${1:-${DATABASE_URL:-}}" if [ -z "$DB_URL" ]; then echo "ERROR: DATABASE_URL not set" echo "Usage: bash scripts/test_migrations.sh [DATABASE_URL]" exit 1 fi # Convert asyncpg URL to psycopg2 for alembic (DDL operations) DB_URL_PSYNC="${DB_URL/postgresql+asyncpg/postgresql+psycopg2}" # Create a test database name TEST_DB="leocrm_migration_test_$(date +%s)" DB_BASE="${DB_URL_PSYNC%/*}" echo "=== Migration Test ===" echo "Creating test database: $TEST_DB" # Create test database psql "$DB_BASE/postgres" -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null || true psql "$DB_BASE/postgres" -c "CREATE DATABASE $TEST_DB;" 2>/dev/null TEST_URL="$DB_BASE/$TEST_DB" echo "=== Step 1: Upgrade head on empty DB ===" DATABASE_URL="$TEST_URL" alembic upgrade head 2>&1 if [ $? -ne 0 ]; then echo "❌ Upgrade head failed!" psql "$DB_BASE/postgres" -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null exit 1 fi echo "✅ Upgrade head succeeded" echo "=== Step 2: Verify tables exist ===" TABLE_COUNT=$(psql "$TEST_URL" -t -c "SELECT count(*) FROM information_schema.tables WHERE table_schema = 'public';" 2>/dev/null | xargs) echo "Tables created: $TABLE_COUNT" if [ "$TABLE_COUNT" -lt 50 ]; then echo "❌ Too few tables ($TABLE_COUNT < 50) — migration may be incomplete" psql "$DB_BASE/postgres" -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null exit 3 fi echo "✅ Table count OK ($TABLE_COUNT tables)" echo "=== Step 3: Verify alembic version ===" VERSION=$(psql "$TEST_URL" -t -c "SELECT version_num FROM alembic_version;" 2>/dev/null | xargs) echo "Alembic version: $VERSION" if [ -z "$VERSION" ]; then echo "❌ No alembic version found" psql "$DB_BASE/postgres" -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null exit 3 fi echo "✅ Alembic version OK" echo "=== Step 4: Downgrade base ===" DATABASE_URL="$TEST_URL" alembic downgrade base 2>&1 if [ $? -ne 0 ]; then echo "⚠️ Downgrade base failed (non-critical)" # Don't fail the test — downgrade is not always lossless else echo "✅ Downgrade base succeeded" fi echo "=== Step 5: Re-upgrade head (idempotency) ===" DATABASE_URL="$TEST_URL" alembic upgrade head 2>&1 if [ $? -ne 0 ]; then echo "❌ Re-upgrade head failed!" psql "$DB_BASE/postgres" -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null exit 1 fi echo "✅ Re-upgrade head succeeded" echo "=== Cleanup ===" psql "$DB_BASE/postgres" -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null echo "✅ Test database dropped" echo "" echo "=== All migration tests passed ===" exit 0