aboutsummaryrefslogtreecommitdiff
path: root/app/tests/test_backends_audiocpp.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/tests/test_backends_audiocpp.py')
-rw-r--r--app/tests/test_backends_audiocpp.py124
1 files changed, 124 insertions, 0 deletions
diff --git a/app/tests/test_backends_audiocpp.py b/app/tests/test_backends_audiocpp.py
index 08de777..8b1698b 100644
--- a/app/tests/test_backends_audiocpp.py
+++ b/app/tests/test_backends_audiocpp.py
@@ -637,6 +637,130 @@ class BuildServerConfigTests(unittest.TestCase):
self.assertEqual(entry["mode"], "offline")
+class CloneOnlyHostingTests(unittest.TestCase):
+ """Clone-only family classification and server.json hosting tasks."""
+
+ def test_clone_only_set_members(self):
+ for family in ("chatterbox", "confucius4_tts", "echo_tts"):
+ self.assertTrue(make_server.is_clone_only_family(family))
+
+ def test_clone_only_from_spec_tasks(self):
+ self.assertTrue(make_server.is_clone_only_family(
+ "future_tts", tasks={"clone"}))
+
+ def test_mixed_and_pure_families_are_not_clone_only(self):
+ self.assertFalse(make_server.is_clone_only_family(
+ "higgs_audio_tts", tasks={"tts", "clone"}))
+ self.assertFalse(make_server.is_clone_only_family(
+ "supertonic", tasks={"tts"}))
+
+ def test_unknown_family_without_tasks_is_not_clone_only(self):
+ # No spec, no explicit knowledge: keep the generic (tts) hosting.
+ self.assertFalse(make_server.is_clone_only_family("brand_new"))
+
+ def test_hosting_task_clone_only_family(self):
+ self.assertEqual(make_server.hosting_task(
+ {"family": "chatterbox", "tasks": ["tts", "clone", "vc"]}),
+ "clon")
+
+ def test_hosting_task_regular_family(self):
+ self.assertEqual(make_server.hosting_task(
+ {"family": "f5_tts", "tasks": ["tts", "clone"]}), "tts")
+
+
+class BuildEntriesHostingTests(unittest.TestCase):
+ """_build_entries hosts clone-only families with task "clon"."""
+
+ @staticmethod
+ def _catalog_entry(family, tasks):
+ return {"family": family, "display_name": family,
+ "description": "", "languages": ["en"], "tasks": tasks,
+ "clone_capable": "clone" in tasks, "packages": [],
+ "install_id": f"{family}_q8_0",
+ "default_path": f"models/{family}-GGUF"}
+
+ @staticmethod
+ def _option(directory):
+ return {"target_directory": directory, "install_id": "pkg",
+ "design": False, "recommended": True}
+
+ def _entries(self, catalog_entry):
+ entries, _, _, _, _ = make_server.wizard._build_entries(
+ [catalog_entry["family"]],
+ {catalog_entry["family"]: [self._option(catalog_entry["family"])]},
+ {catalog_entry["family"]: catalog_entry},
+ lambda install_id: "tts")
+ return entries
+
+ def test_chatterbox_is_hosted_with_clon(self):
+ entry = self._entries(self._catalog_entry(
+ "chatterbox", ["tts", "clone", "vc"]))[0]
+ self.assertEqual(entry["task"], "clon")
+ self.assertEqual(entry["family"], "chatterbox")
+
+ def test_clone_only_spec_family_is_hosted_with_clon(self):
+ entry = self._entries(self._catalog_entry(
+ "confucius4_tts", ["clone"]))[0]
+ self.assertEqual(entry["task"], "clon")
+
+ def test_mixed_family_is_hosted_with_tts(self):
+ entry = self._entries(self._catalog_entry(
+ "f5_tts", ["tts", "clone"]))[0]
+ self.assertEqual(entry["task"], "tts")
+
+
+class RehostCloneOnlyEntriesTests(unittest.TestCase):
+ """server.json repair: clone-only entries re-hosted from "tts"."""
+
+ def setUp(self):
+ self._td = tempfile.TemporaryDirectory()
+ self.server_json = Path(self._td.name) / "server.json"
+
+ def tearDown(self):
+ self._td.cleanup()
+
+ def _data(self, *models):
+ return {"host": "127.0.0.1", "port": 8080, "backend": "cuda",
+ "lazy_load": False, "models": list(models)}
+
+ def _read(self):
+ return json.loads(self.server_json.read_text(encoding="utf-8"))
+
+ def test_chatterbox_tts_entry_is_rehosted_and_persisted(self):
+ data = self._data({"id": "Chatterbox-GGUF", "family": "chatterbox",
+ "path": "models/Chatterbox-GGUF", "task": "tts",
+ "mode": "offline"})
+ repaired = make_server.rehost_clone_only_entries(self.server_json,
+ data)
+ self.assertEqual(repaired, ["Chatterbox-GGUF"])
+ self.assertEqual(data["models"][0]["task"], "clon")
+ # The fix is written back so the server picks it up on restart.
+ self.assertEqual(self._read()["models"][0]["task"], "clon")
+
+ def test_non_clone_only_entries_are_untouched(self):
+ data = self._data({"id": "q", "family": "qwen3_tts",
+ "path": "models/Q", "task": "tts",
+ "mode": "offline"})
+ self.assertEqual(make_server.rehost_clone_only_entries(
+ self.server_json, data), [])
+ self.assertEqual(data["models"][0]["task"], "tts")
+ self.assertFalse(self.server_json.exists())
+
+ def test_vdes_and_clon_tasks_are_left_alone(self):
+ data = self._data({"id": "c", "family": "chatterbox",
+ "path": "m", "task": "clon", "mode": "offline"},
+ {"id": "d", "family": "qwen3_tts",
+ "path": "m2", "task": "vdes", "mode": "offline"})
+ self.assertEqual(make_server.rehost_clone_only_entries(
+ self.server_json, data), [])
+
+ def test_unusable_document_is_ignored(self):
+ self.assertEqual(make_server.rehost_clone_only_entries(
+ self.server_json, {"models": "nope"}), [])
+ self.assertEqual(make_server.rehost_clone_only_entries(
+ self.server_json, {}), [])
+
+
class InstallModelsTests(unittest.TestCase):
"""Printing or auto-running the model install commands."""