Files
claude-plugin/plugins/reviews/skills/audit-terraform/tests/test_log_run.py
T
mroberts 37fc3fb291 Fix audit tool bootstrap and add per-run preflight
audit-code install-tools.sh:
- Buffer the opengrep release JSON before grep -m1; curl died with (23)
  under pipefail when grep quit early.
- Use ${m}: in the PowerShell block; $m: parsed as a scope-qualified var.
- On Arch, skip paru/yay when pacman -Q shows every package installed,
  since --needed still invokes sudo.
- Add --check-only (fast, installs nothing, non-zero naming missing tools)
  and --user-only (no system package managers, no sudo).

log-run.py (both skills): put the skill dir on sys.path so running it as
a script from any cwd no longer raises ModuleNotFoundError.

audit-terraform: move deps from requirements.txt into pyproject
dependency groups and add scripts/install-tools.sh (uv sync --group tools,
then check trivy, tflint, tofu, terragrunt, gh).

Both SKILL.md files gain a 0.5 Preflight step and call scripts through
uv run --project ${SKILL_DIR}. tools_unavailable is now a map of tool to
exact install command; audit-terraform skips trivy when absent and stops
with an install hint instead of crashing when tofu/terragrunt is missing.
2026-09-22 15:21:28 -05:00

111 lines
3.7 KiB
Python

"""Tests for scripts/log-run.py."""
from __future__ import annotations
import importlib.util
import json
import os
import subprocess
import sys
from pathlib import Path
_SPEC = importlib.util.spec_from_file_location(
"log_run",
Path(__file__).parent.parent / "scripts" / "log-run.py",
)
log_run = importlib.util.module_from_spec(_SPEC)
_SPEC.loader.exec_module(log_run)
def _write_usage(tmp_path: Path, usage: dict) -> Path:
p = tmp_path / "usage.json"
p.write_text(json.dumps(usage), encoding="utf-8")
return p
def _read_log(log: Path) -> list[dict]:
return [json.loads(line) for line in log.read_text(encoding="utf-8").splitlines() if line.strip()]
def test_writes_one_row_per_agent_with_finding_counts(tmp_path: Path) -> None:
output = tmp_path / "out"
output.mkdir()
(output / "findings-aws-bp-reviewer.json").write_text(
json.dumps({"findings": [{"resource": "r1", "control": "c1"}]}),
encoding="utf-8",
)
(output / "findings-walkthrough-reviewer.json").write_text(
json.dumps({"overview": "x", "plan_units": []}),
encoding="utf-8",
)
log = tmp_path / "runs.jsonl"
usage = _write_usage(tmp_path, {
"aws-bp-reviewer": {"model": "sonnet", "input_tokens": 100,
"output_tokens": 50, "duration_ms": 1234},
"walkthrough-reviewer": {"model": "sonnet", "input_tokens": 200,
"output_tokens": 80, "duration_ms": 4321},
})
rc = log_run.main([
"--output-dir", str(output), "--run-id", "abc",
"--repo", "/tmp/repo", "--mode", "local",
"--log-path", str(log), "--usage-json", str(usage),
])
assert rc == 0
rows = _read_log(log)
assert len(rows) == 2
by_agent = {r["agent"]: r for r in rows}
assert by_agent["aws-bp-reviewer"]["finding_count"] == 1
assert by_agent["walkthrough-reviewer"]["finding_count"] == 0
def test_missing_findings_file_counts_zero(tmp_path: Path) -> None:
output = tmp_path / "out"
output.mkdir()
log = tmp_path / "runs.jsonl"
usage = _write_usage(tmp_path, {
"phantom-reviewer": {"model": "sonnet", "input_tokens": 0,
"output_tokens": 0, "duration_ms": 0},
})
rc = log_run.main([
"--output-dir", str(output), "--run-id", "x", "--repo", "/r",
"--mode", "ref", "--log-path", str(log), "--usage-json", str(usage),
])
assert rc == 0
assert _read_log(log)[0]["finding_count"] == 0
def test_malformed_findings_file_counts_zero(tmp_path: Path) -> None:
output = tmp_path / "out"
output.mkdir()
(output / "findings-broken-reviewer.json").write_text("{bad", encoding="utf-8")
log = tmp_path / "runs.jsonl"
usage = _write_usage(tmp_path, {
"broken-reviewer": {"model": "haiku", "input_tokens": 10,
"output_tokens": 5, "duration_ms": 100},
})
rc = log_run.main([
"--output-dir", str(output), "--run-id", "x", "--repo", "/r",
"--mode", "local", "--log-path", str(log), "--usage-json", str(usage),
])
assert rc == 0
assert _read_log(log)[0]["finding_count"] == 0
def test_runs_as_a_script_from_another_cwd(tmp_path: Path) -> None:
log = tmp_path / "runs.jsonl"
env = {k: v for k, v in os.environ.items() if k != "PYTHONPATH"}
r = subprocess.run(
[sys.executable, str(_SPEC.origin),
"--output-dir", str(tmp_path), "--run-id", "x", "--repo", "/r",
"--mode", "local", "--log-path", str(log), "--usage-json", "-"],
input=json.dumps({"x-reviewer": {"model": "sonnet"}}),
capture_output=True, text=True, cwd=tmp_path, env=env, check=False,
)
assert r.returncode == 0, r.stderr
assert _read_log(log)[0]["agent"] == "x-reviewer"