#!/usr/bin/env bash set -euo pipefail PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" LOCAL_DEFAULT_PYTHON="$PROJECT_DIR/.venv/bin/python" LEGACY_DEFAULT_PYTHON="$PROJECT_DIR/../.venv/bin/python" PYTHON_BIN="${BILIUP_NEXT_PYTHON:-$LOCAL_DEFAULT_PYTHON}" HOST="${BILIUP_NEXT_SMOKE_HOST:-127.0.0.1}" PORT="${BILIUP_NEXT_SMOKE_PORT:-18787}" if [[ ! -x "$PYTHON_BIN" ]]; then if [[ -x "$LEGACY_DEFAULT_PYTHON" ]]; then PYTHON_BIN="$LEGACY_DEFAULT_PYTHON" else PYTHON_BIN="${BILIUP_NEXT_PYTHON:-python3}" fi fi if [[ ! -x "$PYTHON_BIN" ]]; then echo "python not found: $PYTHON_BIN" >&2 exit 1 fi API_PID="" cleanup() { if [[ -n "${API_PID:-}" ]]; then kill "$API_PID" >/dev/null 2>&1 || true wait "$API_PID" >/dev/null 2>&1 || true fi } trap cleanup EXIT cd "$PROJECT_DIR" echo "==> check generated files" for REQUIRED_FILE in \ "$PROJECT_DIR/config/settings.json" \ "$PROJECT_DIR/config/settings.staged.json" \ "$PROJECT_DIR/runtime/cookies.json" \ "$PROJECT_DIR/runtime/upload_config.json" do if [[ ! -f "$REQUIRED_FILE" ]]; then echo "missing file: $REQUIRED_FILE" >&2 exit 1 fi done echo "==> doctor" PYTHONPATH="$PROJECT_DIR/src" "$PYTHON_BIN" -m biliup_next.app.cli doctor >/dev/null echo "==> init-workspace" PYTHONPATH="$PROJECT_DIR/src" "$PYTHON_BIN" -m biliup_next.app.cli init-workspace >/dev/null echo "==> start api" PYTHONPATH="$PROJECT_DIR/src" "$PYTHON_BIN" -m biliup_next.app.cli serve --host "$HOST" --port "$PORT" >/tmp/biliup-next-cold-start-smoke.log 2>&1 & API_PID="$!" echo "==> wait for health" for _ in $(seq 1 40); do if "$PYTHON_BIN" - "$HOST" "$PORT" <<'PY' import json import sys import urllib.request host = sys.argv[1] port = sys.argv[2] try: with urllib.request.urlopen(f"http://{host}:{port}/health", timeout=0.5) as resp: payload = json.load(resp) if payload.get("ok") is True: raise SystemExit(0) except Exception: pass raise SystemExit(1) PY then break fi sleep 0.5 done echo "==> api settings schema" "$PYTHON_BIN" - "$HOST" "$PORT" <<'PY' import json import sys import urllib.request host = sys.argv[1] port = sys.argv[2] with urllib.request.urlopen(f"http://{host}:{port}/settings/schema", timeout=2) as resp: payload = json.load(resp) assert isinstance(payload, dict) assert payload.get("title") PY echo "==> api tasks" "$PYTHON_BIN" - "$HOST" "$PORT" <<'PY' import json import sys import urllib.request host = sys.argv[1] port = sys.argv[2] with urllib.request.urlopen(f"http://{host}:{port}/tasks?limit=5", timeout=2) as resp: payload = json.load(resp) assert isinstance(payload, dict) assert "items" in payload PY echo "==> cold start smoke ok"