Preformu / tests /test_model_config.py
Kevinshh's picture
Deploy Kernel+Skill architecture to HF Spaces; wire advanced stability features; remove deprecated entry points
19729e9
Raw
History Blame Contribute Delete
4.11 kB
"""模型配置优先级测试:用户 > 管理员 > 环境变量(需求 5 / 15.5)。
验证 ``services.model_config.resolve_chain`` 的优先级、Fallback 拼接与去重,
以及 custom 提供商的可用性判定。导入路径由 tests/conftest.py 设置。
"""
from services.model_config import ( # noqa: E402
UserModelConfig,
resolve_chain,
build_llm_service,
)
def _admin(enabled=True, provider="kimi", api_key="admin-key", model="", base_url=""):
return {"enabled": enabled, "provider": provider, "api_key": api_key,
"model": model, "base_url": base_url}
def test_user_config_takes_priority():
"""用户自配可用时,链首为用户配置,source=user。"""
user = UserModelConfig(provider="deepseek", api_key="user-key", model="deepseek-v4-pro")
chain = resolve_chain(user_cfg=user, admin_cfg=_admin(), env={"OPENAI_API_KEY": "envk"})
assert chain.source == "user"
assert chain.active_provider == "deepseek"
assert chain.active_model == "deepseek-v4-pro"
# 管理员与环境档作为 Fallback 仍在链中。
providers = [s.provider for s in chain.specs]
assert "kimi" in providers and "openai" in providers
def test_admin_used_when_no_user_config():
"""用户未配置时,使用管理员配置,source=admin。"""
chain = resolve_chain(user_cfg=None, admin_cfg=_admin(provider="zhipu", api_key="ak"),
env={"OPENAI_API_KEY": "envk"})
assert chain.source == "admin"
assert chain.active_provider == "zhipu"
# 环境档兜底仍在。
assert "openai" in [s.provider for s in chain.specs]
def test_env_used_when_no_user_or_admin():
"""用户与管理员都没有时,回退环境变量,source=env。"""
chain = resolve_chain(user_cfg=None, admin_cfg=_admin(enabled=False),
env={"DEEPSEEK_API_KEY": "envk"})
assert chain.source == "env"
assert chain.active_provider == "deepseek"
def test_none_when_nothing_configured():
chain = resolve_chain(user_cfg=None, admin_cfg=None, env={})
assert chain.source == "none"
assert chain.specs == []
def test_disabled_admin_is_ignored():
chain = resolve_chain(user_cfg=None, admin_cfg=_admin(enabled=False), env={})
assert chain.source == "none"
def test_custom_user_requires_base_url_and_model():
"""custom 用户配置缺 base_url/model 时不可用,回退下一档。"""
bad = UserModelConfig(provider="custom", api_key="k") # 缺 base_url + model
chain = resolve_chain(user_cfg=bad, admin_cfg=_admin(), env={})
assert chain.source == "admin" # 用户档不可用 → 用管理员
good = UserModelConfig(provider="custom", api_key="k",
base_url="https://x/v1/chat/completions", model="m")
chain2 = resolve_chain(user_cfg=good, admin_cfg=_admin(), env={})
assert chain2.source == "user"
assert chain2.active_provider == "custom"
assert chain2.active_model == "m"
def test_admin_custom_requires_base_url():
"""管理员 custom 配置缺 base_url/model 时视为不可用。"""
chain = resolve_chain(
user_cfg=None,
admin_cfg=_admin(provider="custom", api_key="k"), # 缺 base_url+model
env={},
)
assert chain.source == "none"
def test_dedup_keeps_higher_priority():
"""用户与环境同为 deepseek 时去重,仅保留用户档(更高优先级)。"""
user = UserModelConfig(provider="deepseek", api_key="user-key")
chain = resolve_chain(user_cfg=user, admin_cfg=None, env={"DEEPSEEK_API_KEY": "envk"})
deepseek_specs = [s for s in chain.specs if s.provider == "deepseek"]
assert len(deepseek_specs) == 1
assert deepseek_specs[0].api_key == "user-key"
def test_build_llm_service_preserves_order():
user = UserModelConfig(provider="deepseek", api_key="uk", model="deepseek-v4-flash")
chain = resolve_chain(user_cfg=user, admin_cfg=_admin(provider="kimi", api_key="ak"), env={})
svc = build_llm_service(chain)
assert svc._specs[0].provider == "deepseek"
assert svc._specs[1].provider == "kimi"