Files
cobol-java-v3/tests/hina/test_retry.py
T
hangshuo652 bc1d56d1a4 feat: Phase 2 complete — 13 Phases of COBOL type classification and test benchmark
P0.6: gcov infrastructure
P1: extract_structure output expansion (11 new feature fields)
P2: Confusion group rule engine (8 pairs + contradiction + backtrack)
P3: 4-factor confidence calculation + quality gate update
P4: 33+2 COBOL program type test samples (22 files, 7 categories)
P5: parametrized/ test data generation engine
P6: japanese_data.py lookup tables
P7-10: Type-specific test suites (~159 parametrized tests)
P11: Full classification pipeline (classify_program) + orchestrator integration
P12: Documentation (module-interfaces, test-plan v3.0, coverage-matrix)

Architecture decisions:
- classification_pipeline/ merged to hina/pipeline/
- parametrized/ as independent module
- japanese_data.py as root-level file
- hina/__all__ only exports classify_program()

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-19 23:51:55 +08:00

116 lines
3.3 KiB
Python

"""RH-01~07: Retry Handler — 分层重试 + heal/simple 分离"""
import sys, os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
from hina.retry import RetryHandler, HEALING_FIXES
from data.diff_result import VerificationRun
def _vr(status="PASS", build_log=""):
vr = VerificationRun(status=status, program="TEST")
if build_log:
vr.debug = {"cobol_build": {"log": build_log}}
return vr
def test_immediate_pass():
"""RH-01: 1次 PASS → heal=0, simple=0"""
h = RetryHandler()
vr = h.run(lambda: _vr("PASS"))
assert vr.status == "PASS"
assert vr.heal_retry == 0
assert vr.simple_retry == 0
def test_heal_recovery():
"""RH-02: BLOCKED(not found) → heal修复→PASS"""
calls = [0]
def fn():
calls[0] += 1
if calls[0] == 1:
return _vr("BLOCKED", build_log="file not found: libcob.so")
return _vr("PASS")
h = RetryHandler()
vr = h.run(fn)
assert vr.status == "PASS"
assert vr.heal_retry >= 1
assert vr.simple_retry == 0
def test_simple_retry():
"""RH-03: BLOCKED→重试→PASS (无 heal 匹配)"""
calls = [0]
def fn():
calls[0] += 1
if calls[0] == 1:
return _vr("BLOCKED", build_log="some random error")
return _vr("PASS")
h = RetryHandler()
vr = h.run(fn)
assert vr.status == "PASS"
assert vr.simple_retry >= 1
def test_max_retries_exceeded():
"""RH-04: 全部失败 → FATAL"""
h = RetryHandler(max_heal=1, max_simple=1)
vr = h.run(lambda: _vr("BLOCKED"))
assert vr.status == "FATAL"
assert vr.exit_code == 4
def test_quality_warn_no_retry():
"""RH-05: QUALITY_WARN → 立即返回 不重试"""
h = RetryHandler()
vr = h.run(lambda: _vr("QUALITY_WARN"))
assert vr.status == "QUALITY_WARN"
assert vr.heal_retry == 0
assert vr.simple_retry == 0
def test_heal_fails_then_simple():
"""RH-06: heal 尝试但仍然 BLOCKED → 回退 simple"""
calls = [0]
def fn():
calls[0] += 1
return _vr("BLOCKED", build_log="file not found: libcob.so")
h = RetryHandler(max_heal=2, max_simple=2)
vr = h.run(fn)
assert vr.status == "FATAL"
# 应已消耗所有 heal+simple
assert vr.heal_retry + vr.simple_retry >= 1
def test_concurrent_count_separation():
"""RH-07: heal 和 simple 计数互不影响"""
h = RetryHandler(max_heal=2, max_simple=2)
calls = [0, False] # [count, callable flag]
def fn():
calls[0] += 1
if calls[0] == 1:
return _vr("BLOCKED", build_log="file not found: libcob.so")
return _vr("PASS")
h._try_set_env = lambda k, v: None # no-op fix
# Mock fix to succeed on first heal
original_fix = HEALING_FIXES["compile_error"]["fix"]
HEALING_FIXES["compile_error"]["fix"] = lambda: None
try:
vr = h.run(fn)
assert vr.heal_retry >= 0
assert vr.simple_retry >= 0
# heal 和 simple 的计数不会混淆
finally:
HEALING_FIXES["compile_error"]["fix"] = original_fix
def test_history_records():
"""所有 VR 被记录到 history"""
h = RetryHandler(max_heal=0, max_simple=2)
results = []
def fn():
vr = _vr("BLOCKED") if len(results) < 2 else _vr("PASS")
results.append(vr)
return vr
h.run(fn)
assert len(h.history) >= 2