Files
tracer-cloud--opensre/tests/e2e/openclaw/orchestrator.py
T
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

119 lines
4.7 KiB
Python

"""Build an alert from captured failure context and invoke the OpenSRE
investigation pipeline.
Sits between :mod:`use_case` (which captures the failure) and the
scenario tests (which assert on the investigation output). Mirrors the
``trigger-real-failure → invoke-investigation → assert-RCA-quality``
pattern used by :mod:`tests.e2e.upstream_lambda` and
:mod:`tests.e2e.upstream_prefect_ecs_fargate`, including
``create_alert`` for the alert payload and ``@traceable`` metadata.
"""
from __future__ import annotations
import uuid
from datetime import UTC, datetime
from typing import Any
from platform.observability.trace.hook import traceable
from surfaces.cli.investigation import run_investigation_cli
from tests.e2e.openclaw.infrastructure_sdk.local import OpenClawHandle
from tests.utils.alert_factory import create_alert
_PIPELINE_NAME = "openclaw_mcp_bridge"
_ALERT_NAME = "OpenClaw MCP integration unreachable"
# Keys that carry the RCA's narrative text in the result dict returned
# by ``run_investigation_cli``. ``report`` is the rendered slack-style
# report — it contains the diagnosis AND the "## Recommended Actions"
# section, so a single concatenation is enough to substring-check both
# the failure naming and the remediation hints.
_SUMMARY_KEYS: tuple[str, ...] = ("root_cause", "problem_md", "report")
def summarize_result(result: dict[str, Any]) -> str:
"""Lowercase concatenation of the RCA's narrative fields.
Tests assert on substring presence ("openclaw", "gateway", "stdio",
etc.) so we join ``root_cause`` + ``problem_md`` + ``report`` once
and let the test case do simple ``in`` checks. ``report`` already
embeds the recommended-actions section, so callers don't need a
separate remediation accessor.
"""
return " ".join(str(result.get(key, "")) for key in _SUMMARY_KEYS).lower()
def _build_annotations(failure_context: dict[str, Any], correlation_id: str) -> dict[str, Any]:
"""Compose the alert annotations that ground the agent's diagnosis.
``context_sources="openclaw"`` is the routing hint that tells the
pipeline to prefer OpenClaw-aware tools and prompt fragments. The
failure-mode keys carry the captured details so the agent can
reason about the specific OpenClaw failure rather than inventing a
plausible-sounding cause.
"""
return {
"context_sources": "openclaw",
"service_name": "openclaw",
"correlation_id": correlation_id,
"failure_mode": failure_context.get("failure_mode", "unknown"),
"transport_mode": failure_context.get("transport_mode", ""),
"command": failure_context.get("command", ""),
# Gateway-down has no URL; expose ``args`` as a fallback so the
# annotation key is always present for the agent to read.
"url": failure_context.get("gateway_url") or failure_context.get("args", ""),
"last_error": failure_context.get("last_error", ""),
"error_detail": failure_context.get("error_detail", ""),
}
def run_openclaw_investigation(
handle: OpenClawHandle,
failure_context: dict[str, Any],
) -> dict[str, Any]:
"""Build an alert from ``failure_context`` and run the OpenSRE pipeline.
Wraps :func:`run_investigation_cli` inside a ``@traceable`` block with
metadata that identifies it as an OpenClaw e2e run (handle PIDs,
failure mode, correlation id).
Returns the final agent state dict the scenario test then asserts
on. Expected keys include ``root_cause``, ``problem_md``,
``remediation_steps``, and ``validity_score``.
"""
failure_mode = failure_context.get("failure_mode", "unknown")
correlation_id = f"openclaw-e2e-{failure_mode}-{uuid.uuid4().hex[:8]}"
timestamp = datetime.now(UTC).isoformat()
run_name = f"openclaw_e2e_{failure_mode}_{int(datetime.now(UTC).timestamp())}"
raw_alert = create_alert(
pipeline_name=_PIPELINE_NAME,
run_name=run_name,
status="failed",
timestamp=timestamp,
severity="critical",
alert_name=_ALERT_NAME,
environment="local-e2e",
annotations=_build_annotations(failure_context, correlation_id),
)
@traceable(
run_type="chain",
name=f"openclaw_e2e_{failure_mode}",
metadata={
"alert_id": raw_alert.get("alert_id"),
"alert_name": _ALERT_NAME,
"pipeline_name": _PIPELINE_NAME,
"context_sources": "openclaw",
"failure_mode": failure_mode,
"transport_mode": failure_context.get("transport_mode", ""),
"gateway_pid": handle.gateway_pid,
"gateway_url": handle.gateway_url,
"correlation_id": correlation_id,
},
)
def _invoke() -> dict[str, Any]:
return run_investigation_cli(raw_alert=raw_alert)
return _invoke()