mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-01 17:00:21 +08:00
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:
74
tests/services/test_provider_ops_service_verify_auth.py
Normal file
74
tests/services/test_provider_ops_service_verify_auth.py
Normal 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"}
|
||||
@@ -56,19 +56,8 @@ async def test_maintenance_scheduler_stop_cancels_startup_task_and_removes_jobs(
|
||||
scheduler = MaintenanceScheduler()
|
||||
scheduler.running = True
|
||||
scheduler._startup_task = asyncio.create_task(asyncio.sleep(3600))
|
||||
removed_jobs: list[str] = []
|
||||
|
||||
monkeypatch.setattr(
|
||||
maintenance_scheduler_module,
|
||||
"get_scheduler",
|
||||
lambda: SimpleNamespace(remove_job=lambda job_id: removed_jobs.append(job_id)),
|
||||
)
|
||||
|
||||
await scheduler.stop()
|
||||
|
||||
assert scheduler.running is False
|
||||
assert scheduler._startup_task is None
|
||||
assert set(removed_jobs) == {
|
||||
expected_job_ids = [
|
||||
"stats_aggregation",
|
||||
"stats_hourly_aggregation",
|
||||
"wallet_daily_usage_aggregation",
|
||||
@@ -82,7 +71,22 @@ async def test_maintenance_scheduler_stop_cancels_startup_task_and_removes_jobs(
|
||||
"db_maintenance",
|
||||
"antigravity_ua_refresh",
|
||||
scheduler.CHECKIN_JOB_ID,
|
||||
}
|
||||
]
|
||||
scheduler._registered_job_ids = list(expected_job_ids)
|
||||
removed_jobs: list[str] = []
|
||||
|
||||
monkeypatch.setattr(
|
||||
maintenance_scheduler_module,
|
||||
"get_scheduler",
|
||||
lambda: SimpleNamespace(remove_job=lambda job_id: removed_jobs.append(job_id)),
|
||||
)
|
||||
|
||||
await scheduler.stop()
|
||||
|
||||
assert scheduler.running is False
|
||||
assert scheduler._startup_task is None
|
||||
assert set(removed_jobs) == set(expected_job_ids)
|
||||
assert scheduler._registered_job_ids == []
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
Reference in New Issue
Block a user