feat: Phase 1 - cobol_testgen API + quality fields + retry handler
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user