"""Hardware-free tests, and a deliberately fake child for native IPC tests. Run: python3 -m unittest discover -s tests -p test_worker.py Native fixture: python3 tests/test_worker.py --model ok --threads 2 --clip-dir DIR """ import os import io import contextlib from pathlib import Path import struct import subprocess import sys import tempfile import unittest from unittest.mock import patch sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "python")) from frameyap import worker class FakeModel: def __init__(self): self.calls = [] def transcribe(self, audio, sample_rate): self.calls.append((audio, sample_rate)) return {"text": "héllo 世界"} def fake_child(): # This branch intentionally never imports numpy, torch, moondream or a mic. import argparse parser = argparse.ArgumentParser() parser.add_argument("--model", required=True) parser.add_argument("--threads", required=True) parser.add_argument("--clip-dir", required=True) parser.add_argument("--advanced-debug", action="store_true") args = parser.parse_args() if args.model in ("fail", "missing-model", "missing-import"): worker.send_frame(1, b"F", {"fail": b"", "missing-model": b"M", "missing-import": b"I"}[args.model]) return if args.model == "crash": return if args.model == "hang-warm": import time time.sleep(130) return worker.send_frame(1, b"Y") requests = 0 while True: msg = worker.read_frame(0) if msg is None: return if args.model == "hang": import time time.sleep(70) continue assert len(msg) == 9 and msg[:1] == b"T" requests += 1 if args.advanced_debug and args.model in ("debug-output", "debug-spam"): os.write(2, b"private debug fixture\n") if args.model == "debug-spam": for _ in range(1100): os.write(2, b"x" * 4096) clip = Path(args.clip_dir) / "clip.raw" assert clip.stat().st_size == 3200 * 4 ident = msg[1:9] if args.model == "stale": ident = struct.pack("= 0: os.close(in_w) os.close(out_r) os.close(out_w) def test_safe_error_labels_and_retry(self): class PrivateError(Exception): def __str__(self): raise AssertionError("exception messages must not be accessed") self.assertEqual(worker.safe_request_error("PRIVATE PATH", PrivateError()), b"transcription failed [unknown: Exception]") cases = [ (OSError("PRIVATE AUDIO"), {"text": "ignored"}, b"audio: OSError"), (None, RuntimeError("PRIVATE TRANSCRIPT"), b"inference: RuntimeError"), (None, PrivateError(), b"inference: Exception"), (None, {}, b"response: KeyError"), (None, {"text": 4}, b"response: TypeError"), (None, {"text": "\ud800"}, b"response: UnicodeError"), ] for audio_error, response, label in cases: with self.subTest(label=label), tempfile.TemporaryDirectory() as path: class Model: count = 0 def transcribe(self, **kwargs): self.count += 1 if self.count > 1: return {"text": "retry"} if isinstance(response, Exception): raise response return response model = Model() in_r, in_w = os.pipe() out_r, out_w = os.pipe() try: worker.send_frame(in_w, b"T", struct.pack("= 0: os.close(in_w) os.close(out_r); os.close(out_w) def test_debug_is_explicit_and_protocol_stays_safe(self): for enabled in (False, True): with self.subTest(enabled=enabled), tempfile.TemporaryDirectory() as path: class Failing: def transcribe(self, **kwargs): raise RuntimeError("PRIVATE EXCEPTION DETAIL") in_r, in_w = os.pipe(); out_r, out_w = os.pipe() captured = io.StringIO() try: worker.send_frame(in_w, b"T", struct.pack("= 0: os.close(in_w) os.close(out_r); os.close(out_w) def test_debug_fd_output_never_corrupts_protocol(self): program = ''' import os, sys from frameyap import worker class Model: def transcribe(self, **kwargs): os.write(1, b"native stdout fixture\\n") os.write(2, b"native stderr fixture\\n") return {"text": "private fixture transcript"} worker.load_model = lambda *args: Model() worker.read_clip = lambda *args: [] sys.exit(worker.main(sys.argv[1:])) ''' request = b"T" + struct.pack("= 0: os.close(in_w) os.close(out_r) os.close(out_w) if __name__ == "__main__": if "--clip-dir" in sys.argv: fake_child() else: unittest.main()