Files
banban/talkingq-url/tests/test_warmup_cleanup.py

69 lines
2.7 KiB
Python

"""Verify real aiohttp sessions close on interruption and warmup races."""
import asyncio
import uuid
from unittest.mock import AsyncMock
import pytest
from implementations.minimax_tts import MiniMaxTTS
from implementations.volcano_llm import VolcanoLLM
from services.audio_session import AudioSession
from services.interrupt_handler import interrupt_handler
from services.conversation_history import conversation_history_manager
from handlers.service_connection_handler import prepare_llm_service, prepare_tts_service
@pytest.mark.asyncio
@pytest.mark.parametrize('kind', ['llm', 'tts'])
@pytest.mark.parametrize('phase', ['ready', 'connecting', 'cancelled', 'already_interrupted'])
async def test_warmup_releases_provider_client(monkeypatch, kind, phase):
key = ('warmup-test', uuid.uuid4().hex)
service = VolcanoLLM() if kind == 'llm' else MiniMaxTTS()
session = AudioSession(llm_service=service if kind == 'llm' else None,
tts_service=service if kind == 'tts' else None)
session.device_id, session.session_id = key
monkeypatch.setattr(conversation_history_manager, 'get_history', AsyncMock(return_value=None))
prepare = prepare_llm_service if kind == 'llm' else prepare_tts_service
original_connect = service.connect
entered, resume = asyncio.Event(), asyncio.Event()
async def delayed_connect():
if phase == 'cancelled':
await original_connect()
entered.set()
await resume.wait()
if phase != 'cancelled':
await original_connect()
task = None
try:
if phase == 'already_interrupted':
await interrupt_handler.set_interrupt_state(key, True)
if phase in ('connecting', 'cancelled'):
monkeypatch.setattr(service, 'connect', delayed_connect)
task = asyncio.create_task(prepare(session, *key, {}))
if phase in ('connecting', 'cancelled'):
await entered.wait()
if phase == 'cancelled':
task.cancel()
with pytest.raises(asyncio.CancelledError):
await task
else:
await interrupt_handler.handle_interrupt(key)
resume.set()
await task
else:
await task
if phase == 'ready':
assert service.connected
await interrupt_handler.handle_interrupt(key)
client = service.session if kind == 'llm' else service._client_session
assert client is None or client.closed
assert not service.connected
finally:
if task and not task.done():
task.cancel()
await asyncio.gather(task, return_exceptions=True)
await service.close()
await interrupt_handler.remove_session(key)