Files
play-life/play-life-backend/test_baseline.sh
2026-02-08 17:01:36 +03:00

348 lines
14 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Скрипт для тестирования baseline миграции на чистой БД
# Создает тестовую БД, применяет baseline, и сравнивает схему с production
set -e
# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Получаем переменные окружения
DB_HOST=${DB_HOST:-localhost}
DB_PORT=${DB_PORT:-5432}
DB_USER=${DB_USER:-playeng}
DB_PASSWORD=${DB_PASSWORD:-playeng}
DB_NAME=${DB_NAME:-playeng}
TEST_DB_NAME="playeng_baseline_test_$$"
MIGRATIONS_PATH="migrations"
TMP_DIR=$(mktemp -d)
echo "=== Тестирование baseline миграции на чистой БД ==="
echo ""
# Добавляем ~/go/bin в PATH если migrate не найден
if ! command -v migrate &> /dev/null; then
export PATH="$HOME/go/bin:$PATH"
fi
# Проверяем наличие необходимых инструментов
if ! command -v migrate &> /dev/null; then
echo -e "${RED}Ошибка: migrate не найден. Установите golang-migrate:${NC}"
echo " brew install golang-migrate"
echo " или"
echo " go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest"
exit 1
fi
# Определяем способ выполнения PostgreSQL команд
PG_DUMP_CMD=""
PG_PSQL_CMD=""
POSTGRES_CONTAINER=""
if command -v pg_dump &> /dev/null; then
PG_DUMP_CMD="pg_dump"
PG_PSQL_CMD="psql"
else
# Пытаемся найти PostgreSQL контейнер
if command -v docker &> /dev/null; then
POSTGRES_CONTAINER=$(docker ps --format "{{.Names}}" 2>/dev/null | grep -iE "(postgres|db)" | head -1)
if [ -n "$POSTGRES_CONTAINER" ]; then
PG_DUMP_CMD="docker exec $POSTGRES_CONTAINER pg_dump"
PG_PSQL_CMD="docker exec -i $POSTGRES_CONTAINER psql"
echo -e "${BLUE}Используется PostgreSQL из Docker контейнера: $POSTGRES_CONTAINER${NC}"
fi
fi
fi
HAS_PG_DUMP=false
if [ -n "$PG_DUMP_CMD" ]; then
HAS_PG_DUMP=true
else
echo -e "${YELLOW}Предупреждение: pg_dump не найден. Сравнение схем будет пропущено.${NC}"
echo " Для полного тестирования установите PostgreSQL client tools"
fi
# Проверяем наличие директории миграций
if [ ! -d "$MIGRATIONS_PATH" ]; then
echo -e "${RED}Ошибка: Директория миграций не найдена: $MIGRATIONS_PATH${NC}"
exit 1
fi
# Проверяем наличие baseline миграции
if [ ! -f "$MIGRATIONS_PATH/000001_baseline.up.sql" ]; then
echo -e "${RED}Ошибка: Baseline миграция не найдена: $MIGRATIONS_PATH/000001_baseline.up.sql${NC}"
exit 1
fi
echo "Параметры подключения:"
echo " Host: $DB_HOST"
echo " Port: $DB_PORT"
echo " User: $DB_USER"
echo " Test DB: $TEST_DB_NAME"
echo ""
# Проверяем подключение к БД
echo "1. Проверка подключения к БД..."
if [ -n "$POSTGRES_CONTAINER" ]; then
# Используем Docker
echo "SELECT 1;" | $PG_PSQL_CMD -U $DB_USER -d postgres > /dev/null 2>&1
elif [ -n "$PG_PSQL_CMD" ]; then
# Используем локальный psql
PGPASSWORD=$DB_PASSWORD $PG_PSQL_CMD \
-h $DB_HOST \
-p $DB_PORT \
-U $DB_USER \
-d postgres \
-c "SELECT 1;" > /dev/null 2>&1
else
# Пытаемся через стандартный psql
PGPASSWORD=$DB_PASSWORD psql \
-h $DB_HOST \
-p $DB_PORT \
-U $DB_USER \
-d postgres \
-c "SELECT 1;" > /dev/null 2>&1
fi
if [ $? -ne 0 ]; then
echo -e "${RED}Ошибка: Не удалось подключиться к БД${NC}"
exit 1
fi
echo -e "${GREEN}✓ Подключение успешно${NC}"
echo ""
# Создаем тестовую БД
echo "2. Создание тестовой БД..."
if [ -n "$POSTGRES_CONTAINER" ]; then
echo "CREATE DATABASE $TEST_DB_NAME;" | $PG_PSQL_CMD -U $DB_USER -d postgres > /dev/null 2>&1
elif [ -n "$PG_PSQL_CMD" ]; then
PGPASSWORD=$DB_PASSWORD $PG_PSQL_CMD \
-h $DB_HOST \
-p $DB_PORT \
-U $DB_USER \
-d postgres \
-c "CREATE DATABASE $TEST_DB_NAME;" > /dev/null 2>&1
else
PGPASSWORD=$DB_PASSWORD psql \
-h $DB_HOST \
-p $DB_PORT \
-U $DB_USER \
-d postgres \
-c "CREATE DATABASE $TEST_DB_NAME;" > /dev/null 2>&1
fi
if [ $? -ne 0 ]; then
echo -e "${RED}Ошибка: Не удалось создать тестовую БД${NC}"
exit 1
fi
echo -e "${GREEN}✓ Тестовая БД создана: $TEST_DB_NAME${NC}"
echo ""
# Ждем немного, чтобы БД точно создалась
sleep 1
# Проверяем, что БД создана
echo "3. Проверка существования тестовой БД..."
if [ -n "$POSTGRES_CONTAINER" ]; then
if echo "SELECT 1 FROM pg_database WHERE datname='$TEST_DB_NAME';" | $PG_PSQL_CMD -U $DB_USER -d postgres -t | grep -q 1; then
echo -e "${GREEN}✓ БД подтверждена${NC}"
else
echo -e "${RED}Ошибка: БД не найдена после создания${NC}"
exit 1
fi
fi
echo ""
# Применяем baseline миграцию
echo "4. Применение baseline миграции..."
cd "$(dirname "$0")" || exit 1
if [ -n "$POSTGRES_CONTAINER" ]; then
# Для Docker контейнеров используем psql напрямую, так как migrate может иметь проблемы с подключением
echo -e "${BLUE}Применение миграции через psql (Docker)...${NC}"
if [ -f "$MIGRATIONS_PATH/000001_baseline.up.sql" ]; then
if cat "$MIGRATIONS_PATH/000001_baseline.up.sql" | $PG_PSQL_CMD -U $DB_USER -d $TEST_DB_NAME > /dev/null 2>&1; then
echo -e "${GREEN}✓ Миграция применена через psql${NC}"
# Создаем таблицу schema_migrations вручную для migrate
echo "CREATE TABLE IF NOT EXISTS schema_migrations (version bigint NOT NULL PRIMARY KEY, dirty boolean NOT NULL);" | $PG_PSQL_CMD -U $DB_USER -d $TEST_DB_NAME > /dev/null 2>&1
echo "INSERT INTO schema_migrations (version, dirty) VALUES (1, false) ON CONFLICT (version) DO UPDATE SET dirty = false;" | $PG_PSQL_CMD -U $DB_USER -d $TEST_DB_NAME > /dev/null 2>&1
MIGRATE_SUCCESS=false # Устанавливаем в false, чтобы использовать psql для проверки версии
else
echo -e "${RED}Ошибка: Не удалось применить миграцию через psql${NC}"
exit 1
fi
else
echo -e "${RED}Ошибка: Файл миграции не найден${NC}"
exit 1
fi
DATABASE_URL="postgres://$DB_USER:$DB_PASSWORD@localhost:$DB_PORT/$TEST_DB_NAME?sslmode=disable"
else
DATABASE_URL="postgres://$DB_USER:$DB_PASSWORD@$DB_HOST:$DB_PORT/$TEST_DB_NAME?sslmode=disable"
if ! migrate -path "$MIGRATIONS_PATH" -database "$DATABASE_URL" up; then
echo -e "${RED}Ошибка: Не удалось применить baseline миграцию${NC}"
exit 1
fi
fi
echo -e "${GREEN}✓ Baseline миграция применена${NC}"
echo ""
# Проверяем версию миграции
echo "5. Проверка версии миграции..."
if [ -n "$POSTGRES_CONTAINER" ] && [ "${MIGRATE_SUCCESS:-false}" = "false" ]; then
# Проверяем версию через psql
VERSION=$(echo "SELECT version FROM schema_migrations;" | $PG_PSQL_CMD -U $DB_USER -d $TEST_DB_NAME -t 2>/dev/null | tr -d ' ' | head -1)
if [ -n "$VERSION" ] && [ "$VERSION" != "" ]; then
echo " Версия: $VERSION"
if [ "$VERSION" = "1" ]; then
echo -e "${GREEN}✓ Версия миграции корректна${NC}"
else
echo -e "${YELLOW}⚠ Неожиданная версия миграции: $VERSION${NC}"
fi
else
echo -e "${YELLOW}Не удалось определить версию миграции${NC}"
fi
else
# Используем migrate для проверки версии
VERSION=$(migrate -path "$MIGRATIONS_PATH" -database "$DATABASE_URL" version 2>&1)
echo " Версия: $VERSION"
if echo "$VERSION" | grep -qE "^1"; then
echo -e "${GREEN}✓ Версия миграции корректна${NC}"
else
echo -e "${YELLOW}⚠ Неожиданная версия миграции${NC}"
fi
fi
echo ""
# Экспортируем схему из тестовой БД (если pg_dump доступен)
if [ "$HAS_PG_DUMP" = true ]; then
echo "6. Экспорт схемы из тестовой БД..."
if [ -n "$POSTGRES_CONTAINER" ]; then
$PG_DUMP_CMD -U $DB_USER -d $TEST_DB_NAME --schema-only --no-owner --no-privileges > "$TMP_DIR/baseline_schema.sql"
else
PGPASSWORD=$DB_PASSWORD $PG_DUMP_CMD \
-h $DB_HOST \
-p $DB_PORT \
-U $DB_USER \
-d $TEST_DB_NAME \
--schema-only \
--no-owner \
--no-privileges \
-f "$TMP_DIR/baseline_schema.sql"
fi
if [ $? -ne 0 ]; then
echo -e "${RED}Ошибка: Не удалось экспортировать схему${NC}"
exit 1
fi
echo -e "${GREEN}✓ Схема экспортирована${NC}"
echo ""
# Пытаемся экспортировать схему из production БД для сравнения
echo "7. Экспорт схемы из production БД для сравнения..."
if [ -n "$POSTGRES_CONTAINER" ]; then
if $PG_DUMP_CMD -U $DB_USER -d $DB_NAME --schema-only --no-owner --no-privileges > "$TMP_DIR/production_schema.sql" 2>/dev/null; then
PROD_EXPORT_SUCCESS=true
else
PROD_EXPORT_SUCCESS=false
fi
else
if PGPASSWORD=$DB_PASSWORD $PG_DUMP_CMD \
-h $DB_HOST \
-p $DB_PORT \
-U $DB_USER \
-d $DB_NAME \
--schema-only \
--no-owner \
--no-privileges \
-f "$TMP_DIR/production_schema.sql" 2>/dev/null; then
PROD_EXPORT_SUCCESS=true
else
PROD_EXPORT_SUCCESS=false
fi
fi
if [ "$PROD_EXPORT_SUCCESS" = true ]; then
echo -e "${GREEN}✓ Схема production экспортирована${NC}"
echo ""
# Сравниваем схемы
echo "8. Сравнение схем..."
# Подсчитываем объекты
echo -e "${BLUE}Таблицы:${NC}"
BASELINE_TABLES=$(grep -c "CREATE TABLE" "$TMP_DIR/baseline_schema.sql" || echo "0")
PROD_TABLES=$(grep -c "CREATE TABLE" "$TMP_DIR/production_schema.sql" || echo "0")
echo " Baseline: $BASELINE_TABLES"
echo " Production: $PROD_TABLES"
if [ "$BASELINE_TABLES" -eq "$PROD_TABLES" ]; then
echo -e " ${GREEN}✓ Количество таблиц совпадает${NC}"
else
echo -e " ${YELLOW}⚠ Количество таблиц не совпадает${NC}"
fi
echo ""
echo -e "${BLUE}Индексы:${NC}"
BASELINE_INDEXES=$(grep -c "CREATE.*INDEX" "$TMP_DIR/baseline_schema.sql" || echo "0")
PROD_INDEXES=$(grep -c "CREATE.*INDEX" "$TMP_DIR/production_schema.sql" || echo "0")
echo " Baseline: $BASELINE_INDEXES"
echo " Production: $PROD_INDEXES"
if [ "$BASELINE_INDEXES" -eq "$PROD_INDEXES" ]; then
echo -e " ${GREEN}✓ Количество индексов совпадает${NC}"
else
echo -e " ${YELLOW}⚠ Количество индексов не совпадает${NC}"
fi
echo ""
echo -e "${BLUE}Materialized Views:${NC}"
BASELINE_MV=$(grep -c "CREATE MATERIALIZED VIEW" "$TMP_DIR/baseline_schema.sql" || echo "0")
PROD_MV=$(grep -c "CREATE MATERIALIZED VIEW" "$TMP_DIR/production_schema.sql" || echo "0")
echo " Baseline: $BASELINE_MV"
echo " Production: $PROD_MV"
if [ "$BASELINE_MV" -eq "$PROD_MV" ]; then
echo -e " ${GREEN}✓ Количество materialized views совпадает${NC}"
else
echo -e " ${YELLOW}⚠ Количество materialized views не совпадает${NC}"
fi
echo ""
echo "Для детального сравнения выполните:"
echo " diff $TMP_DIR/baseline_schema.sql $TMP_DIR/production_schema.sql"
echo ""
echo "Или используйте:"
echo " diff -u $TMP_DIR/baseline_schema.sql $TMP_DIR/production_schema.sql | less"
else
echo -e "${YELLOW}Не удалось экспортировать схему production БД${NC}"
echo " Продолжаем без сравнения"
echo ""
echo "Схема baseline сохранена в: $TMP_DIR/baseline_schema.sql"
fi
else
echo "6. Пропуск экспорта схемы (pg_dump недоступен)"
echo ""
echo -e "${YELLOW}Для полного тестирования установите PostgreSQL client tools:${NC}"
echo " macOS: brew install postgresql"
echo " или используйте Docker контейнер с PostgreSQL"
echo ""
fi
echo ""
echo "=== Тестирование завершено ==="
echo ""
echo -e "${GREEN}✓ Baseline миграция успешно применена к чистой БД${NC}"
echo ""