runbook-tutorials/tests/test_showcase.py
tegwick 6d3414d8b7 Retire exercise_status: maturity is the only notion; add CLI tests (RBT-WP-0009-T01)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 295952@bnt-lap001
Assistant-Session: e93f64ad-516c-46eb-9666-aad8d300c477
2026-09-29 21:28:56 +02:00

46 lines
1.5 KiB
Python

from pathlib import Path
import shutil
import subprocess
import pytest
from rtut import pack as P, run as R
ROOT = Path(__file__).resolve().parent.parent
SRC = ROOT / "runbooks/showcase-lighthouse"
@pytest.fixture
def pk(tmp_path):
d = tmp_path / "runbooks" / "showcase"; d.mkdir(parents=True)
shutil.copy(SRC / "pack.yaml", d / "pack.yaml")
return P.load(d / "pack.yaml")
def test_showcase_is_valid():
assert P.load(SRC / "pack.yaml").ok
def test_scripted_playthrough(pk):
r = R.create(pk, "tester", {"keeper": "Ada", "weather": "storm", "motto": "Light on"})
for s in pk.data["steps"]:
sid = s["id"]
R.start(r, sid)
cmd = R.command_for(r, sid) # the operator runs the command...
if cmd:
subprocess.run(cmd, shell=True, check=True, capture_output=True)
v = s["verify"] # ...then the engine verifies the result
res = R.verify(r, sid, confirm=True, manual_ok=True if v["expect"] == "manual" else None)
assert res["passed"], sid
R.complete(r, sid, {n: "1" for n in s.get("evidence", [])})
assert r.complete
assert not Path(r.data["params"]["logdir"]).exists()
R.finalize(r, "succeeded") # every step done: the run may succeed
assert r.data["outcome"] == "succeeded"
def test_bad_logdir_rejected(pk):
with pytest.raises(R.RunError):
R.create(pk, "tester", {"logdir": "/etc"})
with pytest.raises(R.RunError):
R.create(pk, "tester", {"motto": 'x"; rm -rf /'})