"""VLM OCR 节点真实集成测试。 复用 testdata/test_real_hav_sub.png(真实视频字幕截图,一次性入库,避免 每次测试生成)。调用本地 Ollama 服务(192.168.123.70:11434)的真实 glm-ocr 模型做 OCR。Ollama 服务或测试资产缺失时自动跳过;可用时必须执行。 """ import urllib.request from pathlib import Path import pytest from nodes.vlm import invoke from wov_sdk.models import InvokeRequest OLLAMA_HOST = "http://192.168.123.70:11434" MODEL = "glm-ocr:latest" # 测试图片(真实视频字幕帧)上应识别出的字幕文本。 EXPECTED_TEXT = "还有没有什么困扰 或者奇怪的地方吗" # 单体根目录:tests/ 的上一级。 WORKSPACE = Path(__file__).resolve().parent.parent TEST_IMAGE = WORKSPACE / "testdata" / "test_real_hav_sub.png" def _ollama_reachable() -> bool: """探测 Ollama 服务与目标模型是否可用。""" try: req = urllib.request.Request( f"{OLLAMA_HOST}/api/show", data=b'{"model": "%s"}' % MODEL.encode(), headers={"Content-Type": "application/json"}, method="POST", ) with urllib.request.urlopen(req, timeout=5) as resp: return resp.status == 200 except (urllib.error.URLError, OSError): return False @pytest.mark.integration def test_vlm_ocr_real_model(tmp_path) -> None: """复用真实字幕截图 + 真实 glm-ocr:应识别出关键字幕文本并清洗围栏垃圾。""" if not _ollama_reachable(): pytest.skip("Ollama 服务或 glm-ocr 模型不可用,跳过真实模型集成测试") if not TEST_IMAGE.is_file(): pytest.skip("缺少 testdata/test_real_hav_sub.png 测试资产,跳过集成测试") response = invoke( InvokeRequest( run_id="vlm_integration", node_instance_id="", inputs={"image_uri": str(TEST_IMAGE)}, params={"model": MODEL, "ollama_host": OLLAMA_HOST}, output_dir=str(tmp_path / "out"), ) ) assert response.status == "completed", response.error text = response.outputs["text"] print(text) # 关键字幕文本应被识别出来。注意 glm-ocr 在此图上存在已知重复循环 bug: # 识别出正确文本后可能继续循环输出,因此用"包含"断言而非全等, # 下游 subtitle-ocr 的 max_result_chars 守卫会拦截超长输出。 assert EXPECTED_TEXT in text # 围栏垃圾(```)不应出现在输出里。 assert "```" not in text