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>
147 lines
4.9 KiB
Bash
Executable file
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'"
|