Harden runtime diagnostics for milestone 3
Make the milestone 3 runtime story predictable instead of treating doctor, self-check, and startup failures as loosely related surfaces. Split doctor and self-check into distinct read-only flows, add tri-state diagnostic status with stable IDs and next steps, and reuse that wording in CLI output, service logs, and tray-triggered diagnostics. Add non-mutating config/model probes, a make runtime-check gate, and public recovery/validation docs for the X11 GA roadmap. Validation: make runtime-check; PYTHONPATH=src python3 -m unittest discover -s tests -p 'test_*.py'; python3 -m py_compile src/*.py tests/*.py; PYTHONPATH=src python3 -m aman doctor --help; PYTHONPATH=src python3 -m aman self-check --help. Leave milestone 3 open in the roadmap until the manual X11 validation rows are filled.
This commit is contained in:
parent
a3368056ff
commit
ed1b59240b
16 changed files with 1298 additions and 248 deletions
|
|
@ -24,6 +24,7 @@ from aiprocess import (
|
|||
_profile_generation_kwargs,
|
||||
_supports_response_format,
|
||||
ensure_model,
|
||||
probe_managed_model,
|
||||
)
|
||||
from constants import MODEL_SHA256
|
||||
|
||||
|
|
@ -325,6 +326,42 @@ class EnsureModelTests(unittest.TestCase):
|
|||
):
|
||||
ensure_model()
|
||||
|
||||
def test_probe_managed_model_is_read_only_for_valid_cache(self):
|
||||
payload = b"valid-model"
|
||||
checksum = sha256(payload).hexdigest()
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
model_path = Path(td) / "model.gguf"
|
||||
model_path.write_bytes(payload)
|
||||
with patch.object(aiprocess, "MODEL_PATH", model_path), patch.object(
|
||||
aiprocess, "MODEL_SHA256", checksum
|
||||
), patch("aiprocess.urllib.request.urlopen") as urlopen:
|
||||
result = probe_managed_model()
|
||||
|
||||
self.assertEqual(result.status, "ready")
|
||||
self.assertIn("ready", result.message)
|
||||
urlopen.assert_not_called()
|
||||
|
||||
def test_probe_managed_model_reports_missing_cache(self):
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
model_path = Path(td) / "model.gguf"
|
||||
with patch.object(aiprocess, "MODEL_PATH", model_path):
|
||||
result = probe_managed_model()
|
||||
|
||||
self.assertEqual(result.status, "missing")
|
||||
self.assertIn(str(model_path), result.message)
|
||||
|
||||
def test_probe_managed_model_reports_invalid_checksum(self):
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
model_path = Path(td) / "model.gguf"
|
||||
model_path.write_bytes(b"bad-model")
|
||||
with patch.object(aiprocess, "MODEL_PATH", model_path), patch.object(
|
||||
aiprocess, "MODEL_SHA256", "f" * 64
|
||||
):
|
||||
result = probe_managed_model()
|
||||
|
||||
self.assertEqual(result.status, "invalid")
|
||||
self.assertIn("checksum mismatch", result.message)
|
||||
|
||||
|
||||
class ExternalApiProcessorTests(unittest.TestCase):
|
||||
def test_requires_api_key_env_var(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue