#!/usr/bin/env python3 """测试 easyocr_worker 子进程 ready 握手 + OCR 请求往返。 模拟 monitor.py 父进程行为: 1. 启动 easyocr_worker.py 子进程 2. 等待 {"ready": true} 握手(90s 预算,覆盖 3-10s torch+模型加载) 3. 发一张含中文的测试图,验证 OCR 结果 """ import json import subprocess import sys import os import base64 import io import threading from queue import Queue, Empty from PIL import Image, ImageDraw, ImageFont def main(): # ── 1. 生成测试图(白底黑字中文) ── img = Image.new("RGB", (500, 120), "white") d = ImageDraw.Draw(img) try: font = ImageFont.truetype("C:/Windows/Fonts/msyh.ttc", 32) except Exception: font = ImageFont.load_default() d.text((20, 40), "你好世界 测试123", fill="black", font=font) buf = io.BytesIO() img.save(buf, format="PNG") img_b64 = base64.b64encode(buf.getvalue()).decode() print(f"[test] 测试图生成 OK, b64长度={len(img_b64)}", flush=True) worker_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "easyocr_worker.py" ) print(f"[test] worker路径: {worker_path}", flush=True) # ── 2. 启动子进程 ── proc = subprocess.Popen( [sys.executable, "-u", worker_path], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1, ) print(f"[test] 子进程已启动 pid={proc.pid}", flush=True) def _read_line(pipe, q): try: q.put(pipe.readline()) except Exception as e: q.put(f"__READ_ERR__:{e}") # ── 3. 等待 ready 握手(90s 预算) ── q = Queue() t = threading.Thread(target=_read_line, args=(proc.stdout, q), daemon=True) t.start() try: line = q.get(timeout=90) except Empty: print("[test] FAIL: ready 握手 90s 超时", flush=True) proc.kill() return 1 print(f"[test] 握手响应: {line.strip()!r}", flush=True) try: payload = json.loads(line) assert payload.get("ready") is True, f"非 ready 响应: {line!r}" except Exception as e: err = proc.stderr.read()[:1500] print(f"[test] FAIL: 握手解析异常 {e}, stderr={err!r}", flush=True) proc.kill() return 1 print("[test] PASS: ready 握手成功", flush=True) # ── 4. 发送 OCR 请求 ── proc.stdin.write(json.dumps({"img": img_b64}) + "\n") proc.stdin.flush() q2 = Queue() t2 = threading.Thread(target=_read_line, args=(proc.stdout, q2), daemon=True) t2.start() try: rline = q2.get(timeout=30) except Empty: print("[test] FAIL: OCR 请求 30s 超时", flush=True) proc.kill() return 1 print(f"[test] OCR 响应: {rline.strip()!r}", flush=True) try: res = json.loads(rline) assert res.get("ok"), f"OCR 失败: {res}" print(f"[test] OCR 文本: {res['text']!r}", flush=True) assert "你好" in res["text"] or "测试" in res["text"], "识别结果缺中文" except Exception as e: print(f"[test] FAIL: OCR 结果异常 {e}", flush=True) proc.kill() return 1 # ── 5. 诊断信息 ── proc.kill() proc.wait(timeout=3) print("[test] PASS: easyocr 子进程 ready 握手 + OCR 请求往返全部成功", flush=True) return 0 if __name__ == "__main__": sys.exit(main())