OmniRoute/bin/cold-start-bench.sh
Diego Rodrigues de Sa e Souza 7c23dab64d
Some checks are pending
Publish Fork Image to GHCR / Build and Push Fork Image (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Change Classification (push) Waiting to run
CI / Quality Ratchet (push) Blocked by required conditions
CI / Quality Gates (Extended) (push) Waiting to run
CI / Docs Sync (Strict) (push) Waiting to run
CI / Docs Lint (prose — advisory) (push) Waiting to run
CI / i18n UI Coverage (push) Waiting to run
CI / Build language matrix (push) Waiting to run
CI / i18n Validation (push) Blocked by required conditions
CI / PR Test Policy (push) Waiting to run
CI / Build (push) Blocked by required conditions
CI / Package Artifact (push) Blocked by required conditions
CI / Electron Package Smoke (push) Blocked by required conditions
CI / Unit Tests (1/8) (push) Blocked by required conditions
CI / Unit Tests (2/8) (push) Blocked by required conditions
CI / Unit Tests (3/8) (push) Blocked by required conditions
CI / Unit Tests (4/8) (push) Blocked by required conditions
CI / E2E Tests (3/9) (push) Blocked by required conditions
CI / Unit Tests (5/8) (push) Blocked by required conditions
CI / Unit Tests (6/8) (push) Blocked by required conditions
CI / Unit Tests (7/8) (push) Blocked by required conditions
CI / Unit Tests (8/8) (push) Blocked by required conditions
CI / Vitest (MCP / autoCombo / UI components) (push) Blocked by required conditions
CI / Node 24 Compatibility Tests (1/4) (push) Blocked by required conditions
CI / Node 24 Compatibility Tests (2/4) (push) Blocked by required conditions
CI / Node 24 Compatibility Tests (3/4) (push) Blocked by required conditions
CI / Node 24 Compatibility Tests (4/4) (push) Blocked by required conditions
CI / Node 26 Compatibility Build (push) Blocked by required conditions
CI / Node 26 Compatibility Tests (1/4) (push) Blocked by required conditions
CI / Node 26 Compatibility Tests (2/4) (push) Blocked by required conditions
CI / Node 26 Compatibility Tests (3/4) (push) Blocked by required conditions
CI / Node 26 Compatibility Tests (4/4) (push) Blocked by required conditions
CI / Coverage Shard (1/8) (push) Blocked by required conditions
CI / Coverage Shard (2/8) (push) Blocked by required conditions
CI / Coverage Shard (3/8) (push) Blocked by required conditions
CI / Coverage Shard (4/8) (push) Blocked by required conditions
CI / Coverage Shard (5/8) (push) Blocked by required conditions
CI / Coverage Shard (6/8) (push) Blocked by required conditions
CI / Coverage Shard (7/8) (push) Blocked by required conditions
CI / Coverage Shard (8/8) (push) Blocked by required conditions
CI / Coverage (push) Blocked by required conditions
CI / SonarQube (push) Blocked by required conditions
CI / PR Coverage Comment (push) Blocked by required conditions
CI / E2E Tests (1/9) (push) Blocked by required conditions
CI / E2E Tests (2/9) (push) Blocked by required conditions
CI / E2E Tests (4/9) (push) Blocked by required conditions
CI / E2E Tests (5/9) (push) Blocked by required conditions
CI / E2E Tests (6/9) (push) Blocked by required conditions
CI / E2E Tests (7/9) (push) Blocked by required conditions
CI / E2E Tests (8/9) (push) Blocked by required conditions
CI / E2E Tests (9/9) (push) Blocked by required conditions
CI / Integration Tests (1/2) (push) Blocked by required conditions
CI / Integration Tests (2/2) (push) Blocked by required conditions
CI / Security Tests (push) Blocked by required conditions
CI / CI Dashboard (push) Blocked by required conditions
Publish to Docker Hub / Resolve Docker release metadata (push) Waiting to run
Publish to Docker Hub / Build Docker (linux/amd64) (push) Blocked by required conditions
Publish to Docker Hub / Build Docker (linux/arm64) (push) Blocked by required conditions
Publish to Docker Hub / Publish multi-arch manifests (push) Blocked by required conditions
opencode-plugin CI / Test (Node 24) (push) Waiting to run
opencode-plugin CI / Test (Node 22) (push) Waiting to run
opencode-plugin CI / Build (push) Blocked by required conditions
OpenSSF Scorecard / Scorecard analysis (push) Waiting to run
semgrep / semgrep (push) Waiting to run
Wiki Sync / Sync wiki with docs (push) Waiting to run
Release v3.8.40
v3.8.40 cycle integration → main. All test gates green (Unit/Integration/Coverage/Node-compat/Quality-Ratchet). The only red check, 'PR Test Policy', is the test-masking heuristic firing on the cumulative ~57-commit release diff (legitimate assert consolidations already reviewed per-PR — Gemini CLI removal #5246, retired GPT models #5280, provider catalog refreshes); overridden with --admin per the documented release-PR convention. CodeQL/SonarQube advisory scans non-blocking; #5278's code already passed CodeQL on main. Homologated on VPS 192.168.0.15 (v3.8.40 healthy).
2026-06-29 08:40:06 -03:00

82 lines
3.1 KiB
Bash
Executable file

#!/usr/bin/env bash
# bin/cold-start-bench.sh — measure OmniRoute cold-start against the target
# budgets (container start → HTTP listening ≤ 800 ms; first warm
# TTFB ≤ 200 ms). Boots the server on a throwaway port, times until
# /api/health/ping answers 200, measures a warm request, and reports PASS/FAIL.
set -euo pipefail
SCRIPT_NAME="cold-start-bench"
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/_ops-common.sh"
usage() {
cat <<'EOF'
Usage: bin/cold-start-bench.sh [--port <n>] [--start-cmd "<cmd>"] [--url <base>]
[--listen-budget-ms <n>] [--ttfb-budget-ms <n>] [-h|--help]
Boots OmniRoute, times cold-start to the first /api/health/ping 200, measures
warm TTFB, and compares against the cold-start budgets
(listen ≤ 800 ms, TTFB ≤ 200 ms). Exits non-zero if a budget is exceeded.
--url benches an already-running server instead of booting one (skips the boot
timing; only TTFB is measured).
EOF
}
PORT="${PORT:-21987}"
START_CMD=""
BASE_URL=""
LISTEN_BUDGET_MS=800
TTFB_BUDGET_MS=200
while [ $# -gt 0 ]; do
case "$1" in
--port) PORT="${2:?--port needs a value}"; shift 2 ;;
--start-cmd) START_CMD="${2:?--start-cmd needs a value}"; shift 2 ;;
--url) BASE_URL="${2:?--url needs a value}"; shift 2 ;;
--listen-budget-ms) LISTEN_BUDGET_MS="${2:?}"; shift 2 ;;
--ttfb-budget-ms) TTFB_BUDGET_MS="${2:?}"; shift 2 ;;
-h | --help) usage; exit 0 ;;
*) ops_die "unknown argument: $1 (see --help)" ;;
esac
done
ops_require_cmd curl
now_ms() { date +%s%3N; } # ms since epoch (GNU date / Linux)
ping_ok() { curl -fsS -o /dev/null --max-time 2 "$1/api/health/ping" 2>/dev/null; }
SERVER_PID=""
cleanup() { [ -n "$SERVER_PID" ] && kill "$SERVER_PID" 2>/dev/null || true; }
trap cleanup EXIT
if [ -n "$BASE_URL" ]; then
ops_log "benching already-running server at $BASE_URL (boot timing skipped)"
listen_ms=""
else
BASE_URL="http://127.0.0.1:$PORT"
[ -n "$START_CMD" ] || START_CMD="npm start -- --port $PORT"
ops_log "booting: $START_CMD"
start_ms="$(now_ms)"
# shellcheck disable=SC2086
PORT="$PORT" $START_CMD >/tmp/omniroute-coldstart.log 2>&1 &
SERVER_PID="$!"
deadline=$(($(now_ms) + 30000))
until ping_ok "$BASE_URL"; do
kill -0 "$SERVER_PID" 2>/dev/null || ops_die "server process exited during boot (see /tmp/omniroute-coldstart.log)"
[ "$(now_ms)" -gt "$deadline" ] && ops_die "server did not answer /api/health/ping within 30s"
sleep 0.05
done
listen_ms=$(($(now_ms) - start_ms))
fi
ping_ok "$BASE_URL" || ops_die "server at $BASE_URL is not answering /api/health/ping"
ttfb_ms="$(curl -fsS -o /dev/null -w '%{time_starttransfer}' "$BASE_URL/api/health/ping" | awk '{printf "%d", $1 * 1000}')"
fail=0
if [ -n "$listen_ms" ]; then
echo "cold-start (start → listening): ${listen_ms} ms (budget ${LISTEN_BUDGET_MS} ms)"
[ "$listen_ms" -le "$LISTEN_BUDGET_MS" ] || { echo "FAIL: listen budget exceeded"; fail=1; }
fi
echo "warm TTFB: ${ttfb_ms} ms (budget ${TTFB_BUDGET_MS} ms)"
[ "$ttfb_ms" -le "$TTFB_BUDGET_MS" ] || { echo "FAIL: TTFB budget exceeded"; fail=1; }
[ "$fail" -eq 0 ] && echo "PASS: within cold-start budgets"
exit "$fail"