CalejoControl/run_tests_with_db.sh

239 lines
7.4 KiB
Bash

#!/bin/bash
# Calejo Control Adapter - Comprehensive Test Runner
# This script sets up a PostgreSQL database and runs all tests with detailed output
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
POSTGRES_IMAGE="postgres:15"
CONTAINER_NAME="calejo-test-db"
DB_NAME="calejo_test"
DB_USER="test_user"
DB_PASSWORD="test_password"
DB_PORT=5433 # Use different port to avoid conflicts
# Function to print colored output
print_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if Docker is running
if ! docker info > /dev/null 2>&1; then
print_error "Docker is not running. Please start Docker and try again."
exit 1
fi
# Stop and remove existing container if it exists
if docker ps -a | grep -q $CONTAINER_NAME; then
print_info "Stopping existing test database container..."
docker stop $CONTAINER_NAME > /dev/null
docker rm $CONTAINER_NAME > /dev/null
print_success "Existing container removed"
fi
# Start PostgreSQL container
print_info "Starting PostgreSQL test database..."
docker run -d \
--name $CONTAINER_NAME \
-e POSTGRES_DB=$DB_NAME \
-e POSTGRES_USER=$DB_USER \
-e POSTGRES_PASSWORD=$DB_PASSWORD \
-p $DB_PORT:5432 \
$POSTGRES_IMAGE
# Wait for database to be ready
print_info "Waiting for database to be ready..."
for i in {1..30}; do
if docker exec $CONTAINER_NAME pg_isready -U $DB_USER -d $DB_NAME > /dev/null 2>&1; then
print_success "Database is ready!"
break
fi
if [ $i -eq 30 ]; then
print_error "Database failed to start within 30 seconds"
docker logs $CONTAINER_NAME
exit 1
fi
sleep 1
echo -n "."
done
# Create test database schema
print_info "Creating test database schema..."
# Create the necessary tables
SQL_FILE=$(mktemp)
cat > $SQL_FILE << 'EOF'
-- Create stations table
CREATE TABLE IF NOT EXISTS stations (
station_id VARCHAR(50) PRIMARY KEY,
station_name VARCHAR(100),
location VARCHAR(200),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Create pumps table
CREATE TABLE IF NOT EXISTS pumps (
station_id VARCHAR(50),
pump_id VARCHAR(50),
pump_name VARCHAR(100),
control_type VARCHAR(50),
min_speed_hz DECIMAL(5,2) DEFAULT 20.0,
max_speed_hz DECIMAL(5,2) DEFAULT 60.0,
default_setpoint_hz DECIMAL(5,2) DEFAULT 35.0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (station_id, pump_id),
FOREIGN KEY (station_id) REFERENCES stations(station_id)
);
-- Create pump_plans table
CREATE TABLE IF NOT EXISTS pump_plans (
plan_id SERIAL PRIMARY KEY,
station_id VARCHAR(50),
pump_id VARCHAR(50),
target_flow_m3h DECIMAL(8,2),
target_power_kw DECIMAL(8,2),
target_level_m DECIMAL(8,2),
suggested_speed_hz DECIMAL(5,2),
interval_start TIMESTAMP,
interval_end TIMESTAMP,
plan_version INTEGER,
plan_status VARCHAR(20) DEFAULT 'ACTIVE',
plan_created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
plan_updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
optimization_run_id VARCHAR(100),
FOREIGN KEY (station_id, pump_id) REFERENCES pumps(station_id, pump_id)
);
-- Create pump_feedback table
CREATE TABLE IF NOT EXISTS pump_feedback (
feedback_id SERIAL PRIMARY KEY,
station_id VARCHAR(50),
pump_id VARCHAR(50),
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
actual_speed_hz DECIMAL(5,2),
actual_power_kw DECIMAL(8,2),
actual_flow_m3h DECIMAL(8,2),
wet_well_level_m DECIMAL(8,2),
pump_running BOOLEAN,
alarm_active BOOLEAN,
alarm_code VARCHAR(50),
FOREIGN KEY (station_id, pump_id) REFERENCES pumps(station_id, pump_id)
);
-- Create emergency_stop_events table
CREATE TABLE IF NOT EXISTS emergency_stop_events (
event_id SERIAL PRIMARY KEY,
triggered_by VARCHAR(100),
reason TEXT,
station_id VARCHAR(50),
pump_id VARCHAR(50),
event_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
cleared_by VARCHAR(100),
cleared_timestamp TIMESTAMP,
cleared_notes TEXT,
FOREIGN KEY (station_id, pump_id) REFERENCES pumps(station_id, pump_id)
);
-- Insert test data
INSERT INTO stations (station_id, station_name, location) VALUES
('STATION_001', 'Main Pump Station', 'Downtown Area'),
('STATION_002', 'Secondary Station', 'Industrial Zone');
INSERT INTO pumps (station_id, pump_id, pump_name, control_type, min_speed_hz, max_speed_hz, default_setpoint_hz) VALUES
('STATION_001', 'PUMP_001', 'Main Pump 1', 'DIRECT_SPEED', 20.0, 60.0, 35.0),
('STATION_001', 'PUMP_002', 'Main Pump 2', 'LEVEL_CONTROLLED', 20.0, 60.0, 35.0),
('STATION_002', 'PUMP_001', 'Secondary Pump 1', 'POWER_CONTROLLED', 20.0, 60.0, 35.0);
INSERT INTO pump_plans (
station_id, pump_id, target_flow_m3h, target_power_kw, target_level_m,
suggested_speed_hz, interval_start, interval_end, plan_version, optimization_run_id
) VALUES
('STATION_001', 'PUMP_001', 150.0, NULL, NULL, 42.5,
NOW() - INTERVAL '1 hour', NOW() + INTERVAL '1 hour', 1, 'OPT_RUN_001'),
('STATION_001', 'PUMP_002', NULL, NULL, 2.5, 38.0,
NOW() - INTERVAL '1 hour', NOW() + INTERVAL '1 hour', 1, 'OPT_RUN_001'),
('STATION_002', 'PUMP_001', NULL, 18.5, NULL, 40.0,
NOW() - INTERVAL '1 hour', NOW() + INTERVAL '1 hour', 1, 'OPT_RUN_001');
INSERT INTO pump_feedback (
station_id, pump_id, actual_speed_hz, actual_power_kw, actual_flow_m3h,
wet_well_level_m, pump_running, alarm_active
) VALUES
('STATION_001', 'PUMP_001', 42.5, 16.2, 148.5, 1.8, true, false),
('STATION_001', 'PUMP_002', 38.0, 14.8, 135.2, 2.3, true, false),
('STATION_002', 'PUMP_001', 40.0, 18.3, 142.1, 1.9, true, false);
EOF
docker exec -i $CONTAINER_NAME psql -U $DB_USER -d $DB_NAME < $SQL_FILE
rm $SQL_FILE
print_success "Test database schema created with sample data"
# Set environment variables for tests
export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost:$DB_PORT/$DB_NAME"
export TEST_DATABASE_URL="$DATABASE_URL"
print_info "Environment variables set for testing"
# Run tests with detailed output
print_info "Running tests with detailed output..."
echo ""
# Run unit tests first
print_info "=== RUNNING UNIT TESTS ==="
python -m pytest tests/unit/ -v --tb=long --cov=src --cov-report=term-missing --cov-report=html:htmlcov_unit
UNIT_EXIT_CODE=$?
# Run integration tests
print_info "=== RUNNING INTEGRATION TESTS ==="
python -m pytest tests/integration/ -v --tb=long --cov=src --cov-append --cov-report=term-missing --cov-report=html:htmlcov_integration
INTEGRATION_EXIT_CODE=$?
# Generate combined coverage report
print_info "=== GENERATING COMBINED COVERAGE REPORT ==="
python -m pytest --cov=src --cov-report=html:htmlcov_combined --cov-report=term-missing tests/
# Clean up
print_info "Cleaning up test database container..."
docker stop $CONTAINER_NAME > /dev/null
docker rm $CONTAINER_NAME > /dev/null
print_success "Test database container cleaned up"
# Report results
echo ""
print_info "=== TEST RESULTS SUMMARY ==="
if [ $UNIT_EXIT_CODE -eq 0 ] && [ $INTEGRATION_EXIT_CODE -eq 0 ]; then
print_success "All tests passed!"
exit 0
else
if [ $UNIT_EXIT_CODE -ne 0 ]; then
print_error "Unit tests failed with exit code: $UNIT_EXIT_CODE"
fi
if [ $INTEGRATION_EXIT_CODE -ne 0 ]; then
print_error "Integration tests failed with exit code: $INTEGRATION_EXIT_CODE"
fi
exit 1
fi