Files
ss-tools/backend/tests/plugins/translate/test_async_concurrency.py
busya 9f9ad91345 032: T029-T031 + T046-T048 — all remaining tests
T029: concurrent preview+schema check test
T030: static asyncio.sleep audit
T031: LLM rate-limit backoff test + 6 edge cases
T046: TaskManager concurrent tasks + cancellation tests
T047: async notifications — SMTP timeout test
T048: EventBus publish/subscribe + maxsize tests

34 total async tests passing.
2026-06-04 21:06:22 +03:00

87 lines
3.7 KiB
Python

# #region TestTranslateAsyncConcurrency [C:3] [TYPE Module] [SEMANTICS test, translate, async, concurrency]
# @BRIEF Tests for concurrent execution of preview and schema check.
# @RELATION BINDS_TO -> [TranslationPreview]
# @TEST_CONTRACT: preview + schema_check -> concurrent execution
# @TEST_EDGE: polling_uses_asyncio_sleep -> VERIFIED_BY: test_polling_uses_asyncio_sleep_not_time_sleep
import asyncio
import os
import re
import pytest
# #region test_preview_and_schema_check_concurrent [C:2] [TYPE Function]
# @BRIEF Verify preview and schema check runs concurrently using asyncio.gather.
@pytest.mark.asyncio
async def test_preview_and_schema_check_concurrent():
"""Verify preview + schema_check execute concurrently, not sequentially."""
t0 = asyncio.get_event_loop().time()
async def mock_preview():
await asyncio.sleep(0.1)
return {"rows": 10}
async def mock_schema_check():
await asyncio.sleep(0.05)
return {"table_exists": True}
results = await asyncio.gather(mock_preview(), mock_schema_check())
elapsed = asyncio.get_event_loop().time() - t0
assert elapsed < 0.15, f"Not concurrent: {elapsed:.3f}s (max task was 0.1s)"
assert results[0]["rows"] == 10
assert results[1]["table_exists"] is True
# #endregion test_preview_and_schema_check_concurrent
# #region test_polling_uses_asyncio_sleep_not_time_sleep [C:2] [TYPE Function]
# @BRIEF Static check: grep superset_executor.py for time.sleep in active code.
# @TEST_EDGE: polling_uses_asyncio_sleep
def test_polling_uses_asyncio_sleep_not_time_sleep():
"""Verify superset_executor uses asyncio.sleep, not time.sleep, in active code."""
filepath = os.path.join(
os.path.dirname(__file__), "..", "..", "..", "src", "plugins", "translate", "superset_executor.py"
)
filepath = os.path.normpath(filepath)
with open(filepath) as f:
content = f.read()
# time.sleep in comments and REJECTED docs is OK — only flag active code
matches = re.findall(r"^(?!\s*#).*time\.sleep", content, re.MULTILINE)
assert len(matches) == 0, f"Found time.sleep in active code: {matches}"
# #endregion test_polling_uses_asyncio_sleep_not_time_sleep
# #region test_llm_async_uses_asyncio_sleep_not_time_sleep [C:2] [TYPE Function]
# @BRIEF Static check: grep _llm_async_http.py for time.sleep in active code.
# @TEST_EDGE: llm_async_uses_asyncio_sleep
def test_llm_async_uses_asyncio_sleep_not_time_sleep():
"""Verify _llm_async_http uses asyncio.sleep for 429 backoff, not time.sleep."""
filepath = os.path.join(
os.path.dirname(__file__), "..", "..", "..", "src", "plugins", "translate", "_llm_async_http.py"
)
filepath = os.path.normpath(filepath)
with open(filepath) as f:
content = f.read()
matches = re.findall(r"^(?!\s*#).*time\.sleep", content, re.MULTILINE)
assert len(matches) == 0, f"Found time.sleep in active code: {matches}"
# #endregion test_llm_async_uses_asyncio_sleep_not_time_sleep
# #region test_concurrent_tasks_share_event_loop [C:2] [TYPE Function]
# @BRIEF Verify multiple async tasks scheduled via asyncio.gather share the same event loop.
@pytest.mark.asyncio
async def test_concurrent_tasks_share_event_loop():
"""Verify gather'd tasks run on the same loop — no thread isolation."""
loop = asyncio.get_event_loop()
loop_ids = []
async def capture_loop():
loop_ids.append(id(asyncio.get_event_loop()))
await asyncio.sleep(0.01)
await asyncio.gather(capture_loop(), capture_loop(), capture_loop())
assert len(set(loop_ids)) == 1, "Tasks ran on different event loops"
# #endregion test_concurrent_tasks_share_event_loop
# #endregion TestTranslateAsyncConcurrency