Files
tracer-cloud--opensre/tests/synthetic/rds_postgres/test_run_suite_observations.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

417 lines
14 KiB
Python

from __future__ import annotations
import json
import os
from dataclasses import replace
from pathlib import Path
from typing import Any
import pytest
import tests.synthetic.rds_postgres.run_suite as run_suite_module
from tests.synthetic.rds_postgres.scenario_loader import (
SUITE_DIR,
GoldenTrajectoryConfig,
load_scenario,
)
def _fake_final_state() -> dict[str, Any]:
return {
"root_cause": "Replication lag due to write pressure.",
"root_cause_category": "replication_lag",
"validated_claims": [],
"non_validated_claims": [],
"causal_chain": [],
"evidence": {
"aws_cloudwatch_metrics": {
"db_instance_identifier": "payments-prod",
"metrics": [{"metric_name": "CPUUtilization"}],
"observations": ["CPU elevated"],
}
},
"executed_hypotheses": [
{"actions": ["query_grafana_metrics"], "failed_actions": []},
],
"investigation_loop_count": 1,
}
def _fake_final_state_with_two_loops() -> dict[str, Any]:
return {
"root_cause": "Replication lag due to write pressure.",
"root_cause_category": "replication_lag",
"validated_claims": [],
"non_validated_claims": [],
"causal_chain": [],
"evidence": {
"aws_cloudwatch_metrics": {
"db_instance_identifier": "payments-prod",
"metrics": [{"metric_name": "CPUUtilization"}],
"observations": ["CPU elevated"],
}
},
"executed_hypotheses": [
{"actions": ["query_grafana_metrics"], "failed_actions": []},
{"actions": ["query_grafana_logs"], "failed_actions": []},
],
"investigation_loop_count": 2,
}
def _fake_write_observation(
_observation: Any,
observations_dir: Path,
) -> Path:
target = observations_dir / "001-replication-lag" / "latest.json"
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text("{}", encoding="utf-8")
return target
def test_run_suite_applies_trajectory_policy_failure(
monkeypatch,
tmp_path: Path,
) -> None:
fixture = load_scenario(SUITE_DIR / "001-replication-lag")
fixture = replace(
fixture,
answer_key=replace(
fixture.answer_key,
golden_trajectory=GoldenTrajectoryConfig(
ordered_actions=[
"query_grafana_metrics",
"query_grafana_logs",
],
matching="strict",
max_extra_actions=0,
),
),
)
score = run_suite_module.ScenarioScore(
scenario_id=fixture.scenario_id,
passed=True,
root_cause_present=True,
expected_category=fixture.answer_key.root_cause_category,
accepted_categories=tuple(sorted({fixture.answer_key.root_cause_category})),
actual_category=fixture.answer_key.root_cause_category,
missing_keywords=[],
matched_keywords=list(fixture.answer_key.required_keywords),
root_cause="Replication lag due to write pressure.",
)
render_calls: list[str] = []
monkeypatch.setattr(run_suite_module, "load_all_scenarios", lambda _suite_dir: [fixture])
monkeypatch.setattr(
run_suite_module, "run_scenario", lambda *_args, **_kwargs: (_fake_final_state(), score)
)
monkeypatch.setattr(run_suite_module, "write_observation", _fake_write_observation)
monkeypatch.setattr(
run_suite_module,
"render_report_to_console",
lambda *_args, **_kwargs: render_calls.append("called"),
)
results = run_suite_module.run_suite(
[
"--scenario",
fixture.scenario_id,
"--report",
"--observations-dir",
str(tmp_path),
]
)
assert len(results) == 1
assert results[0].passed is False
assert "trajectory policy failed" in results[0].failure_reason
assert render_calls == ["called"]
def test_run_suite_enforces_resolved_loop_threshold_and_persists_score_consistency(
monkeypatch,
tmp_path: Path,
) -> None:
fixture = load_scenario(SUITE_DIR / "001-replication-lag")
fixture = replace(
fixture,
answer_key=replace(
fixture.answer_key,
max_investigation_loops=1,
golden_trajectory=GoldenTrajectoryConfig(
ordered_actions=["query_grafana_metrics"],
matching="set",
),
),
)
score = run_suite_module.ScenarioScore(
scenario_id=fixture.scenario_id,
passed=True,
root_cause_present=True,
expected_category=fixture.answer_key.root_cause_category,
accepted_categories=tuple(sorted({fixture.answer_key.root_cause_category})),
actual_category=fixture.answer_key.root_cause_category,
missing_keywords=[],
matched_keywords=list(fixture.answer_key.required_keywords),
root_cause="Replication lag due to write pressure.",
)
persisted_scores: list[dict[str, Any]] = []
def _capture_write_observation(observation: Any, observations_dir: Path) -> Path:
persisted_scores.append(dict(observation.score))
target = observations_dir / "001-replication-lag" / "latest.json"
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text("{}", encoding="utf-8")
return target
monkeypatch.setattr(run_suite_module, "load_all_scenarios", lambda _suite_dir: [fixture])
monkeypatch.setattr(
run_suite_module,
"run_scenario",
lambda *_args, **_kwargs: (_fake_final_state_with_two_loops(), score),
)
monkeypatch.setattr(run_suite_module, "write_observation", _capture_write_observation)
results = run_suite_module.run_suite(
[
"--scenario",
fixture.scenario_id,
"--observations-dir",
str(tmp_path),
]
)
assert len(results) == 1
assert results[0].passed is False
assert "trajectory policy failed" in results[0].failure_reason
assert "loops_used=2 > 1" in results[0].failure_reason
assert len(persisted_scores) == 1
assert persisted_scores[0]["passed"] is False
assert persisted_scores[0]["failure_reason"] == results[0].failure_reason
def test_run_suite_json_mode_suppresses_report_render(
monkeypatch,
tmp_path: Path,
) -> None:
fixture = load_scenario(SUITE_DIR / "001-replication-lag")
score = run_suite_module.ScenarioScore(
scenario_id=fixture.scenario_id,
passed=True,
root_cause_present=True,
expected_category=fixture.answer_key.root_cause_category,
accepted_categories=tuple(sorted({fixture.answer_key.root_cause_category})),
actual_category=fixture.answer_key.root_cause_category,
missing_keywords=[],
matched_keywords=list(fixture.answer_key.required_keywords),
root_cause="Replication lag due to write pressure.",
)
render_calls: list[str] = []
monkeypatch.setattr(run_suite_module, "load_all_scenarios", lambda _suite_dir: [fixture])
monkeypatch.setattr(
run_suite_module, "run_scenario", lambda *_args, **_kwargs: (_fake_final_state(), score)
)
monkeypatch.setattr(run_suite_module, "write_observation", _fake_write_observation)
monkeypatch.setattr(
run_suite_module,
"render_report_to_console",
lambda *_args, **_kwargs: render_calls.append("called"),
)
_ = run_suite_module.run_suite(
[
"--scenario",
fixture.scenario_id,
"--report",
"--json",
"--observations-dir",
str(tmp_path),
]
)
assert render_calls == []
def test_run_suite_bulk_execution_suppresses_investigation_rendering(
monkeypatch: Any,
tmp_path: Path,
) -> None:
fixture_a = load_scenario(SUITE_DIR / "000-healthy")
fixture_b = load_scenario(SUITE_DIR / "001-replication-lag")
fixtures = [fixture_a, fixture_b]
output_formats_seen: list[str | None] = []
monkeypatch.setenv("TRACER_OUTPUT_FORMAT", "rich")
monkeypatch.setattr(run_suite_module, "load_all_scenarios", lambda _suite_dir: fixtures)
monkeypatch.setattr(run_suite_module, "write_observation", _fake_write_observation)
def _fake_run_scenario(
fixture: Any,
use_mock_grafana: bool = False, # noqa: ARG001
grafana_backend: Any = None, # noqa: ARG001
) -> tuple[dict[str, Any], Any]:
output_formats_seen.append(os.environ.get("TRACER_OUTPUT_FORMAT"))
return _make_deterministic_final_state(), _make_base_score(fixture)
monkeypatch.setattr(run_suite_module, "run_scenario", _fake_run_scenario)
run_suite_module.run_suite(["--levels", "1", "--observations-dir", str(tmp_path)])
assert output_formats_seen == ["none", "none"]
assert os.environ.get("TRACER_OUTPUT_FORMAT") == "rich"
def test_run_suite_single_scenario_keeps_investigation_rendering_mode(
monkeypatch: Any,
tmp_path: Path,
) -> None:
fixture = load_scenario(SUITE_DIR / "001-replication-lag")
output_formats_seen: list[str | None] = []
monkeypatch.setattr(run_suite_module, "load_all_scenarios", lambda _suite_dir: [fixture])
monkeypatch.setattr(run_suite_module, "write_observation", _fake_write_observation)
def _fake_run_scenario(
fixture: Any,
use_mock_grafana: bool = False, # noqa: ARG001
grafana_backend: Any = None, # noqa: ARG001
) -> tuple[dict[str, Any], Any]:
output_formats_seen.append(os.environ.get("TRACER_OUTPUT_FORMAT"))
return _make_deterministic_final_state(), _make_base_score(fixture)
monkeypatch.setattr(run_suite_module, "run_scenario", _fake_run_scenario)
run_suite_module.run_suite(
["--scenario", fixture.scenario_id, "--observations-dir", str(tmp_path)]
)
assert output_formats_seen == [None]
# ---------------------------------------------------------------------------
# Baseline guardrail tests (Phase 0)
# ---------------------------------------------------------------------------
_BASELINE_DIR = Path(__file__).parent / "_baseline"
def _make_deterministic_final_state() -> dict[str, Any]:
"""Empty final state that produces stable canonical payloads without LLM calls."""
return {
"root_cause": "",
"root_cause_category": "unknown",
"validated_claims": [],
"non_validated_claims": [],
"causal_chain": [],
"evidence": {},
"executed_hypotheses": [],
"investigation_loop_count": 0,
"report": "",
}
def _make_base_score(fixture: Any) -> Any:
"""Return a ScenarioScore identical to what score_result produces for an empty final state.
The baseline was generated using score_result with an empty final state, so this
must match exactly — bare ScenarioScore construction omits gates and is not equivalent.
"""
return run_suite_module.score_result(fixture, _make_deterministic_final_state())
def _fake_write_observation_baseline(
_observation: Any,
observations_dir: Path,
) -> Path:
target = observations_dir / "001-replication-lag" / "latest.json"
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text("{}", encoding="utf-8")
return target
def test_baseline_check_passes_against_committed_baseline(
monkeypatch: Any,
tmp_path: Path,
) -> None:
"""run_suite --baseline-check exits cleanly when payloads match the committed baseline."""
fixture = load_scenario(SUITE_DIR / "001-replication-lag")
monkeypatch.setattr(
run_suite_module,
"load_all_scenarios",
lambda _suite_dir: [fixture],
)
monkeypatch.setattr(
run_suite_module,
"run_scenario",
lambda *_args, **_kwargs: (
_make_deterministic_final_state(),
_make_base_score(fixture),
),
)
monkeypatch.setattr(run_suite_module, "write_observation", _fake_write_observation_baseline)
# Should not raise SystemExit
run_suite_module.run_suite(
[
"--scenario",
fixture.scenario_id,
"--observations-dir",
str(tmp_path),
"--baseline-check",
str(_BASELINE_DIR),
]
)
def test_baseline_check_detects_drift(
monkeypatch: Any,
tmp_path: Path,
) -> None:
"""run_suite --baseline-check exits non-zero when a canonical field differs from baseline."""
fixture = load_scenario(SUITE_DIR / "001-replication-lag")
# Tamper with the baseline to simulate drift
tampered_dir = tmp_path / "tampered_baseline"
tampered_dir.mkdir()
original = json.loads((_BASELINE_DIR / "001-replication-lag.json").read_text())
original["status"] = "pass" # invert status to force mismatch
(tampered_dir / "001-replication-lag.json").write_text(
json.dumps(original, indent=2, sort_keys=True)
)
monkeypatch.setattr(
run_suite_module,
"load_all_scenarios",
lambda _suite_dir: [fixture],
)
monkeypatch.setattr(
run_suite_module,
"run_scenario",
lambda *_args, **_kwargs: (
_make_deterministic_final_state(),
_make_base_score(fixture),
),
)
monkeypatch.setattr(run_suite_module, "write_observation", _fake_write_observation_baseline)
with pytest.raises(SystemExit) as exc_info:
run_suite_module.run_suite(
[
"--scenario",
fixture.scenario_id,
"--observations-dir",
str(tmp_path),
"--baseline-check",
str(tampered_dir),
]
)
assert exc_info.value.code == 1