diff --git a/tests/tools/test_voice_mode.py b/tests/tools/test_voice_mode.py index 1d35c486..001aae60 100644 --- a/tests/tools/test_voice_mode.py +++ b/tests/tools/test_voice_mode.py @@ -61,6 +61,16 @@ def mock_sd(monkeypatch): # ============================================================================ class TestDetectAudioEnvironment: + @pytest.fixture(autouse=True) + def _isolate_container_detection(self, monkeypatch): + """Default `is_container` to False so tests don't inherit the host + runner's container state (e.g. CI itself runs inside Docker, where + the production `is_container()` returns True via /.dockerenv or + /proc/1/cgroup and silently appended a 'Running inside Docker' + warning to every scenario). Individual tests opt in via setattr. + """ + monkeypatch.setattr("tools.voice_mode.is_container", lambda: False) + def test_clean_environment_is_available(self, monkeypatch): """No SSH, Docker, or WSL — should be available.""" monkeypatch.delenv("SSH_CLIENT", raising=False) @@ -85,6 +95,20 @@ class TestDetectAudioEnvironment: assert result["available"] is False assert any("SSH" in w for w in result["warnings"]) + def test_docker_container_blocks_voice(self, monkeypatch): + """Running inside a Docker/Podman container should block voice mode.""" + monkeypatch.delenv("SSH_CLIENT", raising=False) + monkeypatch.delenv("SSH_TTY", raising=False) + monkeypatch.delenv("SSH_CONNECTION", raising=False) + monkeypatch.setattr("tools.voice_mode.is_container", lambda: True) + monkeypatch.setattr("tools.voice_mode._import_audio", + lambda: (MagicMock(), MagicMock())) + + from tools.voice_mode import detect_audio_environment + result = detect_audio_environment() + assert result["available"] is False + assert any("Docker container" in w for w in result["warnings"]) + def test_wsl_without_pulse_blocks_voice(self, monkeypatch, tmp_path): """WSL without PULSE_SERVER should block voice mode.""" monkeypatch.delenv("SSH_CLIENT", raising=False) diff --git a/tools/voice_mode.py b/tools/voice_mode.py index 66ecb242..a940957c 100644 --- a/tools/voice_mode.py +++ b/tools/voice_mode.py @@ -49,7 +49,7 @@ def _audio_available() -> bool: return False -from hermes_constants import is_termux as _is_termux_environment +from hermes_constants import is_container, is_termux as _is_termux_environment def _voice_capture_install_hint() -> str: @@ -103,7 +103,6 @@ def detect_audio_environment() -> dict: warnings.append("Running over SSH -- no audio devices available") # Docker/Podman container detection - from hermes_constants import is_container if is_container(): warnings.append("Running inside Docker container -- no audio devices")