mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 09:20:22 +08:00
feat: 扩展 Rust gateway 全功能模块,新增 billing/crypto/wallet crate 及完整数据层
- 新增 aether-billing、aether-crypto、aether-wallet 独立 crate - aether-data 扩展 repository 层:announcements、auth_modules、billing、 candidate_selection、gemini_file_mappings、global_models、management_tokens、 oauth_providers、proxy_nodes、quota、users、wallet 等模块 - aether-gateway 新增 api/auth/billing/control/middleware/scheduler/usage/ video_tasks/hooks/maintenance/model_fetch/provider_transport 等功能模块 - 重构 executor decision 和 gateway state 为模块目录结构 - 新增 gateway router、frontdoor 路由层及对应测试 - Python 侧 API 路由重构,新增 compat/support 模块 - 前端 Logo 组件更新及 Provider 管理页面调整
This commit is contained in:
@@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
import src.services.task.video.cancel as cancel_mod
|
||||
@@ -171,3 +172,122 @@ async def test_video_cancel_service_uses_rust_for_gemini_cancel(
|
||||
plan = execute_sync.await_args.args[0]
|
||||
assert plan.method == "POST"
|
||||
assert plan.body.json_body == {}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_video_cancel_service_returns_503_when_rust_backend_disabled(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
endpoint = SimpleNamespace(
|
||||
id="ep-1",
|
||||
provider_id="prov-1",
|
||||
api_family="openai",
|
||||
endpoint_kind="video",
|
||||
base_url="https://api.openai.com",
|
||||
)
|
||||
key = SimpleNamespace(id="key-1", api_key="encrypted")
|
||||
db = _FakeDB(endpoint, key)
|
||||
service = VideoTaskCancelService(db)
|
||||
task = SimpleNamespace(
|
||||
id="task-1",
|
||||
status=VideoStatus.PROCESSING.value,
|
||||
external_task_id="ext-1",
|
||||
endpoint_id="ep-1",
|
||||
key_id="key-1",
|
||||
request_id="req-1",
|
||||
model="sora-2",
|
||||
completed_at=None,
|
||||
updated_at=None,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(cancel_mod.config, "executor_backend", "python")
|
||||
monkeypatch.setattr(
|
||||
"src.core.crypto.crypto_service.decrypt",
|
||||
lambda value: "upstream-key",
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"src.core.api_format.build_upstream_headers_for_endpoint",
|
||||
lambda *args, **kwargs: {"authorization": "Bearer upstream-key"},
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"src.services.provider.transport.build_provider_url",
|
||||
lambda endpoint, is_stream=False, key=None: "https://api.openai.com/v1/videos",
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"src.clients.http_client.HTTPClientPool.get_default_client_async",
|
||||
AsyncMock(side_effect=AssertionError("python fallback should not run")),
|
||||
)
|
||||
|
||||
response = await service.cancel_task(
|
||||
task=task,
|
||||
task_id="task-1",
|
||||
original_headers={"x-test": "1"},
|
||||
)
|
||||
|
||||
assert isinstance(response, httpx.Response)
|
||||
assert response.status_code == 503
|
||||
assert response.json() == {"error": {"message": "Video 取消仅支持 Rust executor"}}
|
||||
assert db.committed is False
|
||||
assert task.status == VideoStatus.PROCESSING.value
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_video_cancel_service_returns_503_when_rust_executor_unavailable(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
endpoint = SimpleNamespace(
|
||||
id="ep-1",
|
||||
provider_id="prov-1",
|
||||
api_family="gemini",
|
||||
endpoint_kind="video",
|
||||
base_url="https://generativelanguage.googleapis.com",
|
||||
)
|
||||
key = SimpleNamespace(id="key-1", api_key="encrypted")
|
||||
db = _FakeDB(endpoint, key)
|
||||
service = VideoTaskCancelService(db)
|
||||
task = SimpleNamespace(
|
||||
id="task-1",
|
||||
status=VideoStatus.PROCESSING.value,
|
||||
external_task_id="operations/ext-1",
|
||||
endpoint_id="ep-1",
|
||||
key_id="key-1",
|
||||
request_id="req-1",
|
||||
model="veo-3",
|
||||
completed_at=None,
|
||||
updated_at=None,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(cancel_mod.config, "executor_backend", "rust")
|
||||
monkeypatch.setattr(
|
||||
rust_client_mod.RustExecutorClient,
|
||||
"execute_sync_json",
|
||||
AsyncMock(side_effect=rust_client_mod.RustExecutorClientError("executor down")),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"src.core.crypto.crypto_service.decrypt",
|
||||
lambda value: "upstream-key",
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"src.core.api_format.build_upstream_headers_for_endpoint",
|
||||
lambda *args, **kwargs: {"x-goog-api-key": "upstream-key"},
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"src.services.provider.auth.get_provider_auth",
|
||||
AsyncMock(return_value=None),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"src.clients.http_client.HTTPClientPool.get_default_client_async",
|
||||
AsyncMock(side_effect=AssertionError("python fallback should not run")),
|
||||
)
|
||||
|
||||
response = await service.cancel_task(
|
||||
task=task,
|
||||
task_id="task-1",
|
||||
original_headers={"x-test": "1"},
|
||||
)
|
||||
|
||||
assert isinstance(response, httpx.Response)
|
||||
assert response.status_code == 503
|
||||
assert response.json() == {"error": {"message": "执行器暂时不可用,请稍后重试"}}
|
||||
assert db.committed is False
|
||||
assert task.status == VideoStatus.PROCESSING.value
|
||||
|
||||
Reference in New Issue
Block a user