Files
diodiogod-TTS-Audio-Suite/tests/unit/test_audio_cpp_resolver.py

333 lines
11 KiB
Python

from pathlib import Path
from types import SimpleNamespace
import sys
import pytest
REPO_ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(REPO_ROOT))
from utils.audio_cpp import resolver
from utils.audio_cpp.catalog import load_catalog
from utils.audio_cpp.discovery import package_install_path
from utils.audio_cpp.runtime_installer import runtime_install_path
from utils.audio_cpp.settings import AudioCppSettings
@pytest.mark.unit
def test_auto_reuses_machine_external_server_without_loading_owned_dependencies(monkeypatch):
monkeypatch.setattr(
resolver,
"load_settings",
lambda: AudioCppSettings(
connection_mode="external",
external_server_url="HTTP://127.0.0.1:18080/",
executable_path="C:/ignored/audiocpp_server.exe",
),
)
monkeypatch.setattr(
resolver,
"_catalog_module",
lambda: (_ for _ in ()).throw(AssertionError("external mode loaded the catalog")),
)
monkeypatch.setattr(
resolver,
"_downloader_module",
lambda: (_ for _ in ()).throw(AssertionError("external mode loaded a downloader")),
)
monkeypatch.setattr(
resolver,
"_runtime_installer_module",
lambda: (_ for _ in ()).throw(AssertionError("external mode loaded an installer")),
)
result = resolver.resolve_audio_cpp_config(
{
"config": {
"connection_mode": "auto",
"family": "qwen3_tts",
"package_id": "auto",
"task": "auto",
}
}
)
assert result["connection_mode"] == "external_server"
assert result["server_url"] == "http://127.0.0.1:18080"
assert result["binary_path"] == ""
assert result["model_path"] == ""
assert "model_id" not in result
assert result["task"] == "auto"
@pytest.mark.unit
def test_owned_explicit_paths_resolve_recommended_package_task_and_cuda(monkeypatch, tmp_path):
binary = tmp_path / "audiocpp_server.exe"
binary.write_bytes(b"exe")
model = tmp_path / "Qwen-VoiceDesign"
model.mkdir()
monkeypatch.setattr(resolver, "load_settings", lambda: AudioCppSettings())
monkeypatch.setattr(resolver, "_cuda_available", lambda: True)
result = resolver.resolve_audio_cpp_config(
{
"connection_mode": "managed",
"family": "qwen3_tts",
"package_id": "qwen3_tts_1_7b_voicedesign_q8_0",
"requested_task": "auto",
"backend": "auto",
"device": "cuda:2",
"binary_path": str(binary),
"model_path": str(model),
"model_id": "My Qwen model",
}
)
assert result["connection_mode"] == "owned_process"
assert result["package_id"] == "qwen3_tts_1_7b_voicedesign_q8_0"
assert result["task"] == "vdes"
assert result["backend"] == "cuda"
assert result["device_index"] == 2
assert result["binary_path"] == str(binary.resolve())
assert result["model_path"] == str(model.resolve())
assert result["model_id"] == "My-Qwen-model"
@pytest.mark.unit
def test_owned_reuses_external_model_root_and_configured_runtime_root(monkeypatch, tmp_path):
external_models = tmp_path / "existing-audio-cpp" / "models"
managed_models = tmp_path / "suite" / "audio.cpp" / "models"
configured_runtime = tmp_path / "existing-audio-cpp" / "runtime"
settings = AudioCppSettings(
connection_mode="managed",
model_roots=(str(external_models),),
managed_model_root=str(managed_models),
runtime_root=str(configured_runtime),
runtime_backend="cpu",
)
package = load_catalog().package("chatterbox_q8_0")
installed_model = package_install_path(package, external_models)
installed_model.mkdir(parents=True)
(installed_model / package.local_files[0]).write_bytes(b"gguf")
installed_binary = runtime_install_path(configured_runtime, "cpu") / "audiocpp_server.exe"
installed_binary.parent.mkdir(parents=True)
installed_binary.write_bytes(b"exe")
monkeypatch.setattr(resolver, "load_settings", lambda: settings)
result = resolver.resolve_audio_cpp_config(
{
"connection_mode": "auto",
"family": "chatterbox",
"package_id": "auto",
"task": "auto",
"backend": "auto",
"auto_download_model": False,
"auto_download_runtime": False,
}
)
assert result["package_id"] == "chatterbox_q8_0"
assert result["task"] == "clon"
assert result["backend"] == "cpu"
assert result["model_path"] == str(installed_model.resolve())
assert result["binary_path"] == str(installed_binary.resolve())
assert not managed_models.exists()
@pytest.mark.unit
def test_missing_assets_download_only_to_managed_roots(monkeypatch, tmp_path):
external_models = tmp_path / "external" / "models"
managed_models = tmp_path / "managed" / "audio.cpp" / "models"
settings = AudioCppSettings(
connection_mode="managed",
model_roots=(str(external_models),),
managed_model_root=str(managed_models),
runtime_backend="cpu",
)
calls = {}
real_downloader = resolver._downloader_module()
real_runtime = resolver._runtime_installer_module()
def install_package(package, root, catalog, progress=None):
calls["model_root"] = Path(root)
calls["model_progress"] = progress
target = package_install_path(package, root)
target.mkdir(parents=True)
(target / package.local_files[0]).write_bytes(b"gguf")
return SimpleNamespace(path=target, bytes_downloaded=4)
def install_runtime(root, backend, progress=None):
calls["runtime_root"] = Path(root)
calls["backend"] = backend
calls["runtime_progress"] = progress
executable = runtime_install_path(root, backend) / "audiocpp_server.exe"
executable.parent.mkdir(parents=True)
executable.write_bytes(b"exe")
return SimpleNamespace(executable=executable)
monkeypatch.setattr(resolver, "load_settings", lambda: settings)
monkeypatch.setattr(
resolver,
"_downloader_module",
lambda: SimpleNamespace(install_package=install_package),
)
monkeypatch.setattr(
resolver,
"_runtime_installer_module",
lambda: SimpleNamespace(
runtime_install_path=real_runtime.runtime_install_path,
get_runtime_manifest=real_runtime.get_runtime_manifest,
install_windows_runtime=install_runtime,
),
)
result = resolver.resolve_audio_cpp_config(
{
"connection_mode": "managed",
"family": "chatterbox",
"package_id": "chatterbox_q8_0",
"backend": "cpu",
"auto_download_model": True,
"auto_download_runtime": True,
}
)
assert calls["model_root"] == managed_models
assert calls["runtime_root"] == managed_models.parent / "runtime"
assert calls["backend"] == "cpu"
assert callable(calls["model_progress"])
assert callable(calls["runtime_progress"])
assert not external_models.exists()
assert result["model_path"].startswith(str(managed_models.resolve()))
assert result["binary_path"].startswith(str((managed_models.parent / "runtime").resolve()))
@pytest.mark.unit
def test_missing_model_without_permission_has_actionable_error(monkeypatch, tmp_path):
managed_models = tmp_path / "managed" / "models"
binary = tmp_path / "audiocpp_server.exe"
binary.write_bytes(b"exe")
monkeypatch.setattr(
resolver,
"load_settings",
lambda: AudioCppSettings(managed_model_root=str(managed_models)),
)
with pytest.raises(resolver.AudioCppResolutionError, match="enable auto_download_model"):
resolver.resolve_audio_cpp_config(
{
"connection_mode": "managed",
"family": "chatterbox",
"package_id": "chatterbox_q8_0",
"backend": "cpu",
"binary_path": str(binary),
"auto_download_model": False,
}
)
@pytest.mark.unit
def test_miotts_installs_codec_dependency_and_sets_absolute_session_path(monkeypatch, tmp_path):
managed_models = tmp_path / "managed" / "models"
catalog = resolver._catalog_module().load_catalog()
miotts = catalog.package("miotts_1_7b_q8_0")
miotts_dir = package_install_path(miotts, managed_models)
for relative in miotts.local_files:
target = miotts_dir / relative
target.parent.mkdir(parents=True, exist_ok=True)
target.write_bytes(b"miotts")
binary = tmp_path / "audiocpp_server.exe"
binary.write_bytes(b"exe")
installed = {}
def install_package(package, root, **_kwargs):
target = package_install_path(package, root)
for relative in package.local_files:
path = target / relative
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(b"codec")
installed[package.id] = target
return SimpleNamespace(path=target, bytes_downloaded=5)
monkeypatch.setattr(
resolver,
"load_settings",
lambda: AudioCppSettings(managed_model_root=str(managed_models)),
)
monkeypatch.setattr(
resolver,
"_downloader_module",
lambda: SimpleNamespace(install_package=install_package),
)
result = resolver.resolve_audio_cpp_config(
{
"connection_mode": "managed",
"family": "miotts",
"package_id": "miotts_1_7b_q8_0",
"backend": "cpu",
"binary_path": str(binary),
"auto_download_model": True,
}
)
assert "miocodec_q8_0" in installed
assert result["session_options"]["miotts.codec_model_path"] == str(
installed["miocodec_q8_0"].resolve()
)
@pytest.mark.unit
def test_owned_existing_binary_allows_explicit_hip_backend(monkeypatch, tmp_path):
binary = tmp_path / "audiocpp_server.exe"
binary.write_bytes(b"exe")
model = tmp_path / "model"
model.mkdir()
monkeypatch.setattr(resolver, "load_settings", lambda: AudioCppSettings())
result = resolver.resolve_audio_cpp_config(
{
"connection_mode": "existing_binary",
"family": "chatterbox",
"package_id": "chatterbox_q8_0",
"backend": "hip",
"binary_path": str(binary),
"model_path": str(model),
}
)
assert result["backend"] == "hip"
assert result["binary_path"] == str(binary.resolve())
@pytest.mark.unit
def test_cpu_backend_reuses_installed_cuda_profile_before_downloading_duplicate(
monkeypatch, tmp_path
):
model = tmp_path / "model"
model.mkdir()
runtime_root = tmp_path / "runtime"
cuda_binary = runtime_install_path(runtime_root, "cuda") / "audiocpp_server.exe"
cuda_binary.parent.mkdir(parents=True)
cuda_binary.write_bytes(b"cuda-exe")
monkeypatch.setattr(
resolver,
"load_settings",
lambda: AudioCppSettings(runtime_root=str(runtime_root), runtime_backend="cpu"),
)
result = resolver.resolve_audio_cpp_config(
{
"connection_mode": "managed",
"family": "chatterbox",
"package_id": "chatterbox_q8_0",
"model_path": str(model),
"backend": "auto",
"auto_download_runtime": False,
}
)
assert result["backend"] == "cpu"
assert result["binary_path"] == str(cuda_binary.resolve())