feat(workflows): add MySQL and PostgreSQL configurations to unit test workflow
- Introduced MySQL and PostgreSQL environment variables in the unit test workflow for better database integration during testing. - Configured MySQL and PostgreSQL services in the workflow to ensure proper database connectivity and health checks. - Updated the sandbox-v2 environment file to include database connection details for local testing. Made-with: Cursor
This commit is contained in:
parent
7a5c573f10
commit
c7b36aa3b5
3 changed files with 148 additions and 31 deletions
15
.github/env/sandbox-v2.env
vendored
15
.github/env/sandbox-v2.env
vendored
|
|
@ -54,6 +54,21 @@ YAO_CI_SANDBOX_IMAGE=yaoapp/tai-sandbox-test:latest
|
||||||
# -- Tunnel --
|
# -- Tunnel --
|
||||||
YAO_CI_TUNNEL=true
|
YAO_CI_TUNNEL=true
|
||||||
|
|
||||||
|
# ========================================
|
||||||
|
# Database (MySQL / PostgreSQL / SQLite)
|
||||||
|
# ========================================
|
||||||
|
MYSQL_TEST_HOST=127.0.0.1
|
||||||
|
MYSQL_TEST_PORT=3308
|
||||||
|
MYSQL_TEST_USER=test
|
||||||
|
MYSQL_TEST_PASS=123456
|
||||||
|
|
||||||
|
PG_TEST_HOST=127.0.0.1
|
||||||
|
PG_TEST_PORT=5432
|
||||||
|
PG_TEST_USER=test
|
||||||
|
PG_TEST_PASS=123456
|
||||||
|
|
||||||
|
SQLITE_DB=./app/db/yao.db
|
||||||
|
|
||||||
# ========================================
|
# ========================================
|
||||||
# Legacy variable mapping (migrate later)
|
# Legacy variable mapping (migrate later)
|
||||||
# ========================================
|
# ========================================
|
||||||
|
|
|
||||||
160
.github/workflows/unit-test-v1.yml
vendored
160
.github/workflows/unit-test-v1.yml
vendored
|
|
@ -33,6 +33,11 @@ env:
|
||||||
YAO_RUNTIME_HEAP_AVAILABLE: 550000000
|
YAO_RUNTIME_HEAP_AVAILABLE: 550000000
|
||||||
YAO_RUNTIME_PRECOMPILE: true
|
YAO_RUNTIME_PRECOMPILE: true
|
||||||
|
|
||||||
|
MYSQL_TEST_HOST: "127.0.0.1"
|
||||||
|
MYSQL_TEST_PORT: "3308"
|
||||||
|
MYSQL_TEST_USER: "test"
|
||||||
|
MYSQL_TEST_PASS: "123456"
|
||||||
|
|
||||||
REDIS_TEST_HOST: "127.0.0.1"
|
REDIS_TEST_HOST: "127.0.0.1"
|
||||||
REDIS_TEST_PORT: "6379"
|
REDIS_TEST_PORT: "6379"
|
||||||
REDIS_TEST_DB: "2"
|
REDIS_TEST_DB: "2"
|
||||||
|
|
@ -42,6 +47,11 @@ env:
|
||||||
MONGO_TEST_USER: "root"
|
MONGO_TEST_USER: "root"
|
||||||
MONGO_TEST_PASS: "123456"
|
MONGO_TEST_PASS: "123456"
|
||||||
|
|
||||||
|
PG_TEST_HOST: "127.0.0.1"
|
||||||
|
PG_TEST_PORT: "5432"
|
||||||
|
PG_TEST_USER: "test"
|
||||||
|
PG_TEST_PASS: "123456"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Environment Setup & Verification
|
# Environment Setup & Verification
|
||||||
|
|
@ -60,6 +70,37 @@ jobs:
|
||||||
MONGO_INITDB_ROOT_PASSWORD: 123456
|
MONGO_INITDB_ROOT_PASSWORD: 123456
|
||||||
MONGO_INITDB_DATABASE: test
|
MONGO_INITDB_DATABASE: test
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
image: mysql:8.0
|
||||||
|
ports:
|
||||||
|
- 3308:3306
|
||||||
|
env:
|
||||||
|
MYSQL_ROOT_PASSWORD: 123456
|
||||||
|
MYSQL_USER: test
|
||||||
|
MYSQL_PASSWORD: 123456
|
||||||
|
MYSQL_DATABASE: test
|
||||||
|
options: >-
|
||||||
|
--health-cmd="mysqladmin ping -h 127.0.0.1"
|
||||||
|
--health-interval=10s
|
||||||
|
--health-timeout=5s
|
||||||
|
--health-retries=5
|
||||||
|
--character-set-server=utf8mb4
|
||||||
|
--collation-server=utf8mb4_general_ci
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: postgres:14
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
env:
|
||||||
|
POSTGRES_USER: test
|
||||||
|
POSTGRES_PASSWORD: 123456
|
||||||
|
POSTGRES_DB: test
|
||||||
|
options: >-
|
||||||
|
--health-cmd="pg_isready -U test"
|
||||||
|
--health-interval=10s
|
||||||
|
--health-timeout=5s
|
||||||
|
--health-retries=5
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go: ["1.25"]
|
go: ["1.25"]
|
||||||
|
|
@ -147,10 +188,13 @@ jobs:
|
||||||
--user-id "${YAO_CI_OAUTH_USER_ID}" \
|
--user-id "${YAO_CI_OAUTH_USER_ID}" \
|
||||||
--team-id "${YAO_CI_OAUTH_TEAM_ID}" \
|
--team-id "${YAO_CI_OAUTH_TEAM_ID}" \
|
||||||
--scope "${YAO_CI_OAUTH_SCOPE:-tai:tunnel}" \
|
--scope "${YAO_CI_OAUTH_SCOPE:-tai:tunnel}" \
|
||||||
--ttl "${YAO_CI_OAUTH_TTL:-24h}")
|
--ttl "${YAO_CI_OAUTH_TTL:-24h}" 2>/dev/null | tail -1 | tr -d '[:space:]')
|
||||||
|
|
||||||
echo -n "{\"client_id\":\"$CID\",\"tai_id\":\"$TID\",\"machine_id\":\"ci-runner\",\"server\":\"http://${YAO_CI_BRIDGE_IP}:${YAO_CI_HTTP_PORT}\",\"yao_grpc_addr\":\"${YAO_CI_BRIDGE_IP}:${YAO_CI_GRPC_PORT}\",\"access_token\":\"$TOKEN\",\"scope\":\"${YAO_CI_OAUTH_SCOPE}\",\"expires_at\":\"2099-01-01T00:00:00Z\",\"registered\":true}" \
|
local JSON="{\"client_id\":\"$CID\",\"tai_id\":\"$TID\",\"machine_id\":\"ci-runner\",\"server\":\"http://${YAO_CI_BRIDGE_IP}:${YAO_CI_HTTP_PORT}\",\"yao_grpc_addr\":\"${YAO_CI_BRIDGE_IP}:${YAO_CI_GRPC_PORT}\",\"access_token\":\"$TOKEN\",\"scope\":\"${YAO_CI_OAUTH_SCOPE}\",\"expires_at\":\"2099-01-01T00:00:00Z\",\"registered\":true}"
|
||||||
| base64 > "$OUT"
|
echo -n "$JSON" | base64 -w0 > "$OUT"
|
||||||
|
echo ""
|
||||||
|
echo "Credentials JSON (debug): $JSON" | head -c 200
|
||||||
|
echo "..."
|
||||||
echo "Generated credentials for $CID → $OUT"
|
echo "Generated credentials for $CID → $OUT"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -263,49 +307,103 @@ jobs:
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "=== Environment Verification ==="
|
echo "=== Environment Verification ==="
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "--- Yao ---"
|
# ── 1. Service Health ──
|
||||||
|
echo ""
|
||||||
|
echo "--- 1. Service Health ---"
|
||||||
|
|
||||||
|
echo "[Yao]"
|
||||||
check "Yao HTTP (/.well-known/yao)" curl -sf http://127.0.0.1:5099/.well-known/yao
|
check "Yao HTTP (/.well-known/yao)" curl -sf http://127.0.0.1:5099/.well-known/yao
|
||||||
check "Yao gRPC port" nc -z 127.0.0.1 9099
|
check "Yao gRPC port" nc -z 127.0.0.1 9099
|
||||||
|
|
||||||
echo ""
|
echo "[tai-docker]"
|
||||||
echo "--- tai-docker ---"
|
|
||||||
check "tai-docker HTTP (/healthz)" curl -sf http://127.0.0.1:${YAO_CI_TAI_HTTP_PORT}/healthz
|
check "tai-docker HTTP (/healthz)" curl -sf http://127.0.0.1:${YAO_CI_TAI_HTTP_PORT}/healthz
|
||||||
check "tai-docker gRPC port" nc -z 127.0.0.1 ${YAO_CI_TAI_GRPC_PORT}
|
check "tai-docker gRPC port" nc -z 127.0.0.1 ${YAO_CI_TAI_GRPC_PORT}
|
||||||
|
|
||||||
echo ""
|
echo "[tai-k8s]"
|
||||||
echo "--- tai-k8s ---"
|
|
||||||
check "tai-k8s HTTP (/healthz)" curl -sf http://127.0.0.1:8100/healthz
|
check "tai-k8s HTTP (/healthz)" curl -sf http://127.0.0.1:8100/healthz
|
||||||
check "tai-k8s gRPC port" nc -z 127.0.0.1 ${YAO_CI_TAI_K8S_GRPC_PORT}
|
check "tai-k8s gRPC port" nc -z 127.0.0.1 ${YAO_CI_TAI_K8S_GRPC_PORT}
|
||||||
|
|
||||||
echo ""
|
echo "[K8s (k3d)]"
|
||||||
echo "--- Tai Tunnel Registration ---"
|
check "kubectl get nodes" kubectl --kubeconfig=$RUNNER_TEMP/kubeconfig-tai.yml get nodes
|
||||||
sleep 5
|
|
||||||
echo "tai-docker tunnel logs:"
|
echo "[Data Stores]"
|
||||||
docker logs tai-docker 2>&1 | grep -iE "tunnel|register|connected" | tail -5 || true
|
MONGO_CID=$(docker ps -qf "ancestor=mongo:6.0" | head -1)
|
||||||
echo "tai-k8s tunnel logs:"
|
check "MongoDB ping" docker exec "$MONGO_CID" mongosh --quiet \
|
||||||
docker logs tai-k8s 2>&1 | grep -iE "tunnel|register|connected" | tail -5 || true
|
-u ${MONGO_TEST_USER} -p ${MONGO_TEST_PASS} --authenticationDatabase admin \
|
||||||
|
--eval "db.runCommand({ping:1})"
|
||||||
|
|
||||||
|
MYSQL_CID=$(docker ps -qf "ancestor=mysql:8.0" | head -1)
|
||||||
|
check "MySQL ping" docker exec "$MYSQL_CID" mysqladmin ping -h 127.0.0.1 \
|
||||||
|
-u ${MYSQL_TEST_USER} -p${MYSQL_TEST_PASS}
|
||||||
|
|
||||||
|
PG_CID=$(docker ps -qf "ancestor=postgres:14" | head -1)
|
||||||
|
check "PostgreSQL ping" docker exec "$PG_CID" pg_isready -U ${PG_TEST_USER}
|
||||||
|
|
||||||
|
check "Redis ping" docker exec redis redis-cli ping
|
||||||
|
|
||||||
|
# ── 2. Network Topology ──
|
||||||
|
echo ""
|
||||||
|
echo "--- 2. Network Topology ---"
|
||||||
|
|
||||||
|
BRIDGE_IP=${YAO_CI_BRIDGE_IP}
|
||||||
|
echo " docker0 bridge IP: ${BRIDGE_IP}"
|
||||||
|
|
||||||
|
echo "[Runner → Bridge]"
|
||||||
|
check "Bridge IP exists" ip addr show docker0
|
||||||
|
check "Bridge IP reachable" ping -c1 -W2 ${BRIDGE_IP}
|
||||||
|
|
||||||
|
echo "[Runner → Tai Docker API]"
|
||||||
|
check "Tai Docker API (tcp://127.0.0.1:${YAO_CI_TAI_DOCKER_PORT})" \
|
||||||
|
nc -z 127.0.0.1 ${YAO_CI_TAI_DOCKER_PORT}
|
||||||
|
|
||||||
|
echo "[Runner → Tai K8s API proxy]"
|
||||||
|
check "Tai K8s API (127.0.0.1:${YAO_CI_TAI_K8S_PORT})" \
|
||||||
|
nc -z 127.0.0.1 ${YAO_CI_TAI_K8S_PORT}
|
||||||
|
|
||||||
|
echo "[tai-docker → Yao via bridge]"
|
||||||
|
check "tai-docker→Yao HTTP (bridge)" \
|
||||||
|
docker exec tai-docker wget -q -O /dev/null --timeout=3 \
|
||||||
|
http://${BRIDGE_IP}:${YAO_CI_HTTP_PORT}/.well-known/yao
|
||||||
|
check "tai-docker→Yao gRPC (bridge)" \
|
||||||
|
docker exec tai-docker nc -z -w3 ${BRIDGE_IP} ${YAO_CI_GRPC_PORT}
|
||||||
|
|
||||||
|
echo "[tai-k8s → Yao via bridge]"
|
||||||
|
check "tai-k8s→Yao HTTP (bridge)" \
|
||||||
|
docker exec tai-k8s wget -q -O /dev/null --timeout=3 \
|
||||||
|
http://${BRIDGE_IP}:${YAO_CI_HTTP_PORT}/.well-known/yao
|
||||||
|
check "tai-k8s→Yao gRPC (bridge)" \
|
||||||
|
docker exec tai-k8s nc -z -w3 ${BRIDGE_IP} ${YAO_CI_GRPC_PORT}
|
||||||
|
|
||||||
|
echo "[tai-k8s → k3d API server]"
|
||||||
|
K3D_IP=$(docker inspect k3d-tai-test-server-0 2>/dev/null \
|
||||||
|
| jq -r '.[0].NetworkSettings.Networks["k3d-tai-test"].IPAddress' 2>/dev/null || echo "")
|
||||||
|
if [ -n "$K3D_IP" ] && [ "$K3D_IP" != "null" ]; then
|
||||||
|
check "tai-k8s→k3d API (${K3D_IP}:6443)" \
|
||||||
|
docker exec tai-k8s nc -z -w3 ${K3D_IP} 6443
|
||||||
|
else
|
||||||
|
echo " [SKIP] k3d IP not found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 3. Tai Tunnel Registration ──
|
||||||
|
echo ""
|
||||||
|
echo "--- 3. Tai Tunnel Registration ---"
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo "tai-docker tunnel logs:"
|
||||||
|
docker logs tai-docker 2>&1 | grep -iE "tunnel|register|connect" | tail -5 || true
|
||||||
|
echo "tai-k8s tunnel logs:"
|
||||||
|
docker logs tai-k8s 2>&1 | grep -iE "tunnel|register|connect" | tail -5 || true
|
||||||
|
|
||||||
|
check "tai-docker tunnel connected" \
|
||||||
|
bash -c 'docker logs tai-docker 2>&1 | grep -qiE "tunnel.*(connected|registered|established)"'
|
||||||
|
check "tai-k8s tunnel connected" \
|
||||||
|
bash -c 'docker logs tai-k8s 2>&1 | grep -qiE "tunnel.*(connected|registered|established)"'
|
||||||
|
|
||||||
# Check if Tai instances appear registered via Yao
|
|
||||||
WELL_KNOWN=$(curl -sf http://127.0.0.1:5099/.well-known/yao 2>/dev/null || echo "{}")
|
WELL_KNOWN=$(curl -sf http://127.0.0.1:5099/.well-known/yao 2>/dev/null || echo "{}")
|
||||||
echo "Yao .well-known/yao:"
|
echo "Yao .well-known/yao:"
|
||||||
echo "$WELL_KNOWN" | jq . 2>/dev/null || echo "$WELL_KNOWN"
|
echo "$WELL_KNOWN" | jq . 2>/dev/null || echo "$WELL_KNOWN"
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "--- K8s (k3d) ---"
|
|
||||||
check "kubectl get nodes" kubectl --kubeconfig=$RUNNER_TEMP/kubeconfig-tai.yml get nodes
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "--- MongoDB ---"
|
|
||||||
check "MongoDB ping" mongosh --quiet --host 127.0.0.1 --port 27017 \
|
|
||||||
-u root -p 123456 --authenticationDatabase admin \
|
|
||||||
--eval "db.runCommand({ping:1})"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "--- Redis ---"
|
|
||||||
check "Redis ping" docker exec redis redis-cli ping
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "=========================================="
|
echo "=========================================="
|
||||||
if [ $FAILED -gt 0 ]; then
|
if [ $FAILED -gt 0 ]; then
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ func main() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
savedStdout := os.Stdout
|
||||||
|
os.Stdout, _ = os.Open(os.DevNull)
|
||||||
|
|
||||||
config.Conf = config.LoadFrom(filepath.Join(root, ".env"))
|
config.Conf = config.LoadFrom(filepath.Join(root, ".env"))
|
||||||
config.Conf.Root = root
|
config.Conf.Root = root
|
||||||
|
|
||||||
|
|
@ -42,6 +45,7 @@ func main() {
|
||||||
cfg.Session.IsCLI = true
|
cfg.Session.IsCLI = true
|
||||||
|
|
||||||
warnings, err := engine.Load(cfg, engine.LoadOption{Action: "run"})
|
warnings, err := engine.Load(cfg, engine.LoadOption{Action: "run"})
|
||||||
|
os.Stdout = savedStdout
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "ci-token: engine.Load failed: %v\n", err)
|
fmt.Fprintf(os.Stderr, "ci-token: engine.Load failed: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue