Azure Pipeline中运行Google Cloud Spanner Emulator集成测试遇连接错误求助
问题描述
我有一个Go应用,正在使用Azure Pipeline编写集成测试。Azure构建.yaml配置如下:
... - job: Run_Go_Integration_Tests displayName: 'Run Go Integration Tests' steps: - script: | sudo add-apt-repository ppa:longsleep/golang-backports sudo apt update sudo apt install golang-go displayName: 'Install Go' - script: | go version displayName: 'Check Go Version' - task: GoogleCloudSdkTool@1 inputs: checkLatest: true - script: | make ci-itest displayName: 'Running Integration Tests'
make ci-itest执行的相关前置命令如下:
##@ Initialize Spanner gcloud-config: ## Initialize Cloud Spanner Emulator and create emulator config @echo "Creating emulator configuration..." gcloud config configurations create emulator gcloud config set auth/disable_credentials true gcloud config set project ${DEV_SPANNER_PROJECT} gcloud config set api_endpoint_overrides/spanner http://localhost:9020/ gcloud config configurations activate emulator ci-start-spanner: ## Start Cloud Spanner Emulator for CI gcloud components update --quiet @echo "Starting cloud spanner..." gcloud emulators spanner start --quiet &
执行gcloud emulators spanner start时触发如下NewConnectionError错误:
$ gcloud emulators spanner start --quiet Executing: /opt/hostedtoolcache/gcloud/448.0.0/x64/bin/cloud_spanner_emulator/gateway_main --hostname localhost --grpc_port 9010 --http_port 9020 [cloud-spanner-emulator] WARNING: proto: file "google/rpc/status.proto" is already registered [cloud-spanner-emulator] previously from: "google.golang.org/genproto/googleapis/rpc/status" [cloud-spanner-emulator] currently from: "unknown" [cloud-spanner-emulator] See https://protobuf.dev/reference/go/faq#namespace-conflict [cloud-spanner-emulator] [cloud-spanner-emulator] WARNING: proto: file "google/rpc/status.proto" has a name conflict over google.rpc.Status [cloud-spanner-emulator] previously from: "google.golang.org/genproto/googleapis/rpc/status" [cloud-spanner-emulator] currently from: "unknown" [cloud-spanner-emulator] See https://protobuf.dev/reference/go/faq#namespace-conflict [cloud-spanner-emulator] [cloud-spanner-emulator] WARNING: proto: message google.rpc.Status is already registered [cloud-spanner-emulator] previously from: "google.golang.org/genproto/googleapis/rpc/status" [cloud-spanner-emulator] currently from: "unknown" [cloud-spanner-emulator] See https://protobuf.dev/reference/go/faq#namespace-conflict [cloud-spanner-emulator] [cloud-spanner-emulator] WARNING: All log messages before absl::InitializeLog() is called are written to STDERR [cloud-spanner-emulator] I0000 00:00:1695827664.387924 4075 emulator_main.cc:39] Cloud Spanner Emulator running. [cloud-spanner-emulator] I0000 00:00:1695827664.387942 4075 emulator_main.cc:40] Server address: localhost:9010 ERROR: gcloud crashed (ConnectionError): HTTPConnectionPool(host='localhost', port=9020): Max retries exceeded with url: /v1/projects/local/instances?alt=json (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fecb45060d0>: Failed to establish a new connection: [Errno 111] Connection refused'))
解决建议
添加模拟器启动等待逻辑
目前用&将模拟器后台运行,但后续操作没有等待模拟器完成初始化就发起请求,导致连接拒绝。可以在启动命令后加入端口检查循环,确保模拟器就绪:ci-start-spanner: ## Start Cloud Spanner Emulator for CI gcloud components update --quiet @echo "Starting cloud spanner..." gcloud emulators spanner start --quiet & @echo "Waiting for Spanner emulator to be ready..." while ! nc -z localhost 9020; do sleep 1; done若Azure代理未预装
netcat,可在前置步骤添加sudo apt install netcat安装。检查端口占用情况
9020端口可能被其他进程占用,导致模拟器无法正常监听。启动前可检查端口状态:lsof -i :9020 || echo "Port 9020 is free"也可以更换未被占用的端口,修改启动命令和配置中的端口值:
# 修改启动端口为9021 gcloud emulators spanner start --quiet --http-port 9021 & # 同步更新配置中的端点 gcloud config set api_endpoint_overrides/spanner http://localhost:9021修正gcloud端点配置格式
移除端点URL末尾的斜杠,避免潜在的路径解析问题:gcloud config set api_endpoint_overrides/spanner http://localhost:9020使用模拟器环境变量替代手动配置
通过gcloud emulators spanner env-init自动获取正确的环境变量,避免手动配置出错:gcloud-config: ## Initialize Cloud Spanner Emulator and create emulator config @echo "Setting up Spanner emulator environment..." gcloud emulators spanner start --quiet & # 等待模拟器就绪 while ! nc -z localhost 9020; do sleep 1; done # 加载模拟器环境变量 $(eval $(gcloud emulators spanner env-init | sed 's/^export //')) gcloud config set auth/disable_credentials true gcloud config set project ${DEV_SPANNER_PROJECT}升级gcloud SDK版本
当前使用的gcloud 448.0.0版本可能存在模拟器端口监听的兼容性问题,尝试升级到最新稳定版。在Azure Pipeline的GoogleCloudSdkTool@1任务中指定版本:- task: GoogleCloudSdkTool@1 inputs: version: 'latest' # 或指定具体稳定版本如460.0.0
内容的提问来源于stack exchange,提问作者adam2k
相关产品推荐
相关产品推荐

