"""守卫测试:防止旧逐题(per-question)路径在 unit 化迁移后复活或残留。 Task 3-10 已将三池切分、分批整锁、pair-level 聚合、gate 块基线缓存等契约 从"逐题 qid"迁移到"QuestionUnit 整锁"。本测试对迁移后的源码做静态锚点扫描, 锁住四个不可回退的语义标志:一旦有人误引入旧逐题分桶 / 逐题 gate 缓存 / 逐题 累加 / 未走 unit 化的代码,断言即刻失败。 覆盖模块:batching(分批)、pools(三池切分)、inference(pair 聚合)、 app.harness.validate(gate 块核心残留点)。 """ import inspect import re from app.harness import batching, inference, pools def test_no_parallel_perquestion_split_helpers(): """契约迁 unit 后,不得残留会拆 pair 的旧逐题分批 / 切分 / gate 块路径。""" from app.harness import validate as hvalidate # gate 块真实路径 src = ( inspect.getsource(batching) + inspect.getsource(pools) + inspect.getsource(hvalidate) + inspect.getsource(inference) # 覆盖 T6 pair-level 聚合路径 ) # 旧逐题分桶残留:正确率不应按 qid 直接取 assert "correctness.get(qid)" not in src, "batching 仍有逐题分桶残留" # gate 块残留探测:validate.py 是逐题 gate 核心残留点。 # 逐个 baseline_cache.get(...) 调用点都必须按 unit_id 键控、不得回退到裸 qid/question_id, # 否则视为逐题残留复活。跨行实参用容纳换行的懒惰匹配抓全整个调用文本。 baseline_get_calls = re.findall(r"baseline_cache\.get\((?:[^()]|\n)*?\)", src) # 兜底:正则必须真抓到 validate.py 的调用,否则 for 空转又成 tautology assert baseline_get_calls, "守卫失效:未抓到任何 baseline_cache.get 调用" for call in baseline_get_calls: assert "unit_id" in call, f"baseline_cache.get 未按 unit_id 键控(逐题残留): {call}" assert "qid" not in call and "question_id" not in call, ( f"baseline_cache.get 回退逐题 qid: {call}" ) # 逐题累加残留:n_used 不应按逐题 chunk 长度累加(应按 unit) assert "n_used += len(chunk)" not in src, "validate n_used 仍逐题累加(应按 unit)" # 正向 unit 化探测:pools/batching/validate/inference 已走 unit 契约 assert src.count("build_units") >= 1, "pools/batching/validate/inference 未走 unit 化聚合"