fix: 加固续租失败处理、verify_auth 异常捕获及调度器注册追踪

- task_coordinator: 续租连续失败 5 次后主动触发 lock_lost 回调,失败间加指数退避
- proxy_nodes: lock_lost 回调由 lambda 改为具名 async 函数,确保异步停止逻辑正确执行
- provider_ops: 将 prepare_verify_config 纳入外层 try,捕获 ValueError 并返回失败响应
- maintenance_scheduler: 用 _registered_job_ids 动态追踪已注册任务,stop 时按列表清理
- stats_aggregator: 内联 _do_aggregate 为 for/range(2) 循环,消除内嵌函数
This commit is contained in:
fawney19
2026-03-20 01:22:07 +08:00
parent 913ce2dbcb
commit aa83b4a7a7
7 changed files with 223 additions and 127 deletions

View File

@@ -0,0 +1,74 @@
from __future__ import annotations
from typing import Any
import pytest
from src.services.provider_ops.service import ProviderOpsService
from src.services.provider_ops.types import ConnectorAuthType
class _FakeDB:
new: tuple[Any, ...] = ()
dirty: tuple[Any, ...] = ()
deleted: tuple[Any, ...] = ()
def in_transaction(self) -> bool:
return False
def commit(self) -> None:
pass
def rollback(self) -> None:
pass
class _FailingArchitecture:
def get_verify_endpoint(self) -> str:
return "/verify"
async def prepare_verify_config(
self,
_base_url: str,
_config: dict[str, Any],
_credentials: dict[str, Any],
) -> dict[str, Any]:
raise ValueError("invalid refresh token")
def build_verify_headers(
self,
_config: dict[str, Any],
_credentials: dict[str, Any],
) -> dict[str, str]:
raise AssertionError("build_verify_headers should not be reached")
class _FakeRegistry:
def __init__(self, architecture: Any) -> None:
self._architecture = architecture
def get_or_default(self, _architecture_id: str) -> Any:
return self._architecture
@pytest.mark.asyncio
async def test_verify_auth_returns_failure_when_prepare_verify_config_raises_value_error(
monkeypatch: pytest.MonkeyPatch,
) -> None:
service = ProviderOpsService(_FakeDB())
architecture = _FailingArchitecture()
monkeypatch.setattr(
"src.services.provider_ops.service.get_registry",
lambda: _FakeRegistry(architecture),
)
result = await service.verify_auth(
base_url="https://example.com",
architecture_id="sub2api",
auth_type=ConnectorAuthType.SESSION_LOGIN,
config={},
credentials={"refresh_token": "stale-token"},
)
assert result == {"success": False, "message": "invalid refresh token"}