Files
EvoScientist/tests/test_legacy_artifacts.py
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

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