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>
98 lines
3.4 KiB
Python
98 lines
3.4 KiB
Python
"""Tests for ``EvoScientist.config.legacy_artifacts`` (design doc §10 step 4).
|
|
|
|
Startup must refuse — with an explicit reset guide — when any pre-Registry
|
|
model configuration artifact remains: an old ``providers.yaml``, an old
|
|
``run-runtime-snapshots.sqlite3``, or leftover LLM fields in
|
|
``config.yaml``. Platform fields in ``config.yaml`` are fine.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
import yaml
|
|
|
|
from EvoScientist.config.legacy_artifacts import (
|
|
LEGACY_CONFIG_YAML_KEYS,
|
|
LegacyArtifactsError,
|
|
assert_no_legacy_artifacts,
|
|
find_legacy_artifacts,
|
|
)
|
|
|
|
|
|
def test_clean_config_dir_passes(tmp_path):
|
|
(tmp_path / "config.yaml").write_text(
|
|
yaml.safe_dump({"workspace_dir": "/tmp/ws", "langgraph_port": 2024}),
|
|
encoding="utf-8",
|
|
)
|
|
assert find_legacy_artifacts(tmp_path) == []
|
|
assert_no_legacy_artifacts(tmp_path) # must not raise
|
|
|
|
|
|
def test_missing_config_yaml_passes(tmp_path):
|
|
assert find_legacy_artifacts(tmp_path) == []
|
|
assert_no_legacy_artifacts(tmp_path)
|
|
|
|
|
|
def test_legacy_providers_yaml_refused(tmp_path):
|
|
(tmp_path / "providers.yaml").write_text("providers: []\n", encoding="utf-8")
|
|
found = find_legacy_artifacts(tmp_path)
|
|
assert any("providers.yaml" in item for item in found)
|
|
with pytest.raises(LegacyArtifactsError) as excinfo:
|
|
assert_no_legacy_artifacts(tmp_path)
|
|
message = str(excinfo.value)
|
|
assert "providers.yaml" in message
|
|
# The reset guide is part of the refusal (section 10 step 4).
|
|
assert "Delete" in message
|
|
assert "Model Registry" in message
|
|
|
|
|
|
def test_legacy_snapshot_database_refused(tmp_path):
|
|
(tmp_path / "run-runtime-snapshots.sqlite3").touch()
|
|
found = find_legacy_artifacts(tmp_path)
|
|
assert any("run-runtime-snapshots.sqlite3" in item for item in found)
|
|
with pytest.raises(LegacyArtifactsError, match="run-runtime-snapshots"):
|
|
assert_no_legacy_artifacts(tmp_path)
|
|
|
|
|
|
def test_leftover_llm_fields_in_config_yaml_refused(tmp_path):
|
|
(tmp_path / "config.yaml").write_text(
|
|
yaml.safe_dump(
|
|
{
|
|
"workspace_dir": "/tmp/ws",
|
|
"model": "glm-5.2",
|
|
"zhipu_api_key": "sk-old",
|
|
"model_fallbacks": ["gpt-5"],
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
found = find_legacy_artifacts(tmp_path)
|
|
assert len(found) == 1
|
|
assert "model" in found[0]
|
|
assert "zhipu_api_key" in found[0]
|
|
with pytest.raises(LegacyArtifactsError) as excinfo:
|
|
assert_no_legacy_artifacts(tmp_path)
|
|
assert "zhipu_api_key" in str(excinfo.value)
|
|
|
|
|
|
def test_all_artifacts_reported_together(tmp_path):
|
|
(tmp_path / "providers.yaml").touch()
|
|
(tmp_path / "run-runtime-snapshots.sqlite3").touch()
|
|
(tmp_path / "config.yaml").write_text(
|
|
yaml.safe_dump({"provider": "zhipu"}), encoding="utf-8"
|
|
)
|
|
found = find_legacy_artifacts(tmp_path)
|
|
assert len(found) == 3
|
|
|
|
|
|
def test_invalid_config_yaml_not_misread_as_legacy(tmp_path):
|
|
(tmp_path / "config.yaml").write_text("{{{{ not yaml", encoding="utf-8")
|
|
# Unparseable YAML yields no key evidence — other layers report it.
|
|
assert find_legacy_artifacts(tmp_path) == []
|
|
|
|
|
|
def test_legacy_key_set_covers_cutover_fields():
|
|
# Spot-check the section-10 cutover list stays comprehensive.
|
|
for key in ("provider", "model", "auxiliary_model", "anthropic_api_key"):
|
|
assert key in LEGACY_CONFIG_YAML_KEYS
|