#!/bin/bash # 启动测试环境脚本 # 用于在commit前自动化测试时启动必要的依赖服务 set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 配置 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" TEST_LOG_DIR="$PROJECT_ROOT/test_logs" PID_FILE="$PROJECT_ROOT/test_environment.pid" # 日志文件 LOG_FILE="$TEST_LOG_DIR/test_environment.log" ES_LOG_FILE="$TEST_LOG_DIR/elasticsearch.log" API_LOG_FILE="$TEST_LOG_DIR/api_test.log" echo -e "${GREEN}========================================${NC}" echo -e "${GREEN}启动测试环境${NC}" echo -e "${GREEN}========================================${NC}" # 创建日志目录 mkdir -p "$TEST_LOG_DIR" # 检查是否已经运行 if [ -f "$PID_FILE" ]; then OLD_PID=$(cat "$PID_FILE") if ps -p $OLD_PID > /dev/null 2>&1; then echo -e "${YELLOW}测试环境已在运行 (PID: $OLD_PID)${NC}" echo -e "${BLUE}如需重启,请先运行: ./scripts/stop_test_environment.sh${NC}" exit 0 else rm -f "$PID_FILE" fi fi # 激活conda环境 echo -e "${BLUE}激活conda环境...${NC}" source /home/tw/miniconda3/etc/profile.d/conda.sh conda activate searchengine # 设置环境变量 echo -e "${BLUE}设置测试环境变量...${NC}" export PYTHONPATH="$PROJECT_ROOT:$PYTHONPATH" export TESTING_MODE=true export LOG_LEVEL=DEBUG # Elasticsearch配置 export ES_HOST="http://localhost:9200" export ES_USERNAME="elastic" export ES_PASSWORD="changeme" # API配置 export API_HOST="127.0.0.1" export API_PORT="6003" # 使用不同的端口避免冲突 export TENANT_ID="test_tenant" # 测试配置 export TEST_TIMEOUT=60 export TEST_RETRY_COUNT=3 echo -e "${BLUE}环境配置:${NC}" echo " ES_HOST: $ES_HOST" echo " API_HOST: $API_HOST:$API_PORT" echo " TENANT_ID: $TENANT_ID" echo " LOG_LEVEL: $LOG_LEVEL" echo " TESTING_MODE: $TESTING_MODE" # 检查Elasticsearch是否运行 echo -e "${BLUE}检查Elasticsearch状态...${NC}" if curl -s "$ES_HOST/_cluster/health" > /dev/null; then echo -e "${GREEN}✓ Elasticsearch正在运行${NC}" else echo -e "${YELLOW}⚠ Elasticsearch未运行,尝试启动...${NC}" # 尝试启动Elasticsearch(如果安装了本地版本) if command -v elasticsearch &> /dev/null; then echo -e "${BLUE}启动本地Elasticsearch...${NC}" elasticsearch -d -p "$TEST_LOG_DIR/es.pid" sleep 10 # 再次检查 if curl -s "$ES_HOST/_cluster/health" > /dev/null; then echo -e "${GREEN}✓ Elasticsearch启动成功${NC}" else echo -e "${RED}✗ Elasticsearch启动失败${NC}" echo -e "${YELLOW}请手动启动Elasticsearch或配置远程ES地址${NC}" exit 1 fi else echo -e "${RED}✗ 未找到本地Elasticsearch${NC}" echo -e "${YELLOW}请启动Elasticsearch服务或修改ES_HOST配置${NC}" exit 1 fi fi # 等待Elasticsearch就绪 echo -e "${BLUE}等待Elasticsearch就绪...${NC}" for i in {1..30}; do if curl -s "$ES_HOST/_cluster/health?wait_for_status=yellow&timeout=1s" | grep -q '"status":"green\|yellow"'; then echo -e "${GREEN}✓ Elasticsearch已就绪${NC}" break fi if [ $i -eq 30 ]; then echo -e "${RED}✗ Elasticsearch就绪超时${NC}" exit 1 fi sleep 1 done # 创建测试索引(如果需要) echo -e "${BLUE}准备测试数据索引...${NC}" curl -X PUT "$ES_HOST/test_products" -H 'Content-Type: application/json' -d' { "settings": { "number_of_shards": 1, "number_of_replicas": 0, "analysis": { "analyzer": { "ansj": { "type": "custom", "tokenizer": "keyword" } } } }, "mappings": { "properties": { "name": { "type": "text", "analyzer": "ansj" }, "brand_name": { "type": "text", "analyzer": "ansj" }, "tags": { "type": "text", "analyzer": "ansj" }, "price": { "type": "double" }, "category_id": { "type": "integer" }, "spu_id": { "type": "keyword" }, "text_embedding": { "type": "dense_vector", "dims": 1024 } } } }' > /dev/null 2>&1 || echo -e "${YELLOW}索引可能已存在${NC}" # 插入测试数据 echo -e "${BLUE}插入测试数据...${NC}" curl -X POST "$ES_HOST/test_products/_bulk" -H 'Content-Type: application/json' -d' {"index": {"_id": "1"}} {"name": "红色连衣裙", "brand_name": "测试品牌", "tags": ["红色", "连衣裙", "女装"], "price": 299.0, "category_id": 1, "spu_id": "dress_001"} {"index": {"_id": "2"}} {"name": "蓝色连衣裙", "brand_name": "测试品牌", "tags": ["蓝色", "连衣裙", "女装"], "price": 399.0, "category_id": 1, "spu_id": "dress_002"} {"index": {"_id": "3"}} {"name": "智能手机", "brand_name": "科技品牌", "tags": ["智能", "手机", "数码"], "price": 2999.0, "category_id": 2, "spu_id": "phone_001"} {"index": {"_id": "4"}} {"name": "笔记本电脑", "brand_name": "科技品牌", "tags": ["笔记本", "电脑", "办公"], "price": 5999.0, "category_id": 3, "spu_id": "laptop_001"} ' > /dev/null 2>&1 || echo -e "${YELLOW}测试数据可能已存在${NC}" # 启动测试API服务 echo -e "${BLUE}启动测试API服务...${NC}" cd "$PROJECT_ROOT" # 使用后台模式启动API python -m api.app \ --host $API_HOST \ --port $API_PORT \ --tenant $TENANT_ID \ --es-host $ES_HOST \ > "$API_LOG_FILE" 2>&1 & API_PID=$! echo $API_PID > "$PID_FILE" # 等待API服务启动 echo -e "${BLUE}等待API服务启动...${NC}" for i in {1..30}; do if curl -s "http://$API_HOST:$API_PORT/health" > /dev/null; then echo -e "${GREEN}✓ API服务已就绪 (PID: $API_PID)${NC}" break fi if [ $i -eq 30 ]; then echo -e "${RED}✗ API服务启动超时${NC}" kill $API_PID 2>/dev/null || true rm -f "$PID_FILE" exit 1 fi sleep 1 done # 验证测试环境 echo -e "${BLUE}验证测试环境...${NC}" # 测试Elasticsearch连接 if curl -s "$ES_HOST/_cluster/health" | grep -q '"status":"green\|yellow"'; then echo -e "${GREEN}✓ Elasticsearch连接正常${NC}" else echo -e "${RED}✗ Elasticsearch连接失败${NC}" exit 1 fi # 测试API健康检查 if curl -s "http://$API_HOST:$API_PORT/health" | grep -q '"status"'; then echo -e "${GREEN}✓ API服务健康检查通过${NC}" else echo -e "${RED}✗ API服务健康检查失败${NC}" exit 1 fi # 测试基本搜索功能 if curl -s "http://$API_HOST:$API_PORT/search?q=红色连衣裙" | grep -q '"hits"'; then echo -e "${GREEN}✓ 基本搜索功能正常${NC}" else echo -e "${YELLOW}⚠ 基本搜索功能可能有问题,但继续进行${NC}" fi # 输出环境信息 echo -e "${GREEN}========================================${NC}" echo -e "${GREEN}测试环境启动完成!${NC}" echo -e "${GREEN}========================================${NC}" echo -e "${BLUE}服务信息:${NC}" echo " Elasticsearch: $ES_HOST" echo " API服务: http://$API_HOST:$API_PORT" echo " 测试客户: $TENANT_ID" echo -e "${BLUE}进程信息:${NC}" echo " API PID: $API_PID" echo " PID文件: $PID_FILE" echo -e "${BLUE}日志文件:${NC}" echo " 环境日志: $LOG_FILE" echo " API日志: $API_LOG_FILE" echo " ES日志: $ES_LOG_FILE" echo -e "${BLUE}测试命令:${NC}" echo " 运行所有测试: python scripts/run_tests.py" echo " 单元测试: pytest tests/unit/ -v" echo " 集成测试: pytest tests/integration/ -v" echo " API测试: pytest tests/integration/test_api_integration.py -v" echo "e${NC}" echo -e "${BLUE}停止环境: ./scripts/stop_test_environment.sh${NC}" # 保存环境变量到文件供测试脚本使用 cat > "$PROJECT_ROOT/test_env.sh" << EOF #!/bin/bash export ES_HOST="$ES_HOST" export ES_USERNAME="$ES_USERNAME" export ES_PASSWORD="$ES_PASSWORD" export API_HOST="$API_HOST" export API_PORT="$API_PORT" export TENANT_ID="$TENANT_ID" export TESTING_MODE="$TESTING_MODE" export LOG_LEVEL="$LOG_LEVEL" export PYTHONPATH="$PROJECT_ROOT:\$PYTHONPATH" EOF chmod +x "$PROJECT_ROOT/test_env.sh" echo -e "${GREEN}测试环境已准备就绪!${NC}"