aboutsummaryrefslogtreecommitdiff
path: root/app/tests
diff options
context:
space:
mode:
Diffstat (limited to 'app/tests')
-rw-r--r--app/tests/test_backends.py10
-rw-r--r--app/tests/test_backends_audiocpp.py497
-rw-r--r--app/tests/test_backends_faster.py3
-rw-r--r--app/tests/test_hub.py9
4 files changed, 262 insertions, 257 deletions
diff --git a/app/tests/test_backends.py b/app/tests/test_backends.py
index 47dc5d4..4ff6f6e 100644
--- a/app/tests/test_backends.py
+++ b/app/tests/test_backends.py
@@ -71,7 +71,7 @@ class DetectAllTests(unittest.TestCase):
(checkout / "server.json").write_text('{"models":[]}',
encoding="utf-8")
from backends import audiocpp
- with patch.object(audiocpp, "find_local_checkout",
+ with patch.object(audiocpp.build, "find_local_checkout",
return_value=checkout), \
patch("backends.common.server_running",
return_value=False):
@@ -84,9 +84,9 @@ class DetectAllTests(unittest.TestCase):
def test_audiocpp_running_when_remote_server_identified(self):
from backends import audiocpp
- with patch.object(audiocpp, "find_local_checkout",
+ with patch.object(audiocpp.build, "find_local_checkout",
return_value=None), \
- patch.object(audiocpp.probe, "identify_server",
+ patch.object(audiocpp.status.probe, "identify_server",
return_value="audiocpp"):
status = audiocpp.detect()
# Not installed (no checkout) but a remote server answers.
@@ -280,12 +280,12 @@ class RemoteSuppressionTests(unittest.TestCase):
encoding="utf-8")
(Path(td) / "audiocpp-server.pid").write_text(
"4242", encoding="utf-8")
- with patch.object(audiocpp, "find_local_checkout",
+ with patch.object(audiocpp.build, "find_local_checkout",
return_value=checkout), \
patch.object(servers_mod, "LOG_DIR", Path(td)), \
patch.object(servers_mod, "_pid_alive",
return_value=True), \
- patch.object(audiocpp.probe, "identify_server",
+ patch.object(audiocpp.status.probe, "identify_server",
return_value="audiocpp"):
status = audiocpp.detect()
self.assertTrue(status.managed)
diff --git a/app/tests/test_backends_audiocpp.py b/app/tests/test_backends_audiocpp.py
index 05b47bd..59bd039 100644
--- a/app/tests/test_backends_audiocpp.py
+++ b/app/tests/test_backends_audiocpp.py
@@ -13,7 +13,10 @@ from unittest.mock import MagicMock, patch
from converter import config
from backends import audiocpp as make_server
-from backends import common
+import os
+
+from backends import common, servers
+from ui import taskview
from ui import tui
FAKE_CONFIG = (
@@ -132,17 +135,17 @@ class FindWavFilesTests(unittest.TestCase):
self._touch("notes.txt")
(self.folder / "sub").mkdir()
(self.folder / "sub" / "c.wav").write_bytes(b"x")
- names = [path.name for path in make_server.find_wav_files(self.folder)]
+ names = [path.name for path in common.find_wav_files(self.folder)]
self.assertEqual(names, ["a.WAV", "b.wav"])
def test_sorted_alphabetically_case_insensitive(self):
for name in ("Zed.wav", "alpha.wav", "Beta.wav"):
self._touch(name)
- names = [path.name for path in make_server.find_wav_files(self.folder)]
+ names = [path.name for path in common.find_wav_files(self.folder)]
self.assertEqual(names, ["alpha.wav", "Beta.wav", "Zed.wav"])
def test_empty_directory_returns_empty_list(self):
- self.assertEqual(make_server.find_wav_files(self.folder), [])
+ self.assertEqual(common.find_wav_files(self.folder), [])
class DetectWavDirTests(unittest.TestCase):
@@ -167,42 +170,42 @@ class DetectWavDirTests(unittest.TestCase):
def test_unique_wav_dir_in_tts_root_returned(self):
found = self._wav_dir(self.tts_root, "voices")
- self.assertEqual(make_server.detect_wav_dir(self.audiocpp,
+ self.assertEqual(common.detect_wav_dir(self.audiocpp,
self.tts_root),
found)
def test_unique_wav_dir_in_audiocpp_root_returned(self):
found = self._wav_dir(self.audiocpp, "reference")
- self.assertEqual(make_server.detect_wav_dir(self.audiocpp,
+ self.assertEqual(common.detect_wav_dir(self.audiocpp,
self.tts_root),
found)
def test_root_itself_containing_wavs_returned(self):
(self.tts_root / "direct.wav").write_bytes(b"x")
- self.assertEqual(make_server.detect_wav_dir(self.audiocpp,
+ self.assertEqual(common.detect_wav_dir(self.audiocpp,
self.tts_root),
self.tts_root)
def test_multiple_wav_dirs_returns_none(self):
self._wav_dir(self.tts_root, "one")
self._wav_dir(self.audiocpp, "two")
- self.assertIsNone(make_server.detect_wav_dir(self.audiocpp,
+ self.assertIsNone(common.detect_wav_dir(self.audiocpp,
self.tts_root))
def test_output_dir_of_tts_root_excluded(self):
self._wav_dir(self.tts_root, "output")
- self.assertIsNone(make_server.detect_wav_dir(self.audiocpp,
+ self.assertIsNone(common.detect_wav_dir(self.audiocpp,
self.tts_root))
def test_no_wavs_returns_none(self):
- self.assertIsNone(make_server.detect_wav_dir(self.audiocpp,
+ self.assertIsNone(common.detect_wav_dir(self.audiocpp,
self.tts_root))
def test_nested_wav_dir_not_seen(self):
nested = self.tts_root / "outer" / "inner"
nested.mkdir(parents=True)
(nested / "voice.wav").write_bytes(b"x")
- self.assertIsNone(make_server.detect_wav_dir(self.audiocpp,
+ self.assertIsNone(common.detect_wav_dir(self.audiocpp,
self.tts_root))
@@ -210,27 +213,27 @@ class ConfigPortTests(unittest.TestCase):
def test_port_parsed_from_config_url(self):
with patch.object(config, "AUDIOCPP_API_URL",
"http://127.0.0.1:8080"):
- self.assertEqual(make_server.config_port(), 8080)
+ self.assertEqual(make_server.configsync.config_port(), 8080)
def test_missing_port_falls_back(self):
with patch.object(config, "AUDIOCPP_API_URL", "http://127.0.0.1"):
- self.assertEqual(make_server.config_port(),
+ self.assertEqual(make_server.configsync.config_port(),
make_server.FALLBACK_PORT)
def test_invalid_url_falls_back(self):
with patch.object(config, "AUDIOCPP_API_URL", "not a url"):
- self.assertEqual(make_server.config_port(),
+ self.assertEqual(make_server.configsync.config_port(),
make_server.FALLBACK_PORT)
def test_url_with_port_replaces_port(self):
# audiocpp reuses the shared helper (backends.common.url_with_port).
self.assertEqual(
- make_server.url_with_port("http://127.0.0.1:8080", 9000),
+ common.url_with_port("http://127.0.0.1:8080", 9000),
"http://127.0.0.1:9000")
def test_url_without_port_adds_port(self):
self.assertEqual(
- make_server.url_with_port("http://localhost", 8080),
+ common.url_with_port("http://localhost", 8080),
"http://localhost:8080")
@@ -247,7 +250,7 @@ class UpdateConfigPortTests(unittest.TestCase):
self._tmp.cleanup()
def test_rewrites_port_preserving_comment(self):
- changed = make_server.update_config_api_url_port(
+ changed = make_server.configsync.update_config_api_url_port(
8080, config_path=self.config_path)
self.assertTrue(changed)
text = self.config_path.read_text(encoding="utf-8")
@@ -260,18 +263,18 @@ class UpdateConfigPortTests(unittest.TestCase):
def test_returns_false_when_no_url_line(self):
path = Path(self._tmp.name) / "other.py"
path.write_text('CHUNK_SIZE = 250\n', encoding="utf-8")
- self.assertFalse(make_server.update_config_api_url_port(
+ self.assertFalse(make_server.configsync.update_config_api_url_port(
8080, config_path=path))
def test_port_unchanged_is_a_success_noop(self):
# The file already holds the port: success, nothing rewritten.
- self.assertTrue(make_server.update_config_api_url_port(
+ self.assertTrue(make_server.configsync.update_config_api_url_port(
9999, config_path=self.config_path))
self.assertEqual(self.config_path.read_text(encoding="utf-8"),
FAKE_CONFIG)
def test_returns_false_when_file_missing(self):
- self.assertFalse(make_server.update_config_api_url_port(
+ self.assertFalse(make_server.configsync.update_config_api_url_port(
8080, config_path=Path(self._tmp.name) / "nope.py"))
@@ -291,7 +294,7 @@ class UpdateConfigModelIdsTests(unittest.TestCase):
self._tmp.cleanup()
def test_rewrites_both_ids_preserving_lines(self):
- changed = make_server.update_config_model_ids(
+ changed = make_server.configsync.update_config_model_ids(
"higgs", "higgs", config_path=self.config_path)
self.assertTrue(changed)
text = self.config_path.read_text(encoding="utf-8")
@@ -301,7 +304,7 @@ class UpdateConfigModelIdsTests(unittest.TestCase):
self.assertIn('AUDIOCPP_API_URL = "http://127.0.0.1:9999"', text)
def test_clone_id_optional(self):
- changed = make_server.update_config_model_ids(
+ changed = make_server.configsync.update_config_model_ids(
"voxcpm2", config_path=self.config_path)
self.assertTrue(changed)
text = self.config_path.read_text(encoding="utf-8")
@@ -310,7 +313,7 @@ class UpdateConfigModelIdsTests(unittest.TestCase):
def test_ids_unchanged_is_a_success_noop(self):
# Both ids already hold their values: success, nothing rewritten.
- changed = make_server.update_config_model_ids(
+ changed = make_server.configsync.update_config_model_ids(
"qwen", "qwen-clone", config_path=self.config_path)
self.assertTrue(changed)
self.assertEqual(self.config_path.read_text(encoding="utf-8"),
@@ -319,11 +322,11 @@ class UpdateConfigModelIdsTests(unittest.TestCase):
def test_returns_false_when_lines_missing(self):
path = Path(self._tmp.name) / "other.py"
path.write_text('CHUNK_SIZE = 250\n', encoding="utf-8")
- self.assertFalse(make_server.update_config_model_ids(
+ self.assertFalse(make_server.configsync.update_config_model_ids(
"higgs", "higgs", config_path=path))
def test_returns_false_when_file_missing(self):
- self.assertFalse(make_server.update_config_model_ids(
+ self.assertFalse(make_server.configsync.update_config_model_ids(
"higgs", "higgs",
config_path=Path(self._tmp.name) / "nope.py"))
@@ -337,32 +340,32 @@ class ResolveWavDirArgTests(unittest.TestCase):
self._tmp.cleanup()
def test_resolves_to_absolute(self):
- self.assertEqual(make_server.resolve_wav_dir_arg(str(self.folder)),
+ self.assertEqual(common.resolve_wav_dir_arg(str(self.folder)),
self.folder.resolve())
def test_strips_surrounding_quotes(self):
quoted = f'"{self.folder}"'
- self.assertEqual(make_server.resolve_wav_dir_arg(quoted),
+ self.assertEqual(common.resolve_wav_dir_arg(quoted),
self.folder.resolve())
def test_strips_single_quotes(self):
quoted = f"'{self.folder}'"
- self.assertEqual(make_server.resolve_wav_dir_arg(quoted),
+ self.assertEqual(common.resolve_wav_dir_arg(quoted),
self.folder.resolve())
def test_strips_whitespace(self):
- self.assertEqual(make_server.resolve_wav_dir_arg(f" {self.folder} "),
+ self.assertEqual(common.resolve_wav_dir_arg(f" {self.folder} "),
self.folder.resolve())
def test_expands_tilde(self):
- with patch.object(make_server.os.path, "expanduser",
+ with patch.object(os.path, "expanduser",
return_value=str(self.folder)) as mock_expand:
- result = make_server.resolve_wav_dir_arg("~/voices")
+ result = common.resolve_wav_dir_arg("~/voices")
mock_expand.assert_called_once_with("~/voices")
self.assertEqual(result, self.folder.resolve())
def test_trailing_slash_preserved_as_dir(self):
- self.assertEqual(make_server.resolve_wav_dir_arg(f"{self.folder}/"),
+ self.assertEqual(common.resolve_wav_dir_arg(f"{self.folder}/"),
self.folder.resolve())
@@ -388,20 +391,20 @@ class FindLocalCheckoutTests(unittest.TestCase):
def test_none_when_no_checkout_in_app_dir(self):
with tempfile.TemporaryDirectory() as td, \
- patch.object(make_server, "APP_DIR", Path(td)):
- self.assertIsNone(make_server.find_local_checkout())
+ patch.object(make_server.build, "APP_DIR", Path(td)):
+ self.assertIsNone(make_server.build.find_local_checkout())
def test_returns_the_managed_checkout(self):
with tempfile.TemporaryDirectory() as td, \
- patch.object(make_server, "APP_DIR", Path(td)):
+ patch.object(make_server.build, "APP_DIR", Path(td)):
checkout = _make_checkout(Path(td))
- self.assertEqual(make_server.find_local_checkout(), checkout)
+ self.assertEqual(make_server.build.find_local_checkout(), checkout)
def test_none_when_checkout_lacks_model_specs(self):
with tempfile.TemporaryDirectory() as td, \
- patch.object(make_server, "APP_DIR", Path(td)):
+ patch.object(make_server.build, "APP_DIR", Path(td)):
(Path(td) / "audio.cpp").mkdir()
- self.assertIsNone(make_server.find_local_checkout())
+ self.assertIsNone(make_server.build.find_local_checkout())
class LoadModelCatalogTests(unittest.TestCase):
@@ -413,7 +416,7 @@ class LoadModelCatalogTests(unittest.TestCase):
self._td.cleanup()
def test_includes_tts_families_excludes_asr(self):
- catalog = make_server.load_model_catalog(self.checkout)
+ catalog = make_server.catalog.load_model_catalog(self.checkout)
families = [entry["family"] for entry in catalog]
self.assertIn("qwen3_tts", families)
self.assertIn("higgs_audio_tts", families)
@@ -422,19 +425,19 @@ class LoadModelCatalogTests(unittest.TestCase):
self.assertNotIn("qwen3_asr", families)
def test_skips_families_with_no_packages(self):
- catalog = make_server.load_model_catalog(self.checkout)
+ catalog = make_server.catalog.load_model_catalog(self.checkout)
self.assertNotIn("empty_tts",
[entry["family"] for entry in catalog])
def test_families_sorted_alphabetically_by_display_name(self):
- catalog = make_server.load_model_catalog(self.checkout)
+ catalog = make_server.catalog.load_model_catalog(self.checkout)
names = [entry["display_name"].lower() for entry in catalog]
self.assertEqual(names, sorted(names))
self.assertNotIn("tested", catalog[0])
self.assertNotIn("TESTED_FAMILIES", dir(make_server))
def test_default_package_and_target_directory_resolved(self):
- catalog = make_server.load_model_catalog(self.checkout)
+ catalog = make_server.catalog.load_model_catalog(self.checkout)
by_family = {entry["family"]: entry for entry in catalog}
higgs = by_family["higgs_audio_tts"]
self.assertEqual(higgs["install_id"], "higgs_audio_tts_4b_q8_0")
@@ -449,12 +452,12 @@ class LoadModelCatalogTests(unittest.TestCase):
{"id": "voxcpm2_q8_0", "format": "gguf",
"target_directory": "VoxCPM2-GGUF"},
])
- catalog = make_server.load_model_catalog(self.checkout)
+ catalog = make_server.catalog.load_model_catalog(self.checkout)
by_family = {entry["family"]: entry for entry in catalog}
self.assertEqual(by_family["voxcpm2"]["install_id"], "voxcpm2_bf16")
def test_clone_capability_from_tasks(self):
- catalog = make_server.load_model_catalog(self.checkout)
+ catalog = make_server.catalog.load_model_catalog(self.checkout)
by_family = {entry["family"]: entry for entry in catalog}
self.assertTrue(by_family["higgs_audio_tts"]["clone_capable"])
self.assertFalse(by_family["supertonic"]["clone_capable"])
@@ -463,7 +466,7 @@ class LoadModelCatalogTests(unittest.TestCase):
empty = Path(self._td.name) / "empty"
empty.mkdir()
with self.assertRaises(NotADirectoryError):
- make_server.load_model_catalog(empty)
+ make_server.catalog.load_model_catalog(empty)
class DetectBackendTests(unittest.TestCase):
@@ -485,58 +488,58 @@ class DetectBackendTests(unittest.TestCase):
return build_dir
def test_no_build_dir_returns_none(self):
- self.assertIsNone(make_server.detect_backend(self.checkout))
+ self.assertIsNone(make_server.catalog.detect_backend(self.checkout))
def test_unique_linux_backend_detected(self):
self._build("linux-cuda-release")
- self.assertEqual(make_server.detect_backend(self.checkout), "cuda")
+ self.assertEqual(make_server.catalog.detect_backend(self.checkout), "cuda")
def test_windows_exe_backend_detected(self):
self._build("windows-vulkan-debug", binary="audiocpp_server.exe")
- self.assertEqual(make_server.detect_backend(self.checkout), "vulkan")
+ self.assertEqual(make_server.catalog.detect_backend(self.checkout), "vulkan")
def test_hip_backend_detected(self):
self._build("linux-hip-release")
- self.assertEqual(make_server.detect_backend(self.checkout), "hip")
+ self.assertEqual(make_server.catalog.detect_backend(self.checkout), "hip")
def test_cpu_backend_detected(self):
self._build("linux-cpu-release")
- self.assertEqual(make_server.detect_backend(self.checkout), "cpu")
+ self.assertEqual(make_server.catalog.detect_backend(self.checkout), "cpu")
def test_metal_maps_to_cpu(self):
self._build("macos-metal-release")
- self.assertEqual(make_server.detect_backend(self.checkout), "cpu")
+ self.assertEqual(make_server.catalog.detect_backend(self.checkout), "cpu")
def test_multiple_backends_returns_none(self):
self._build("linux-cuda-release")
self._build("linux-cpu-release")
- self.assertIsNone(make_server.detect_backend(self.checkout))
+ self.assertIsNone(make_server.catalog.detect_backend(self.checkout))
def test_multiple_builds_same_backend_detected(self):
self._build("linux-cuda-release")
self._build("windows-cuda-debug")
- self.assertEqual(make_server.detect_backend(self.checkout), "cuda")
+ self.assertEqual(make_server.catalog.detect_backend(self.checkout), "cuda")
def test_build_dir_without_binary_ignored(self):
(self.checkout / "build" / "linux-cuda-release").mkdir(parents=True)
- self.assertIsNone(make_server.detect_backend(self.checkout))
+ self.assertIsNone(make_server.catalog.detect_backend(self.checkout))
def test_non_matching_build_dir_name_ignored(self):
self._build("linux-mybuild-release")
- self.assertIsNone(make_server.detect_backend(self.checkout))
+ self.assertIsNone(make_server.catalog.detect_backend(self.checkout))
class BackendOptionsTests(unittest.TestCase):
"""Aligned backend menu labels and the [auto-detected] default."""
def test_options_have_aligned_dashes(self):
- options, default_index = make_server._backend_options()
+ options, default_index = make_server.catalog._backend_options()
dash_columns = {label.index(" - ") for label, _ in options}
self.assertEqual(len(dash_columns), 1)
self.assertEqual(default_index, 0)
def test_detected_backend_marked_and_defaulted(self):
- options, default_index = make_server._backend_options("vulkan")
+ options, default_index = make_server.catalog._backend_options("vulkan")
labels = [label for label, _ in options]
self.assertEqual(default_index, labels.index(next(
label for label, value in options
@@ -545,22 +548,22 @@ class BackendOptionsTests(unittest.TestCase):
self.assertEqual(options[default_index][1], "vulkan")
def test_unknown_detected_backend_is_ignored(self):
- options, default_index = make_server._backend_options("opencl")
+ options, default_index = make_server.catalog._backend_options("opencl")
self.assertEqual(default_index, 0)
self.assertFalse(any("[auto-detected]" in label
for label, _ in options))
def test_labels_keep_backend_values(self):
- options, _ = make_server._backend_options()
+ options, _ = make_server.catalog._backend_options()
self.assertEqual([value for _, value in options],
list(make_server.BACKENDS))
class BuildServerConfigTests(unittest.TestCase):
def test_single_entry_without_voice_dir(self):
- entry = make_server.build_model_entry(
+ entry = make_server.catalog.build_model_entry(
"higgs_audio_tts", "higgs", "models/Higgs-GGUF")
- cfg = make_server.build_server_config(
+ cfg = make_server.catalog.build_server_config(
"127.0.0.1", 8080, "cuda", False, [entry])
self.assertEqual(cfg["host"], "127.0.0.1")
self.assertEqual(cfg["port"], 8080)
@@ -570,15 +573,15 @@ class BuildServerConfigTests(unittest.TestCase):
self.assertNotIn("voice_dir", cfg)
def test_voice_dir_added_when_given(self):
- entry = make_server.build_model_entry("voxcpm2", "voxcpm2", "models/V")
- cfg = make_server.build_server_config(
+ entry = make_server.catalog.build_model_entry("voxcpm2", "voxcpm2", "models/V")
+ cfg = make_server.catalog.build_server_config(
"0.0.0.0", 9000, "cpu", True, [entry],
voice_dir="/abs/voices")
self.assertTrue(cfg["lazy_load"])
self.assertEqual(cfg["voice_dir"], "/abs/voices")
def test_model_entry_shape(self):
- entry = make_server.build_model_entry("index_tts2", "indextts2", "p")
+ entry = make_server.catalog.build_model_entry("index_tts2", "indextts2", "p")
self.assertEqual(entry["id"], "indextts2")
self.assertEqual(entry["family"], "index_tts2")
self.assertEqual(entry["path"], "p")
@@ -586,7 +589,7 @@ class BuildServerConfigTests(unittest.TestCase):
self.assertEqual(entry["mode"], "offline")
def test_model_entry_design_task(self):
- entry = make_server.build_model_entry(
+ entry = make_server.catalog.build_model_entry(
"qwen3_tts", "qwen-design", "p", task="vdes")
self.assertEqual(entry["task"], "vdes")
self.assertEqual(entry["mode"], "offline")
@@ -612,9 +615,9 @@ class InstallModelsTests(unittest.TestCase):
def test_declined_download_prints_commands_deduped(self):
buf = io.StringIO()
with redirect_stdout(buf), \
- patch.object(make_server.common,
+ patch.object(common,
"run_console_subprocess") as run:
- make_server._install_models(self.checkout, self.guidance,
+ make_server.models._install_models(self.checkout, self.guidance,
download=False)
out = buf.getvalue()
self.assertEqual(out.count("install higgs_audio_tts_4b_q8_0"), 1)
@@ -622,9 +625,9 @@ class InstallModelsTests(unittest.TestCase):
run.assert_not_called()
def test_accepted_download_runs_each_command(self):
- with patch.object(make_server.common,
+ with patch.object(common,
"run_console_subprocess", return_value=0) as run:
- make_server._install_models(self.checkout, self.guidance,
+ make_server.models._install_models(self.checkout, self.guidance,
download=True)
self.assertEqual(run.call_count, 2)
commands = [call[0][0] for call in run.call_args_list]
@@ -641,9 +644,9 @@ class InstallModelsTests(unittest.TestCase):
self.manager.unlink()
buf = io.StringIO()
with redirect_stdout(buf), \
- patch.object(make_server.common,
+ patch.object(common,
"run_console_subprocess") as run:
- make_server._install_models(self.checkout, self.guidance,
+ make_server.models._install_models(self.checkout, self.guidance,
download=True)
self.assertIn("install higgs_audio_tts_4b_q8_0", buf.getvalue())
run.assert_not_called()
@@ -652,9 +655,9 @@ class InstallModelsTests(unittest.TestCase):
results = iter([1, 0])
buf = io.StringIO()
with redirect_stdout(buf), \
- patch.object(make_server.common, "run_console_subprocess",
+ patch.object(common, "run_console_subprocess",
side_effect=lambda *a, **k: next(results)) as run:
- make_server._install_models(self.checkout, self.guidance,
+ make_server.models._install_models(self.checkout, self.guidance,
download=True)
self.assertEqual(run.call_count, 2)
self.assertIn("exited with code 1", buf.getvalue())
@@ -662,17 +665,17 @@ class InstallModelsTests(unittest.TestCase):
def test_decide_download_skips_prompt_without_manager(self):
self.manager.unlink()
confirm = MagicMock()
- self.assertFalse(make_server._decide_download(self.checkout, [], confirm))
+ self.assertFalse(make_server.models._decide_download(self.checkout, [], confirm))
confirm.assert_not_called()
def test_decide_download_asks_when_manager_present(self):
confirm = MagicMock(return_value=True)
- self.assertTrue(make_server._decide_download(self.checkout, [], confirm))
+ self.assertTrue(make_server.models._decide_download(self.checkout, [], confirm))
confirm.assert_called_once()
def test_decide_download_defaults_to_yes(self):
confirm = MagicMock(return_value=True)
- make_server._decide_download(self.checkout, [], confirm)
+ make_server.models._decide_download(self.checkout, [], confirm)
self.assertIs(confirm.call_args[0][1], True)
def test_decide_download_skips_prompt_when_all_models_present(self):
@@ -680,7 +683,7 @@ class InstallModelsTests(unittest.TestCase):
target.mkdir(parents=True)
(target / "model.gguf").write_bytes(b"x")
confirm = MagicMock()
- self.assertFalse(make_server._decide_download(
+ self.assertFalse(make_server.models._decide_download(
self.checkout, [{"path": "models/higgs"}], confirm))
confirm.assert_not_called()
@@ -689,7 +692,7 @@ class InstallModelsTests(unittest.TestCase):
target.mkdir(parents=True)
(target / "model.gguf").write_bytes(b"x")
confirm = MagicMock(return_value=True)
- self.assertTrue(make_server._decide_download(
+ self.assertTrue(make_server.models._decide_download(
self.checkout,
[{"path": "models/higgs"}, {"path": "models/absent"}],
confirm))
@@ -699,30 +702,30 @@ class InstallModelsTests(unittest.TestCase):
target = self.checkout / "models" / "higgs"
target.mkdir(parents=True)
(target / "model.gguf").write_bytes(b"x")
- self.assertTrue(make_server._all_models_present(
+ self.assertTrue(make_server.models._all_models_present(
self.checkout, [{"path": "models/higgs"}]))
def test_all_models_present_false_when_one_missing(self):
target = self.checkout / "models" / "higgs"
target.mkdir(parents=True)
(target / "model.gguf").write_bytes(b"x")
- self.assertFalse(make_server._all_models_present(
+ self.assertFalse(make_server.models._all_models_present(
self.checkout,
[{"path": "models/higgs"}, {"path": "models/absent"}]))
def test_all_models_present_false_for_empty_selection(self):
- self.assertFalse(make_server._all_models_present(self.checkout, []))
+ self.assertFalse(make_server.models._all_models_present(self.checkout, []))
def test_all_models_present_honors_absolute_paths(self):
target = self.checkout / "models" / "higgs"
target.mkdir(parents=True)
(target / "model.gguf").write_bytes(b"x")
- self.assertTrue(make_server._all_models_present(
+ self.assertTrue(make_server.models._all_models_present(
self.checkout, [{"path": str(target)}]))
def test_all_models_present_false_for_empty_dir(self):
(self.checkout / "models" / "higgs").mkdir(parents=True)
- self.assertFalse(make_server._all_models_present(
+ self.assertFalse(make_server.models._all_models_present(
self.checkout, [{"path": "models/higgs"}]))
@@ -741,31 +744,31 @@ class TranscribeWavDirTests(unittest.TestCase):
def test_transcribes_to_stem_map_with_absolute_paths(self):
transcripts = {str(self.narrator): "First.",
str(self.other): "Second."}
- with patch.object(make_server, "transcribe_reference_audio",
+ with patch.object(make_server.voices, "transcribe_reference_audio",
side_effect=lambda path, model_name="base":
transcripts[path]):
- result = make_server.transcribe_wav_dir(
+ result = make_server.voices.transcribe_wav_dir(
[self.narrator, self.other], "base")
self.assertEqual(list(result), ["narrator", "other"])
self.assertEqual(result["narrator"], "First.")
def test_failed_transcription_keeps_empty_string(self):
- with patch.object(make_server, "transcribe_reference_audio",
+ with patch.object(make_server.voices, "transcribe_reference_audio",
return_value=None):
- result = make_server.transcribe_wav_dir([self.narrator], "base")
+ result = make_server.voices.transcribe_wav_dir([self.narrator], "base")
self.assertEqual(result["narrator"], "")
def test_whisper_model_name_passed_through(self):
- with patch.object(make_server, "transcribe_reference_audio",
+ with patch.object(make_server.voices, "transcribe_reference_audio",
return_value="text") as mock_transcribe:
- make_server.transcribe_wav_dir([self.narrator], "large-v3")
+ make_server.voices.transcribe_wav_dir([self.narrator], "large-v3")
self.assertEqual(mock_transcribe.call_args.kwargs["model_name"],
"large-v3")
def test_write_prompt_text_format(self):
- path = make_server.write_prompt_text(
+ path = common.write_prompt_text(
self.folder, {"narrator": "Hello.", "other": "World."})
- self.assertEqual(path, self.folder / make_server.PROMPT_TEXT_FILENAME)
+ self.assertEqual(path, self.folder / common.PROMPT_TEXT_FILENAME)
text = path.read_text(encoding="utf-8")
self.assertIn("narrator|Hello.", text)
self.assertIn("other|World.", text)
@@ -775,21 +778,21 @@ class DesignPackageTests(unittest.TestCase):
"""Voice-design package detection."""
def test_detects_voicedesign_in_id(self):
- self.assertTrue(make_server.is_design_package(
+ self.assertTrue(make_server.catalog.is_design_package(
{"id": "qwen3_tts_1_7b_voicedesign_q8_0"}))
def test_detects_voicedesign_in_directory(self):
- self.assertTrue(make_server.is_design_package(
+ self.assertTrue(make_server.catalog.is_design_package(
{"target_directory": "Foo-VoiceDesign-GGUF"}))
def test_detects_separated_voice_design(self):
- self.assertTrue(make_server.is_design_package(
+ self.assertTrue(make_server.catalog.is_design_package(
{"display_name": "Voice Design Q8_0"}))
def test_ignores_other_packages(self):
- self.assertFalse(make_server.is_design_package(
+ self.assertFalse(make_server.catalog.is_design_package(
{"id": "higgs_audio_tts_4b_q8_0"}))
- self.assertFalse(make_server.is_design_package({}))
+ self.assertFalse(make_server.catalog.is_design_package({}))
class PackageDirOptionsTests(unittest.TestCase):
@@ -807,7 +810,7 @@ class PackageDirOptionsTests(unittest.TestCase):
"target_directory": "VoiceDesign-GGUF"},
],
}
- options = make_server.package_dir_options(entry)
+ options = make_server.catalog.package_dir_options(entry)
self.assertEqual([o["target_directory"] for o in options],
["Base-GGUF", "VoiceDesign-GGUF"])
self.assertTrue(options[0]["recommended"])
@@ -826,7 +829,7 @@ class PackageDirOptionsTests(unittest.TestCase):
"target_directory": "Default-GGUF"},
],
}
- options = make_server.package_dir_options(entry)
+ options = make_server.catalog.package_dir_options(entry)
self.assertEqual([o["target_directory"] for o in options],
["Default-GGUF", "Other-GGUF"])
@@ -848,25 +851,25 @@ class FindAudiocppServerBinTests(unittest.TestCase):
(bin_dir / binary).write_bytes(b"x")
def test_no_build_dir_returns_none(self):
- self.assertIsNone(make_server.find_audiocpp_server_bin(self.checkout))
+ self.assertIsNone(make_server.build.find_audiocpp_server_bin(self.checkout))
def test_finds_built_binary(self):
self._build("linux-cuda-release")
self.assertEqual(
- make_server.find_audiocpp_server_bin(self.checkout),
+ make_server.build.find_audiocpp_server_bin(self.checkout),
self.checkout / "build" / "linux-cuda-release" / "bin"
/ "audiocpp_server")
def test_finds_windows_exe(self):
self._build("windows-vulkan-debug", binary="audiocpp_server.exe")
self.assertEqual(
- make_server.find_audiocpp_server_bin(self.checkout).name,
+ make_server.build.find_audiocpp_server_bin(self.checkout).name,
"audiocpp_server.exe")
def test_build_dir_without_binary_returns_none(self):
(self.checkout / "build" / "linux-cuda-release" / "bin").mkdir(
parents=True)
- self.assertIsNone(make_server.find_audiocpp_server_bin(self.checkout))
+ self.assertIsNone(make_server.build.find_audiocpp_server_bin(self.checkout))
class BuiltServerBinaryTests(unittest.TestCase):
@@ -889,24 +892,24 @@ class BuiltServerBinaryTests(unittest.TestCase):
self._build("linux-cuda-release")
self._build("linux-cpu-release")
self.assertEqual(
- make_server.built_server_binary(self.checkout, "cpu"),
+ make_server.build.built_server_binary(self.checkout, "cpu"),
self.checkout / "build" / "linux-cpu-release" / "bin"
/ "audiocpp_server")
def test_returns_none_for_unbuilt_backend(self):
self._build("linux-cuda-release")
self.assertIsNone(
- make_server.built_server_binary(self.checkout, "vulkan"))
+ make_server.build.built_server_binary(self.checkout, "vulkan"))
def test_metal_counts_as_cpu(self):
self._build("macos-metal-release")
self.assertEqual(
- make_server.built_server_binary(self.checkout, "cpu"),
+ make_server.build.built_server_binary(self.checkout, "cpu"),
self.checkout / "build" / "macos-metal-release" / "bin"
/ "audiocpp_server")
def test_no_build_dir_returns_none(self):
- self.assertIsNone(make_server.built_server_binary(self.checkout, "cpu"))
+ self.assertIsNone(make_server.build.built_server_binary(self.checkout, "cpu"))
class BuildAudiocppTests(unittest.TestCase):
@@ -921,7 +924,7 @@ class BuildAudiocppTests(unittest.TestCase):
(self.scripts / "build_linux.sh").write_text("#!/bin/sh\n",
encoding="utf-8")
self.log_dir = Path(self._td.name) / "logs"
- self.addCleanup(make_server.common.drain_post_tui_notices)
+ self.addCleanup(common.drain_post_tui_notices)
def tearDown(self):
self._td.cleanup()
@@ -938,9 +941,9 @@ class BuildAudiocppTests(unittest.TestCase):
return sorted(self.log_dir.glob("audiocpp_build_*.log"))
def test_runs_build_script_with_backend_and_target(self):
- with patch.object(make_server.common, "run_console_subprocess",
+ with patch.object(common, "run_console_subprocess",
return_value=0) as run:
- rc = make_server.build_audiocpp(self.checkout, "cuda")
+ rc = make_server.build.build_audiocpp(self.checkout, "cuda")
self.assertEqual(rc, 0)
argv = run.call_args[0][0]
self.assertEqual(argv[:3], ["sh", str(self.scripts / "build_linux.sh"),
@@ -954,24 +957,24 @@ class BuildAudiocppTests(unittest.TestCase):
def test_missing_script_returns_nonzero(self):
for f in self.scripts.iterdir():
f.unlink()
- rc = make_server.build_audiocpp(self.checkout, "cuda")
+ rc = make_server.build.build_audiocpp(self.checkout, "cuda")
self.assertNotEqual(rc, 0)
def test_console_path_writes_no_log_and_no_notice(self):
- with patch.object(make_server.common, "LOG_DIR", self.log_dir), \
- patch.object(make_server.common, "run_console_subprocess",
+ with patch.object(common, "LOG_DIR", self.log_dir), \
+ patch.object(common, "run_console_subprocess",
return_value=0):
- rc = make_server.build_audiocpp(self.checkout, "cuda")
+ rc = make_server.build.build_audiocpp(self.checkout, "cuda")
self.assertEqual(rc, 0)
self.assertEqual(self._log_files(), [])
- self.assertEqual(make_server.common.drain_post_tui_notices(), [])
+ self.assertEqual(common.drain_post_tui_notices(), [])
def test_tui_success_writes_log_and_no_notice(self):
emitted, emit = self._emit()
- with patch.object(make_server.common, "LOG_DIR", self.log_dir), \
- patch.object(make_server.common, "run_console_subprocess",
+ with patch.object(common, "LOG_DIR", self.log_dir), \
+ patch.object(common, "run_console_subprocess",
return_value=0):
- rc = make_server.build_audiocpp(self.checkout, "cuda",
+ rc = make_server.build.build_audiocpp(self.checkout, "cuda",
emit=emit)
self.assertEqual(rc, 0)
self.assertEqual(len(self._log_files()), 1)
@@ -979,21 +982,21 @@ class BuildAudiocppTests(unittest.TestCase):
self.assertIn("[INFO] Building audiocpp_server", log_text)
self.assertIn("--backend cuda", log_text)
self.assertTrue(emitted)
- self.assertEqual(make_server.common.drain_post_tui_notices(), [])
+ self.assertEqual(common.drain_post_tui_notices(), [])
def test_tui_failure_writes_log_and_records_notice(self):
emitted, emit = self._emit()
- with patch.object(make_server.common, "LOG_DIR", self.log_dir), \
- patch.object(make_server.common, "run_console_subprocess",
+ with patch.object(common, "LOG_DIR", self.log_dir), \
+ patch.object(common, "run_console_subprocess",
return_value=3):
- rc = make_server.build_audiocpp(self.checkout, "cuda",
+ rc = make_server.build.build_audiocpp(self.checkout, "cuda",
emit=emit)
self.assertEqual(rc, 3)
logs = self._log_files()
self.assertEqual(len(logs), 1)
log_text = logs[0].read_text(encoding="utf-8")
self.assertIn("failed (exit code 3)", log_text)
- notices = make_server.common.drain_post_tui_notices()
+ notices = common.drain_post_tui_notices()
self.assertEqual(len(notices), 1)
notice = notices[0]
self.assertIn("failed (exit code 3)", notice)
@@ -1010,25 +1013,25 @@ class BuildAudiocppTests(unittest.TestCase):
emitted, emit = self._emit()
cancel = threading.Event()
cancel.set()
- with patch.object(make_server.common, "LOG_DIR", self.log_dir), \
- patch.object(make_server.common, "run_console_subprocess",
+ with patch.object(common, "LOG_DIR", self.log_dir), \
+ patch.object(common, "run_console_subprocess",
return_value=130):
- rc = make_server.build_audiocpp(self.checkout, "cuda",
+ rc = make_server.build.build_audiocpp(self.checkout, "cuda",
emit=emit, cancel=cancel)
self.assertEqual(rc, 130)
self.assertEqual(len(self._log_files()), 1)
- self.assertEqual(make_server.common.drain_post_tui_notices(), [])
+ self.assertEqual(common.drain_post_tui_notices(), [])
def test_tui_missing_script_records_guidance_notice(self):
for f in self.scripts.iterdir():
f.unlink()
emitted, emit = self._emit()
- with patch.object(make_server.common, "LOG_DIR", self.log_dir):
- rc = make_server.build_audiocpp(self.checkout, "cuda",
+ with patch.object(common, "LOG_DIR", self.log_dir):
+ rc = make_server.build.build_audiocpp(self.checkout, "cuda",
emit=emit)
self.assertNotEqual(rc, 0)
self.assertEqual(self._log_files(), [])
- notices = make_server.common.drain_post_tui_notices()
+ notices = common.drain_post_tui_notices()
self.assertEqual(len(notices), 1)
self.assertIn("No build script found", notices[0])
@@ -1045,18 +1048,18 @@ class AudiocppDetectTests(unittest.TestCase):
self._td.cleanup()
def test_not_cloned(self):
- with patch.object(make_server, "find_local_checkout", return_value=None):
- status = make_server.detect()
+ with patch.object(make_server.build, "find_local_checkout", return_value=None):
+ status = make_server.status.detect()
self.assertFalse(status.installed)
self.assertFalse(status.configured)
self.assertIn("not cloned", status.details[0])
def test_cloned_not_built_not_configured(self):
- with patch.object(make_server, "find_local_checkout",
+ with patch.object(make_server.build, "find_local_checkout",
return_value=self.checkout), \
- patch.object(make_server, "find_audiocpp_server_bin",
+ patch.object(make_server.build, "find_audiocpp_server_bin",
return_value=None):
- status = make_server.detect()
+ status = make_server.status.detect()
self.assertFalse(status.installed)
self.assertFalse(status.configured)
self.assertEqual(status.launch_hint, "")
@@ -1069,9 +1072,9 @@ class AudiocppDetectTests(unittest.TestCase):
binary.write_bytes(b"x")
server_json = self.checkout / "server.json"
server_json.write_text('{"models":[]}', encoding="utf-8")
- with patch.object(make_server, "find_local_checkout",
+ with patch.object(make_server.build, "find_local_checkout",
return_value=self.checkout):
- status = make_server.detect()
+ status = make_server.status.detect()
self.assertTrue(status.installed)
self.assertTrue(status.configured)
self.assertIn(str(binary), status.launch_hint)
@@ -1083,9 +1086,9 @@ class AudiocppDetectTests(unittest.TestCase):
/ "audiocpp_server"
binary.parent.mkdir(parents=True)
binary.write_bytes(b"x")
- with patch.object(make_server, "find_local_checkout",
+ with patch.object(make_server.build, "find_local_checkout",
return_value=self.checkout):
- status = make_server.detect()
+ status = make_server.status.detect()
self.assertTrue(status.installed)
self.assertFalse(status.configured)
self.assertEqual(status.partial, "built (not configured)")
@@ -1104,11 +1107,11 @@ class NonInteractiveMainTests(unittest.TestCase):
# Isolate config.py rewrites so no test touches the real one.
self.fake_config = self.root / "config.py"
self.fake_config.write_text(FAKE_CONFIG, encoding="utf-8")
- patcher = patch.object(make_server, "CONFIG_PATH", self.fake_config)
+ patcher = patch.object(make_server.configsync, "CONFIG_PATH", self.fake_config)
patcher.start()
self.addCleanup(patcher.stop)
# Tests run without a tty -> main() takes the non-interactive path.
- patcher = patch.object(make_server, "_interactive", return_value=False)
+ patcher = patch.object(make_server.wizard, "_interactive", return_value=False)
patcher.start()
self.addCleanup(patcher.stop)
@@ -1121,14 +1124,14 @@ class NonInteractiveMainTests(unittest.TestCase):
transcribe_effect = transcribe if transcribe is not None \
else MagicMock()
with patch.object(sys, "argv", argv), \
- patch.object(make_server, "find_local_checkout",
+ patch.object(make_server.build, "find_local_checkout",
return_value=None if no_checkout
else self.checkout), \
- patch.object(make_server, "transcribe_reference_audio",
+ patch.object(make_server.voices, "transcribe_reference_audio",
side_effect=transcribe_effect), \
- patch.object(make_server, "whisper_backend_available",
+ patch.object(make_server.voices, "whisper_backend_available",
return_value=whisper):
- return make_server.main()
+ return make_server.wizard.main()
def _args(self, *extra):
return ["--wavs", str(self.folder), "--output", str(self.output)] \
@@ -1140,7 +1143,7 @@ class NonInteractiveMainTests(unittest.TestCase):
self.assertEqual(exit_code, 0)
data = json.loads(self.output.read_text(encoding="utf-8"))
self.assertEqual(data["host"], "127.0.0.1")
- self.assertEqual(data["port"], make_server.config_port())
+ self.assertEqual(data["port"], make_server.configsync.config_port())
self.assertEqual(data["backend"], "cuda")
self.assertTrue(data["lazy_load"])
self.assertEqual([m["id"] for m in data["models"]],
@@ -1192,7 +1195,7 @@ class NonInteractiveMainTests(unittest.TestCase):
"Higgs-Audio-v3-TTS-4B-GGUF"])
self.assertTrue(data["lazy_load"])
self.assertEqual(data["voice_dir"], str(self.folder.resolve()))
- prompt = (self.folder / make_server.PROMPT_TEXT_FILENAME).read_text(
+ prompt = (self.folder / common.PROMPT_TEXT_FILENAME).read_text(
encoding="utf-8")
self.assertIn("narrator|a transcript", prompt)
@@ -1282,8 +1285,8 @@ class FetchServerEndpointsTests(unittest.TestCase):
"data": [{"id": "qwen", "family": "qwen3_tts", "task": "tts"},
{"id": "legacy"}],
}).encode("utf-8")])
- with patch.object(make_server.urllib.request, "urlopen", urlopen):
- models = make_server.fetch_server_models("http://127.0.0.1:8080")
+ with patch("urllib.request.urlopen", urlopen):
+ models = make_server.remote.fetch_server_models("http://127.0.0.1:8080")
# Missing fields mirror the converter's client: empty strings.
self.assertEqual(models, [
{"id": "qwen", "family": "qwen3_tts", "task": "tts"},
@@ -1294,36 +1297,36 @@ class FetchServerEndpointsTests(unittest.TestCase):
def test_fetch_models_trailing_slash_url(self):
urlopen, calls = self._urlopen_responding(
[b'{"data": [{"id": "m"}]}'])
- with patch.object(make_server.urllib.request, "urlopen", urlopen):
- make_server.fetch_server_models("http://host:8080/")
+ with patch("urllib.request.urlopen", urlopen):
+ make_server.remote.fetch_server_models("http://host:8080/")
self.assertEqual(calls, ["http://host:8080/v1/models"])
def test_fetch_models_connection_error_returns_none(self):
import urllib.error
urlopen, _ = self._urlopen_responding(
[], errors=[urllib.error.URLError("Connection refused")])
- with patch.object(make_server.urllib.request, "urlopen", urlopen):
+ with patch("urllib.request.urlopen", urlopen):
self.assertIsNone(
- make_server.fetch_server_models("http://127.0.0.1:8080"))
+ make_server.remote.fetch_server_models("http://127.0.0.1:8080"))
def test_fetch_models_non_json_body_returns_none(self):
# A port answering TCP but not speaking audiocpp_server JSON.
urlopen, _ = self._urlopen_responding([b"<html>not json</html>"])
- with patch.object(make_server.urllib.request, "urlopen", urlopen):
+ with patch("urllib.request.urlopen", urlopen):
self.assertIsNone(
- make_server.fetch_server_models("http://127.0.0.1:8080"))
+ make_server.remote.fetch_server_models("http://127.0.0.1:8080"))
def test_fetch_models_unexpected_document_yields_empty_list(self):
urlopen, _ = self._urlopen_responding([b'{"foo": 1}'])
- with patch.object(make_server.urllib.request, "urlopen", urlopen):
+ with patch("urllib.request.urlopen", urlopen):
self.assertEqual(
- make_server.fetch_server_models("http://127.0.0.1:8080"), [])
+ make_server.remote.fetch_server_models("http://127.0.0.1:8080"), [])
def test_fetch_voices_parses_names_and_encodes_model(self):
urlopen, calls = self._urlopen_responding(
[b'{"voices": ["narrator", "obama"]}'])
- with patch.object(make_server.urllib.request, "urlopen", urlopen):
- voices = make_server.fetch_server_voices(
+ with patch("urllib.request.urlopen", urlopen):
+ voices = make_server.remote.fetch_server_voices(
"http://127.0.0.1:8080", "qwen")
self.assertEqual(voices, ["narrator", "obama"])
self.assertEqual(calls,
@@ -1333,15 +1336,15 @@ class FetchServerEndpointsTests(unittest.TestCase):
import urllib.error
urlopen, _ = self._urlopen_responding(
[], errors=[urllib.error.URLError("boom")])
- with patch.object(make_server.urllib.request, "urlopen", urlopen):
+ with patch("urllib.request.urlopen", urlopen):
self.assertIsNone(
- make_server.fetch_server_voices("http://h", "qwen"))
+ make_server.remote.fetch_server_voices("http://h", "qwen"))
def test_fetch_voices_non_list_shape_returns_none(self):
urlopen, _ = self._urlopen_responding([b'{"voices": 5}'])
- with patch.object(make_server.urllib.request, "urlopen", urlopen):
+ with patch("urllib.request.urlopen", urlopen):
self.assertIsNone(
- make_server.fetch_server_voices("http://h", "qwen"))
+ make_server.remote.fetch_server_voices("http://h", "qwen"))
class MissingModelEntriesTests(unittest.TestCase):
@@ -1366,29 +1369,29 @@ class MissingModelEntriesTests(unittest.TestCase):
{"id": "a", "path": "models/present"},
{"id": "b", "path": "models/absent"},
])
- missing = make_server.missing_model_entries(path)
+ missing = make_server.models.missing_model_entries(path)
self.assertEqual([m["id"] for m in missing], ["b"])
def test_empty_directory_counts_as_missing(self):
(self.dir / "models" / "empty").mkdir(parents=True)
path = self._server_json([{"id": "a", "path": "models/empty"}])
- self.assertEqual(len(make_server.missing_model_entries(path)), 1)
+ self.assertEqual(len(make_server.models.missing_model_entries(path)), 1)
def test_absolute_paths_honored(self):
target = self.dir / "absolute"
target.mkdir()
(target / "m.gguf").write_bytes(b"x")
path = self._server_json([{"id": "a", "path": str(target)}])
- self.assertEqual(make_server.missing_model_entries(path), [])
+ self.assertEqual(make_server.models.missing_model_entries(path), [])
def test_unreadable_json_returns_empty(self):
path = self.dir / "server.json"
path.write_text("not json", encoding="utf-8")
- self.assertEqual(make_server.missing_model_entries(path), [])
+ self.assertEqual(make_server.models.missing_model_entries(path), [])
def test_no_models_returns_empty(self):
path = self._server_json([])
- self.assertEqual(make_server.missing_model_entries(path), [])
+ self.assertEqual(make_server.models.missing_model_entries(path), [])
class ModelInstallHintsTests(unittest.TestCase):
@@ -1409,7 +1412,7 @@ class ModelInstallHintsTests(unittest.TestCase):
}],
}), encoding="utf-8")
missing = [{"id": "qwen", "rel": "models/Qwen3-TTS-12Hz-0.6B-Base-GGUF"}]
- hints = make_server.model_install_hints(checkout, missing)
+ hints = make_server.models.model_install_hints(checkout, missing)
self.assertEqual(len(hints), 1)
self.assertIn("qwen3_tts_0_6b_base_q8_0", hints[0])
@@ -1418,7 +1421,7 @@ class ModelInstallHintsTests(unittest.TestCase):
with tempfile.TemporaryDirectory() as td:
checkout = Path(td)
(checkout / "model_specs").mkdir()
- hints = make_server.model_install_hints(
+ hints = make_server.models.model_install_hints(
checkout, [{"id": "x", "rel": "models/nope"}])
self.assertIn("models/nope", hints[0])
self.assertNotIn("install", hints[0])
@@ -1443,11 +1446,11 @@ class DetectServerSpecTests(unittest.TestCase):
def test_spec_has_cwd_and_identity(self):
checkout = self._checkout()
- with patch.object(make_server, "find_local_checkout",
+ with patch.object(make_server.build, "find_local_checkout",
return_value=checkout), \
- patch.object(make_server, "_detect_remote",
+ patch.object(make_server.status, "_detect_remote",
return_value=(False, {})):
- status = make_server.detect()
+ status = make_server.status.detect()
self.assertEqual(len(status.servers), 1)
spec = status.servers[0]
self.assertEqual(spec.cwd, checkout)
@@ -1456,11 +1459,11 @@ class DetectServerSpecTests(unittest.TestCase):
def test_models_missing_flag_and_details(self):
checkout = self._checkout()
- with patch.object(make_server, "find_local_checkout",
+ with patch.object(make_server.build, "find_local_checkout",
return_value=checkout), \
- patch.object(make_server, "_detect_remote",
+ patch.object(make_server.status, "_detect_remote",
return_value=(False, {})):
- status = make_server.detect()
+ status = make_server.status.detect()
self.assertTrue(status.models_missing)
self.assertTrue(any("not downloaded" in line
for line in status.details))
@@ -1488,13 +1491,13 @@ class InstalledModelEntriesTests(unittest.TestCase):
{"id": "a", "path": "models/present"},
{"id": "b", "path": "models/absent"},
])
- installed = make_server.installed_model_entries(path)
+ installed = make_server.models.installed_model_entries(path)
self.assertEqual([m["id"] for m in installed], ["a"])
def test_unreadable_json_returns_empty(self):
path = self.dir / "server.json"
path.write_text("not json", encoding="utf-8")
- self.assertEqual(make_server.installed_model_entries(path), [])
+ self.assertEqual(make_server.models.installed_model_entries(path), [])
class MissingModelInstallGuidanceTests(unittest.TestCase):
@@ -1517,7 +1520,7 @@ class MissingModelInstallGuidanceTests(unittest.TestCase):
{"id": "qwen", "rel": "models/Qwen3-TTS-12Hz-0.6B-Base-GGUF"},
{"id": "x", "rel": "models/nope"},
]
- guidance = make_server.missing_model_install_guidance(
+ guidance = make_server.models.missing_model_install_guidance(
checkout, missing)
self.assertEqual(guidance,
[("qwen", "qwen3_tts_0_6b_base_q8_0")])
@@ -1537,22 +1540,22 @@ class LoadServerConfigTests(unittest.TestCase):
path = self.dir / "server.json"
path.write_text(json.dumps({"host": "0.0.0.0", "models": []}),
encoding="utf-8")
- self.assertEqual(make_server.load_server_config(path),
+ self.assertEqual(make_server.catalog.load_server_config(path),
{"host": "0.0.0.0", "models": []})
def test_missing_file_returns_none(self):
- self.assertIsNone(make_server.load_server_config(
+ self.assertIsNone(make_server.catalog.load_server_config(
self.dir / "nope.json"))
def test_unreadable_json_returns_none(self):
path = self.dir / "server.json"
path.write_text("not json", encoding="utf-8")
- self.assertIsNone(make_server.load_server_config(path))
+ self.assertIsNone(make_server.catalog.load_server_config(path))
def test_non_dict_document_returns_none(self):
path = self.dir / "server.json"
path.write_text("[1, 2, 3]", encoding="utf-8")
- self.assertIsNone(make_server.load_server_config(path))
+ self.assertIsNone(make_server.catalog.load_server_config(path))
class ServerConfigSelectionsTests(unittest.TestCase):
@@ -1561,7 +1564,7 @@ class ServerConfigSelectionsTests(unittest.TestCase):
def setUp(self):
self._tmp = tempfile.TemporaryDirectory()
self.checkout = _make_checkout(Path(self._tmp.name))
- self.catalog = make_server.load_model_catalog(self.checkout)
+ self.catalog = make_server.catalog.load_model_catalog(self.checkout)
def tearDown(self):
self._tmp.cleanup()
@@ -1576,7 +1579,7 @@ class ServerConfigSelectionsTests(unittest.TestCase):
{"id": "higgs", "family": "higgs_audio_tts",
"path": "models/Higgs-Audio-v3-TTS-4B-GGUF", "task": "tts"},
]}
- selected, tasks = make_server.server_config_selections(config,
+ selected, tasks = make_server.catalog.server_config_selections(config,
self.catalog)
self.assertEqual(selected["qwen3_tts"],
["Qwen3-TTS-12Hz-1.7B-Base-GGUF",
@@ -1593,7 +1596,7 @@ class ServerConfigSelectionsTests(unittest.TestCase):
config = {"models": [
{"id": "x", "family": "not_a_family", "path": "models/x"},
]}
- selected, tasks = make_server.server_config_selections(config,
+ selected, tasks = make_server.catalog.server_config_selections(config,
self.catalog)
self.assertEqual(selected, {})
self.assertEqual(tasks, {})
@@ -1603,13 +1606,13 @@ class ServerConfigSelectionsTests(unittest.TestCase):
{"id": "qwen", "family": "qwen3_tts",
"path": "/abs/Qwen3-TTS-12Hz-1.7B-Base-GGUF", "task": "tts"},
]}
- selected, tasks = make_server.server_config_selections(config,
+ selected, tasks = make_server.catalog.server_config_selections(config,
self.catalog)
self.assertEqual(selected["qwen3_tts"],
["/abs/Qwen3-TTS-12Hz-1.7B-Base-GGUF"])
def test_empty_models_yield_empty_selections(self):
- selected, tasks = make_server.server_config_selections({"models": []},
+ selected, tasks = make_server.catalog.server_config_selections({"models": []},
self.catalog)
self.assertEqual(selected, {})
self.assertEqual(tasks, {})
@@ -1641,7 +1644,7 @@ class UnusedInstalledEntriesTests(unittest.TestCase):
{"id": "dropped", "path": "models/dropped"},
{"id": "missing", "path": "models/missing"},
])
- unused = make_server.unused_installed_entries(
+ unused = make_server.models.unused_installed_entries(
path, {"models/kept"})
self.assertEqual([entry["id"] for entry in unused], ["dropped"])
@@ -1649,7 +1652,7 @@ class UnusedInstalledEntriesTests(unittest.TestCase):
path = self._server_json([
{"id": "kept", "path": "models/kept"},
])
- unused = make_server.unused_installed_entries(
+ unused = make_server.models.unused_installed_entries(
path, {"models/kept"})
self.assertEqual(unused, [])
@@ -1678,7 +1681,7 @@ class DeleteModelFilesTests(unittest.TestCase):
self._tmp.cleanup()
def test_removes_dirs_and_counts(self):
- removed = make_server.delete_model_files(
+ removed = make_server.models.delete_model_files(
self.server_json,
[{"id": "a", "rel": "models/a"}, {"id": "b", "rel": "models/b"}])
self.assertEqual(removed, 2)
@@ -1687,14 +1690,14 @@ class DeleteModelFilesTests(unittest.TestCase):
self.assertTrue((self.dir / "models" / "c").exists())
def test_missing_paths_ignored(self):
- removed = make_server.delete_model_files(
+ removed = make_server.models.delete_model_files(
self.server_json, [{"id": "ghost", "rel": "models/ghost"}])
self.assertEqual(removed, 0)
def test_removes_single_file(self):
file_path = self.dir / "models" / "single.gguf"
file_path.write_bytes(b"x")
- removed = make_server.delete_model_files(
+ removed = make_server.models.delete_model_files(
self.server_json, [{"id": "s", "rel": "models/single.gguf"}])
self.assertEqual(removed, 1)
self.assertFalse(file_path.exists())
@@ -1703,7 +1706,7 @@ class DeleteModelFilesTests(unittest.TestCase):
target = self.dir / "absolute"
target.mkdir()
(target / "m.gguf").write_bytes(b"x")
- removed = make_server.delete_model_files(
+ removed = make_server.models.delete_model_files(
self.server_json, [{"id": "a", "rel": str(target)}])
self.assertEqual(removed, 1)
self.assertFalse(target.exists())
@@ -1716,8 +1719,8 @@ class InstallModelsApiTests(unittest.TestCase):
with tempfile.TemporaryDirectory() as td:
checkout = Path(td)
guidance = [("qwen", "qwen3_tts_0_6b_base_q8_0")]
- with patch.object(make_server, "_install_models") as mk:
- make_server.install_models(checkout, guidance)
+ with patch.object(make_server.models, "_install_models") as mk:
+ make_server.models.install_models(checkout, guidance)
mk.assert_called_once_with(checkout, guidance, download=True,
emit=None, cancel=None)
@@ -1728,7 +1731,7 @@ class HandInstallGuidanceTests(unittest.TestCase):
def test_lists_each_model_and_its_path(self):
with tempfile.TemporaryDirectory() as td:
checkout = Path(td)
- message = make_server.hand_install_guidance(checkout, [
+ message = make_server.models.hand_install_guidance(checkout, [
{"id": "qwen", "rel": "models/Qwen3-TTS-12Hz-0.6B-Base-GGUF"},
{"id": "higgs", "rel": "models/Higgs-Audio-4B-GGUF"},
])
@@ -1743,7 +1746,7 @@ class WizardNavigationTests(unittest.TestCase):
"""Esc in the audio.cpp wizard goes back one screen (via tui.Wizard)."""
def _args(self):
- return make_server.build_parser().parse_args([])
+ return make_server.wizard.build_parser().parse_args([])
def _checkout(self):
tmp = tempfile.TemporaryDirectory()
@@ -1754,12 +1757,12 @@ class WizardNavigationTests(unittest.TestCase):
# Configure audio.cpp (modify flow): the families tree is the first
# screen, so Esc on it must abort the wizard — not re-show itself.
checkout = self._checkout()
- with patch.object(make_server, "find_local_checkout",
+ with patch.object(make_server.build, "find_local_checkout",
return_value=checkout), \
patch.object(tui, "checkbox_tree",
- return_value=make_server._GO_BACK):
- settings = make_server._wizard(None, self._args(),
- make_server.build_parser())
+ return_value=make_server.wizard._GO_BACK):
+ settings = make_server.wizard._wizard(None, self._args(),
+ make_server.wizard.build_parser())
self.assertIsNone(settings)
def test_modify_flow_offers_build_when_not_built(self):
@@ -1771,7 +1774,7 @@ class WizardNavigationTests(unittest.TestCase):
(checkout / "server.json").write_text(
json.dumps({"models": [], "backend": "vulkan"}),
encoding="utf-8")
- catalog = make_server.load_model_catalog(checkout)
+ catalog = make_server.catalog.load_model_catalog(checkout)
supertonic = next(i for i, entry in enumerate(catalog)
if entry["family"] == "supertonic")
confirm_questions = []
@@ -1793,14 +1796,14 @@ class WizardNavigationTests(unittest.TestCase):
confirm_questions.append(question)
return False # decline the build
- with patch.object(make_server, "find_local_checkout",
+ with patch.object(make_server.build, "find_local_checkout",
return_value=checkout), \
patch.object(tui, "checkbox_tree", side_effect=fake_tree), \
patch.object(tui, "line_edit", side_effect=fake_line_edit), \
patch.object(tui, "menu", side_effect=fake_menu), \
patch.object(tui, "confirm", side_effect=fake_confirm):
- settings = make_server._wizard(None, self._args(),
- make_server.build_parser())
+ settings = make_server.wizard._wizard(None, self._args(),
+ make_server.wizard.build_parser())
self.assertIsNotNone(settings)
self.assertEqual(settings["backend"], "vulkan")
self.assertFalse(settings["build"])
@@ -1813,11 +1816,11 @@ class WizardNavigationTests(unittest.TestCase):
# Esc on "Bind host" must fall back to the model-family tree, then
# re-selecting proceeds through the rest of the wizard.
checkout = self._checkout()
- catalog = make_server.load_model_catalog(checkout)
+ catalog = make_server.catalog.load_model_catalog(checkout)
supertonic = next(i for i, entry in enumerate(catalog)
if entry["family"] == "supertonic")
tree_calls = []
- hosts = iter([make_server._GO_BACK, "127.0.0.1"])
+ hosts = iter([make_server.wizard._GO_BACK, "127.0.0.1"])
def fake_tree(*args, **kwargs):
tree_calls.append(1)
@@ -1830,7 +1833,7 @@ class WizardNavigationTests(unittest.TestCase):
return "8080"
return default
- with patch.object(make_server, "find_local_checkout",
+ with patch.object(make_server.build, "find_local_checkout",
return_value=checkout), \
patch.object(tui, "checkbox_tree",
side_effect=fake_tree), \
@@ -1838,8 +1841,8 @@ class WizardNavigationTests(unittest.TestCase):
side_effect=fake_line_edit), \
patch.object(tui, "menu", return_value="cuda"), \
patch.object(tui, "confirm", return_value=True):
- settings = make_server._wizard(None, self._args(),
- make_server.build_parser())
+ settings = make_server.wizard._wizard(None, self._args(),
+ make_server.wizard.build_parser())
self.assertIsNotNone(settings)
# The tree was re-shown after the host screen's Esc.
self.assertEqual(len(tree_calls), 2)
@@ -1855,12 +1858,12 @@ class UninstallTests(unittest.TestCase):
with tempfile.TemporaryDirectory() as td:
checkout = Path(td) / "audio.cpp"
checkout.mkdir()
- with patch.object(make_server, "find_local_checkout",
+ with patch.object(make_server.build, "find_local_checkout",
return_value=checkout), \
- patch.object(make_server.servers, "pid_for",
+ patch.object(servers, "pid_for",
return_value=1234), \
- patch.object(make_server.servers, "stop") as mk_stop:
- rc = make_server.uninstall()
+ patch.object(servers, "stop") as mk_stop:
+ rc = make_server.build.uninstall()
self.assertEqual(rc, 0)
self.assertFalse(checkout.exists())
mk_stop.assert_called_once_with("audiocpp")
@@ -1868,12 +1871,12 @@ class UninstallTests(unittest.TestCase):
def test_skips_stop_without_a_pid_file(self):
# No pid file: the server was never started by this tool, so
# stop (and its "stop it manually" noise) is skipped.
- with patch.object(make_server, "find_local_checkout",
+ with patch.object(make_server.build, "find_local_checkout",
return_value=None), \
- patch.object(make_server.servers, "pid_for",
+ patch.object(servers, "pid_for",
return_value=None), \
- patch.object(make_server.servers, "stop") as mk_stop:
- rc = make_server.uninstall()
+ patch.object(servers, "stop") as mk_stop:
+ rc = make_server.build.uninstall()
self.assertEqual(rc, 0)
mk_stop.assert_not_called()
@@ -1883,12 +1886,12 @@ class UninstallTests(unittest.TestCase):
with tempfile.TemporaryDirectory() as td:
checkout = Path(td) / "audio.cpp"
checkout.mkdir()
- with patch.object(make_server, "find_local_checkout",
+ with patch.object(make_server.build, "find_local_checkout",
return_value=checkout), \
- patch.object(make_server.servers, "pid_for",
+ patch.object(servers, "pid_for",
return_value=1234), \
- patch.object(make_server.servers, "stop"):
- rc = make_server.uninstall(emit=lambda line: None,
+ patch.object(servers, "stop"):
+ rc = make_server.build.uninstall(emit=lambda line: None,
cancel=None)
self.assertEqual(rc, 0)
self.assertFalse(checkout.exists())
@@ -1901,12 +1904,12 @@ class UninstallTests(unittest.TestCase):
checkout.mkdir()
cancel = threading.Event()
cancel.set()
- with patch.object(make_server, "find_local_checkout",
+ with patch.object(make_server.build, "find_local_checkout",
return_value=checkout), \
- patch.object(make_server.servers, "pid_for",
+ patch.object(servers, "pid_for",
return_value=1234), \
- patch.object(make_server.servers, "stop"):
- rc = make_server.uninstall(cancel=cancel)
+ patch.object(servers, "stop"):
+ rc = make_server.build.uninstall(cancel=cancel)
self.assertEqual(rc, 130)
self.assertTrue(checkout.exists())
@@ -1920,23 +1923,23 @@ class SetupScreenTests(unittest.TestCase):
in-TUI task view (two parallel lanes on a fresh install)."""
def test_abort_returns_one_without_executing(self):
- with patch.object(make_server, "_wizard", return_value=None) as mk_wizard, \
- patch.object(make_server, "_execute_lanes") as mk_lanes:
- rc = make_server.setup_screen(None)
+ with patch.object(make_server.wizard, "_wizard", return_value=None) as mk_wizard, \
+ patch.object(make_server.wizard, "_execute_lanes") as mk_lanes:
+ rc = make_server.wizard.setup_screen(None)
self.assertEqual(rc, 1)
mk_wizard.assert_called_once()
mk_lanes.assert_not_called()
def test_success_runs_the_tail_in_the_task_view(self):
settings = {"audiocpp_dir": Path("/x")}
- lanes = [make_server.taskview.TaskLane(
- "Build", [make_server.taskview.TaskStep("t", lambda emit, cancel: 0)])]
- with patch.object(make_server, "_wizard", return_value=settings), \
- patch.object(make_server, "_execute_lanes",
+ lanes = [taskview.TaskLane(
+ "Build", [taskview.TaskStep("t", lambda emit, cancel: 0)])]
+ with patch.object(make_server.wizard, "_wizard", return_value=settings), \
+ patch.object(make_server.wizard, "_execute_lanes",
return_value=lanes) as mk_lanes, \
- patch.object(make_server.taskview, "run_lanes",
+ patch.object(taskview, "run_lanes",
return_value=0) as mk_run:
- rc = make_server.setup_screen(None)
+ rc = make_server.wizard.setup_screen(None)
self.assertEqual(rc, 0)
mk_lanes.assert_called_once()
self.assertIs(mk_lanes.call_args[0][0], settings)
@@ -1973,8 +1976,8 @@ class ExecuteLanesTests(unittest.TestCase):
return settings
def test_two_lanes_when_building(self):
- args = make_server.build_parser().parse_args([])
- lanes = make_server._execute_lanes(self._settings(), args)
+ args = make_server.wizard.build_parser().parse_args([])
+ lanes = make_server.wizard._execute_lanes(self._settings(), args)
self.assertEqual([lane.title for lane in lanes],
["Build", "Configure & download"])
self.assertEqual([s.title for s in lanes[0].steps],
@@ -1985,15 +1988,15 @@ class ExecuteLanesTests(unittest.TestCase):
"Download models"])
def test_single_lane_when_not_building(self):
- args = make_server.build_parser().parse_args([])
- lanes = make_server._execute_lanes(
+ args = make_server.wizard.build_parser().parse_args([])
+ lanes = make_server.wizard._execute_lanes(
self._settings(build=False), args)
self.assertEqual([lane.title for lane in lanes],
["Configure & download"])
def test_flattened_console_steps_keep_the_build_first(self):
- args = make_server.build_parser().parse_args([])
- steps = make_server._execute_steps(self._settings(), args)
+ args = make_server.wizard.build_parser().parse_args([])
+ steps = make_server.wizard._execute_steps(self._settings(), args)
self.assertEqual([s.title for s in steps],
["Build audiocpp_server (cuda)",
"Transcribe reference voices",
@@ -2001,11 +2004,11 @@ class ExecuteLanesTests(unittest.TestCase):
"Download models"])
def test_download_step_prints_the_launch_hint(self):
- args = make_server.build_parser().parse_args([])
- lanes = make_server._execute_lanes(self._settings(), args)
+ args = make_server.wizard.build_parser().parse_args([])
+ lanes = make_server.wizard._execute_lanes(self._settings(), args)
install_step = lanes[1].steps[2]
- with patch.object(make_server, "_install_models"), \
- patch.object(make_server, "_print_launch_hint") as mk_hint:
+ with patch.object(make_server.models, "_install_models"), \
+ patch.object(make_server.build, "_print_launch_hint") as mk_hint:
install_step.work(lambda line: None, threading.Event())
mk_hint.assert_called_once_with(Path("/x"), Path("/x/server.json"))
@@ -2016,9 +2019,9 @@ class LaunchHintTests(unittest.TestCase):
def _capture(self, audiocpp_dir, output_path, binary=None):
buf = io.StringIO()
with redirect_stdout(buf), \
- patch.object(make_server, "find_audiocpp_server_bin",
+ patch.object(make_server.build, "find_audiocpp_server_bin",
return_value=binary):
- make_server._print_launch_hint(audiocpp_dir, output_path)
+ make_server.build._print_launch_hint(audiocpp_dir, output_path)
return buf.getvalue()
def test_built_server_prints_nothing(self):
diff --git a/app/tests/test_backends_faster.py b/app/tests/test_backends_faster.py
index 55d617c..800acb0 100644
--- a/app/tests/test_backends_faster.py
+++ b/app/tests/test_backends_faster.py
@@ -173,7 +173,8 @@ class MainTests(unittest.TestCase):
return_value=False)
patcher.start()
self.addCleanup(patcher.stop)
- patcher = patch.object(make_voices, "_interactive", return_value=False)
+ patcher = patch.object(make_voices.setup, "interactive",
+ return_value=False)
patcher.start()
self.addCleanup(patcher.stop)
diff --git a/app/tests/test_hub.py b/app/tests/test_hub.py
index 9f72ad9..d8a21bc 100644
--- a/app/tests/test_hub.py
+++ b/app/tests/test_hub.py
@@ -1972,7 +1972,7 @@ class AudiocppServerConfigTests(unittest.TestCase):
import json
with tempfile.TemporaryDirectory() as td:
mod, checkout, server_json = self._make_checkout(td, port=8080)
- with patch.object(mod, "find_local_checkout",
+ with patch.object(mod.build, "find_local_checkout",
return_value=checkout):
self.assertTrue(mod.update_server_config_port(9090))
data = json.loads(server_json.read_text(encoding="utf-8"))
@@ -1986,16 +1986,17 @@ class AudiocppServerConfigTests(unittest.TestCase):
with tempfile.TemporaryDirectory() as td:
mod, checkout, server_json = self._make_checkout(td, port=8080)
before = server_json.read_text(encoding="utf-8")
- with patch.object(mod, "find_local_checkout",
+ with patch.object(mod.build, "find_local_checkout",
return_value=checkout):
self.assertTrue(mod.update_server_config_port(8080))
self.assertEqual(server_json.read_text(encoding="utf-8"), before)
def test_false_when_no_checkout(self):
from backends import audiocpp as audiocpp_backend
- with patch.object(audiocpp_backend, "find_local_checkout",
+ with patch.object(audiocpp_backend.build, "find_local_checkout",
return_value=None):
- self.assertFalse(audiocpp_backend.update_server_config_port(9090))
+ self.assertFalse(
+ audiocpp_backend.update_server_config_port(9090))
class ConfigureBackendsDispatchTests(unittest.TestCase):