import json import pytest from tools.answers import model_client as model from tools.runtime import answer_health as health from tools.knowledge.publication import checkpoint_state, PENDING_FILE from tools.sync.index_state import durable_json, VERSION_FILE from test_index_sync import snapshot def test_generation_poll_never_calls_provider_and_reports_unknown(monkeypatch): monkeypatch.setenv("ANSWER_API_KEY", "private-secret") monkeypatch.setenv("ANSWER_MODEL", "test") monkeypatch.setenv("ANSWER_LLM_URL", "https://provider.example/v1/chat/completions") monkeypatch.setattr(model, "_status", {}) def forbidden(*args, **kwargs): pytest.fail("Health polling must not call LLM") monkeypatch.setattr(model, "_complete_request", forbidden) assert model.generation_status()["status"] == "unknown" assert "private-secret" not in json.dumps(model.generation_status()) def test_probe_records_success_failure_and_configuration_change(monkeypatch): monkeypatch.setenv("ANSWER_API_KEY", "test-secret") monkeypatch.setenv("ANSWER_MODEL", "test") monkeypatch.setenv("ANSWER_LLM_URL", "https://provider.example/v1/chat/completions") monkeypatch.setattr(model, "_status", {}) monkeypatch.setattr(model, "_complete_request", lambda *a, **kw: {"choices": [{"message": {"content": "OK"}}]}) assert model.probe_generation()["ready"] is True def fail(*args, **kwargs): raise ConnectionError("do not expose private-secret") monkeypatch.setattr(model, "_complete_request", fail) result = model.probe_generation() assert not result["ready"] and result["reason"] == "model_probe_failed" assert "private-secret" not in json.dumps(result) monkeypatch.setenv("ANSWER_MODEL", "new-model") assert model.generation_status()["status"] == "unknown" def test_content_health_distinguishes_current_stale_corrupt_and_pending(tmp_path): version = {"version": "old"} snapshot(tmp_path, version) index = {"extraction_schema":2,"extraction_policy":"scoped-assertions-v2", "version": "content", "index_version": version, "graph_ready": False, "units": []} checkpoint_state(tmp_path, index) db = tmp_path / "zp_index.sqlite" assert health.content_readiness(db, version, graph_available=False)["ready"] path = tmp_path / "knowledge/index.json" path.write_text(path.read_text() + " ") assert health.content_readiness(db, version, graph_available=False)["reason"] == "content_checkpoint_invalid" checkpoint_state(tmp_path, {**index, "index_version": {"version": "new"}}) assert health.content_readiness(db, version, graph_available=False)["reason"] == "content_version_mismatch" durable_json(tmp_path / PENDING_FILE, {}) assert health.content_readiness(db, version, graph_available=False)["reason"] == "content_publication_incomplete"