#!/bin/bash
set -e
echo "=========================================="
echo " CORTEX HUB INTEGRATION TESTS SETUP "
echo "=========================================="
# Ensure Docker is in PATH for macOS
export PATH=$PATH:/usr/local/bin:/opt/homebrew/bin
# 1. Provide an .env if missing
if [ ! -f ".env" ]; then
echo "Creating default .env for testing..."
echo "CORTEX_ADMIN_PASSWORD=admin" > .env
echo "SECRET_KEY=integration-secret-key-123" >> .env
echo "SUPER_ADMINS=axieyangb@gmail.com" >> .env
echo "GEMINI_API_KEY=AIzaSyBn5HYiZ8yKmNL0ambyz4Aspr5lKw1sKuI" >> .env
fi
# LOAD ENV FOR ALL SUBSEQUENT COMMANDS
set -a
source .env
set +a
# Load variables to use them in this script
export $(grep -v '^#' .env | xargs)
# Parse flags
NO_REBUILD=false
NATIVE_MODE=false
for arg in "$@"; do
if [[ "$arg" == "--no-rebuild" ]]; then
NO_REBUILD=true
fi
if [[ "$arg" == "--native" ]]; then
NATIVE_MODE=true
fi
done
# Check if docker daemon is reachable (i.e., not inside DevContainer without DIND) or if specifically skipped
DOCKER_AVAILABLE=false
if docker info >/dev/null 2>&1 && [ "$SKIP_DOCKER_NODES" != "true" ] && [ "$NATIVE_MODE" != "true" ]; then
DOCKER_AVAILABLE=true
export SKIP_DOCKER_NODES=false
else
echo "Docker skipping, not reachable, or Native mode requested. Skipping Docker nodes..."
export SKIP_DOCKER_NODES=true
DOCKER_AVAILABLE=false
fi
if [ "$NO_REBUILD" = true ] && [ "$IS_RUNNING" = true ]; then
echo "Service is already running and --no-rebuild flag provided."
echo "Skipping rebuild and starting tests directly..."
else
if [ "$DOCKER_AVAILABLE" = true ] && [ "$NATIVE_MODE" = false ]; then
# 2. Cleanup existing test environment
if docker info >/dev/null 2>&1; then
echo "Purging existing test/dev environment..."
# Stop default dev stack if running to avoid port 8002 conflict
docker compose stop ai-frontend ai-hub browser-service 2>/dev/null || true
docker-compose -p cortexai down -v
fi
echo "Purging database and old containers..."
docker compose down -v --remove-orphans
docker kill test-node-1 test-node-2 2>/dev/null || true
docker rm test-node-1 test-node-2 2>/dev/null || true
# 3. Build & start the Hub stack via the unified start_server.sh script
echo "Starting AI Hub mesh via ./start_server.sh..."
if [ "$NO_REBUILD" = true ]; then
bash ./start_server.sh
else
bash ./start_server.sh --rebuild
fi
# Wait for healthy
echo "Waiting for AI Hub to be ready..."
sleep 5
until curl -I -s http://localhost:8002/api/v1/users/login/local | grep -q "405"; do
echo "Waiting for AI Hub Backend..."
sleep 2
done
sleep 3
echo "AI Hub Backend is online."
else
# Start AI Hub Backend natively via uvicorn
echo "Starting AI Hub natively in the background..."
export DATABASE_URL="sqlite:///./data/ai-hub-test.db"
export ENVIRONMENT="development"
export PATH_PREFIX="/api/v1"
# Purge local test database
rm -f /tmp/cortex_hub_test.db
mkdir -p ai-hub/data
pkill -f uvicorn || true
pkill -f agent_node.main || true
sleep 1
if [ -d "ai-hub" ]; then
cd ai-hub
elif [ -d "/app/ai-hub" ]; then
cd /app/ai-hub
fi
if [ -f "../venv/bin/activate" ]; then source ../venv/bin/activate; elif [ -f "venv/bin/activate" ]; then source venv/bin/activate; elif [ -f "../cortex-ai/bin/activate" ]; then source ../cortex-ai/bin/activate; elif [ -f "/tmp/venv2/bin/activate" ]; then source /tmp/venv2/bin/activate; elif [ -f "/tmp/venv/bin/activate" ]; then source /tmp/venv/bin/activate; else echo "No venv found for uvicorn"; fi
PYTHONDONTWRITEBYTECODE=1 GRPC_PORT=50055 DATA_DIR=./data DATABASE_URL=sqlite:////tmp/cortex_hub_test.db AGENT_NODE_SRC_DIR=../agent-node SKILLS_SRC_DIR=../skills uvicorn app.main:app --host 0.0.0.0 --port 8010 > native_hub.log 2>&1 &
HUB_PID=$!
cd - > /dev/null
# Wait for healthy
echo "Waiting for AI Hub to be ready..."
sleep 2
until curl -I -s http://localhost:8010/api/v1/users/login/local | grep -q "405"; do
echo "Waiting for AI Hub Backend natively..."
sleep 2
done
sleep 3
echo "AI Hub Backend is online."
fi
fi
# 4. User setup via Pytest fixtures
echo "=========================================="
echo " EXECUTING E2E INTEGRATION SUITE "
echo "=========================================="
if [ "$NATIVE_MODE" = true ] || [ "$NATIVE" = 1 ] || [ "$DOCKER_AVAILABLE" = false ]; then
export SYNC_TEST_BASE_URL="http://127.0.0.1:8010/api/v1"
export TEST_HUB_URL="http://127.0.0.1:8010"
export TEST_GRPC_ENDPOINT="127.0.0.1:50055"
fi
if [ -f "cortex-ai/bin/activate" ]; then source cortex-ai/bin/activate; elif [ -f "/tmp/venv2/bin/activate" ]; then source /tmp/venv2/bin/activate; elif [ -f "venv/bin/activate" ]; then source venv/bin/activate; elif [ -f "/tmp/venv/bin/activate" ]; then source /tmp/venv/bin/activate; else echo "No venv found, hoping pytest is in global PATH."; fi
TEST_TARGETS=()
for arg in "$@"; do
if [[ "$arg" != "--no-rebuild" ]] && [[ "$arg" != "--native" ]]; then
TEST_TARGETS+=("$arg")
fi
done
if [ ${#TEST_TARGETS[@]} -eq 0 ]; then
TEST_TARGETS=("ai-hub/integration_tests/")
fi
PYTHONPATH=ai-hub python3 -m pytest "${TEST_TARGETS[@]}" -v
if [ "$NO_REBUILD" = false ] || [ "$IS_RUNNING" = false ]; then
echo "=========================================="
echo " TEARING DOWN INTEGRATION ENVIRONMENT "
if [ "$DOCKER_AVAILABLE" = true ]; then
docker compose down -v
else
kill $HUB_PID || true
fi
echo "Done!"
else
echo "=========================================="
echo " SKIPPING TEARDOWN DUE TO --no-rebuild "
echo "=========================================="
echo "Done!"
fi