import hashlib import json from typer.testing import CliRunner from tht.cli import app from tht.jobs.dwh_pipeline import DwhPreprocessPipeline from tht.jobs.locking import _lock_name FP = "sha256:" + hashlib.sha256(b"test").hexdigest() def test_dwh_and_evidence_jobs_have_distinct_lock_names(): assert _lock_name("demo", "dwh") != _lock_name("demo", "evidence") def test_selected_dwh_stages_run_in_declared_order(tmp_path): calls = [] pipeline = DwhPreprocessPipeline( workspace_id="demo", workspace_root=tmp_path, config_fingerprint=FP, input_fingerprint=FP, introspect=lambda: calls.append("introspect"), build_lsh=lambda: calls.append("lsh"), ) report = pipeline.run(("introspect", "lsh")) assert report.status == "succeeded" assert calls == ["introspect", "lsh"] assert [stage.name for stage in report.stages] == ["introspect", "lsh"] def test_preprocess_dwh_json_is_pristine(monkeypatch, tmp_path): import tht.cli.preprocess_cmd as command class Report: status = "succeeded" def model_dump(self, mode=None): return {"status": "succeeded", "run_id": "a" * 32, "stages": []} seen = {} def run(config, *, steps, resume): seen.update(config=config, steps=steps, resume=resume) return Report() monkeypatch.setattr(command, "run_dwh_from_config", run) response = CliRunner().invoke( app, [ "preprocess", "dwh", "--steps", "introspect,lsh", "--json", "-c", str(tmp_path / "workspace.yaml"), ], ) assert response.exit_code == 0, response.output assert json.loads(response.output)["run_id"] == "a" * 32 assert seen["steps"] == ("introspect", "lsh") def test_preprocess_dwh_rejects_unknown_or_duplicate_steps(monkeypatch, tmp_path): import tht.cli.preprocess_cmd as command called = False def forbidden(*args, **kwargs): nonlocal called called = True monkeypatch.setattr(command, "run_dwh_from_config", forbidden) runner = CliRunner() for value in ("introspect,unknown", "lsh,lsh", ""): response = runner.invoke( app, ["preprocess", "dwh", "--steps", value, "--json", "-c", str(tmp_path / "w.yaml")], ) assert response.exit_code == 2 assert json.loads(response.output)["status"] == "failed" assert called is False