#!/usr/bin/env bash # Local E2E: build image, run container with .env secrets, smoke-test text + image. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" IMAGE="${E2E_IMAGE:-cursor-agent-api-proxy:latest}" PORT="${E2E_PORT:-18766}" CONTAINER="${E2E_CONTAINER:-cursor-agent-api-e2e}" TIMEOUT="${E2E_TIMEOUT:-180}" ENV_FILE="${REPO_ROOT}/.env" if [ ! -f "$ENV_FILE" ]; then echo "Error: .env not found at $ENV_FILE" >&2 exit 1 fi cleanup() { docker rm -f "$CONTAINER" >/dev/null 2>&1 || true } trap cleanup EXIT echo "==> Building $IMAGE" docker build -t "$IMAGE" "$ROOT" cleanup echo "==> Starting container (host network, PORT=$PORT)" docker run -d --name "$CONTAINER" --network host --env-file "$ENV_FILE" -e "PORT=$PORT" "$IMAGE" >/dev/null echo "==> Waiting for /health" for i in $(seq 1 60); do if curl -sf "http://127.0.0.1:${PORT}/health" >/dev/null 2>&1; then break fi if [ "$i" -eq 60 ]; then echo "Health check failed" >&2 docker logs "$CONTAINER" 2>&1 | tail -30 exit 1 fi sleep 1 done echo "==> Plain text chat" AUTH_ARGS=() if [ -n "${PROXY_INTERNAL_TOKEN:-}" ]; then AUTH_ARGS=(-H "Authorization: Bearer ${PROXY_INTERNAL_TOKEN}") fi TEXT_RESP="$(curl -sf --max-time "$TIMEOUT" "http://127.0.0.1:${PORT}/v1/chat/completions" \ "${AUTH_ARGS[@]}" \ -H "Content-Type: application/json" \ -d '{"model":"auto","stream":false,"messages":[{"role":"user","content":"Reply with exactly: HELLO"}]}')" echo "$TEXT_RESP" | grep -q '"content":"HELLO"' || { echo "Plain chat failed:" >&2 echo "$TEXT_RESP" >&2 exit 1 } echo "OK: plain chat" PNG_B64="iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==" echo "==> Image chat (data: PNG)" IMG_RESP="$(curl -sf --max-time "$TIMEOUT" "http://127.0.0.1:${PORT}/v1/chat/completions" \ "${AUTH_ARGS[@]}" \ -H "Content-Type: application/json" \ -d "{\"model\":\"auto\",\"stream\":false,\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What color is this 1x1 pixel? Reply with one color word only.\"},{\"type\":\"image_url\",\"image_url\":{\"url\":\"data:image/png;base64,${PNG_B64}\"}}]}]}")" echo "$IMG_RESP" | grep -q '"finish_reason":"stop"' || { echo "Image chat failed:" >&2 echo "$IMG_RESP" >&2 docker logs "$CONTAINER" 2>&1 | tail -40 exit 1 } CONTENT="$(echo "$IMG_RESP" | sed -n 's/.*"content":"\([^"]*\)".*/\1/p' | head -1)" if [ -z "$CONTENT" ]; then echo "Image chat returned empty content:" >&2 echo "$IMG_RESP" >&2 exit 1 fi echo "OK: image chat → $CONTENT" echo "==> All E2E checks passed"