增加sqlalchemy后端,优化日志结构

This commit is contained in:
strepsiades
2026-04-07 20:22:25 +08:00
parent c377264610
commit ba73b30a04
23 changed files with 1586 additions and 308 deletions
+93
View File
@@ -10,6 +10,8 @@ import pytest
import httpx
from sync_state_machine.datasource.api.client import ApiClient
from sync_state_machine.datasource.api.datasource import ApiDataSource
from sync_state_machine.logging import clear_scope_display_names, set_scope_display_name
class _FakeResponse:
@@ -50,6 +52,25 @@ class _FailingAsyncClient:
self.closed = True
class _FakeCollection:
def __init__(self, scope: str) -> None:
self.scope = scope
def set_state_machine_runtime(self, runtime) -> None:
del runtime
class _FakeProjectNode:
node_type = "project"
def __init__(self, data_id: str, name: str) -> None:
self.data_id = data_id
self._data = {"name": name}
def get_data(self) -> dict:
return dict(self._data)
@pytest.mark.asyncio
async def test_api_client_global_rate_limit_applies_to_concurrent_requests() -> None:
client = ApiClient(
@@ -120,6 +141,78 @@ async def test_api_client_logs_one_line_request_summary_in_debug_mode(caplog: py
assert "🔎 ApiClient request: method=GET endpoint=/ping elapsed=" in caplog.text
@pytest.mark.asyncio
async def test_api_client_request_summary_includes_session_label_with_scope_fallback(
caplog: pytest.LogCaptureFixture,
) -> None:
clear_scope_display_names()
client = ApiClient(
base_url="http://example.com",
uid="uid",
secret="secret",
debug=True,
)
logger_name = "sync_state_machine.datasource.api.client"
fake_client = _FakeAsyncClient()
client._client = fake_client
client.set_scope("project_id:project-1")
with caplog.at_level(logging.INFO, logger=logger_name):
await client.request("GET", "/ping")
assert "session=project_id:project-1 method=GET endpoint=/ping" in caplog.text
caplog.clear()
client.set_session_label("project:Alpha")
with caplog.at_level(logging.INFO, logger=logger_name):
await client.request("GET", "/ping")
assert "session=project:Alpha method=GET endpoint=/ping" in caplog.text
clear_scope_display_names()
@pytest.mark.asyncio
async def test_api_client_request_summary_uses_registered_project_name_for_project_id_requests(
caplog: pytest.LogCaptureFixture,
) -> None:
clear_scope_display_names()
set_scope_display_name("project_id:project-1", "project:Alpha")
client = ApiClient(
base_url="http://example.com",
uid="uid",
secret="secret",
debug=True,
)
logger_name = "sync_state_machine.datasource.api.client"
fake_client = _FakeAsyncClient()
client._client = fake_client
client.set_scope("global")
with caplog.at_level(logging.INFO, logger=logger_name):
await client.request("GET", "/supplier/list", params={"project_id": "project-1"})
clear_scope_display_names()
assert "session=project:Alpha method=GET endpoint=/supplier/list" in caplog.text
def test_api_datasource_updates_client_session_label_from_project_node() -> None:
clear_scope_display_names()
datasource = ApiDataSource(
base_url="http://example.com",
uid="uid",
secret="secret",
debug=True,
)
datasource.set_collection(_FakeCollection("project_id:project-1"))
assert datasource.client.get_log_session_label() == "project_id:project-1"
datasource._on_node_loaded(None, _FakeProjectNode(data_id="project-1", name="Alpha"))
assert datasource.client.get_log_session_label() == "project:Alpha"
clear_scope_display_names()
@pytest.mark.asyncio
async def test_api_client_get_signature_keeps_list_params_in_signature_source() -> None:
client = ApiClient(