#!/usr/bin/env bash set -euo pipefail # Скрипт автоматизированного прогона E2E-теста всей цепочки DWH через REST API Airflow. # Отрабатывает 2 "учебных дня" для проверки инкрементальной загрузки. ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT" warn() { echo ":: ${1}" >&2; } # Загружаем переменные из .env, если файл существует, иначе используем дефолты if [ -f ".env" ]; then export $(grep -v '^#' .env | xargs) fi AIRFLOW_USER=${AIRFLOW_USER:-admin} AIRFLOW_PASSWORD=${AIRFLOW_PASSWORD:-admin} API_URL="http://localhost:8080/api/v1/dags" # Функция для триггера DAG и ожидания его завершения trigger_and_wait() { local dag_id=$1 warn "Запуск $dag_id через REST API..." # 0. Unpause DAG curl -s -X PATCH "$API_URL/$dag_id" \ --user "$AIRFLOW_USER:$AIRFLOW_PASSWORD" \ -H "Content-Type: application/json" \ -d '{"is_paused": false}' > /dev/null # 1. Trigger local response response=$(curl -s -X POST "$API_URL/$dag_id/dagRuns" \ --user "$AIRFLOW_USER:$AIRFLOW_PASSWORD" \ -H "Content-Type: application/json" \ -d '{}') local run_id run_id=$(echo "$response" | grep -o '"dag_run_id": "[^"]*' | cut -d'"' -f4) if [ -z "$run_id" ]; then echo "Ошибка запуска $dag_id. Ответ API: $response" >&2 exit 1 fi warn "Успешный триггер. Run ID: $run_id" # 2. Wait warn "Ожидание завершения $dag_id..." local attempts=0 local max_attempts=120 # 10 минут (120 * 5 сек) while true; do local status status=$(curl -s "$API_URL/$dag_id/dagRuns/$run_id" \ --user "$AIRFLOW_USER:$AIRFLOW_PASSWORD" | grep -o '"state": "[^"]*' | cut -d'"' -f4) if [ "$status" = "success" ]; then warn "DAG $dag_id завершен: SUCCESS" break elif [ "$status" = "failed" ]; then echo "DAG $dag_id УПАЛ (FAILED)!" >&2 exit 1 elif [ "$status" = "queued" ] || [ "$status" = "running" ] || [ "$status" = "" ]; then attempts=$((attempts + 1)) if [ "$attempts" -ge "$max_attempts" ]; then echo "Таймаут ожидания $dag_id!" >&2 exit 1 fi sleep 5 else echo "Неизвестный статус: $status" >&2 exit 1 fi done } warn "=== DDL: Создание схем и таблиц ===" trigger_and_wait "bookings_stg_ddl" trigger_and_wait "bookings_ods_ddl" trigger_and_wait "bookings_dds_ddl" trigger_and_wait "bookings_dm_ddl" warn "=== DAY 1: Initial Load ===" trigger_and_wait "bookings_to_gp_stage" trigger_and_wait "bookings_to_gp_ods" trigger_and_wait "bookings_to_gp_dds" trigger_and_wait "bookings_to_gp_dm" warn "=== DAY 2: Increment ===" trigger_and_wait "bookings_to_gp_stage" trigger_and_wait "bookings_to_gp_ods" trigger_and_wait "bookings_to_gp_dds" trigger_and_wait "bookings_to_gp_dm" warn "=== Верификация данных ===" # Выполняем простые проверки строк, чтобы убедиться, что данные дошли до витрины docker compose -f docker-compose.yml exec greenplum bash -c "su - gpadmin -c \"psql -d gp_dwh -c \\\" SELECT 'STG bookings' as layer, COUNT(*) FROM stg.bookings UNION ALL SELECT 'ODS bookings', COUNT(*) FROM ods.bookings UNION ALL SELECT 'DDS fact', COUNT(*) FROM dds.fact_flight_sales UNION ALL SELECT 'DM report', COUNT(*) FROM dm.sales_report; \\\"\"" warn "E2E ETL тест успешно завершен!"