chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-03-27: - update .custodian-brief.md for the-custodian
This commit is contained in:
131
e2e-framework/runner.py
Normal file
131
e2e-framework/runner.py
Normal file
@@ -0,0 +1,131 @@
|
||||
"""
|
||||
Full e2e lifecycle: up → health-wait → test → down → result.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
from .sandbox import Sandbox
|
||||
from .schema import E2EConfig
|
||||
|
||||
|
||||
@dataclass
|
||||
class RunResult:
|
||||
sandbox_id: str
|
||||
repo: str
|
||||
passed: bool
|
||||
exit_code: int
|
||||
duration_s: float
|
||||
output: str
|
||||
error: str = ""
|
||||
|
||||
|
||||
def run_e2e(
|
||||
repo_path: Path,
|
||||
host: str,
|
||||
ssh_user: str = "root",
|
||||
ssh_key: str | None = None,
|
||||
keep: bool = False,
|
||||
) -> RunResult:
|
||||
config = E2EConfig.load(repo_path)
|
||||
sandbox = Sandbox(
|
||||
host=host,
|
||||
repo_path=repo_path,
|
||||
ssh_user=ssh_user,
|
||||
ssh_key=ssh_key,
|
||||
)
|
||||
project_name = f"e2e-{config.name}-{sandbox.sandbox_id}"
|
||||
compose_path = f"{sandbox.remote_dir}/{config.compose_file}"
|
||||
started = time.time()
|
||||
output_lines: list[str] = []
|
||||
|
||||
def log(msg: str) -> None:
|
||||
print(msg)
|
||||
output_lines.append(msg)
|
||||
|
||||
log(f"\n{'='*60}")
|
||||
log(f"E2E run: {config.name} sandbox={sandbox.sandbox_id}")
|
||||
log(f"Host: {host} project: {project_name}")
|
||||
log(f"{'='*60}\n")
|
||||
|
||||
try:
|
||||
# 1. Provision
|
||||
sandbox.provision()
|
||||
|
||||
# 2. docker compose up
|
||||
env_flags = " ".join(f"-e {k}={v}" for k, v in config.env.items())
|
||||
up_cmd = (
|
||||
f"cd {sandbox.remote_dir} && "
|
||||
f"docker compose -p {project_name} -f {compose_path} up -d"
|
||||
)
|
||||
log(f"[runner] docker compose up ({project_name})")
|
||||
rc, out = sandbox.run(up_cmd, timeout=180, stream=False)
|
||||
output_lines.append(out)
|
||||
if rc != 0:
|
||||
raise RuntimeError(f"docker compose up failed (exit {rc}):\n{out}")
|
||||
|
||||
# 3. Health checks
|
||||
for hc in config.health_checks:
|
||||
ok = sandbox.wait_for_url(hc.url, timeout=hc.timeout)
|
||||
if not ok:
|
||||
raise RuntimeError(f"Health check failed: {hc.name} ({hc.url})")
|
||||
|
||||
# 4. Run tests
|
||||
log(f"\n[runner] running: {config.test_command}")
|
||||
test_cmd = f"cd {sandbox.remote_dir} && {config.test_command}"
|
||||
rc, test_out = sandbox.run(test_cmd, timeout=config.timeout, stream=False)
|
||||
output_lines.append(test_out)
|
||||
print(test_out)
|
||||
|
||||
passed = rc == 0
|
||||
duration = time.time() - started
|
||||
log(f"\n[runner] {'PASSED' if passed else 'FAILED'} (exit={rc}, {duration:.1f}s)")
|
||||
|
||||
return RunResult(
|
||||
sandbox_id=sandbox.sandbox_id,
|
||||
repo=config.name,
|
||||
passed=passed,
|
||||
exit_code=rc,
|
||||
duration_s=duration,
|
||||
output="\n".join(output_lines),
|
||||
)
|
||||
|
||||
except Exception as exc:
|
||||
duration = time.time() - started
|
||||
log(f"\n[runner] ERROR: {exc}")
|
||||
return RunResult(
|
||||
sandbox_id=sandbox.sandbox_id,
|
||||
repo=config.name,
|
||||
passed=False,
|
||||
exit_code=-1,
|
||||
duration_s=duration,
|
||||
output="\n".join(output_lines),
|
||||
error=str(exc),
|
||||
)
|
||||
|
||||
finally:
|
||||
_compose_down(sandbox, project_name, compose_path, config, keep)
|
||||
|
||||
|
||||
def _compose_down(
|
||||
sandbox: Sandbox,
|
||||
project_name: str,
|
||||
compose_path: str,
|
||||
config: E2EConfig,
|
||||
keep: bool,
|
||||
) -> None:
|
||||
if keep or config.cleanup == "never":
|
||||
print(f"[runner] skipping cleanup (keep={keep}, cleanup={config.cleanup})")
|
||||
return
|
||||
|
||||
print(f"[runner] docker compose down ({project_name})")
|
||||
down_cmd = (
|
||||
f"cd {sandbox.remote_dir} && "
|
||||
f"docker compose -p {project_name} -f {compose_path} down -v --remove-orphans 2>&1 || true"
|
||||
)
|
||||
sandbox.run(down_cmd, timeout=60)
|
||||
|
||||
if not keep:
|
||||
sandbox.teardown()
|
||||
Reference in New Issue
Block a user