mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 13:40:27 +02:00
refactor(webui): replace inline get_pipeline/resolve_voice_target closures with domain modules
- Replace get_pipeline() closure with PipelinePool from domain/pipeline_factory - Replace resolve_voice_target() closure with domain function from voice_utils - Remove dead _load_pipeline() function and unused is_plugin_registered import - Add 33 tests for resolve_voice_target and PipelinePool - Add 10 regression tests verifying domain extraction preserves behavior - 1131 tests pass (+61 new)
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from abogen.domain.pipeline_factory import (
|
||||
PipelinePool,
|
||||
create_pipeline_for_job,
|
||||
dispose_pipelines,
|
||||
resolve_device,
|
||||
)
|
||||
|
||||
|
||||
class TestResolveDevice:
|
||||
@patch("abogen.utils.load_config", return_value={"use_gpu": True})
|
||||
@patch("abogen.domain.pipeline_factory.select_device", return_value="cuda:0")
|
||||
def test_gpu_enabled(self, _sel, _cfg):
|
||||
assert resolve_device(use_gpu=True) == "cuda:0"
|
||||
|
||||
@patch("abogen.utils.load_config", return_value={"use_gpu": True})
|
||||
def test_gpu_disabled_by_job(self, _cfg):
|
||||
assert resolve_device(use_gpu=False) == "cpu"
|
||||
|
||||
@patch("abogen.utils.load_config", return_value={"use_gpu": False})
|
||||
@patch("abogen.domain.pipeline_factory.select_device", return_value="cuda:0")
|
||||
def test_gpu_disabled_by_config(self, _sel, _cfg):
|
||||
assert resolve_device(use_gpu=True) == "cpu"
|
||||
|
||||
|
||||
class TestCreatePipelineForJob:
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline")
|
||||
@patch("abogen.domain.pipeline_factory.is_plugin_registered", return_value=True)
|
||||
def test_supertonic_provider(self, _reg, mock_create):
|
||||
mock_create.return_value = MagicMock()
|
||||
result = create_pipeline_for_job("supertonic", "en", use_gpu=True)
|
||||
mock_create.assert_called_once_with("supertonic")
|
||||
assert result is mock_create.return_value
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline")
|
||||
@patch("abogen.domain.pipeline_factory.is_plugin_registered", return_value=True)
|
||||
@patch("abogen.domain.pipeline_factory.resolve_device", return_value="cpu")
|
||||
def test_kokoro_provider(self, _dev, _reg, mock_create):
|
||||
mock_create.return_value = MagicMock()
|
||||
result = create_pipeline_for_job("kokoro", "en", use_gpu=False)
|
||||
mock_create.assert_called_once_with("kokoro", lang_code="en", device="cpu")
|
||||
assert result is mock_create.return_value
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline")
|
||||
@patch("abogen.domain.pipeline_factory.is_plugin_registered", return_value=False)
|
||||
@patch("abogen.domain.pipeline_factory.resolve_device", return_value="cpu")
|
||||
def test_unknown_provider_falls_back_to_kokoro(self, _dev, _reg, mock_create):
|
||||
mock_create.return_value = MagicMock()
|
||||
result = create_pipeline_for_job("unknown_provider", "en", use_gpu=False)
|
||||
mock_create.assert_called_once_with("kokoro", lang_code="en", device="cpu")
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline")
|
||||
@patch("abogen.domain.pipeline_factory.is_plugin_registered", return_value=True)
|
||||
@patch("abogen.domain.pipeline_factory.resolve_device", return_value="cpu")
|
||||
def test_empty_provider_defaults_to_kokoro(self, _dev, _reg, mock_create):
|
||||
mock_create.return_value = MagicMock()
|
||||
result = create_pipeline_for_job("", "en", use_gpu=False)
|
||||
mock_create.assert_called_once_with("kokoro", lang_code="en", device="cpu")
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline")
|
||||
@patch("abogen.domain.pipeline_factory.is_plugin_registered", return_value=True)
|
||||
@patch("abogen.domain.pipeline_factory.resolve_device", return_value="cpu")
|
||||
def test_none_provider_defaults_to_kokoro(self, _dev, _reg, mock_create):
|
||||
mock_create.return_value = MagicMock()
|
||||
result = create_pipeline_for_job(None, "en", use_gpu=False)
|
||||
mock_create.assert_called_once_with("kokoro", lang_code="en", device="cpu")
|
||||
|
||||
|
||||
class TestDisposePipelines:
|
||||
def test_disposes_all_and_clears(self):
|
||||
p1 = MagicMock()
|
||||
p2 = MagicMock()
|
||||
pipelines = {"kokoro": p1, "supertonic": p2}
|
||||
dispose_pipelines(pipelines)
|
||||
p1.dispose.assert_called_once()
|
||||
p2.dispose.assert_called_once()
|
||||
assert pipelines == {}
|
||||
|
||||
def test_handles_dispose_error(self):
|
||||
p1 = MagicMock()
|
||||
p1.dispose.side_effect = RuntimeError("boom")
|
||||
pipelines = {"kokoro": p1}
|
||||
dispose_pipelines(pipelines)
|
||||
assert pipelines == {}
|
||||
|
||||
def test_empty_dict(self):
|
||||
pipelines = {}
|
||||
dispose_pipelines(pipelines)
|
||||
assert pipelines == {}
|
||||
|
||||
|
||||
class TestPipelinePool:
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline_for_job")
|
||||
@patch("abogen.domain.pipeline_factory.initialize_voice_cache")
|
||||
def test_get_creates_and_caches(self, _cache, mock_create):
|
||||
mock_pipeline = MagicMock()
|
||||
mock_create.return_value = mock_pipeline
|
||||
pool = PipelinePool()
|
||||
|
||||
result = pool.get("kokoro", "en", use_gpu=True)
|
||||
assert result is mock_pipeline
|
||||
mock_create.assert_called_once()
|
||||
|
||||
result2 = pool.get("kokoro", "en", use_gpu=True)
|
||||
assert result2 is mock_pipeline
|
||||
assert mock_create.call_count == 1
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline_for_job")
|
||||
@patch("abogen.domain.pipeline_factory.initialize_voice_cache")
|
||||
def test_get_initializes_voice_cache_once(self, mock_cache, mock_create):
|
||||
mock_create.return_value = MagicMock()
|
||||
pool = PipelinePool()
|
||||
|
||||
job = MagicMock()
|
||||
pool.get("kokoro", "en", use_gpu=True, job=job)
|
||||
assert mock_cache.call_count == 1
|
||||
|
||||
pool.get("kokoro", "en", use_gpu=True, job=job)
|
||||
assert mock_cache.call_count == 1
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.initialize_voice_cache")
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline_for_job")
|
||||
def test_get_no_job_skips_voice_cache(self, mock_create, mock_cache):
|
||||
mock_create.return_value = MagicMock()
|
||||
pool = PipelinePool()
|
||||
pool.get("kokoro", "en", use_gpu=True)
|
||||
mock_cache.assert_not_called()
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline_for_job")
|
||||
def test_get_separately_per_provider(self, mock_create):
|
||||
p1 = MagicMock(name="kokoro")
|
||||
p2 = MagicMock(name="supertonic")
|
||||
mock_create.side_effect = [p1, p2]
|
||||
pool = PipelinePool()
|
||||
|
||||
r1 = pool.get("kokoro", "en", use_gpu=True)
|
||||
r2 = pool.get("supertonic", "en", use_gpu=True)
|
||||
assert r1 is p1
|
||||
assert r2 is p2
|
||||
assert mock_create.call_count == 2
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline_for_job")
|
||||
@patch("abogen.domain.pipeline_factory.initialize_voice_cache")
|
||||
def test_dispose_all(self, mock_cache, mock_create):
|
||||
p1 = MagicMock(name="kokoro")
|
||||
p2 = MagicMock(name="supertonic")
|
||||
mock_create.side_effect = [p1, p2]
|
||||
pool = PipelinePool()
|
||||
|
||||
pool.get("kokoro", "en", use_gpu=True)
|
||||
pool.get("supertonic", "en", use_gpu=True)
|
||||
pool.dispose_all()
|
||||
|
||||
p1.dispose.assert_called_once()
|
||||
p2.dispose.assert_called_once()
|
||||
assert pool._pipelines == {}
|
||||
assert pool._voice_cache_initialized is False
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline_for_job")
|
||||
def test_dispose_empty_pool(self, mock_create):
|
||||
pool = PipelinePool()
|
||||
pool.dispose_all()
|
||||
mock_create.assert_not_called()
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline_for_job")
|
||||
@patch("abogen.domain.pipeline_factory.initialize_voice_cache")
|
||||
@patch("abogen.domain.pipeline_factory.is_plugin_registered", return_value=False)
|
||||
def test_unknown_provider_falls_back(self, _reg, _cache, mock_create):
|
||||
mock_create.return_value = MagicMock()
|
||||
pool = PipelinePool()
|
||||
pool.get("bogus_provider", "en", use_gpu=True)
|
||||
mock_create.assert_called_once_with("kokoro", "en", True)
|
||||
@@ -0,0 +1,195 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from abogen.domain.voice_utils import (
|
||||
coerce_truthy,
|
||||
formula_from_kokoro_entry,
|
||||
infer_provider_from_spec,
|
||||
resolve_voice_target,
|
||||
split_speaker_reference,
|
||||
supertonic_voice_from_spec,
|
||||
)
|
||||
|
||||
|
||||
class TestSplitSpeakerReference:
|
||||
def test_speaker_prefix(self):
|
||||
assert split_speaker_reference("speaker:af_sarah") == ("af_sarah", "speaker:af_sarah")
|
||||
|
||||
def test_profile_prefix(self):
|
||||
assert split_speaker_reference("profile:custom") == ("custom", "profile:custom")
|
||||
|
||||
def test_no_prefix(self):
|
||||
assert split_speaker_reference("af_sarah") == (None, "af_sarah")
|
||||
|
||||
def test_empty(self):
|
||||
assert split_speaker_reference("") == (None, "")
|
||||
|
||||
def test_none(self):
|
||||
assert split_speaker_reference(None) == (None, "")
|
||||
|
||||
def test_unknown_prefix(self):
|
||||
assert split_speaker_reference("unknown:name") == (None, "unknown:name")
|
||||
|
||||
def test_empty_name_after_colon(self):
|
||||
assert split_speaker_reference("speaker:") == (None, "speaker:")
|
||||
|
||||
|
||||
class TestSupertonicVoiceFromSpec:
|
||||
def test_uppercase_passthrough(self):
|
||||
assert supertonic_voice_from_spec("M1", "M1") == "M1"
|
||||
|
||||
def test_lowercase_converted(self):
|
||||
assert supertonic_voice_from_spec("m1", "M1") == "M1"
|
||||
|
||||
def test_empty_spec_uses_fallback(self):
|
||||
assert supertonic_voice_from_spec("", "F1") == "F1"
|
||||
|
||||
def test_formula_spec_uses_fallback(self):
|
||||
assert supertonic_voice_from_spec("af_sarah*0.5+bf_emma*0.5", "M1") == "M1"
|
||||
|
||||
def test_empty_both_gives_default(self):
|
||||
assert supertonic_voice_from_spec("", "") == "M1"
|
||||
|
||||
|
||||
class TestFormulaFromKokoroEntry:
|
||||
def test_single_voice(self):
|
||||
entry = {"voices": [["af_sarah", 1.0]]}
|
||||
result = formula_from_kokoro_entry(entry)
|
||||
assert "af_sarah" in result
|
||||
assert "1.000000" in result
|
||||
|
||||
def test_weighted_mix(self):
|
||||
entry = {"voices": [["af_sarah", 0.6], ["bf_emma", 0.4]]}
|
||||
result = formula_from_kokoro_entry(entry)
|
||||
assert "af_sarah" in result
|
||||
assert "bf_emma" in result
|
||||
assert "+" in result
|
||||
|
||||
def test_empty_voices(self):
|
||||
assert formula_from_kokoro_entry({"voices": []}) == ""
|
||||
|
||||
def test_missing_voices_key(self):
|
||||
assert formula_from_kokoro_entry({}) == ""
|
||||
|
||||
def test_invalid_entries_filtered(self):
|
||||
entry = {"voices": [["af_sarah", "bad"], ["bf_emma", 0.5]]}
|
||||
result = formula_from_kokoro_entry(entry)
|
||||
assert "bf_emma" in result
|
||||
assert "af_sarah" not in result
|
||||
|
||||
|
||||
class TestCoerceTruthy:
|
||||
def test_bool_passthrough(self):
|
||||
assert coerce_truthy(True) is True
|
||||
assert coerce_truthy(False) is False
|
||||
|
||||
def test_string_true(self):
|
||||
assert coerce_truthy("yes") is True
|
||||
assert coerce_truthy("1") is True
|
||||
|
||||
def test_string_false(self):
|
||||
assert coerce_truthy("false") is False
|
||||
assert coerce_truthy("0") is False
|
||||
assert coerce_truthy("") is False
|
||||
|
||||
def test_none_default(self):
|
||||
assert coerce_truthy(None) is True
|
||||
assert coerce_truthy(None, False) is False
|
||||
|
||||
def test_int(self):
|
||||
assert coerce_truthy(1) is True
|
||||
assert coerce_truthy(0) is False
|
||||
|
||||
|
||||
class TestInferProviderFromSpec:
|
||||
@patch("abogen.domain.voice_utils.get_voices", return_value=["af_sarah", "bf_emma"])
|
||||
def test_known_kokoro_voice(self, _mock):
|
||||
assert infer_provider_from_spec("af_sarah") == "kokoro"
|
||||
|
||||
@patch("abogen.domain.voice_utils.get_voices", return_value=["af_sarah"])
|
||||
def test_uppercase_supertonic(self, _mock):
|
||||
assert infer_provider_from_spec("M1") == "supertonic"
|
||||
|
||||
@patch("abogen.domain.voice_utils.get_voices", return_value=["af_sarah"])
|
||||
def test_formula_kokoro(self, _mock):
|
||||
assert infer_provider_from_spec("af_sarah*0.5+bf_emma*0.5") == "kokoro"
|
||||
|
||||
@patch("abogen.domain.voice_utils.get_voices", return_value=["af_sarah"])
|
||||
def test_empty_fallback(self, _mock):
|
||||
assert infer_provider_from_spec("", "kokoro") == "kokoro"
|
||||
|
||||
@patch("abogen.domain.voice_utils.get_voices", return_value=["af_sarah"])
|
||||
def test_unknown_falls_back(self, _mock):
|
||||
assert infer_provider_from_spec("unknown_xyz", "supertonic") == "supertonic"
|
||||
|
||||
|
||||
class TestResolveVoiceTarget:
|
||||
def test_empty_spec_kokoro_default(self):
|
||||
provider, spec, speed, steps = resolve_voice_target(
|
||||
"", {}, job_voice="af_sarah", job_tts_provider="kokoro",
|
||||
)
|
||||
assert provider == "kokoro"
|
||||
assert spec == ""
|
||||
|
||||
def test_speaker_profile_kokoro(self):
|
||||
profiles = {
|
||||
"narrator": {
|
||||
"provider": "kokoro",
|
||||
"voices": [["af_sarah", 0.7], ["bf_emma", 0.3]],
|
||||
},
|
||||
}
|
||||
provider, spec, speed, steps = resolve_voice_target(
|
||||
"speaker:narrator", profiles,
|
||||
)
|
||||
assert provider == "kokoro"
|
||||
assert "af_sarah" in spec
|
||||
assert speed is None
|
||||
assert steps is None
|
||||
|
||||
def test_speaker_profile_supertonic(self):
|
||||
profiles = {
|
||||
"narrator": {
|
||||
"provider": "supertonic",
|
||||
"voice": "F1",
|
||||
"speed": 1.2,
|
||||
"total_steps": 10,
|
||||
},
|
||||
}
|
||||
provider, spec, speed, steps = resolve_voice_target(
|
||||
"speaker:narrator", profiles,
|
||||
job_voice="M1", job_speed=1.0, job_supertonic_total_steps=5,
|
||||
)
|
||||
assert provider == "supertonic"
|
||||
assert spec == "F1"
|
||||
assert speed == 1.2
|
||||
assert steps == 10
|
||||
|
||||
@patch("abogen.domain.voice_utils.get_voices", return_value=["af_sarah"])
|
||||
def test_direct_supertonic_spec(self, _mock):
|
||||
provider, spec, speed, steps = resolve_voice_target(
|
||||
"M1", {},
|
||||
job_voice="M1",
|
||||
)
|
||||
assert provider == "supertonic"
|
||||
assert spec == "M1"
|
||||
|
||||
@patch("abogen.domain.voice_utils.get_voices", return_value=["af_sarah"])
|
||||
def test_direct_kokoro_spec(self, _mock):
|
||||
provider, spec, speed, steps = resolve_voice_target(
|
||||
"af_sarah", {},
|
||||
job_tts_provider="kokoro",
|
||||
)
|
||||
assert provider == "kokoro"
|
||||
assert spec == "af_sarah"
|
||||
|
||||
def test_profile_missing_provider_defaults_kokoro(self):
|
||||
profiles = {
|
||||
"narrator": {
|
||||
"voices": [["af_sarah", 1.0]],
|
||||
},
|
||||
}
|
||||
provider, spec, speed, steps = resolve_voice_target(
|
||||
"speaker:narrator", profiles,
|
||||
)
|
||||
assert provider == "kokoro"
|
||||
@@ -0,0 +1,145 @@
|
||||
"""Regression tests: domain extraction must not break webui conversion_runner.
|
||||
|
||||
These tests verify that the refactored WebUI code paths still call into the
|
||||
correct domain functions and produce the same results as the old inline logic.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from abogen.domain.voice_utils import resolve_voice_target
|
||||
from abogen.domain.pipeline_factory import PipelinePool
|
||||
|
||||
|
||||
class TestResolveVoiceTargetRegression:
|
||||
"""Verify that the domain resolve_voice_target produces the same results
|
||||
as the old closure in conversion_runner.py."""
|
||||
|
||||
def test_empty_spec_returns_kokoro_default(self):
|
||||
provider, spec, speed, steps = resolve_voice_target(
|
||||
"", {}, job_voice="af_sarah", job_tts_provider="kokoro",
|
||||
)
|
||||
assert provider == "kokoro"
|
||||
assert spec == ""
|
||||
|
||||
def test_speaker_in_profile_kokoro(self):
|
||||
profiles = {
|
||||
"narrator": {
|
||||
"provider": "kokoro",
|
||||
"voices": [["af_sarah", 0.7], ["bf_emma", 0.3]],
|
||||
},
|
||||
}
|
||||
provider, spec, speed, steps = resolve_voice_target(
|
||||
"speaker:narrator", profiles,
|
||||
)
|
||||
assert provider == "kokoro"
|
||||
assert "af_sarah" in spec
|
||||
assert speed is None
|
||||
assert steps is None
|
||||
|
||||
def test_speaker_in_profile_supertonic(self):
|
||||
profiles = {
|
||||
"narrator": {
|
||||
"provider": "supertonic",
|
||||
"voice": "F1",
|
||||
"speed": 1.2,
|
||||
"total_steps": 10,
|
||||
},
|
||||
}
|
||||
provider, spec, speed, steps = resolve_voice_target(
|
||||
"speaker:narrator", profiles,
|
||||
job_voice="M1", job_speed=1.0, job_supertonic_total_steps=5,
|
||||
)
|
||||
assert provider == "supertonic"
|
||||
assert spec == "F1"
|
||||
assert speed == 1.2
|
||||
assert steps == 10
|
||||
|
||||
def test_unknown_speaker_infers_from_spec(self):
|
||||
with patch("abogen.domain.voice_utils.get_voices", return_value=["af_sarah"]):
|
||||
provider, spec, speed, steps = resolve_voice_target(
|
||||
"af_sarah", {}, job_tts_provider="kokoro",
|
||||
)
|
||||
assert provider == "kokoro"
|
||||
assert spec == "af_sarah"
|
||||
|
||||
def test_uppercase_spec_infers_supertonic(self):
|
||||
with patch("abogen.domain.voice_utils.get_voices", return_value=["af_sarah"]):
|
||||
provider, spec, speed, steps = resolve_voice_target(
|
||||
"M1", {}, job_voice="M1",
|
||||
)
|
||||
assert provider == "supertonic"
|
||||
assert spec == "M1"
|
||||
|
||||
|
||||
class TestPipelinePoolRegression:
|
||||
"""Verify that PipelinePool behaves like the old inline get_pipeline closure."""
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline_for_job")
|
||||
@patch("abogen.domain.pipeline_factory.initialize_voice_cache")
|
||||
def test_same_provider_returns_cached_pipeline(self, _cache, mock_create):
|
||||
mock_pipeline = MagicMock()
|
||||
mock_create.return_value = mock_pipeline
|
||||
pool = PipelinePool()
|
||||
|
||||
r1 = pool.get("kokoro", "en", use_gpu=True)
|
||||
r2 = pool.get("kokoro", "en", use_gpu=True)
|
||||
assert r1 is r2
|
||||
assert mock_create.call_count == 1
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline_for_job")
|
||||
@patch("abogen.domain.pipeline_factory.initialize_voice_cache")
|
||||
def test_different_providers_get_separate_pipelines(self, _cache, mock_create):
|
||||
p1 = MagicMock(name="kokoro")
|
||||
p2 = MagicMock(name="supertonic")
|
||||
mock_create.side_effect = [p1, p2]
|
||||
pool = PipelinePool()
|
||||
|
||||
r1 = pool.get("kokoro", "en", use_gpu=True)
|
||||
r2 = pool.get("supertonic", "en", use_gpu=True)
|
||||
assert r1 is p1
|
||||
assert r2 is p2
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline_for_job")
|
||||
@patch("abogen.domain.pipeline_factory.initialize_voice_cache")
|
||||
def test_dispose_all_cleans_up(self, _cache, mock_create):
|
||||
p1 = MagicMock()
|
||||
p2 = MagicMock()
|
||||
mock_create.side_effect = [p1, p2]
|
||||
pool = PipelinePool()
|
||||
|
||||
pool.get("kokoro", "en", use_gpu=True)
|
||||
pool.get("supertonic", "en", use_gpu=True)
|
||||
pool.dispose_all()
|
||||
|
||||
p1.dispose.assert_called_once()
|
||||
p2.dispose.assert_called_once()
|
||||
assert pool._pipelines == {}
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline_for_job")
|
||||
@patch("abogen.domain.pipeline_factory.initialize_voice_cache")
|
||||
def test_voice_cache_initialized_only_once(self, mock_cache, mock_create):
|
||||
mock_create.return_value = MagicMock()
|
||||
pool = PipelinePool()
|
||||
job = MagicMock()
|
||||
|
||||
pool.get("kokoro", "en", use_gpu=True, job=job)
|
||||
pool.get("kokoro", "en", use_gpu=True, job=job)
|
||||
assert mock_cache.call_count == 1
|
||||
|
||||
@patch("abogen.domain.pipeline_factory.create_pipeline_for_job")
|
||||
@patch("abogen.domain.pipeline_factory.initialize_voice_cache")
|
||||
def test_after_dispose_voice_cache_can_reinitialize(self, mock_cache, mock_create):
|
||||
mock_create.return_value = MagicMock()
|
||||
pool = PipelinePool()
|
||||
job = MagicMock()
|
||||
|
||||
pool.get("kokoro", "en", use_gpu=True, job=job)
|
||||
assert mock_cache.call_count == 1
|
||||
|
||||
pool.dispose_all()
|
||||
assert pool._voice_cache_initialized is False
|
||||
|
||||
pool.get("kokoro", "en", use_gpu=True, job=job)
|
||||
assert mock_cache.call_count == 2
|
||||
Reference in New Issue
Block a user