Files
wehub-resource-sync 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
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

328 lines
11 KiB
Python

"""Tests for /rca history and /rca show."""
from __future__ import annotations
import io
import json
from pathlib import Path
import pytest
from rich.console import Console
from core.agent_harness.session import JsonlSessionStorage
from surfaces.interactive_shell.command_registry import dispatch_slash
from surfaces.interactive_shell.session import Session
SessionStore = JsonlSessionStorage()
def _capture() -> tuple[Console, io.StringIO]:
buf = io.StringIO()
return Console(file=buf, force_terminal=False, highlight=False), buf
def test_rca_history_lists_persisted_reports(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
session = Session()
SessionStore.open_session(session)
SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "redis timeout", "problem_md": "cache unavailable"},
trigger="/investigate generic",
)
console, buf = _capture()
assert dispatch_slash("/rca history", Session(), console) is True
output = buf.getvalue()
assert "RCA history" in output
assert "redis timeout" in output
assert "/investigate generic" in output
def test_rca_show_renders_full_report(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
session = Session()
SessionStore.open_session(session)
inv_id = SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "bad deploy", "problem_md": "## Report\nRollback required"},
trigger="/investigate grafana",
)
console, buf = _capture()
assert dispatch_slash(f"/rca show {inv_id[:4]}", Session(), console) is True
output = buf.getvalue()
assert "bad deploy" in output
assert "Rollback required" in output
def test_bare_rca_defaults_to_history(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
console, buf = _capture()
assert dispatch_slash("/rca", Session(), console) is True
assert "no persisted RCA reports yet" in buf.getvalue()
def test_tty_rca_menu_latest_shows_report(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
from surfaces.interactive_shell.command_registry import rca_cmds
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
session = Session()
SessionStore.open_session(session)
inv_id = SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "connection pool exhausted", "problem_md": "## Report\nPool at max"},
trigger="/investigate generic",
)
monkeypatch.setattr(rca_cmds, "repl_tty_interactive", lambda: True)
monkeypatch.setattr(rca_cmds, "repl_choose_one", lambda **_: rca_cmds._RCA_LATEST)
console, buf = _capture()
assert dispatch_slash("/rca", session, console) is True
output = buf.getvalue()
assert "connection pool exhausted" in output
assert "Pool at max" in output
assert inv_id[:8] in output
def test_tty_rca_history_menu_picks_report_directly(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
from surfaces.interactive_shell.command_registry import rca_cmds
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
session = Session()
SessionStore.open_session(session)
older_id = SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "older issue", "problem_md": "older report"},
trigger="/investigate grafana",
)
SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "newer issue", "problem_md": "newer report"},
trigger="/investigate generic",
)
monkeypatch.setattr(rca_cmds, "repl_tty_interactive", lambda: True)
monkeypatch.setattr(rca_cmds, "repl_choose_one", lambda **_: older_id)
console, buf = _capture()
assert dispatch_slash("/rca history", session, console) is True
output = buf.getvalue()
assert "older issue" in output
assert "older report" in output
assert "newer issue" not in output
def test_tty_rca_root_menu_history_picks_report(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
from surfaces.interactive_shell.command_registry import rca_cmds
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
session = Session()
SessionStore.open_session(session)
older_id = SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "older issue", "problem_md": "older report"},
trigger="/investigate grafana",
)
SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "newer issue", "problem_md": "newer report"},
trigger="/investigate generic",
)
picks = iter([rca_cmds._RCA_HISTORY, older_id])
monkeypatch.setattr(rca_cmds, "repl_tty_interactive", lambda: True)
monkeypatch.setattr(rca_cmds, "repl_choose_one", lambda **_: next(picks))
console, buf = _capture()
assert dispatch_slash("/rca", session, console) is True
output = buf.getvalue()
assert "older issue" in output
assert "older report" in output
assert "newer issue" not in output
def test_rca_save_writes_markdown(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
session = Session()
SessionStore.open_session(session)
SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "redis timeout", "problem_md": "cache unavailable"},
trigger="/investigate generic",
)
dest = tmp_path / "report.md"
console, buf = _capture()
assert dispatch_slash(f"/rca save {dest}", Session(), console) is True
assert (
dest.read_text(encoding="utf-8")
== "## Root Cause\n\nredis timeout\n\n## Report\n\ncache unavailable\n"
)
assert "saved:" in buf.getvalue()
def test_rca_save_by_id_writes_json(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
session = Session()
SessionStore.open_session(session)
inv_id = SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "bad deploy", "problem_md": "rollback required"},
trigger="/investigate grafana",
)
dest = tmp_path / "report.json"
console, buf = _capture()
assert dispatch_slash(f"/rca save {inv_id[:4]} {dest}", Session(), console) is True
payload = json.loads(dest.read_text(encoding="utf-8"))
assert payload["root_cause"] == "bad deploy"
assert payload["problem_md"] == "rollback required"
assert payload["investigation_id"] == inv_id
assert "saved:" in buf.getvalue()
def test_rca_save_strips_quoted_path(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
session = Session()
SessionStore.open_session(session)
inv_id = SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "quoted path", "problem_md": "saved body"},
trigger="/investigate generic",
)
dest = tmp_path / "quoted.md"
console, buf = _capture()
assert dispatch_slash(f"/rca save {inv_id[:4]} '{dest}'", Session(), console) is True
assert dest.read_text(encoding="utf-8").startswith("## Root Cause")
assert "saved:" in buf.getvalue()
def test_rca_save_to_new_folder_adds_default_filename(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
session = Session()
SessionStore.open_session(session)
inv_id = SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "folder save", "problem_md": "in subfolder"},
trigger="/investigate generic",
)
folder = tmp_path / "rca_reports"
folder.mkdir()
console, buf = _capture()
assert dispatch_slash(f"/rca save {inv_id[:4]} {folder}/", Session(), console) is True
saved = folder / f"rca-{inv_id[:8]}.md"
assert saved.exists()
assert "folder save" in saved.read_text(encoding="utf-8")
assert "saved:" in buf.getvalue()
def test_rca_save_to_new_folder_trailing_slash_creates_subdirectory(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
session = Session()
SessionStore.open_session(session)
inv_id = SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "nested save", "problem_md": "inside new folder"},
trigger="/investigate generic",
)
folder = tmp_path / "new_rca_folder"
console, buf = _capture()
assert dispatch_slash(f"/rca save {inv_id[:4]} {folder}/", Session(), console) is True
saved = folder / f"rca-{inv_id[:8]}.md"
assert saved.exists()
assert "nested save" in saved.read_text(encoding="utf-8")
assert "saved:" in buf.getvalue()
def test_rca_save_unknown_id_reports_not_found(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
session = Session()
SessionStore.open_session(session)
SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "existing issue", "problem_md": "existing report"},
trigger="/investigate generic",
)
dest = tmp_path / "report.md"
console, buf = _capture()
assert dispatch_slash(f"/rca save badid {dest}", Session(), console) is True
output = buf.getvalue()
assert "RCA report not found" in output
assert "no persisted RCA reports yet" not in output
assert not dest.exists()
def test_normalize_rca_save_path_strips_quotes() -> None:
from surfaces.interactive_shell.command_registry import rca_cmds
dest = rca_cmds._normalize_rca_save_path("'/tmp/report.md'", investigation_id="abcd1234")
assert dest == Path("/tmp/report.md")
def test_tty_rca_save_menu_picks_latest_and_prompts_path(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
from surfaces.interactive_shell.command_registry import rca_cmds
monkeypatch.setattr("config.constants.OPENSRE_HOME_DIR", tmp_path)
session = Session()
SessionStore.open_session(session)
SessionStore.append_investigation_result(
session.session_id,
{"root_cause": "latest root cause", "problem_md": "latest body"},
trigger="/investigate generic",
)
dest = tmp_path / "picked.md"
monkeypatch.setattr(rca_cmds, "repl_tty_interactive", lambda: True)
monkeypatch.setattr(rca_cmds, "repl_choose_one", lambda **_: rca_cmds._RCA_LATEST)
monkeypatch.setattr(rca_cmds, "_prompt_rca_save_path", lambda _console: str(dest))
console, buf = _capture()
assert dispatch_slash("/rca save", session, console) is True
assert "latest root cause" in dest.read_text(encoding="utf-8")
assert "saved:" in buf.getvalue()