feat(pool): 增加 OAuth 账号池管理功能

- 新增 pool manager / strategy / health_policy / cost_tracker / redis_ops 等核心模块
- 新增 pool admin API 路由与 schemas
- 新增 OAuth 账号类型解析 (oauth_plan)
- 前端增加 PoolManagement 页面、PoolConfigDialog、PoolImportDialog、PoolStatusCard 组件
- 补充 pool config / cost tracker / health policy / manager / strategy / trace 等测试
This commit is contained in:
fawney19
2026-02-27 13:58:58 +08:00
parent 579b5e4623
commit 76a6d0ce8e
35 changed files with 5761 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
"""Tests for pool_config.py — configuration parsing and defaults."""
from __future__ import annotations
from src.services.provider.pool.config import (
PoolConfig,
UnschedulableRule,
parse_pool_config,
)
def test_parse_pool_config_returns_none_when_no_advanced_section() -> None:
assert parse_pool_config({}) is None
assert parse_pool_config(None) is None
assert parse_pool_config({"other_key": 1}) is None
def test_parse_pool_config_returns_defaults_for_empty_advanced() -> None:
cfg = parse_pool_config({"pool_advanced": {}})
assert cfg is not None
assert cfg.sticky_session_ttl_seconds == 3600
assert cfg.load_threshold_percent == 80
assert cfg.lru_enabled is True
assert cfg.cost_window_seconds == 18000
assert cfg.cost_limit_per_key_tokens is None
assert cfg.cost_soft_threshold_percent == 80
assert cfg.rate_limit_cooldown_seconds == 300
assert cfg.overload_cooldown_seconds == 30
assert cfg.proactive_refresh_seconds == 180
assert cfg.health_policy_enabled is True
assert cfg.unschedulable_rules == []
def test_parse_pool_config_overrides_values() -> None:
cfg = parse_pool_config(
{
"pool_advanced": {
"sticky_session_ttl_seconds": 7200,
"load_threshold_percent": 90,
"lru_enabled": False,
"cost_window_seconds": 36000,
"cost_limit_per_key_tokens": 100000,
"cost_soft_threshold_percent": 70,
"rate_limit_cooldown_seconds": 600,
"overload_cooldown_seconds": 60,
"proactive_refresh_seconds": 300,
"health_policy_enabled": False,
}
}
)
assert cfg is not None
assert cfg.sticky_session_ttl_seconds == 7200
assert cfg.load_threshold_percent == 90
assert cfg.lru_enabled is False
assert cfg.cost_window_seconds == 36000
assert cfg.cost_limit_per_key_tokens == 100000
assert cfg.cost_soft_threshold_percent == 70
assert cfg.rate_limit_cooldown_seconds == 600
assert cfg.overload_cooldown_seconds == 60
assert cfg.proactive_refresh_seconds == 300
assert cfg.health_policy_enabled is False
def test_parse_pool_config_parses_unschedulable_rules() -> None:
cfg = parse_pool_config(
{
"pool_advanced": {
"unschedulable_rules": [
{"keyword": "rate_limit", "duration_minutes": 10},
{"keyword": "overloaded"},
{"invalid": "entry"}, # should be skipped
"not_a_dict", # should be skipped
]
}
}
)
assert cfg is not None
assert len(cfg.unschedulable_rules) == 2
assert cfg.unschedulable_rules[0] == UnschedulableRule(
keyword="rate_limit", duration_minutes=10
)
assert cfg.unschedulable_rules[1] == UnschedulableRule(keyword="overloaded", duration_minutes=5)
def test_parse_pool_config_handles_invalid_types_gracefully() -> None:
# Invalid int values should fall back to defaults
cfg = parse_pool_config(
{
"pool_advanced": {
"sticky_session_ttl_seconds": "not_a_number",
"cost_limit_per_key_tokens": "bad",
}
}
)
assert cfg is not None
assert cfg.sticky_session_ttl_seconds == 3600 # default
assert cfg.cost_limit_per_key_tokens is None # default for opt_int
def test_pool_config_is_frozen() -> None:
cfg = PoolConfig()
try:
cfg.sticky_session_ttl_seconds = 999 # type: ignore[misc]
assert False, "Should have raised FrozenInstanceError"
except AttributeError:
pass