4b6817381b
Benchmark image — build + push to ECR (any adapter) / build + push (push) Waiting to run
CI / quality (ubuntu-latest) (push) Waiting to run
CI / test (tools-runtime) (push) Waiting to run
CI / test (e2e-general) (push) Waiting to run
CI / test (cli-runtime) (push) Waiting to run
CI / test (e2e-provider-and-openclaw) (push) Waiting to run
CI / test (integrations-and-misc) (push) Waiting to run
CI / coverage-report (push) Blocked by required conditions
CI / test-kubernetes (push) Waiting to run
CI / should-run-thorough (push) Waiting to run
CI / test-thorough (cloudwatch-demo) (push) Blocked by required conditions
CI / test-thorough (flink-ecs) (push) Blocked by required conditions
CI / test-thorough (upstream-lambda) (push) Blocked by required conditions
CI / test-thorough (prefect-ecs-fargate) (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Blocked by required conditions
Release / publish-release (push) Blocked by required conditions
Release / publish-main-release (push) Blocked by required conditions
Release / prepare (push) Waiting to run
Release / verify (push) Blocked by required conditions
Release / build-python-dist (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Blocked by required conditions
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Waiting to run
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Waiting to run
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Waiting to run
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
186 lines
5.6 KiB
Python
186 lines
5.6 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
from integrations.openclaw.delivery import send_openclaw_report
|
|
|
|
|
|
def _state(**overrides: Any) -> dict[str, Any]:
|
|
base: dict[str, Any] = {
|
|
"alert_name": "Checkout API error rate spike",
|
|
"root_cause": "A bad deploy introduced 5xx errors.",
|
|
"remediation_steps": ["Roll back the deploy", "Verify health checks"],
|
|
"validity_score": 0.92,
|
|
"openclaw_context": {},
|
|
}
|
|
base.update(overrides)
|
|
return base
|
|
|
|
|
|
def _creds(**overrides: Any) -> dict[str, Any]:
|
|
base = {
|
|
"mode": "streamable-http",
|
|
"url": "https://openclaw.example.com/mcp",
|
|
"auth_token": "tok",
|
|
"command": "",
|
|
"args": [],
|
|
}
|
|
base.update(overrides)
|
|
return base
|
|
|
|
|
|
def test_send_openclaw_report_success_creates_conversation(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
calls: list[tuple[str, dict[str, Any]]] = []
|
|
|
|
monkeypatch.setattr(
|
|
"integrations.openclaw.delivery.openclaw_runtime_unavailable_reason",
|
|
lambda _config: None,
|
|
)
|
|
|
|
def _fake_call(_config: Any, tool_name: str, arguments: dict[str, Any]) -> dict[str, Any]:
|
|
calls.append((tool_name, arguments))
|
|
return {"is_error": False, "tool": tool_name, "arguments": arguments, "text": "ok"}
|
|
|
|
monkeypatch.setattr("integrations.openclaw.delivery.call_openclaw_tool", _fake_call)
|
|
|
|
posted, error = send_openclaw_report(
|
|
_state(),
|
|
"Full RCA report",
|
|
_creds(),
|
|
)
|
|
|
|
assert posted is True
|
|
assert error is None
|
|
assert calls == [
|
|
(
|
|
"conversations_create",
|
|
{
|
|
"title": "Checkout API error rate spike",
|
|
"content": (
|
|
"Full RCA report\n\nRoot cause: A bad deploy introduced 5xx errors.\n\n"
|
|
"Remediation steps:\n- Roll back the deploy\n- Verify health checks\n\n"
|
|
"Confidence: 92%"
|
|
),
|
|
},
|
|
)
|
|
]
|
|
|
|
|
|
def test_send_openclaw_report_invalid_config_returns_false() -> None:
|
|
posted, error = send_openclaw_report(
|
|
_state(),
|
|
"report",
|
|
{"mode": "stdio", "command": "", "args": [], "url": ""},
|
|
)
|
|
|
|
assert posted is False
|
|
assert error is not None
|
|
assert "invalid" in error.lower()
|
|
|
|
|
|
def test_send_openclaw_report_runtime_unavailable_returns_false(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
monkeypatch.setattr(
|
|
"integrations.openclaw.delivery.openclaw_runtime_unavailable_reason",
|
|
lambda _config: "Command not found: openclaw",
|
|
)
|
|
|
|
posted, error = send_openclaw_report(
|
|
_state(), "report", _creds(mode="stdio", command="openclaw")
|
|
)
|
|
|
|
assert posted is False
|
|
assert error == "Command not found: openclaw"
|
|
|
|
|
|
def test_send_openclaw_report_tool_error_returns_false(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
monkeypatch.setattr(
|
|
"integrations.openclaw.delivery.openclaw_runtime_unavailable_reason",
|
|
lambda _config: None,
|
|
)
|
|
monkeypatch.setattr(
|
|
"integrations.openclaw.delivery.call_openclaw_tool",
|
|
lambda _config, _tool_name, _arguments: {
|
|
"is_error": True,
|
|
"text": "route missing",
|
|
},
|
|
)
|
|
|
|
posted, error = send_openclaw_report(_state(), "report", _creds())
|
|
|
|
assert posted is False
|
|
assert error == "route missing"
|
|
|
|
|
|
def test_send_openclaw_report_exception_returns_false(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
monkeypatch.setattr(
|
|
"integrations.openclaw.delivery.openclaw_runtime_unavailable_reason",
|
|
lambda _config: None,
|
|
)
|
|
monkeypatch.setattr(
|
|
"integrations.openclaw.delivery.call_openclaw_tool",
|
|
lambda *_args, **_kwargs: (_ for _ in ()).throw(RuntimeError("boom")),
|
|
)
|
|
|
|
posted, error = send_openclaw_report(_state(), "report", _creds())
|
|
|
|
assert posted is False
|
|
assert error is not None
|
|
assert "boom" in error
|
|
|
|
|
|
def test_send_openclaw_report_forwards_conversation_id(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
calls: list[tuple[str, dict[str, Any]]] = []
|
|
|
|
monkeypatch.setattr(
|
|
"integrations.openclaw.delivery.openclaw_runtime_unavailable_reason",
|
|
lambda _config: None,
|
|
)
|
|
|
|
def _fake_call(_config: Any, tool_name: str, arguments: dict[str, Any]) -> dict[str, Any]:
|
|
calls.append((tool_name, arguments))
|
|
return {"is_error": False, "tool": tool_name, "arguments": arguments}
|
|
|
|
monkeypatch.setattr("integrations.openclaw.delivery.call_openclaw_tool", _fake_call)
|
|
|
|
posted, error = send_openclaw_report(
|
|
_state(openclaw_context={"conversation_id": "conv-1"}),
|
|
"report",
|
|
_creds(),
|
|
)
|
|
|
|
assert posted is True
|
|
assert error is None
|
|
assert calls[0][0] == "message_send"
|
|
assert calls[0][1]["conversationId"] == "conv-1"
|
|
|
|
|
|
def test_send_openclaw_report_merges_transport_overrides(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
seen_configs: list[tuple[str, str]] = []
|
|
|
|
monkeypatch.setattr(
|
|
"integrations.openclaw.delivery.openclaw_runtime_unavailable_reason",
|
|
lambda config: seen_configs.append((config.mode, config.command)) or None,
|
|
)
|
|
monkeypatch.setattr(
|
|
"integrations.openclaw.delivery.call_openclaw_tool",
|
|
lambda _config, tool_name, arguments: {
|
|
"is_error": False,
|
|
"tool": tool_name,
|
|
"arguments": arguments,
|
|
},
|
|
)
|
|
|
|
posted, error = send_openclaw_report(
|
|
_state(openclaw_context={"mode": "stdio", "command": "openclaw", "args": ["mcp", "serve"]}),
|
|
"report",
|
|
_creds(),
|
|
)
|
|
|
|
assert posted is True
|
|
assert error is None
|
|
assert seen_configs[0] == ("stdio", "openclaw")
|