feat: add P2 harness machine contracts
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
|
||||
from typer.testing import CliRunner
|
||||
@@ -51,9 +52,10 @@ def test_preprocess_failed_job_report_is_sanitized_json_and_nonzero(monkeypatch,
|
||||
|
||||
|
||||
def test_preprocess_real_failed_stage_result_exits_nonzero(monkeypatch, tmp_path):
|
||||
import tht.cli.preprocess_cmd as command
|
||||
from test_corpus_pipeline import Source, item, pipeline
|
||||
|
||||
import tht.cli.preprocess_cmd as command
|
||||
|
||||
result = pipeline(
|
||||
tmp_path, Source([(item("one", "a"), RuntimeError("SENSITIVE EVIDENCE secret"))])
|
||||
).run_as_job(
|
||||
@@ -129,3 +131,32 @@ def test_preprocess_evidence_gc_json_is_pristine(monkeypatch, tmp_path):
|
||||
)
|
||||
assert response.exit_code == 0, response.output
|
||||
assert json.loads(response.output)["dry_run"] is True
|
||||
|
||||
|
||||
def test_preprocess_evidence_uses_runtime_identity_for_dev_fd_config(monkeypatch, tmp_path):
|
||||
import tht.cli.preprocess_cmd as command
|
||||
|
||||
cfg = SimpleNamespace(
|
||||
runtime_identity=SimpleNamespace(workspace_id="runtime-workspace"),
|
||||
embeddings=SimpleNamespace(model="m", dim=4),
|
||||
vector=SimpleNamespace(max_chunk_chars=10, retain_published_generations=1),
|
||||
paths=SimpleNamespace(artifacts=tmp_path / "artifacts"),
|
||||
model_dump_json=lambda: "{}",
|
||||
)
|
||||
captured = {}
|
||||
|
||||
class FakePipeline:
|
||||
def __init__(self, **kwargs):
|
||||
captured.update(kwargs)
|
||||
|
||||
def run_as_job(self, **kwargs):
|
||||
captured.update(kwargs)
|
||||
return SimpleNamespace(model_dump=lambda mode=None: {"status": "succeeded"})
|
||||
|
||||
monkeypatch.setattr(command, "_load_config_or_exit", lambda _: cfg)
|
||||
monkeypatch.setattr("tht.adapters.factory.build_evidence_sources", lambda _: [])
|
||||
monkeypatch.setattr("tht.adapters.factory.build_vector_store", lambda *_args, **_kwargs: object())
|
||||
monkeypatch.setattr("tht.cli.vector_cmd.make_embedder", lambda _: object())
|
||||
monkeypatch.setattr("tht.corpus.pipeline.CorpusPipeline", FakePipeline)
|
||||
command.run_from_config(Path("/dev/fd/3"))
|
||||
assert captured["workspace_id"] == "runtime-workspace"
|
||||
|
||||
@@ -187,3 +187,37 @@ def test_memory_solved_index_help_uses_semantic_store_wording():
|
||||
assert res.exit_code == 0, res.output
|
||||
assert "semantic" in res.output.lower() or "qdrant" in res.output.lower()
|
||||
assert "vectordb" not in res.output.lower()
|
||||
|
||||
|
||||
def test_vector_index_schema_json_is_single_document(monkeypatch, tmp_path):
|
||||
import json
|
||||
|
||||
cfg = _qdrant_runtime_config(tmp_path)
|
||||
_write_schema_artifacts(tmp_path)
|
||||
store = _FakeVectorStore()
|
||||
monkeypatch.setattr("tht.adapters.factory.build_vector_store", lambda cfg, require_write: store)
|
||||
monkeypatch.setattr("tht.cli.vector_cmd.make_embedder", lambda _: _FakeEmbedder())
|
||||
response = CliRunner().invoke(app, ["vector", "index-schema", "--json", "-c", str(cfg)])
|
||||
assert response.exit_code == 0, response.output
|
||||
assert response.stdout.count("\n") == 1
|
||||
payload = json.loads(response.stdout)
|
||||
assert payload["status"] == "succeeded"
|
||||
assert payload["code"] == "ok"
|
||||
assert payload["counts"]["added"] == 2
|
||||
|
||||
|
||||
def test_vector_index_schema_json_failure_is_safe(monkeypatch, tmp_path):
|
||||
import json
|
||||
|
||||
cfg = _qdrant_runtime_config(tmp_path)
|
||||
_write_schema_artifacts(tmp_path)
|
||||
monkeypatch.setattr(
|
||||
"tht.adapters.factory.build_vector_store",
|
||||
lambda cfg, require_write: (_ for _ in ()).throw(RuntimeError("secret qdrant endpoint")),
|
||||
)
|
||||
response = CliRunner().invoke(app, ["vector", "index-schema", "--json", "-c", str(cfg)])
|
||||
assert response.exit_code != 0
|
||||
assert response.stdout.count("\n") == 1
|
||||
payload = json.loads(response.stdout)
|
||||
assert payload == {"status": "failed", "code": "schema_index_failed"}
|
||||
assert "secret qdrant" not in response.stdout
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# ruff: noqa: DTZ001
|
||||
from datetime import datetime
|
||||
|
||||
import yaml
|
||||
@@ -221,3 +222,62 @@ def test_suggest_fks_write_merges_and_is_idempotent(tmp_path):
|
||||
assert "nessuna FK da suggerire" in res2.output
|
||||
ann2 = Annotations.from_yaml(ann_path)
|
||||
assert len(ann2.tables["fact_ablazione"].foreign_keys) == 2
|
||||
|
||||
|
||||
def test_suggest_fks_json_is_single_deterministic_document_without_writing(tmp_path):
|
||||
import hashlib
|
||||
import json
|
||||
|
||||
cfg = _write_workspace(tmp_path)
|
||||
staged = tmp_path / "staged"
|
||||
staged.mkdir()
|
||||
(staged / "z.sql").write_text(
|
||||
"SELECT * FROM fact_ablazione f JOIN dim_patient p ON f.cod_paz = p.cod_paz"
|
||||
)
|
||||
(staged / "a.sql").write_text(
|
||||
"SELECT * FROM fact_ablazione f JOIN dim_time p ON f.data_time_key = p.day_key"
|
||||
)
|
||||
response = CliRunner().invoke(
|
||||
app, ["schema", "suggest-fks", "--json", "-c", str(cfg), "--from-sql", str(staged)]
|
||||
)
|
||||
assert response.exit_code == 0, response.output
|
||||
assert response.stdout.count("\n") == 1
|
||||
payload = json.loads(response.stdout)
|
||||
assert payload["status"] == "succeeded"
|
||||
assert payload["code"] == "ok"
|
||||
assert payload["candidate_count"] == 2
|
||||
assert payload["candidate_digest"].startswith("sha256:")
|
||||
assert payload["orphan_count"] == 0
|
||||
# The digest is over the canonical candidate export and --json never writes annotations.
|
||||
expected = json.dumps(payload["candidates"], ensure_ascii=False, sort_keys=True, separators=(",", ":"))
|
||||
assert payload["candidate_digest"] == "sha256:" + hashlib.sha256(expected.encode()).hexdigest()
|
||||
assert not (tmp_path / "artifacts" / "mschema" / "annotations.yaml").exists()
|
||||
|
||||
|
||||
def test_suggest_fks_json_failure_is_safe_and_single_document(tmp_path):
|
||||
import json
|
||||
|
||||
cfg = _write_workspace(tmp_path)
|
||||
(tmp_path / "artifacts" / "mschema" / "physical.yaml").unlink()
|
||||
response = CliRunner().invoke(app, ["schema", "suggest-fks", "--json", "-c", str(cfg)])
|
||||
assert response.exit_code != 0
|
||||
assert response.stdout.count("\n") == 1
|
||||
payload = json.loads(response.stdout)
|
||||
assert payload == {"status": "failed", "code": "physical_schema_missing"}
|
||||
assert str(tmp_path) not in response.stdout
|
||||
|
||||
|
||||
def test_schema_check_json_reports_orphan_count_without_prose(tmp_path):
|
||||
import json
|
||||
|
||||
cfg = _write_workspace(tmp_path)
|
||||
Annotations(tables={"gone": TableAnnotation(description="x")}).to_yaml(
|
||||
tmp_path / "artifacts" / "mschema" / "annotations.yaml"
|
||||
)
|
||||
response = CliRunner().invoke(app, ["schema", "check", "--json", "-c", str(cfg)])
|
||||
assert response.exit_code == 3
|
||||
assert response.stdout.count("\n") == 1
|
||||
assert json.loads(response.stdout) == {
|
||||
"status": "failed", "code": "annotation_orphans", "orphan_count": 1,
|
||||
"orphans": ["gone"],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user