fix: assert global error presence for fault-mixed soak scenarios
This commit is contained in:
@@ -242,3 +242,12 @@ class TestLiveInvariantsAndCaps:
|
|||||||
inv_fault_errors_present(rows, fault_source_names=[]) # 未配故障源直接通过
|
inv_fault_errors_present(rows, fault_source_names=[]) # 未配故障源直接通过
|
||||||
with pytest.raises(AssertionError):
|
with pytest.raises(AssertionError):
|
||||||
inv_fault_errors_present([_row("c")], fault_source_names=["bad_1"])
|
inv_fault_errors_present([_row("c")], fault_source_names=["bad_1"])
|
||||||
|
|
||||||
|
|
||||||
|
class TestAnyErrors:
|
||||||
|
def test_presence_and_absence(self):
|
||||||
|
from tools.soak.scoreboard import inv_any_errors
|
||||||
|
|
||||||
|
inv_any_errors([_row("a", error="TransientError: x"), _row("b")])
|
||||||
|
with pytest.raises(AssertionError, match="故障未生效"):
|
||||||
|
inv_any_errors([_row("c")])
|
||||||
|
|||||||
@@ -198,12 +198,11 @@ def _scoreboard(args: argparse.Namespace, env: dict[str, str]) -> None:
|
|||||||
asyncio.run(_live_checks(args, env, verdicts))
|
asyncio.run(_live_checks(args, env, verdicts))
|
||||||
else:
|
else:
|
||||||
verdicts.append(("记账归零/gate 可再准入", "SKIP — memory 后端跨进程不可查"))
|
verdicts.append(("记账归零/gate 可再准入", "SKIP — memory 后端跨进程不可查"))
|
||||||
# 不变量 2c: P5/P6 且配置了故障源 → 故障必须真实发生
|
# 不变量 2c: P5/P6 故障混编池下错误必须真实发生。紧闸源被限流闸跳过
|
||||||
|
# 不产错误行、故障名单无法从配置泛化推断 → 钉全局存在性,按源归因
|
||||||
|
# 交报告"错误分布"人工核对(findings §4 条 2 的比例校准留待 P5 常态化)
|
||||||
if args.scenario in ("P5", "P6"):
|
if args.scenario in ("P5", "P6"):
|
||||||
fault_names = [
|
_check("故障混编生效(P5/P6)", sb.inv_any_errors, rows)
|
||||||
name for name in rpm_conf if rpm_conf[name] <= 10
|
|
||||||
] # 紧闸源;坏 key/黑洞源由错误分布人工核对(findings §4 条 2 校准留待 P5 实跑)
|
|
||||||
_check("故障混编生效(P5/P6)", sb.inv_fault_errors_present, rows, fault_source_names=fault_names)
|
|
||||||
rate = sb.structured_success_rate(rows, session_suffix="-p3")
|
rate = sb.structured_success_rate(rows, session_suffix="-p3")
|
||||||
verdicts.append(("P3 结构化成功率", f"{rate:.3f}(基线首跑建立)"))
|
verdicts.append(("P3 结构化成功率", f"{rate:.3f}(基线首跑建立)"))
|
||||||
report = sb.render_report(args.run_id, rows, verdicts)
|
report = sb.render_report(args.run_id, rows, verdicts)
|
||||||
|
|||||||
@@ -179,3 +179,12 @@ def inv_fault_errors_present(rows: list[Row], *, fault_source_names: list[str])
|
|||||||
return
|
return
|
||||||
fault_errors = [r for r in rows if r.get("error") and r["source_name"] in fault_source_names]
|
fault_errors = [r for r in rows if r.get("error") and r["source_name"] in fault_source_names]
|
||||||
assert fault_errors, f"故障源 {fault_source_names} 零错误行——故障混编未生效"
|
assert fault_errors, f"故障源 {fault_source_names} 零错误行——故障混编未生效"
|
||||||
|
|
||||||
|
|
||||||
|
def inv_any_errors(rows: list[Row]) -> None:
|
||||||
|
"""不变量 2c 的兜底形态(P5/P6): 故障源混编池下错误行必然存在。
|
||||||
|
|
||||||
|
紧闸源被限流闸跳过不产错误行,故障名单无法从配置泛化推断——按源归因
|
||||||
|
交报告"错误分布"人工核对;此处只钉全局存在性。
|
||||||
|
"""
|
||||||
|
assert any(r.get("error") for r in rows), "P5/P6 故障混编池零错误行——故障未生效"
|
||||||
|
|||||||
Reference in New Issue
Block a user