| #!/bin/bash
|
|
|
|
|
|
|
|
|
| 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..."
|
|
|
|
|
| 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
|
|
|
|
|
| SHOULD_BUILD=false
|
| if [ ! -f "$BINARY_PATH" ]; then
|
| echo "Binary not found, will build..."
|
| SHOULD_BUILD=true
|
| else
|
|
|
| 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..."
|
|
|
| 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..."
|
|
|
|
|
| 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"
|
|
|
|
|
| for i in {1..10}; do
|
| if ! ps -p "$PID" > /dev/null 2>&1; then
|
| break
|
| fi
|
| sleep 1
|
| done
|
|
|
|
|
| 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
|
|
|