Stub optional streaming test deps on Windows#7800
Conversation
Greptile SummaryThis PR adds lightweight
Confidence Score: 4/5Safe to merge — test-only change with no production code modified; both stubs cover exactly the symbols imported at collection time and the combined run passes 81 tests. The stub attributes match what streaming.py and vad_gate.py actually import from the real modules. The minor inconsistency is that test_dg_start_guard.py force-assigns to sys.modules rather than using setdefault like its companion file, which could silently replace the registered stub object mid-session when files are collected in a specific order. This is harmless today because the stubs are functionally identical and streaming.py's from-import bindings are already resolved, but it is a latent maintenance trap if the stubs ever diverge. backend/tests/unit/test_dg_start_guard.py — the hard sys.modules assignment on line 56 is the only point worth a second look. Important Files Changed
Sequence DiagramsequenceDiagram
participant pytest
participant dg_start_guard as test_dg_start_guard.py
participant backoff as test_streaming_deepgram_backoff.py
participant sys_modules as sys.modules
participant streaming as utils.stt.streaming
participant vad_gate as utils.stt.vad_gate
note over pytest: Collection phase
pytest->>dg_start_guard: collect (module-level code)
dg_start_guard->>sys_modules: setdefault(deepgram, database, ...) stubs
dg_start_guard->>sys_modules: force-write speaker_embedding stub
dg_start_guard->>streaming: import connect_to_deepgram
streaming->>sys_modules: resolve speaker_embedding stub symbols
pytest->>backoff: collect (module-level code)
backoff->>sys_modules: setdefault(deepgram, database, ...) stubs
backoff->>sys_modules: setdefault speaker_embedding stub (no-op if already set)
backoff->>sys_modules: setdefault vad stub
backoff->>streaming: import (already cached)
backoff->>vad_gate: import GatedDeepgramSocket
vad_gate->>sys_modules: resolve vad stub symbols
note over pytest: Test execution phase
pytest->>dg_start_guard: run 2 tests
pytest->>backoff: run 79 tests
Reviews (1): Last reviewed commit: "test(backend): stub optional streaming d..." | Re-trigger Greptile |
| _speaker_embedding = ModuleType('utils.stt.speaker_embedding') | ||
| _speaker_embedding.SPEAKER_MATCH_THRESHOLD = 0.45 | ||
| _speaker_embedding.async_extract_embedding_from_bytes = AsyncMock(return_value=None) | ||
| _speaker_embedding.compare_embeddings = MagicMock(return_value=0.0) | ||
| sys.modules['utils.stt.speaker_embedding'] = _speaker_embedding |
There was a problem hiding this comment.
Hard overwrite vs
setdefault inconsistency
test_streaming_deepgram_backoff.py uses sys.modules.setdefault(...) for this same stub while this file uses a bare assignment. If pytest collects the backoff file first (installing its stub), this line then replaces sys.modules['utils.stt.speaker_embedding'] with a different ModuleType object — a silent no-op in practice because streaming.py's from ... import bindings are already resolved to the earlier stub's objects, but it can confuse future maintainers and any tool that inspects sys.modules after collection. Using setdefault here too would be consistent with the existing pattern in the companion file and is also less surprising given the NOTE about avoiding pollution already present in this file.
There was a problem hiding this comment.
Addressed in 1091d01d5 by switching this stub registration to sys.modules.setdefault(...).
I also applied the same pattern to the new Parakeet diarization test stub so the PR consistently avoids replacing an existing utils.stt.speaker_embedding module during collection.
Revalidated on the Windows backend venv:
python -m pytest tests\unit\test_dg_start_guard.py tests\unit\test_streaming_deepgram_backoff.py tests\unit\test_parakeet_diarization.py tests\unit\test_parakeet_stream_session.py -q-> 100 passedpython -m black --line-length 120 --skip-string-normalization tests\unit\test_dg_start_guard.py tests\unit\test_streaming_deepgram_backoff.py tests\unit\test_parakeet_diarization.py tests\unit\test_parakeet_stream_session.py --checkpython -m py_compile tests\unit\test_dg_start_guard.py tests\unit\test_streaming_deepgram_backoff.py tests\unit\test_parakeet_diarization.py tests\unit\test_parakeet_stream_session.py
|
Expanded this PR with the same Windows lightweight-test-environment fix pattern for the Parakeet tests:
Local validation on the Windows backend venv:
|
Summary
utils.stt.speaker_embeddingin the Deepgram start-guard and streaming backoff unit tests so they do not require SciPy in a minimal backend test environment.utils.stt.vadsurface needed by the streaming backoff death-reason tests so they can importGatedDeepgramSocketwithout installingonnxruntime.test_parakeet_diarization.py, including a local cosine distance helper, so the diarization tests stay focused on speaker clustering and fallback behavior.cdistand torch buffer/model-loading surfaces intest_parakeet_stream_session.pyso Parakeet stream-session tests run in a lightweight Windows backend venv without native ML dependencies.Why
On this Windows backend venv, several streaming-related unit tests failed during collection before reaching their assertions because imports pulled in optional native/transitive dependencies:
scipythroughutils.stt.speaker_embeddingand Parakeet stream-session codeonnxruntimethroughutils.stt.vadwhen the backoff tests importGatedDeepgramSocketwebsockets/Deepgram client modules throughutils.stt.streamingin Parakeet diarization teststorchmodel-loading helpers before the stream-session tests can use their manual VAD mockThese tests exercise Deepgram connection retry/start/death-reason behavior and Parakeet diarization/session control flow, not hosted speaker embedding, ONNX VAD inference, SciPy distance kernels, or torch model loading. Local test stubs keep the unit tests focused and runnable in lightweight Windows environments.
Testing
python -m pytest tests\unit\test_dg_start_guard.py -q-> 2 passedpython -m pytest tests\unit\test_streaming_deepgram_backoff.py -q-> 79 passedpython -m pytest tests\unit\test_dg_start_guard.py tests\unit\test_streaming_deepgram_backoff.py -q-> 81 passedpython -m pytest tests\unit\test_parakeet_diarization.py tests\unit\test_parakeet_stream_session.py -q-> 19 passedpython -m pytest tests\unit\test_dg_start_guard.py tests\unit\test_streaming_deepgram_backoff.py tests\unit\test_parakeet_diarization.py tests\unit\test_parakeet_stream_session.py -q-> 100 passedpython -m black --line-length 120 --skip-string-normalization tests\unit\test_dg_start_guard.py tests\unit\test_streaming_deepgram_backoff.py tests\unit\test_parakeet_diarization.py tests\unit\test_parakeet_stream_session.py --checkpython -m py_compile tests\unit\test_dg_start_guard.py tests\unit\test_streaming_deepgram_backoff.py tests\unit\test_parakeet_diarization.py tests\unit\test_parakeet_stream_session.pygit diff --check -- backend/tests/unit/test_dg_start_guard.py backend/tests/unit/test_streaming_deepgram_backoff.py backend/tests/unit/test_parakeet_diarization.py backend/tests/unit/test_parakeet_stream_session.py