Files
EvoScientist/tests/test_runtime_snapshots.py
T
m4 8a0ab17936 chore: baseline WIP before unified model configuration implementation
Pre-existing uncommitted work (runtime snapshots, message budget middleware) preserved as baseline.
2026-07-20 20:15:38 +08:00

153 lines
4.9 KiB
Python

"""Tests for server-side run configuration snapshots."""
from __future__ import annotations
from unittest.mock import MagicMock, patch
import pytest
from EvoScientist.config.provider_profiles import (
ProviderProfileError,
replace_provider_profiles,
)
from EvoScientist.llm.runtime_snapshots import (
create_run_runtime_snapshot,
get_run_runtime_snapshot,
get_snapshot_chat_model,
)
@pytest.fixture
def provider_config_dir(tmp_path, monkeypatch):
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
return tmp_path / "evoscientist"
def _document(api_key: str = "first-secret", base_url: str = "https://one.test/v1"):
return {
"version": 3,
"providers": [
{
"id": "lab-openai",
"name": "Lab OpenAI",
"adapter": "openai-compatible",
"base_url": base_url,
"api_key": api_key,
"enabled": True,
"runtime": {"timeout_seconds": 90, "max_retries": 1},
"models": [
{
"id": "research-model",
"name": "Research Model",
"model_id": "vendor/research-1",
"enabled": True,
"runtime": {
"limit_mode": "combined",
"context_window_tokens": 32_768,
"max_output_tokens": 4_096,
"min_effective_input_tokens": 4_096,
"limits_status": "confirmed",
"limits_source": "provider",
},
}
],
}
],
}
def test_snapshot_keeps_connection_and_runtime_after_profile_changes(provider_config_dir):
replace_provider_profiles(_document())
created = create_run_runtime_snapshot(
"run-request-a", model="research-model", provider="lab-openai"
)
assert created is not None
assert created.options.resolved_input_limit == 28_672
assert created.profile.api_key == "first-secret"
assert "first-secret" not in str(created.public_payload())
assert "first-secret" not in (
provider_config_dir / "run-runtime-snapshots.sqlite3"
).read_bytes().decode("utf-8", errors="ignore")
replace_provider_profiles(
_document("second-secret", "https://two.test/v1")
)
loaded = get_run_runtime_snapshot("run-request-a")
assert loaded is not None
assert loaded.profile.api_key == "first-secret"
assert loaded.profile.base_url == "https://one.test/v1"
assert loaded.options.timeout_seconds == 90
def test_snapshot_id_is_idempotent_and_cannot_change_model(provider_config_dir):
replace_provider_profiles(_document())
first = create_run_runtime_snapshot(
"run-request-a", model="research-model", provider="lab-openai"
)
repeated = create_run_runtime_snapshot(
"run-request-a", model="research-model", provider="lab-openai"
)
assert repeated == first
with pytest.raises(ValueError, match="already bound"):
create_run_runtime_snapshot(
"run-request-a", model="another-model", provider="lab-openai"
)
def test_static_provider_does_not_need_a_custom_snapshot(provider_config_dir):
assert (
create_run_runtime_snapshot(
"run-request-a", model="gpt-5", provider="openai"
)
is None
)
def test_glm_alias_is_static_even_when_custom_registry_is_stale(
provider_config_dir, monkeypatch
):
monkeypatch.setenv("ZHIPU_API_KEY", "test-zhipu-key")
provider_config_dir.mkdir(parents=True)
(provider_config_dir / "providers.yaml").write_text(
"version: 2\nproviders: []\n", encoding="utf-8"
)
assert (
create_run_runtime_snapshot(
"run-request-glm", model="glm-5.2", provider="glm"
)
is None
)
def test_zhipu_snapshot_requires_its_own_api_key(provider_config_dir, monkeypatch):
monkeypatch.delenv("ZHIPU_API_KEY", raising=False)
monkeypatch.setenv("OPENAI_API_KEY", "unrelated-openai-key")
with pytest.raises(ProviderProfileError, match="ZHIPU_API_KEY_NOT_CONFIGURED"):
create_run_runtime_snapshot(
"run-request-zhipu", model="glm-5.2", provider="zhipu"
)
def test_snapshot_model_builder_uses_frozen_profile(provider_config_dir):
replace_provider_profiles(_document())
create_run_runtime_snapshot(
"run-request-a", model="research-model", provider="lab-openai"
)
model = MagicMock()
with patch(
"EvoScientist.llm.models.get_profile_chat_model", return_value=model
) as factory:
resolved = get_snapshot_chat_model("run-request-a")
assert resolved is model
profile, provider_model = factory.call_args.args
assert profile.api_key == "first-secret"
assert provider_model.model_id == "vendor/research-1"