69 lines
2.7 KiB
Python
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)
|