Files
foxhunt/scripts/LEVEL_3_ROLLBACK_TEST.sh
jgrusewski 8d89fe80ff chore: Second cleanup wave - organize root directory
- Archive: 85 agent .txt files → docs/archive/agents/legacy_txt/
- Scripts: Move 110 shell scripts → scripts/ (keep deploy.sh in root)
- Models: Move 18 .safetensors → ml/models/checkpoints/training_artifacts/
- Delete: 34 directories (~33GB freed) - target/, coverage_*, test artifacts
- Build: Clean 14 build artifacts (.rlib, .o, .pid, binaries)
- Tests: Move 14 .rs files → tests/standalone/
- SQL: Move 5 files → sql/ (keep init-db*.sql for Docker)
- Wave 153: Archive to docs/archive/historical/wave153/
- Docs: Archive 9 markdown files to wave_d/reports/ and historical/

Total impact: ~34GB freed (both waves), root directory cleaned from 583 to ~40 essential files
Directory count reduced from 65 to 31 (52% reduction)
All historical data preserved in organized archive structure
2025-10-30 01:26:02 +01:00

298 lines
12 KiB
Bash
Executable File

#!/bin/bash
# ================================================================================================
# Level 3 Rollback Test: Full Rollback to Wave C (Target: ~15 minutes)
# Agent R1 - Rollback & Disaster Recovery Specialist
# ================================================================================================
#
# SCENARIO: Complete redeployment to Wave C baseline (before Wave D)
# EXPECTED: System rolled back to last known good Wave C state
#
# ================================================================================================
set -e # Exit on error
echo "===================================================================================================="
echo "LEVEL 3 ROLLBACK TEST: Full Rollback to Wave C"
echo "===================================================================================================="
echo ""
# Start timer
START_TIME=$(date +%s)
# Configuration
WAVE_C_TAG="wave-c-baseline" # Git tag for Wave C baseline
WAVE_D_TAG="wave-d-v1.0" # Git tag for current Wave D deployment
BACKUP_DIR="/tmp/foxhunt_rollback_$(date +%s)"
# Step 1: Pre-rollback preparation
echo "Step 1: Pre-rollback preparation"
echo "------------------------------------------------------------------------------------"
# Create backup directory
mkdir -p "$BACKUP_DIR"
echo " ✓ Created backup directory: $BACKUP_DIR"
# Tag current Wave D state (if not already tagged)
cd /home/jgrusewski/Work/foxhunt
CURRENT_COMMIT=$(git rev-parse HEAD)
echo " ✓ Current commit: $CURRENT_COMMIT"
if ! git tag -l | grep -q "^$WAVE_D_TAG$"; then
git tag "$WAVE_D_TAG" "$CURRENT_COMMIT"
echo " ✓ Tagged Wave D deployment: $WAVE_D_TAG"
else
echo " ⚠ Tag $WAVE_D_TAG already exists"
fi
# Backup database
echo " ✓ Backing up database..."
BACKUP_FILE="$BACKUP_DIR/foxhunt_wave_d_backup.sql"
PGPASSWORD=foxhunt_dev_password pg_dump -h localhost -U foxhunt -d foxhunt -f "$BACKUP_FILE" 2>/dev/null || {
echo " ⚠ WARNING: Database backup failed"
BACKUP_FILE=""
}
if [ -n "$BACKUP_FILE" ] && [ -f "$BACKUP_FILE" ]; then
BACKUP_SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
echo " ✅ Database backup created: $BACKUP_FILE ($BACKUP_SIZE)"
fi
# Backup .env files
echo " ✓ Backing up environment files..."
cp /home/jgrusewski/Work/foxhunt/.env "$BACKUP_DIR/.env.wave_d" 2>/dev/null || true
cp /home/jgrusewski/Work/foxhunt/.env.production "$BACKUP_DIR/.env.production.wave_d" 2>/dev/null || true
echo " ✓ Environment files backed up"
echo ""
# Step 2: Stop all services
echo "Step 2: Stopping all services"
echo "------------------------------------------------------------------------------------"
SHUTDOWN_START=$(date +%s)
# Stop Foxhunt services
PIDS=$(pgrep -f "api_gateway|trading_service|backtesting_service|ml_training_service|trading_agent_service" || true)
if [ -n "$PIDS" ]; then
echo " ✓ Stopping Foxhunt services (PIDs: $PIDS)..."
kill -TERM $PIDS 2>/dev/null || true
# Wait for graceful shutdown
for i in {1..30}; do
REMAINING=$(pgrep -f "api_gateway|trading_service|backtesting_service|ml_training_service|trading_agent_service" | wc -l)
if [ "$REMAINING" -eq 0 ]; then
echo " ✅ Services stopped in ${i}s"
break
fi
sleep 1
done
# Force kill if needed
REMAINING=$(pgrep -f "api_gateway|trading_service|backtesting_service|ml_training_service|trading_agent_service" | wc -l)
if [ "$REMAINING" -gt 0 ]; then
echo " ⚠ Forcing shutdown of $REMAINING processes..."
kill -9 $(pgrep -f "api_gateway|trading_service|backtesting_service|ml_training_service|trading_agent_service") 2>/dev/null || true
fi
else
echo " ⚠ No services running"
fi
SHUTDOWN_END=$(date +%s)
SHUTDOWN_TIME=$((SHUTDOWN_END - SHUTDOWN_START))
echo " ✓ Shutdown completed in ${SHUTDOWN_TIME}s"
echo ""
# Step 3: Rollback database (Level 2 rollback)
echo "Step 3: Rolling back database to Wave C state"
echo "------------------------------------------------------------------------------------"
MIGRATION_START=$(date +%s)
# Run Level 2 rollback (database migration revert)
echo " ✓ Executing database rollback..."
if [ -f "/home/jgrusewski/Work/foxhunt/migrations/045_wave_d_regime_tracking.down.sql" ]; then
PGPASSWORD=foxhunt_dev_password psql -h localhost -U foxhunt -d foxhunt \
-f /home/jgrusewski/Work/foxhunt/migrations/045_wave_d_regime_tracking.down.sql \
2>&1 | grep -E "DROP|REVOKE|NOTICE|ERROR|Wave D" || echo " ✓ Database rollback completed"
else
echo " ⚠ WARNING: Down migration not found, attempting alternative method..."
# Use migration 046 if available
if [ -f "/home/jgrusewski/Work/foxhunt/migrations/046_rollback_regime_detection.sql" ]; then
PGPASSWORD=foxhunt_dev_password psql -h localhost -U foxhunt -d foxhunt \
-f /home/jgrusewski/Work/foxhunt/migrations/046_rollback_regime_detection.sql \
2>&1 | grep -E "DROP|REVOKE|NOTICE|ERROR|Wave D" || echo " ✓ Alternative rollback completed"
fi
fi
# Verify database state
REGIME_TABLES=$(PGPASSWORD=foxhunt_dev_password psql -h localhost -U foxhunt -d foxhunt -tAc "
SELECT COUNT(*) FROM information_schema.tables
WHERE table_name IN ('regime_states', 'regime_transitions', 'adaptive_strategy_metrics');
" 2>/dev/null || echo "unknown")
if [ "$REGIME_TABLES" = "0" ]; then
echo " ✅ Database rollback successful (Wave D tables removed)"
else
echo " ❌ Database rollback failed ($REGIME_TABLES Wave D tables remain)"
fi
MIGRATION_END=$(date +%s)
MIGRATION_TIME=$((MIGRATION_END - MIGRATION_START))
echo " ✓ Database rollback completed in ${MIGRATION_TIME}s"
echo ""
# Step 4: Checkout Wave C baseline code
echo "Step 4: Checking out Wave C baseline code"
echo "------------------------------------------------------------------------------------"
CHECKOUT_START=$(date +%s)
# Find Wave C baseline commit
if git tag -l | grep -q "^$WAVE_C_TAG$"; then
echo " ✓ Found Wave C tag: $WAVE_C_TAG"
WAVE_C_COMMIT=$(git rev-list -n 1 "$WAVE_C_TAG")
else
# Fallback: Find commit before Wave D Phase 3 (feature implementation)
echo " ⚠ No Wave C tag found, searching for baseline commit..."
WAVE_C_COMMIT=$(git log --all --oneline | grep -E "Wave C.*COMPLETE|WAVE_C.*IMPLEMENTATION.*COMPLETE" | head -1 | awk '{print $1}')
if [ -z "$WAVE_C_COMMIT" ]; then
# Ultimate fallback: commit before "Wave D Phase 3"
WAVE_C_COMMIT=$(git log --all --oneline --before="2025-10-17" | head -1 | awk '{print $1}')
fi
fi
echo " ✓ Wave C baseline commit: $WAVE_C_COMMIT"
# Stash current changes (if any)
if ! git diff-index --quiet HEAD --; then
echo " ✓ Stashing uncommitted changes..."
git stash push -m "Rollback: Stashing Wave D changes before rollback to Wave C"
fi
# Checkout Wave C baseline
echo " ✓ Checking out Wave C baseline..."
git checkout "$WAVE_C_COMMIT" 2>&1 | grep -E "HEAD|Previous|error" || echo " ✓ Checkout completed"
# Verify checkout
CURRENT_COMMIT=$(git rev-parse HEAD)
if [ "$CURRENT_COMMIT" = "$WAVE_C_COMMIT" ]; then
echo " ✅ Successfully checked out Wave C baseline"
else
echo " ❌ Checkout failed (HEAD: $CURRENT_COMMIT, Expected: $WAVE_C_COMMIT)"
fi
CHECKOUT_END=$(date +%s)
CHECKOUT_TIME=$((CHECKOUT_END - CHECKOUT_START))
echo " ✓ Git checkout completed in ${CHECKOUT_TIME}s"
echo ""
# Step 5: Rebuild services with Wave C codebase
echo "Step 5: Rebuilding services from Wave C codebase"
echo "------------------------------------------------------------------------------------"
REBUILD_START=$(date +%s)
# Clean build to ensure no Wave D artifacts
echo " ✓ Cleaning previous build artifacts..."
cd /home/jgrusewski/Work/foxhunt
cargo clean 2>&1 | grep -E "Removing|error" || echo " ✓ Clean completed"
# Rebuild entire workspace
echo " ✓ Rebuilding workspace (release mode)..."
cargo build --workspace --release 2>&1 | grep -E "Compiling|Finished|error" || echo " ✓ Build completed"
REBUILD_END=$(date +%s)
REBUILD_TIME=$((REBUILD_END - REBUILD_START))
echo " ✓ Rebuild completed in ${REBUILD_TIME}s"
echo ""
# Step 6: Smoke test Wave C deployment
echo "Step 6: Smoke testing Wave C deployment"
echo "------------------------------------------------------------------------------------"
# Check feature count
echo " ✓ Checking feature count..."
FEATURE_COUNT=$(cargo run --release -p ml --example check_feature_count 2>&1 | grep "Wave C: feature_count:" | grep -oP '\d+' || echo "unknown")
if [ "$FEATURE_COUNT" = "201" ]; then
echo " ✅ VERIFIED: Wave C feature count = 201"
elif [ "$FEATURE_COUNT" = "225" ]; then
echo " ❌ FAILED: Feature count = 225 (Wave D still active)"
else
echo " ⚠ WARNING: Could not verify feature count (got: $FEATURE_COUNT)"
fi
# Check for Wave D code
WAVE_D_CODE=$(grep -r "enable_wave_d_regime" /home/jgrusewski/Work/foxhunt/ml/src/features/ 2>/dev/null | wc -l)
if [ "$WAVE_D_CODE" -eq 0 ]; then
echo " ✅ VERIFIED: No Wave D code present"
else
echo " ⚠ WARNING: Wave D code references still exist ($WAVE_D_CODE occurrences)"
echo " ⚠ This may be expected if Wave C already had placeholders"
fi
# Test basic compilation
echo " ✓ Running basic compilation test..."
cargo check --workspace 2>&1 | grep -E "Checking|Finished|error" || echo " ✓ Check completed"
echo " ⚠ NOTE: Services NOT started automatically (manual start required)"
echo ""
# Step 7: Calculate rollback time
echo "Step 7: Rollback Performance Metrics"
echo "------------------------------------------------------------------------------------"
END_TIME=$(date +%s)
TOTAL_TIME=$((END_TIME - START_TIME))
echo " • Total rollback time: ${TOTAL_TIME}s"
echo " • Shutdown time: ${SHUTDOWN_TIME}s"
echo " • Database rollback time: ${MIGRATION_TIME}s"
echo " • Git checkout time: ${CHECKOUT_TIME}s"
echo " • Rebuild time: ${REBUILD_TIME}s"
echo " • Target time: <900s (15 minutes)"
if [ $TOTAL_TIME -lt 900 ]; then
echo " ✅ PASSED: Rollback completed within 15-minute target"
else
echo " ⚠ MISSED TARGET: Rollback took ${TOTAL_TIME}s (>900s)"
fi
echo ""
# Summary
echo "===================================================================================================="
echo "LEVEL 3 ROLLBACK TEST: SUMMARY"
echo "===================================================================================================="
echo ""
echo "Result:"
echo " • Git state: Wave C baseline ($WAVE_C_COMMIT)"
echo " • Database: Wave D tables removed ($REGIME_TABLES tables remain)"
echo " • Feature count: $FEATURE_COUNT (expected: 201)"
echo " • Services: STOPPED (manual restart required)"
echo " • Rollback time: ${TOTAL_TIME}s (~$((TOTAL_TIME / 60)) minutes)"
echo ""
echo "Data Loss:"
echo " • All Wave D regime detection data DELETED"
echo " • Wave D code changes REVERTED"
if [ -n "$BACKUP_FILE" ] && [ -f "$BACKUP_FILE" ]; then
echo " • Full backup: $BACKUP_FILE ($BACKUP_SIZE)"
fi
echo " • Backup directory: $BACKUP_DIR"
echo ""
echo "Recovery Path:"
echo " To re-deploy Wave D:"
echo " 1. Checkout Wave D tag: git checkout $WAVE_D_TAG"
echo " 2. Restore database (optional): psql < $BACKUP_FILE"
echo " 3. Re-apply migrations: sqlx migrate run"
echo " 4. Rebuild services: cargo build --workspace --release"
echo " 5. Restart all services"
echo ""
echo "Manual Steps Required:"
echo " 1. Start services: cargo run -p api_gateway &"
echo " 2. Verify health checks: curl http://localhost:8080/health"
echo " 3. Run integration tests: cargo test --workspace"
echo " 4. Monitor Grafana dashboards"
echo ""
echo "===================================================================================================="
exit 0