agenthub/scripts/test-backup-restore.sh
Paperclip FoundingEngineer bdd5d92ba7 Initial AgentHub codebase for Coolify deployment
Complete implementation ready for Coolify:
- Node.js 22 + Fastify + socket.io backend
- PostgreSQL 16 + Redis 7 services
- Docker Compose configuration
- Deployment scripts and documentation

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-01 21:25:57 +00:00

147 lines
4.9 KiB
Bash
Executable file

#!/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'"