358 lines
11 KiB
Bash
Executable File
358 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
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
|
|
CONFIG_FILE="${CONFIG_FILE:-config.e2e.yaml}"
|
|
LOG_DIR="./tests/logs"
|
|
PID_DIR="./tests/pids"
|
|
|
|
# Detect database schema from config file if possible
|
|
DETECTED_SCHEMA=""
|
|
if [ -f "$CONFIG_FILE" ]; then
|
|
DETECTED_SCHEMA=$(grep -E '^\s*schema:' "$CONFIG_FILE" | sed -E 's/^\s*schema:\s*"?([^"]+)"?.*/\1/' | tr -d ' ')
|
|
fi
|
|
|
|
# Service ports (from config.e2e.yaml)
|
|
API_PORT=8080
|
|
NOTIFIER_WS_PORT=8081
|
|
|
|
echo -e "${GREEN}=== Attune E2E Services Startup ===${NC}\n"
|
|
|
|
# Display configuration info
|
|
echo -e "${BLUE}Configuration:${NC}"
|
|
echo -e " • Config file: ${YELLOW}$CONFIG_FILE${NC}"
|
|
if [ -n "$DETECTED_SCHEMA" ]; then
|
|
echo -e " • Database schema: ${YELLOW}$DETECTED_SCHEMA${NC}"
|
|
else
|
|
echo -e " • Database schema: ${YELLOW}attune${NC} (default)"
|
|
fi
|
|
echo ""
|
|
|
|
# Create necessary directories
|
|
mkdir -p "$LOG_DIR"
|
|
mkdir -p "$PID_DIR"
|
|
mkdir -p "./tests/artifacts"
|
|
mkdir -p "./tests/venvs"
|
|
|
|
# Function to check if a service is running
|
|
is_service_running() {
|
|
local pid_file="$PID_DIR/$1.pid"
|
|
if [ -f "$pid_file" ]; then
|
|
local pid=$(cat "$pid_file")
|
|
if ps -p $pid > /dev/null 2>&1; then
|
|
return 0
|
|
else
|
|
rm -f "$pid_file"
|
|
return 1
|
|
fi
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# Function to stop a service
|
|
stop_service() {
|
|
local service_name=$1
|
|
local pid_file="$PID_DIR/$service_name.pid"
|
|
|
|
if [ -f "$pid_file" ]; then
|
|
local pid=$(cat "$pid_file")
|
|
echo -e "${YELLOW}→${NC} Stopping $service_name (PID: $pid)..."
|
|
kill $pid 2>/dev/null || true
|
|
sleep 2
|
|
if ps -p $pid > /dev/null 2>&1; then
|
|
echo -e "${YELLOW}!${NC} Forcefully killing $service_name..."
|
|
kill -9 $pid 2>/dev/null || true
|
|
fi
|
|
rm -f "$pid_file"
|
|
echo -e "${GREEN}✓${NC} $service_name stopped"
|
|
fi
|
|
}
|
|
|
|
# Function to start a service
|
|
start_service() {
|
|
local service_name=$1
|
|
local binary_name=$2
|
|
local log_file="$LOG_DIR/$service_name.log"
|
|
local pid_file="$PID_DIR/$service_name.pid"
|
|
|
|
echo -e "${YELLOW}→${NC} Starting $service_name..."
|
|
|
|
# Build the service if not already built
|
|
if [ ! -f "./target/debug/$binary_name" ]; then
|
|
echo -e "${BLUE} Building $binary_name...${NC}"
|
|
cargo build --bin $binary_name 2>&1 | tee "$LOG_DIR/$service_name-build.log"
|
|
fi
|
|
|
|
# Start the service
|
|
# Only set ATTUNE__ENVIRONMENT if using default e2e config
|
|
# Otherwise, let the config file determine the environment
|
|
if [ "$CONFIG_FILE" = "config.e2e.yaml" ]; then
|
|
ATTUNE__ENVIRONMENT=e2e ATTUNE_CONFIG="$CONFIG_FILE" ./target/debug/$binary_name > "$log_file" 2>&1 &
|
|
else
|
|
ATTUNE_CONFIG="$CONFIG_FILE" ./target/debug/$binary_name > "$log_file" 2>&1 &
|
|
fi
|
|
local pid=$!
|
|
echo $pid > "$pid_file"
|
|
|
|
# Wait a moment and check if it's still running
|
|
sleep 2
|
|
if ps -p $pid > /dev/null 2>&1; then
|
|
echo -e "${GREEN}✓${NC} $service_name started (PID: $pid)"
|
|
echo -e " Log: ${BLUE}$log_file${NC}"
|
|
return 0
|
|
else
|
|
echo -e "${RED}✗${NC} $service_name failed to start"
|
|
echo -e " Check log: ${RED}$log_file${NC}"
|
|
tail -20 "$log_file"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to check service health
|
|
check_service_health() {
|
|
local service_name=$1
|
|
local health_url=$2
|
|
local max_attempts=${3:-30}
|
|
local attempt=0
|
|
|
|
echo -e "${YELLOW}→${NC} Checking $service_name health..."
|
|
|
|
while [ $attempt -lt $max_attempts ]; do
|
|
if curl -s -f "$health_url" > /dev/null 2>&1; then
|
|
echo -e "${GREEN}✓${NC} $service_name is healthy"
|
|
return 0
|
|
fi
|
|
attempt=$((attempt + 1))
|
|
sleep 1
|
|
done
|
|
|
|
echo -e "${RED}✗${NC} $service_name health check failed after $max_attempts attempts"
|
|
return 1
|
|
}
|
|
|
|
# Check for existing services and stop them
|
|
echo -e "${YELLOW}Checking for running E2E services...${NC}"
|
|
for service in api executor worker sensor notifier; do
|
|
if is_service_running $service; then
|
|
stop_service $service
|
|
fi
|
|
done
|
|
echo ""
|
|
|
|
# Check dependencies
|
|
echo -e "${YELLOW}Checking dependencies...${NC}"
|
|
|
|
# Check PostgreSQL
|
|
echo -e "${YELLOW}→${NC} Checking PostgreSQL..."
|
|
echo -e " Attempting connection to: ${BLUE}postgresql://postgres@localhost:5432/attune_e2e${NC}"
|
|
|
|
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d attune_e2e -c '\q' 2>/tmp/pg_check_error.txt
|
|
PG_EXIT=$?
|
|
|
|
if [ $PG_EXIT -eq 0 ]; then
|
|
echo -e "${GREEN}✓${NC} PostgreSQL connection successful"
|
|
else
|
|
echo -e "${RED}✗${NC} Cannot connect to PostgreSQL database 'attune_e2e'"
|
|
echo ""
|
|
echo -e "${YELLOW}Diagnostic Information:${NC}"
|
|
|
|
# Check if PostgreSQL is running at all
|
|
if ! pg_isready -h localhost -p 5432 > /dev/null 2>&1; then
|
|
echo -e " ${RED}✗${NC} PostgreSQL server is not running on localhost:5432"
|
|
echo -e " Start it with: ${YELLOW}sudo systemctl start postgresql${NC}"
|
|
else
|
|
echo -e " ${GREEN}✓${NC} PostgreSQL server is running"
|
|
|
|
# Check if the database exists
|
|
if ! PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -lqt 2>/dev/null | cut -d \| -f 1 | grep -qw attune_e2e; then
|
|
echo -e " ${RED}✗${NC} Database 'attune_e2e' does not exist"
|
|
echo -e " Create it with: ${YELLOW}./scripts/setup-e2e-db.sh${NC}"
|
|
else
|
|
echo -e " ${GREEN}✓${NC} Database 'attune_e2e' exists"
|
|
echo -e " ${RED}✗${NC} Connection failed for another reason"
|
|
|
|
# Show the actual error
|
|
if [ -f /tmp/pg_check_error.txt ] && [ -s /tmp/pg_check_error.txt ]; then
|
|
echo -e "\n${YELLOW}Error details:${NC}"
|
|
cat /tmp/pg_check_error.txt | sed 's/^/ /'
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
rm -f /tmp/pg_check_error.txt
|
|
exit 1
|
|
fi
|
|
|
|
# Check RabbitMQ
|
|
echo -e "${YELLOW}→${NC} Checking RabbitMQ..."
|
|
echo -e " Testing connection to: ${BLUE}localhost:5672 (AMQP)${NC}"
|
|
|
|
if nc -z localhost 5672 2>/dev/null || timeout 1 bash -c 'cat < /dev/null > /dev/tcp/localhost/5672' 2>/dev/null; then
|
|
echo -e "${GREEN}✓${NC} RabbitMQ is running (AMQP port 5672)"
|
|
else
|
|
echo -e "${RED}✗${NC} RabbitMQ is not running on port 5672"
|
|
echo ""
|
|
echo -e "${YELLOW}Diagnostic Information:${NC}"
|
|
|
|
# Check if RabbitMQ process is running
|
|
if pgrep -x rabbitmq-server > /dev/null || pgrep -x beam.smp > /dev/null; then
|
|
echo -e " ${YELLOW}!${NC} RabbitMQ process is running but port 5672 is not accessible"
|
|
echo -e " The service may still be starting up"
|
|
echo -e " Check status: ${YELLOW}sudo rabbitmq-diagnostics status${NC}"
|
|
echo -e " View logs: ${YELLOW}sudo journalctl -u rabbitmq-server -n 50${NC}"
|
|
else
|
|
echo -e " ${RED}✗${NC} RabbitMQ process is not running"
|
|
echo -e " Start it with: ${YELLOW}sudo systemctl start rabbitmq-server${NC}"
|
|
echo -e " Or: ${YELLOW}sudo service rabbitmq-server start${NC}"
|
|
fi
|
|
|
|
# Check if port might be in use by something else
|
|
if netstat -tuln 2>/dev/null | grep -q :5672 || ss -tuln 2>/dev/null | grep -q :5672; then
|
|
echo -e " ${YELLOW}!${NC} Port 5672 appears to be in use"
|
|
echo -e " Check what's using it: ${YELLOW}sudo lsof -i :5672${NC}"
|
|
fi
|
|
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# Build all services first
|
|
echo -e "${YELLOW}Building all services...${NC}"
|
|
echo -e " Building binaries: ${BLUE}api, executor, worker, sensor, notifier${NC}"
|
|
echo -e " This may take a few moments..."
|
|
|
|
cargo build --bins 2>&1 | tee "$LOG_DIR/build.log"
|
|
BUILD_EXIT=${PIPESTATUS[0]}
|
|
|
|
if [ $BUILD_EXIT -ne 0 ]; then
|
|
echo -e "${RED}✗${NC} Build failed"
|
|
echo ""
|
|
echo -e "${YELLOW}Last 30 lines of build output:${NC}"
|
|
tail -30 "$LOG_DIR/build.log" | sed 's/^/ /'
|
|
echo ""
|
|
echo -e "Full build log: ${RED}$LOG_DIR/build.log${NC}"
|
|
exit 1
|
|
fi
|
|
echo -e "${GREEN}✓${NC} All services built successfully\n"
|
|
|
|
# Start services in order
|
|
echo -e "${GREEN}=== Starting Services ===${NC}\n"
|
|
|
|
# 1. Start API service
|
|
if ! start_service "api" "attune-api"; then
|
|
echo -e "${RED}Failed to start API service${NC}"
|
|
exit 1
|
|
fi
|
|
sleep 2
|
|
|
|
# Check API health
|
|
if ! check_service_health "API" "http://127.0.0.1:$API_PORT/health"; then
|
|
echo -e "${RED}API service is not healthy${NC}"
|
|
echo ""
|
|
echo -e "${YELLOW}Last 20 lines of API log:${NC}"
|
|
tail -20 "$LOG_DIR/api.log" | sed 's/^/ /'
|
|
echo ""
|
|
echo -e "Full log: ${RED}$LOG_DIR/api.log${NC}"
|
|
exit 1
|
|
fi
|
|
echo ""
|
|
|
|
# 2. Start Executor service
|
|
if ! start_service "executor" "attune-executor"; then
|
|
echo -e "${RED}Failed to start Executor service${NC}"
|
|
echo ""
|
|
echo -e "${YELLOW}Last 20 lines of Executor log:${NC}"
|
|
tail -20 "$LOG_DIR/executor.log" | sed 's/^/ /'
|
|
echo ""
|
|
echo -e "Full log: ${RED}$LOG_DIR/executor.log${NC}"
|
|
exit 1
|
|
fi
|
|
sleep 2
|
|
echo ""
|
|
|
|
# 3. Start Worker service
|
|
if ! start_service "worker" "attune-worker"; then
|
|
echo -e "${RED}Failed to start Worker service${NC}"
|
|
echo ""
|
|
echo -e "${YELLOW}Last 20 lines of Worker log:${NC}"
|
|
tail -20 "$LOG_DIR/worker.log" | sed 's/^/ /'
|
|
echo ""
|
|
echo -e "Full log: ${RED}$LOG_DIR/worker.log${NC}"
|
|
exit 1
|
|
fi
|
|
sleep 2
|
|
echo ""
|
|
|
|
# 4. Start Sensor service
|
|
if ! start_service "sensor" "attune-sensor"; then
|
|
echo -e "${RED}Failed to start Sensor service${NC}"
|
|
echo ""
|
|
echo -e "${YELLOW}Last 20 lines of Sensor log:${NC}"
|
|
tail -20 "$LOG_DIR/sensor.log" | sed 's/^/ /'
|
|
echo ""
|
|
echo -e "Full log: ${RED}$LOG_DIR/sensor.log${NC}"
|
|
exit 1
|
|
fi
|
|
sleep 2
|
|
echo ""
|
|
|
|
# 5. Start Notifier service
|
|
if ! start_service "notifier" "attune-notifier"; then
|
|
echo -e "${RED}Failed to start Notifier service${NC}"
|
|
echo ""
|
|
echo -e "${YELLOW}Last 20 lines of Notifier log:${NC}"
|
|
tail -20 "$LOG_DIR/notifier.log" | sed 's/^/ /'
|
|
echo ""
|
|
echo -e "Full log: ${RED}$LOG_DIR/notifier.log${NC}"
|
|
exit 1
|
|
fi
|
|
sleep 2
|
|
echo ""
|
|
|
|
# Display running services
|
|
echo -e "${GREEN}=== All Services Started ===${NC}\n"
|
|
echo -e "${GREEN}Running Services:${NC}"
|
|
for service in api executor worker sensor notifier; do
|
|
pid_file="$PID_DIR/$service.pid"
|
|
if [ -f "$pid_file" ]; then
|
|
pid=$(cat "$pid_file")
|
|
echo -e " • ${GREEN}$service${NC} (PID: $pid)"
|
|
fi
|
|
done
|
|
|
|
echo -e "\n${GREEN}Service Endpoints:${NC}"
|
|
echo -e " • API: ${BLUE}http://127.0.0.1:$API_PORT${NC}"
|
|
echo -e " • Health: ${BLUE}http://127.0.0.1:$API_PORT/health${NC}"
|
|
echo -e " • Docs: ${BLUE}http://127.0.0.1:$API_PORT/docs${NC}"
|
|
echo -e " • WebSocket: ${BLUE}ws://127.0.0.1:$NOTIFIER_WS_PORT${NC}"
|
|
|
|
echo -e "\n${GREEN}Logs:${NC}"
|
|
for service in api executor worker sensor notifier; do
|
|
echo -e " • $service: ${BLUE}$LOG_DIR/$service.log${NC}"
|
|
done
|
|
|
|
echo -e "\n${GREEN}Management:${NC}"
|
|
echo -e " • View logs: ${YELLOW}tail -f $LOG_DIR/<service>.log${NC}"
|
|
echo -e " • Stop all: ${YELLOW}./scripts/stop-e2e-services.sh${NC}"
|
|
echo -e " • Run tests: ${YELLOW}cargo test --test integration${NC}"
|
|
|
|
echo -e "\n${GREEN}Test User:${NC}"
|
|
echo -e " • Login: ${YELLOW}test@attune.local${NC}"
|
|
echo -e " • Password: ${YELLOW}TestPass123!${NC}"
|
|
|
|
echo -e "\n${GREEN}Quick Test:${NC}"
|
|
echo -e " ${YELLOW}curl http://127.0.0.1:$API_PORT/health"
|
|
echo -e " ${YELLOW}curl -X POST http://127.0.0.1:$API_PORT/auth/login \\"
|
|
echo -e " ${YELLOW} -H 'Content-Type: application/json' \\"
|
|
echo -e " ${YELLOW} -d '{\"login\":\"test@attune.local\",\"password\":\"TestPass123!\"}'${NC}"
|
|
|
|
echo ""
|