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())