2025-01-01 17:38:22 -07:00
|
|
|
import os
|
2025-01-01 21:50:41 -07:00
|
|
|
import shutil
|
2025-01-13 20:15:46 -07:00
|
|
|
import sys
|
|
|
|
from unittest.mock import MagicMock, Mock, patch
|
2024-12-31 02:55:51 -07:00
|
|
|
|
2025-01-13 20:15:46 -07:00
|
|
|
import aiofiles.threadpool
|
2025-01-09 18:41:44 -07:00
|
|
|
import numpy as np
|
2024-12-31 02:55:51 -07:00
|
|
|
import pytest
|
2024-12-30 13:25:30 -07:00
|
|
|
|
2025-01-01 21:50:41 -07:00
|
|
|
|
2025-01-01 17:38:22 -07:00
|
|
|
def cleanup_mock_dirs():
|
|
|
|
"""Clean up any MagicMock directories created during tests"""
|
|
|
|
mock_dir = "MagicMock"
|
|
|
|
if os.path.exists(mock_dir):
|
|
|
|
shutil.rmtree(mock_dir)
|
|
|
|
|
2025-01-01 21:50:41 -07:00
|
|
|
|
2025-01-07 04:30:02 -07:00
|
|
|
@pytest.fixture(autouse=True)
|
|
|
|
def setup_aiofiles():
|
|
|
|
"""Setup aiofiles mock wrapper"""
|
|
|
|
aiofiles.threadpool.wrap.register(MagicMock)(
|
|
|
|
lambda *args, **kwargs: aiofiles.threadpool.AsyncBufferedIOBase(*args, **kwargs)
|
|
|
|
)
|
|
|
|
yield
|
|
|
|
|
|
|
|
|
2025-01-01 17:38:22 -07:00
|
|
|
@pytest.fixture(autouse=True)
|
|
|
|
def cleanup():
|
|
|
|
"""Automatically clean up before and after each test"""
|
|
|
|
cleanup_mock_dirs()
|
|
|
|
yield
|
|
|
|
cleanup_mock_dirs()
|
|
|
|
|
2025-01-01 21:50:41 -07:00
|
|
|
|
2025-01-03 17:54:17 -07:00
|
|
|
# Mock modules before they're imported
|
2024-12-31 01:57:00 -07:00
|
|
|
sys.modules["transformers"] = Mock()
|
|
|
|
sys.modules["phonemizer"] = Mock()
|
|
|
|
sys.modules["models"] = Mock()
|
|
|
|
sys.modules["models.build_model"] = Mock()
|
|
|
|
sys.modules["kokoro"] = Mock()
|
|
|
|
sys.modules["kokoro.generate"] = Mock()
|
|
|
|
sys.modules["kokoro.phonemize"] = Mock()
|
|
|
|
sys.modules["kokoro.tokenize"] = Mock()
|
2024-12-30 13:25:30 -07:00
|
|
|
|
2025-01-09 07:20:14 -07:00
|
|
|
# Mock ONNX runtime
|
|
|
|
mock_onnx = Mock()
|
|
|
|
mock_onnx.InferenceSession = Mock()
|
|
|
|
mock_onnx.SessionOptions = Mock()
|
|
|
|
mock_onnx.GraphOptimizationLevel = Mock()
|
|
|
|
mock_onnx.ExecutionMode = Mock()
|
|
|
|
sys.modules["onnxruntime"] = mock_onnx
|
2024-12-30 13:25:30 -07:00
|
|
|
|
2025-01-09 07:20:14 -07:00
|
|
|
# Create mock settings module
|
|
|
|
mock_settings_module = Mock()
|
|
|
|
mock_settings = Mock()
|
|
|
|
mock_settings.model_dir = "/mock/model/dir"
|
|
|
|
mock_settings.onnx_model_path = "mock.onnx"
|
|
|
|
mock_settings_module.settings = mock_settings
|
|
|
|
sys.modules["api.src.core.config"] = mock_settings_module
|
|
|
|
|
|
|
|
|
|
|
|
class MockTTSModel:
|
|
|
|
_instance = None
|
|
|
|
_onnx_session = None
|
|
|
|
VOICES_DIR = "/mock/voices/dir"
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
self._initialized = False
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def get_instance(cls):
|
|
|
|
if cls._instance is None:
|
|
|
|
cls._instance = cls()
|
|
|
|
return cls._instance
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def initialize(cls, model_dir):
|
|
|
|
cls._onnx_session = Mock()
|
|
|
|
cls._onnx_session.run = Mock(return_value=[np.zeros(48000)])
|
|
|
|
cls._instance._initialized = True
|
|
|
|
return cls._onnx_session
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def setup(cls):
|
|
|
|
if not cls._instance._initialized:
|
|
|
|
cls.initialize("/mock/model/dir")
|
|
|
|
return cls._instance
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def generate_from_tokens(cls, tokens, voicepack, speed):
|
|
|
|
if not cls._instance._initialized:
|
|
|
|
raise RuntimeError("Model not initialized. Call setup() first.")
|
|
|
|
return np.zeros(48000)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def process_text(cls, text, language):
|
|
|
|
return "mock phonemes", [1, 2, 3]
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_device():
|
|
|
|
return "cpu"
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def mock_tts_service(monkeypatch):
|
|
|
|
"""Mock TTSService for testing"""
|
|
|
|
mock_service = Mock()
|
|
|
|
mock_service._get_voice_path.return_value = "/mock/path/voice.pt"
|
|
|
|
mock_service._load_voice.return_value = np.zeros((1, 192))
|
2025-01-09 18:41:44 -07:00
|
|
|
|
2025-01-09 07:20:14 -07:00
|
|
|
# Mock TTSModel.generate_from_tokens since we call it directly
|
|
|
|
mock_generate = Mock(return_value=np.zeros(48000))
|
2025-01-09 18:41:44 -07:00
|
|
|
monkeypatch.setattr(
|
2025-01-10 22:03:16 -07:00
|
|
|
"api.src.routers.development.TTSModel.generate_from_tokens", mock_generate
|
2025-01-09 18:41:44 -07:00
|
|
|
)
|
|
|
|
|
2025-01-09 07:20:14 -07:00
|
|
|
return mock_service
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def mock_audio_service(monkeypatch):
|
|
|
|
"""Mock AudioService"""
|
|
|
|
mock_service = Mock()
|
|
|
|
mock_service.convert_audio.return_value = b"mock audio data"
|
2025-01-10 22:03:16 -07:00
|
|
|
monkeypatch.setattr("api.src.routers.development.AudioService", mock_service)
|
2025-01-09 07:20:14 -07:00
|
|
|
return mock_service
|