feat: Phase 1 - cobol_testgen API + quality fields + retry handler

This commit is contained in:
hangshuo652
2026-06-18 15:47:35 +08:00
parent 7fcdb41a85
commit 097530b036
6 changed files with 1845 additions and 0 deletions
+82
View File
@@ -0,0 +1,82 @@
"""
分层重试 — 部署在 orchestrator 调用者层(main.py / worker.py)。
"""
import logging
import os
from typing import Callable
from data.diff_result import VerificationRun
logger = logging.getLogger(__name__)
HEALING_FIXES = {
"compile_error": {
"detect": lambda log: "not found" in (log or "").lower(),
"fix": lambda: _try_set_env(
"COB_LIBRARY_PATH",
"D:\\360安全浏览器下载\\GC32-BDB-SP1-rename-7z-to-exe\\lib\\gnucobol",
),
},
"s0c7": {
"detect": lambda log: "S0C7" in (log or ""),
"fix": lambda: logger.warning("[Retry] S0C7 需要人工修正测试数据中的数值字段"),
},
}
def _try_set_env(key: str, value: str) -> None:
"""尝试设置环境变量(如果当前未设置)"""
if not os.environ.get(key):
os.environ[key] = value
logger.info(f"[Retry] 已设置环境变量 {key}={value}")
else:
logger.info(f"[Retry] {key} 已存在,跳过")
class RetryHandler:
def __init__(self, max_heal: int = 2, max_simple: int = 3):
self.max_heal = max_heal
self.max_simple = max_simple
self.heal_count = 0
self.simple_count = 0
self.history: list[VerificationRun] = []
def run(self, pipeline_fn: Callable[[], VerificationRun]) -> VerificationRun:
while (self.heal_count + self.simple_count) < (self.max_heal + self.max_simple):
vr = pipeline_fn()
self.history.append(vr)
if vr.status in ("PASS", "QUALITY_WARN"):
vr.heal_retry = self.heal_count
vr.simple_retry = self.simple_count
vr.total_retry = self.heal_count + self.simple_count
return vr
if vr.status in ("BLOCKED", "ERROR") and self.heal_count < self.max_heal:
build_log = vr.debug.get("cobol_build", {}).get("log", "")
healed = False
for name, fix_def in HEALING_FIXES.items():
if fix_def["detect"](build_log):
fix_def["fix"]()
self.heal_count += 1
healed = True
logger.info(
f"[Retry] 自愈修复应用: {name} "
f"(heal_retry={self.heal_count})"
)
break
if healed:
continue
self.simple_count += 1
logger.info(f"[Retry] 朴素重试 (simple_retry={self.simple_count})")
logger.error("[Retry] 重试次数超过上限,标记 FATAL")
vr = self.history[-1] if self.history else VerificationRun(
status="FATAL", exit_code=4
)
vr.status = "FATAL"
vr.exit_code = 4
vr.heal_retry = self.heal_count
vr.simple_retry = self.simple_count
vr.total_retry = self.heal_count + self.simple_count
return vr