feat: pristine harness JSON interfaces and require-existing semantic mode (P2)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
@@ -9,6 +10,7 @@ from typer.testing import CliRunner
|
||||
|
||||
from tht.cli import app
|
||||
from tht.memory import MemoryRecord, save_registry
|
||||
from tht.ports.vector import VectorStoreError
|
||||
|
||||
|
||||
class _FakeEmbedder:
|
||||
@@ -33,6 +35,10 @@ class _FakeVectorStore:
|
||||
return 3
|
||||
|
||||
|
||||
def _sha_file(path: Path) -> str:
|
||||
return "sha256:" + hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def _qdrant_runtime_config(tmp_path: Path) -> Path:
|
||||
cfg = tmp_path / "workspace.yaml"
|
||||
cfg.write_text(
|
||||
@@ -76,9 +82,7 @@ tables:
|
||||
type: bigint
|
||||
"""
|
||||
)
|
||||
(tmp_path / "artifacts" / "mschema" / "annotations.yaml").write_text(
|
||||
"tables: {}\n"
|
||||
)
|
||||
(tmp_path / "artifacts" / "mschema" / "annotations.yaml").write_text("tables: {}\n")
|
||||
|
||||
|
||||
def _memory_record() -> MemoryRecord:
|
||||
@@ -111,6 +115,73 @@ def test_vector_index_schema_accepts_qdrant_only_runtime_config(tmp_path, monkey
|
||||
assert store.upserts
|
||||
|
||||
|
||||
def test_vector_index_schema_json_is_pristine_and_reports_artifacts(tmp_path, monkeypatch):
|
||||
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.stderr == ""
|
||||
assert json.loads(response.stdout) == {
|
||||
"artifactIdentities": [
|
||||
{
|
||||
"digest": _sha_file(tmp_path / "artifacts" / "mschema" / "annotations.yaml"),
|
||||
"kind": "schema_annotations",
|
||||
},
|
||||
{
|
||||
"digest": _sha_file(tmp_path / "artifacts" / "mschema" / "physical.yaml"),
|
||||
"kind": "physical_schema",
|
||||
},
|
||||
],
|
||||
"code": "ok",
|
||||
"collection": "psd-clinical",
|
||||
"counts": {
|
||||
"added": 2,
|
||||
"columns": 1,
|
||||
"deleted": 0,
|
||||
"records": 2,
|
||||
"tables": 1,
|
||||
"unchanged": 0,
|
||||
"updated": 0,
|
||||
},
|
||||
"operation": "index_schema",
|
||||
"schemaVersion": 1,
|
||||
"status": "succeeded",
|
||||
"workspaceId": "psd-clinical",
|
||||
"workspaceRevision": "a" * 40,
|
||||
}
|
||||
|
||||
|
||||
def test_vector_index_schema_json_failure_is_pristine(tmp_path, monkeypatch):
|
||||
cfg = _qdrant_runtime_config(tmp_path)
|
||||
_write_schema_artifacts(tmp_path)
|
||||
|
||||
def boom(cfg, require_write):
|
||||
raise VectorStoreError("semantic_index_incompatible")
|
||||
|
||||
monkeypatch.setattr("tht.adapters.factory.build_vector_store", boom)
|
||||
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 == 1
|
||||
assert response.stderr == ""
|
||||
assert json.loads(response.stdout) == {
|
||||
"code": "semantic_index_incompatible",
|
||||
"error": "semantic index incompatible",
|
||||
"operation": "index_schema",
|
||||
"schemaVersion": 1,
|
||||
"status": "failed",
|
||||
"workspaceId": "psd-clinical",
|
||||
"workspaceRevision": "a" * 40,
|
||||
}
|
||||
|
||||
|
||||
def test_memory_promote_accepts_qdrant_only_runtime_config(tmp_path, monkeypatch):
|
||||
cfg = _qdrant_runtime_config(tmp_path)
|
||||
store = _FakeVectorStore()
|
||||
|
||||
Reference in New Issue
Block a user