#!/usr/bin/env bash set -euo pipefail # AgentHub Backup/Restore Integration Test # Tests the full backup → restore cycle to an ephemeral database # Success criterion for BARAAA-46: "Dump nightly fonctionne ; restore testée vers DB éphémère" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # Test configuration TEST_DB_NAME="agenthub_restore_test_$(date +%s)" BACKUP_DIR="${PROJECT_ROOT}/test-backups" BACKUP_FILE="${BACKUP_DIR}/test_backup_$(date +%Y%m%d_%H%M%S).dump" # Postgres connection (from .env or defaults) export PGHOST="${PGHOST:-localhost}" export PGPORT="${PGPORT:-5432}" export PGUSER="${PGUSER:-agenthub}" export PGDATABASE="${PGDATABASE:-agenthub}" echo "========================================" echo "AgentHub Backup/Restore Test" echo "========================================" log_info "Source DB: ${PGDATABASE}" log_info "Test DB: ${TEST_DB_NAME}" log_info "Backup file: ${BACKUP_FILE}" echo "" # Step 1: Create test backup directory log_info "Step 1/6: Creating backup directory" mkdir -p "${BACKUP_DIR}" # Step 2: Run backup script to create a dump log_info "Step 2/6: Creating backup from source database" export BACKUP_DIR="${BACKUP_DIR}" export RETENTION_DAYS=1 # Check if source DB exists and has tables TABLE_COUNT=$(psql -t -c "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE';" 2>/dev/null || echo "0") if [[ "${TABLE_COUNT}" -lt 1 ]]; then log_error "Source database has no tables. Run migrations first: npm run migrate" exit 1 fi log_info "Source database has ${TABLE_COUNT} tables" # Create backup using pg_dump directly pg_dump -Fc \ -h "${PGHOST}" \ -p "${PGPORT}" \ -U "${PGUSER}" \ -d "${PGDATABASE}" \ -f "${BACKUP_FILE}" # Verify backup file if [[ ! -s "${BACKUP_FILE}" ]]; then log_error "Backup file is empty or missing: ${BACKUP_FILE}" exit 1 fi BACKUP_SIZE=$(stat -f%z "${BACKUP_FILE}" 2>/dev/null || stat -c%s "${BACKUP_FILE}") log_info "Backup created: ${BACKUP_SIZE} bytes" # Step 3: Create ephemeral test database log_info "Step 3/6: Creating ephemeral test database '${TEST_DB_NAME}'" psql -h "${PGHOST}" -p "${PGPORT}" -U "${PGUSER}" -d postgres -c "CREATE DATABASE ${TEST_DB_NAME} OWNER ${PGUSER};" >/dev/null # Step 4: Restore backup to test database log_info "Step 4/6: Restoring backup to test database" pg_restore -h "${PGHOST}" -p "${PGPORT}" -U "${PGUSER}" -d "${TEST_DB_NAME}" \ --no-owner \ --no-acl \ "${BACKUP_FILE}" 2>&1 | grep -v "^WARNING:" || true # Step 5: Verify restore log_info "Step 5/6: Verifying restored database" # Check table count RESTORED_TABLE_COUNT=$(psql -h "${PGHOST}" -p "${PGPORT}" -U "${PGUSER}" -d "${TEST_DB_NAME}" -t -c " SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE'; ") RESTORED_TABLE_COUNT=$(echo "${RESTORED_TABLE_COUNT}" | tr -d ' ') if [[ "${RESTORED_TABLE_COUNT}" != "${TABLE_COUNT}" ]]; then log_error "Table count mismatch: source=${TABLE_COUNT}, restored=${RESTORED_TABLE_COUNT}" exit 1 fi log_info "Table count verified: ${RESTORED_TABLE_COUNT} tables" # Check schema consistency (compare table names) SOURCE_TABLES=$(psql -h "${PGHOST}" -p "${PGPORT}" -U "${PGUSER}" -d "${PGDATABASE}" -t -c " SELECT tablename FROM pg_tables WHERE schemaname = 'public' ORDER BY tablename; ") RESTORED_TABLES=$(psql -h "${PGHOST}" -p "${PGPORT}" -U "${PGUSER}" -d "${TEST_DB_NAME}" -t -c " SELECT tablename FROM pg_tables WHERE schemaname = 'public' ORDER BY tablename; ") if [[ "${SOURCE_TABLES}" != "${RESTORED_TABLES}" ]]; then log_error "Schema mismatch between source and restored database" log_error "Source tables: ${SOURCE_TABLES}" log_error "Restored tables: ${RESTORED_TABLES}" exit 1 fi log_info "Schema verified: all tables match" # Step 6: Cleanup log_info "Step 6/6: Cleaning up test database and backup" psql -h "${PGHOST}" -p "${PGPORT}" -U "${PGUSER}" -d postgres -c "DROP DATABASE ${TEST_DB_NAME};" >/dev/null rm -f "${BACKUP_FILE}" rmdir "${BACKUP_DIR}" 2>/dev/null || true echo "" echo "========================================" log_info "✅ Backup/Restore test PASSED" echo "========================================" echo "" echo "Validation results:" echo " ✓ Backup created successfully (${BACKUP_SIZE} bytes)" echo " ✓ Backup file has non-zero size" echo " ✓ Ephemeral database created" echo " ✓ Restore completed without errors" echo " ✓ Table count matches (${TABLE_COUNT} tables)" echo " ✓ Schema matches between source and restored DB" echo " ✓ Cleanup completed" echo "" log_info "Success criterion met: 'Dump nightly fonctionne ; restore testée vers DB éphémère'"