Speculative fix for a sometimes speech crash bug.
This commit is contained in:
@@ -26,6 +26,14 @@ def build_output_manager():
|
||||
"SoundDriver": sound_driver,
|
||||
"SpeechDriver": speech_driver,
|
||||
"DebugManager": Mock(write_debug_out=Mock()),
|
||||
"TextManager": Mock(
|
||||
replace_head_lines=Mock(side_effect=lambda text: text)
|
||||
),
|
||||
"PunctuationManager": Mock(
|
||||
proceed_punctuation=Mock(
|
||||
side_effect=lambda text, _ignore_punctuation: text
|
||||
)
|
||||
),
|
||||
},
|
||||
}
|
||||
return output_manager, sound_driver, speech_driver
|
||||
@@ -122,6 +130,40 @@ def test_interrupt_output_waits_only_briefly_for_slow_cancel():
|
||||
output_manager.interrupt_thread.join(timeout=1.0)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_cancel_speech_skips_when_speech_driver_is_busy():
|
||||
output_manager, _sound_driver, speech_driver = build_output_manager()
|
||||
output_manager.speech_driver_lock_timeout = 0.01
|
||||
output_manager.speech_driver_lock.acquire()
|
||||
|
||||
try:
|
||||
start_time = time.monotonic()
|
||||
output_manager.cancel_speech()
|
||||
elapsed = time.monotonic() - start_time
|
||||
finally:
|
||||
output_manager.speech_driver_lock.release()
|
||||
|
||||
assert elapsed < 0.2
|
||||
speech_driver.cancel.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_speak_text_drops_speech_when_cancel_holds_driver_lock():
|
||||
output_manager, _sound_driver, speech_driver = build_output_manager()
|
||||
output_manager.speech_driver_lock_timeout = 0.01
|
||||
output_manager.speech_driver_lock.acquire()
|
||||
|
||||
try:
|
||||
start_time = time.monotonic()
|
||||
output_manager.speak_text("hello", interrupt=False, flush=False)
|
||||
elapsed = time.monotonic() - start_time
|
||||
finally:
|
||||
output_manager.speech_driver_lock.release()
|
||||
|
||||
assert elapsed < 0.2
|
||||
speech_driver.speak.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_key_interrupt_command_uses_nonblocking_interrupt():
|
||||
module = load_key_interrupt_module()
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import json
|
||||
import time
|
||||
|
||||
from fenrirscreenreader.core import remoteInstanceRegistry
|
||||
|
||||
|
||||
def test_write_instance_prunes_stale_registry_files(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
remoteInstanceRegistry, "get_registry_dir", lambda: str(tmp_path)
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
remoteInstanceRegistry,
|
||||
"process_exists",
|
||||
lambda pid: pid == 456,
|
||||
)
|
||||
|
||||
stale_instance = tmp_path / "123.json"
|
||||
stale_instance.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"pid": 123,
|
||||
"updated_at": time.time(),
|
||||
}
|
||||
)
|
||||
+ "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
invalid_instance = tmp_path / "invalid.json"
|
||||
invalid_instance.write_text("not json\n", encoding="utf-8")
|
||||
|
||||
remoteInstanceRegistry.write_instance({"pid": 456})
|
||||
|
||||
assert not stale_instance.exists()
|
||||
assert not invalid_instance.exists()
|
||||
assert (tmp_path / "456.json").exists()
|
||||
Reference in New Issue
Block a user