421a664336
- Remove legacy provider profiles, admin-token auth, /model command, model picker widget, and config.yaml LLM fields (design doc section 10) - Wire CLI/channels/cron and async sub-agents through the local snapshot entry; run creation rejects model config outside runtime_snapshot_id - Add periodic run-snapshot TTL cleanup to the config service lifespan - Isolate tests from the real config dir and activate the registry where run/model paths fail closed in bootstrap Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
73 lines
2.5 KiB
Python
73 lines
2.5 KiB
Python
"""Tests for the CLI startup gates (design doc §10 step 4, §8.1).
|
|
|
|
``_startup_gates`` is the shared refuse-startup path for the chat entry and
|
|
``serve``: legacy model-configuration artifacts abort with the reset guide,
|
|
and a bootstrap registry aborts with ``MODEL_REGISTRY_NOT_READY`` — both
|
|
with exit code 1, never a silent fall-through to an implicit model.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
import typer
|
|
|
|
import EvoScientist.config.legacy_artifacts as legacy_artifacts
|
|
import EvoScientist.model_registry.runtime as runtime_module
|
|
from EvoScientist.cli.commands import _startup_gates
|
|
from EvoScientist.config.legacy_artifacts import LegacyArtifactsError
|
|
from EvoScientist.model_registry.errors import (
|
|
MODEL_REGISTRY_NOT_READY,
|
|
ModelRegistryError,
|
|
)
|
|
|
|
|
|
def test_legacy_artifacts_abort_startup(monkeypatch):
|
|
monkeypatch.setattr(
|
|
legacy_artifacts,
|
|
"assert_no_legacy_artifacts",
|
|
MagicMock(side_effect=LegacyArtifactsError("legacy providers.yaml found")),
|
|
)
|
|
with pytest.raises(typer.Exit) as excinfo:
|
|
_startup_gates()
|
|
assert excinfo.value.exit_code == 1
|
|
|
|
|
|
def test_bootstrap_registry_aborts_startup(monkeypatch):
|
|
monkeypatch.setattr(
|
|
legacy_artifacts, "assert_no_legacy_artifacts", MagicMock()
|
|
)
|
|
runtime = MagicMock()
|
|
runtime.registry_defaults.side_effect = ModelRegistryError(
|
|
MODEL_REGISTRY_NOT_READY, "bootstrap"
|
|
)
|
|
monkeypatch.setattr(runtime_module, "get_snapshot_runtime", lambda: runtime)
|
|
with pytest.raises(typer.Exit) as excinfo:
|
|
_startup_gates()
|
|
assert excinfo.value.exit_code == 1
|
|
|
|
|
|
def test_clean_environment_passes(monkeypatch):
|
|
monkeypatch.setattr(
|
|
legacy_artifacts, "assert_no_legacy_artifacts", MagicMock()
|
|
)
|
|
runtime = MagicMock()
|
|
runtime.registry_defaults.return_value = (MagicMock(), None, 2)
|
|
monkeypatch.setattr(runtime_module, "get_snapshot_runtime", lambda: runtime)
|
|
_startup_gates() # must not raise
|
|
|
|
|
|
def test_non_bootstrap_registry_error_propagates(monkeypatch):
|
|
"""Only NOT_READY is converted to a guided exit; other errors bubble up."""
|
|
monkeypatch.setattr(
|
|
legacy_artifacts, "assert_no_legacy_artifacts", MagicMock()
|
|
)
|
|
runtime = MagicMock()
|
|
runtime.registry_defaults.side_effect = ModelRegistryError(
|
|
"SNAPSHOT_EXPIRED", "expired"
|
|
)
|
|
monkeypatch.setattr(runtime_module, "get_snapshot_runtime", lambda: runtime)
|
|
with pytest.raises(ModelRegistryError):
|
|
_startup_gates()
|