Validate complete speech decode windows and retain rejected ASR output

This commit is contained in:
karl committed 2026-10-13 09:03:20 +02:00
1 parent e28e20af38
commit af6ce29125
4 files changed
+146 -21

No files matched your search

+43 -1
View File
@@ -4,11 +4,53 @@ from pathlib import Path
import unittest
import tempfile
import sys
from run import segments, run_owned
import os
import wave
from run import segments, run_owned, recognized_window, decode_command, decoded_frames
from score import score
class ContractTests(unittest.TestCase):
@unittest.skipUnless(os.environ.get("SEARCHI_TEST_FFMPEG"), "Requires verified CPU FFmpeg")
def test_actual_ffmpeg_full_window_and_partial_tail_sample_coverage(self):
ffmpeg = Path(os.environ["SEARCHI_TEST_FFMPEG"])
with tempfile.TemporaryDirectory() as parent:
scratch = Path(parent)
for rate in [44100, 48000]:
with self.subTest(rate=rate):
source = scratch / f"source-{rate}.wav"
with wave.open(str(source), "wb") as audio:
audio.setnchannels(1)
audio.setsampwidth(2)
audio.setframerate(rate)
audio.writeframes(b"\x00\x00" * (rate * 31))
for offset, length, expected in [(0, 30000, 480000), (30000, 1000, 16000)]:
output = scratch / "decoded.wav"
run_owned(decode_command(ffmpeg, source, offset, length, output), scratch,
"samplecoverage", [(output, 970000)], 30)
self.assertEqual(decoded_frames(output, length), expected)
def test_threefold_truncation_rejected(self):
with tempfile.TemporaryDirectory() as parent:
path = Path(parent) / "truncated.wav"
with wave.open(str(path), "wb") as audio:
audio.setnchannels(1)
audio.setsampwidth(2)
audio.setframerate(16000)
audio.writeframes(b"\x00\x00" * 160000)
with self.assertRaises(ValueError):
decoded_frames(path, 30000)
def test_invalid_actual_json_is_retained_and_next_window_parses(self):
invalid = {"transcription": [{"offsets": {"from": 0, "to": 30010}, "text": "synthetic test"}]}
valid = {"transcription": [{"offsets": {"from": 0, "to": 10}, "text": "synthetic test"}]}
rows = [recognized_window(raw, offset, 30000, 1, 2) for raw, offset in [(invalid, 0), (valid, 30000)]]
self.assertEqual(rows[0]["actual_whisper_json"], invalid)
self.assertEqual(rows[0]["segments"], [])
self.assertIn("validation_error", rows[0])
self.assertNotIn("validation_error", rows[1])
self.assertEqual(rows[1]["segments"][0]["start_ms"], 30000)
def test_timeout_and_output_overflow_terminate_owned_child(self):
for name, code, error, timeout in [
("timeout", "import time; time.sleep(10)", TimeoutError, 0.1),