Prhub

#23305 [misc] CI hygiene: enforce __main__ entry, drop silent-skipped tests, fix rerun-test protoc

原始 PR 作者 hnyls2002 合并时间 2026-04-21 12:16 文件变更 19 提交数 7 评论 10 代码增减 +102 / -3169

执行摘要

CI 卫生:强制 __main__ 入口,删除静默跳过测试,修复 rerun-test

CI runner通过python3 file.py -f调用测试文件,但pytest风格文件若缺少if __name__ == "__main__":块,则仅import后退出0,测试函数从未执行,CI却显示绿色。此问题容易在review中漏掉,导致测试覆盖率虚高。PR body明确指出了根因和影响。

该PR值得精读,尤其关注ci_register.py中AST验证的实现模式,这是一种轻量级且有效的CI防护手段。设计决策:使用静态分析而非运行时检查,避免了性能开销。同时,删除测试文件时保留原作者信息和恢复路径,体现了良好的工程实践。

讨论亮点

fxmarty-amd: "Why are the tests removed? Does it not mean that some part of sglang codebase still exist, but are simply untested?"
作者回复:这些测试文件从未在CI中实际运行,删除是临时措施,后续PR会恢复并正确注册。团队已知此风险,并计划跟进修复。

实现拆解

  1. AST健全性检查:在python/sglang/test/ci/ci_register.py中添加_is_main_block_with_call函数,使用AST解析每个注册文件,检查是否存在调用unittest.main()pytest.main()的可执行__main__块。collect_tests增加sanity_check=True参数,在收集测试时验证所有非disabled文件,未通过则报错。
  2. 修复静默跳过文件:为6个文件添加__main__块和必要的fixture修复(如test_streaming_session_unit.py_FakeReq.finished_len = None),使其在CI中实际执行。同时从test_dump_comparator.py中删除依赖GPU的TestMainBasic子集。
  3. 删除不可修复的跳过文件:删除9个因缺少__main__、依赖特定硬件或性能断言而长期静默跳过的测试文件,包括test_bnb.pytest_int4fp8_moe.pytest_zimage_turbo.pypython/sglang/jit_kernel/tests/test_dependency.pytest_repeat_interleave.pytest_glm47_moe_detector.pytest_model_hooks.pytest_mrope.pytest_patch_embed_perf.py。PR body标注了原始作者,欢迎后续修复后重新添加。
  4. 修复rerun-test CPU job:在.github/workflows/rerun-test.yml中添加Install protocInstall Rust toolchain步骤,与pr-test.yml保持一致,避免sglang-grpc编译时因缺少protoc而失败。
文件 模块 状态 重要度
python/sglang/test/ci/ci_register.py 测试注册 modified 7.07
test/registered/unit/mem_cache/test_streaming_session_unit.py 流式会话测试 modified 5.92
.github/workflows/rerun-test.yml CI 工作流 modified 5.0

关键符号

_is_main_block_with_call ut_parse_one_file test_streaming_release_kv_cache_defers_tail_free

关键源码片段

python/sglang/test/ci/ci_register.py test-coverage

核心变更:添加 AST 健全性检查函数 `_is_main_block_with_call`,在 `collect_tests` 中验证每个注册文件的 `__main__` 块存在性,是修复静默跳过漏洞的关键。

def _is_main_block_with_call(filepath: str) -> bool:
    """检查文件是否包含调用unittest.main()或pytest.main()的可执行__main__块。"""
    with open(filepath) as f:
        tree = ast.parse(f.read())
    # 遍历顶层节点,寻找 if __name__ == "__main__": 块
    for node in ast.walk(tree):
        if isinstance(node, ast.If) and _is_name_main(node):
            # 在 if 块内查找函数调用
            for child in ast.walk(node):
                if isinstance(child, ast.Call):
                    func_name = _get_func_name(child)
                    if func_name in {"unittest.main", "pytest.main"}:
                        return True
    return False# 在 collect_tests 中调用
if sanity_check and registry_files:
    for filepath in registry_files:
        if not _is_main_block_with_call(filepath):
            raise RuntimeError(f"{filepath} 缺少可执行的__main__块,将导致CI静默跳过")

评论区精华

删除测试文件是否导致功能未经测试 question

fxmarty-amd 质疑删除测试文件后相关代码将不再被测试,担心质量下降。

结论:作者确认这些测试从未在 CI 中实际运行,删除是临时措施,后续 PR 会恢复并正确注册。团队已知风险。 · 已解决

风险与影响

测试覆盖缺失:删除的9个测试文件对应功能(如BNB量化、MRoPE、模型钩子等)暂时失去CI覆盖,直到后续PR恢复。但原始代码从未在CI中执行,因此实际无回归风险。CI工作流修复rerun-test.yml的protoc修复确保CPU重跑任务不再因编译失败而阻塞,但若依赖版本变化可能仍需调整。

对CI系统:显著提升测试覆盖率真实性,消除静默跳过漏洞。未来所有注册测试文件必须包含可执行__main__块,否则CI会报错。对开发者:需确保新增测试文件遵循该规范,review时注意检查。对用户:无直接影响。对团队:降低了测试维护成本,但需在后续PR中恢复已删除测试文件。

测试覆盖暂时缺失 CI 工作流修复

关联 Issue

#22897 streaming session: trim spec v2 overshoot in cache_finished_req

完整报告

参与讨论