axonhub / scripts /e2e /e2e-backend.sh
llzai's picture
Upload 1793 files
9853396 verified
#!/bin/bash
# E2E Backend Server Management Script
# This script manages the backend server for E2E testing
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
E2E_DB="${SCRIPT_DIR}/axonhub-e2e.db"
E2E_PORT=8099
BINARY_NAME="axonhub-e2e"
BINARY_PATH="${SCRIPT_DIR}/${BINARY_NAME}"
PID_FILE="${SCRIPT_DIR}/.e2e-backend.pid"
LOG_FILE="${SCRIPT_DIR}/e2e-backend.log"
DB_TYPE_FILE="${SCRIPT_DIR}/.e2e-backend-db-type"
DB_TYPE="${AXONHUB_E2E_DB_TYPE:-sqlite}"
MYSQL_CONTAINER="axonhub-e2e-mysql"
MYSQL_PORT=13306
MYSQL_ROOT_PASSWORD="axonhub_test_root"
MYSQL_DATABASE="axonhub_e2e"
MYSQL_USER="axonhub"
MYSQL_PASSWORD="axonhub_test"
POSTGRES_CONTAINER="axonhub-e2e-postgres"
POSTGRES_PORT=15432
POSTGRES_DATABASE="axonhub_e2e"
POSTGRES_USER="axonhub"
POSTGRES_PASSWORD="axonhub_test"
USE_EXISTING_DB="${AXONHUB_E2E_USE_EXISTING_DB:-false}"
check_docker() {
if ! command -v docker >/dev/null 2>&1; then
echo "Docker is required for ${DB_TYPE} database." >&2
exit 1
fi
if ! docker info >/dev/null 2>&1; then
echo "Docker daemon is not running." >&2
exit 1
fi
}
setup_mysql() {
check_docker
if docker ps -a --format '{{.Names}}' | grep -q "^${MYSQL_CONTAINER}$"; then
docker rm -f "$MYSQL_CONTAINER" >/dev/null 2>&1 || true
fi
docker run -d \
--name "$MYSQL_CONTAINER" \
-e MYSQL_ROOT_PASSWORD="$MYSQL_ROOT_PASSWORD" \
-e MYSQL_DATABASE="$MYSQL_DATABASE" \
-e MYSQL_USER="$MYSQL_USER" \
-e MYSQL_PASSWORD="$MYSQL_PASSWORD" \
-p "${MYSQL_PORT}:3306" \
mysql:8.0 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci \
>/dev/null
for i in {1..30}; do
if docker exec "$MYSQL_CONTAINER" mysqladmin ping -h localhost -u root -p"$MYSQL_ROOT_PASSWORD" >/dev/null 2>&1; then
return 0
fi
sleep 1
done
docker logs "$MYSQL_CONTAINER" >&2 || true
echo "MySQL failed to start." >&2
exit 1
}
setup_postgres() {
check_docker
if docker ps -a --format '{{.Names}}' | grep -q "^${POSTGRES_CONTAINER}$"; then
docker rm -f "$POSTGRES_CONTAINER" >/dev/null 2>&1 || true
fi
docker run -d \
--name "$POSTGRES_CONTAINER" \
-e POSTGRES_DB="$POSTGRES_DATABASE" \
-e POSTGRES_USER="$POSTGRES_USER" \
-e POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \
-p "${POSTGRES_PORT}:5432" \
postgres:15-alpine \
>/dev/null
for i in {1..30}; do
if docker exec "$POSTGRES_CONTAINER" pg_isready -U "$POSTGRES_USER" >/dev/null 2>&1; then
return 0
fi
sleep 1
done
docker logs "$POSTGRES_CONTAINER" >&2 || true
echo "PostgreSQL failed to start." >&2
exit 1
}
cleanup_database() {
local type="$1"
case "$type" in
mysql)
if [ "$USE_EXISTING_DB" != "true" ] && [ "${AXONHUB_E2E_KEEP_DB:-false}" != "true" ] && command -v docker >/dev/null 2>&1; then
docker rm -f "$MYSQL_CONTAINER" >/dev/null 2>&1 || true
fi
;;
postgres)
if [ "$USE_EXISTING_DB" != "true" ] && [ "${AXONHUB_E2E_KEEP_DB:-false}" != "true" ] && command -v docker >/dev/null 2>&1; then
docker rm -f "$POSTGRES_CONTAINER" >/dev/null 2>&1 || true
fi
;;
sqlite)
if [ "${AXONHUB_E2E_KEEP_DB:-false}" != "true" ]; then
rm -f "$E2E_DB"
fi
;;
esac
}
load_db_type() {
if [ -f "$DB_TYPE_FILE" ]; then
DB_TYPE=$(cat "$DB_TYPE_FILE")
else
DB_TYPE="${AXONHUB_E2E_DB_TYPE:-sqlite}"
fi
}
cd "$SCRIPT_DIR"
case "${1:-}" in
start)
echo "Starting E2E backend server..."
# Check if server is already running
if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")
if ps -p "$PID" > /dev/null 2>&1; then
echo "E2E backend server is already running (PID: $PID)"
exit 0
else
echo "Removing stale PID file"
rm -f "$PID_FILE"
fi
fi
load_db_type
case "$DB_TYPE" in
sqlite)
if [ -f "$E2E_DB" ]; then
echo "Removing old E2E database: $E2E_DB"
rm -f "$E2E_DB"
fi
DB_DIALECT="sqlite3"
DB_DSN="file:${E2E_DB}?cache=shared&_fk=1"
;;
mysql)
if [ "$USE_EXISTING_DB" = "true" ]; then
echo "Using existing MySQL database for E2E..."
else
echo "Preparing MySQL database for E2E..."
setup_mysql
fi
DB_DIALECT="${AXONHUB_E2E_DB_DIALECT:-mysql}"
if [ -n "${AXONHUB_E2E_DB_DSN:-}" ]; then
DB_DSN="$AXONHUB_E2E_DB_DSN"
else
DB_DSN="${MYSQL_USER}:${MYSQL_PASSWORD}@tcp(localhost:${MYSQL_PORT})/${MYSQL_DATABASE}?charset=utf8mb4&parseTime=True&loc=Local"
fi
;;
postgres)
if [ "$USE_EXISTING_DB" = "true" ]; then
echo "Using existing PostgreSQL database for E2E..."
else
echo "Preparing PostgreSQL database for E2E..."
setup_postgres
fi
DB_DIALECT="${AXONHUB_E2E_DB_DIALECT:-postgres}"
if [ -n "${AXONHUB_E2E_DB_DSN:-}" ]; then
DB_DSN="$AXONHUB_E2E_DB_DSN"
else
DB_DSN="host=localhost port=${POSTGRES_PORT} user=${POSTGRES_USER} password=${POSTGRES_PASSWORD} dbname=${POSTGRES_DATABASE} sslmode=disable"
fi
;;
*)
echo "Unsupported E2E database type: $DB_TYPE"
exit 1
;;
esac
# Build backend if binary doesn't exist or is older than 30 minutes
SHOULD_BUILD=false
if [ ! -f "$BINARY_PATH" ]; then
echo "Binary not found, will build..."
SHOULD_BUILD=true
else
# Check if binary is older than 30 minutes (1800 seconds)
CURRENT_TIME=$(date +%s)
BINARY_TIME=$(stat -c %Y "$BINARY_PATH" 2>/dev/null || stat -f %m "$BINARY_PATH" 2>/dev/null)
AGE=$((CURRENT_TIME - BINARY_TIME))
if [ $AGE -gt 1800 ]; then
echo "Binary is older than 30 minutes (age: $((AGE / 60)) minutes), will rebuild..."
SHOULD_BUILD=true
fi
fi
if [ "$SHOULD_BUILD" = true ]; then
echo "Building E2E backend..."
cd "$PROJECT_ROOT"
go build -o "$BINARY_PATH" ./cmd/axonhub
cd "$SCRIPT_DIR"
fi
echo "Using $DB_DSN database for E2E..."
# Start backend server with E2E configuration
echo "Starting backend on port $E2E_PORT using $DB_TYPE database..."
AXONHUB_SERVER_PORT=$E2E_PORT \
AXONHUB_DB_DIALECT="$DB_DIALECT" \
AXONHUB_DB_DSN="$DB_DSN" \
AXONHUB_LOG_OUTPUT="stdio" \
AXONHUB_LOG_LEVEL="debug" \
AXONHUB_LOG_ENCODING="console" \
nohup "$BINARY_PATH" > "$LOG_FILE" 2>&1 &
BACKEND_PID=$!
echo $BACKEND_PID > "$PID_FILE"
echo "$DB_TYPE" > "$DB_TYPE_FILE"
echo "E2E backend server started (PID: $BACKEND_PID)"
echo "Waiting for server to be ready..."
# Wait for server to be ready (max 30 seconds)
for i in {1..30}; do
if curl -s "http://localhost:$E2E_PORT/health" > /dev/null 2>&1 || \
curl -s "http://localhost:$E2E_PORT/" > /dev/null 2>&1; then
echo "E2E backend server is ready!"
exit 0
fi
sleep 1
done
echo "Warning: Server may not be ready yet. Check $LOG_FILE for details."
exit 0
;;
stop)
echo "Stopping E2E backend server..."
if [ ! -f "$PID_FILE" ]; then
echo "No PID file found. Server may not be running."
exit 0
fi
load_db_type
PID=$(cat "$PID_FILE")
if ps -p "$PID" > /dev/null 2>&1; then
echo "Stopping server (PID: $PID)..."
kill "$PID"
# Wait for process to stop
for i in {1..10}; do
if ! ps -p "$PID" > /dev/null 2>&1; then
break
fi
sleep 1
done
# Force kill if still running
if ps -p "$PID" > /dev/null 2>&1; then
echo "Force killing server..."
kill -9 "$PID"
fi
echo "E2E backend server stopped"
else
echo "Server process not found (PID: $PID)"
fi
rm -f "$PID_FILE"
if [ "${AXONHUB_E2E_KEEP_DB:-false}" != "true" ]; then
cleanup_database "$DB_TYPE"
rm -f "$DB_TYPE_FILE"
else
echo "Database preserved (--keep-db flag)"
rm -f "$DB_TYPE_FILE"
fi
;;
restart)
"$0" stop
sleep 2
"$0" start
;;
status)
if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")
if ps -p "$PID" > /dev/null 2>&1; then
echo "E2E backend server is running (PID: $PID)"
exit 0
else
echo "E2E backend server is not running (stale PID file)"
exit 1
fi
else
echo "E2E backend server is not running"
exit 1
fi
;;
clean)
echo "Cleaning E2E artifacts..."
"$0" stop
load_db_type
cleanup_database "$DB_TYPE"
rm -f "$E2E_DB" "$LOG_FILE" "$BINARY_PATH" "$DB_TYPE_FILE"
echo "E2E artifacts cleaned"
;;
*)
echo "Usage: $0 {start|stop|restart|status|clean}"
echo ""
echo "Commands:"
echo " start - Start E2E backend server (removes old DB, builds if needed)"
echo " stop - Stop E2E backend server"
echo " restart - Restart E2E backend server"
echo " status - Check E2E backend server status"
echo " clean - Stop server and remove E2E database and logs"
exit 1
;;
esac