Files
trycua--cua/tests/cold_start_benchmark.py
wehub-resource-sync 91e75e620b
CI: cua-driver distro-compat matrix / debian:12 (glibc 2.36) (push) Has been cancelled
CI: SPDX Headers / Check SPDX headers (warn-only) (push) Has been cancelled
CD: Docs MCP Server / build (linux/amd64) (push) Has been cancelled
CD: Docs MCP Server / build (linux/arm64) (push) Has been cancelled
CD: Docs MCP Server / merge (push) Has been cancelled
CI: cua-driver distro-compat matrix / Resolve release version (push) Has been cancelled
CI: cua-driver distro-compat matrix / fedora:41 (glibc 2.40) (push) Has been cancelled
CI: cua-driver distro-compat matrix / rockylinux:9 (glibc 2.34) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:22.04 (glibc 2.35) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:24.04 (glibc 2.39) (push) Has been cancelled
CI: cua-driver distro-compat matrix / Distro compat summary (push) Has been cancelled
CI: Rust Linux unit / Rust Linux unit and compile (push) Has been cancelled
CI: Rust Windows unit / Rust Windows unit and compile (push) Has been cancelled
CI: Nix Linux Rust source / Nix / compositor build (push) Has been cancelled
CI: Nix Linux Rust source / Nix / driver package (push) Has been cancelled
CI: Nix Linux Rust source / Nix / Rust unit tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:03:19 +08:00

116 lines
3.5 KiB
Python

"""Cold start benchmark for cloud sandboxes.
Measures provisioning time for each OS type across 2 attempts and
exports results as GitHub Actions env vars for Slack notification.
"""
import asyncio
import json
import os
import time
import urllib.request
from cua_sandbox import Image, Sandbox
OS_CONFIGS = [
("linux", Image.linux()),
("android", Image.android("14")),
]
ATTEMPTS = 2
async def measure_cold_start(image, timeout: float = 120) -> tuple[float | None, str | None]:
"""Create an ephemeral sandbox and return (seconds, error)."""
t0 = time.time()
try:
async with Sandbox.ephemeral(image) as sb:
elapsed = time.time() - t0
# Quick health check
screenshot = await sb.screenshot()
if len(screenshot) < 500:
return elapsed, "screenshot too small"
return elapsed, None
except Exception as e:
return time.time() - t0, str(e)[:80]
def color_for_time(seconds: float | None) -> str:
if seconds is None:
return "🔴"
if seconds < 15:
return "🟢"
if seconds < 60:
return "🟡"
return "🔴"
def fmt(seconds: float | None, error: str | None) -> str:
if error:
return f"❌ {error}"
return f"{seconds:.1f}s"
async def main():
results: dict[str, list[tuple[float | None, str | None]]] = {}
for os_name, image in OS_CONFIGS:
results[os_name] = []
for attempt in range(ATTEMPTS):
print(f"[{os_name}] attempt {attempt + 1}/{ATTEMPTS}...")
elapsed, error = await measure_cold_start(image)
results[os_name].append((elapsed, error))
if error:
print(f" ❌ {elapsed:.1f}s - {error}")
else:
print(f" ✅ {elapsed:.1f}s")
# Build Slack message as a table
lines = ["*☁️ Cloud Sandbox Cold Start Benchmark*\n"]
lines.append("```")
lines.append(f"{'OS':<12} {'Attempt 1':<20} {'Attempt 2':<20}")
lines.append(f"{'─'*12} {'─'*20} {'─'*20}")
worst_color = "#36a64f" # green
for os_name in [c[0] for c in OS_CONFIGS]:
cols = []
for elapsed, error in results[os_name]:
icon = color_for_time(elapsed if not error else None)
cols.append(f"{icon} {fmt(elapsed, error)}")
# Track worst color
if error:
worst_color = "#dc3545"
elif elapsed and elapsed >= 60 and worst_color != "#dc3545":
worst_color = "#ffa500"
elif elapsed and elapsed >= 15 and worst_color == "#36a64f":
worst_color = "#ffa500"
lines.append(f"{os_name:<12} {cols[0]:<20} {cols[1]:<20}")
lines.append("```")
msg = "\n".join(lines)
print(f"\n{msg}")
# Export to GitHub Actions
gh_env = os.environ.get("GITHUB_ENV")
if gh_env:
with open(gh_env, "a") as f:
f.write(f"SLACK_MESSAGE<<EOF\n{msg}\nEOF\n")
f.write(f"SLACK_COLOR={worst_color}\n")
# Send directly via webhook (local runs or CI with SLACK_WEBHOOK set)
webhook_url = os.environ.get("SLACK_WEBHOOK")
if webhook_url and not gh_env:
payload = json.dumps(
{"text": msg, "attachments": [{"color": worst_color, "text": ""}]}
).encode()
req = urllib.request.Request(
webhook_url, data=payload, headers={"Content-Type": "application/json"}
)
with urllib.request.urlopen(req) as resp:
print(f"\nSlack webhook sent: {resp.status}")
if __name__ == "__main__":
asyncio.run(main())