mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
feat(pool,scheduling): 号池调度维度、配额冷却机制与管理后台重构
- 新增 scheduling_dimensions 模块,为每个 Key 计算多维调度状态(手动/冷却/熔断/成本/健康) - 新增 quota_cooldown 模块,统一判定 Key 的有效冷却原因 - Pool 管理后台 API 扩展 Key 详情字段(调度状态/维度/配额/OAuth 信息) - 前端 Pool 管理页面重写,支持调度状态展示、批量清理封禁 Key - Handler 基类增加请求调度元数据采集,stream telemetry 增强 - 请求时间线组件增强,支持 attempted 候选展示 - Kiro OAuth 凭证导入解析改进 - 新增 usage 表 provider_key 索引迁移 - 补充调度维度、配额冷却、候选枚举等单元测试 Closes #197 Co-authored-by: AAEE86 <33052466+AAEE86@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from src.services.scheduling.aware_scheduler import CacheAwareScheduler
|
||||
|
||||
|
||||
def _mock_key(key_id: str, api_formats: list[str]) -> MagicMock:
|
||||
key = MagicMock()
|
||||
key.id = key_id
|
||||
key.is_active = True
|
||||
key.api_formats = api_formats
|
||||
key.cache_ttl_minutes = 1
|
||||
key.internal_priority = 1
|
||||
return key
|
||||
|
||||
|
||||
def _mock_endpoint(api_format: str) -> MagicMock:
|
||||
endpoint = MagicMock()
|
||||
endpoint.id = f"ep_{api_format.lower().replace(':', '_')}"
|
||||
endpoint.is_active = True
|
||||
endpoint.api_format = api_format
|
||||
endpoint.api_family = api_format.split(":", 1)[0]
|
||||
endpoint.endpoint_kind = api_format.split(":", 1)[1]
|
||||
endpoint.format_acceptance_config = None
|
||||
return endpoint
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_pool_provider_enumerates_all_key_candidates() -> None:
|
||||
scheduler = CacheAwareScheduler()
|
||||
builder = scheduler._candidate_builder
|
||||
builder._check_model_support = AsyncMock(return_value=(True, None, None, {"m"})) # type: ignore[method-assign]
|
||||
builder._check_key_availability = MagicMock(return_value=(True, None, None)) # type: ignore[method-assign]
|
||||
|
||||
provider = MagicMock()
|
||||
provider.id = "p_pool"
|
||||
provider.name = "pool_provider"
|
||||
provider.enable_format_conversion = False
|
||||
provider.config = {"pool_advanced": {}}
|
||||
provider.endpoints = [_mock_endpoint("openai:chat")]
|
||||
provider.api_keys = [
|
||||
_mock_key("k1", ["openai:chat"]),
|
||||
_mock_key("k2", ["openai:chat"]),
|
||||
]
|
||||
|
||||
candidates = await builder._build_candidates(
|
||||
db=MagicMock(),
|
||||
providers=[provider],
|
||||
client_format="openai:chat",
|
||||
model_name="dummy-model",
|
||||
affinity_key="aff-1",
|
||||
global_conversion_enabled=True,
|
||||
)
|
||||
|
||||
assert len(candidates) == 2
|
||||
assert {str(c.key.id) for c in candidates} == {"k1", "k2"}
|
||||
Reference in New Issue
Block a user