Files
EvoScientist/tests/test_cli_startup_gates.py
T
m4 421a664336 feat(runtime)!: complete legacy removal, local snapshot entries, and TTL cleanup
- 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>
2026-07-21 18:10:23 +08:00

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()