# PR #21338 完整报告

- 仓库：`sgl-project/sglang`
- 标题：[CI] Fix resource leak when setUpClass fails
- 合并时间：2026-03-26 07:22
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/21338

---

# 执行摘要
此 PR 修复了 Python unittest 中 setUpClass 失败时 tearDownClass 被跳过导致的资源泄漏问题，通过修改 CustomTestCase 添加自动清理机制，并更新文档推广防御性写法。变更影响所有测试类，提升 CI 稳定性，降低端口冲突风险。

# 功能与动机
**动机**：这是一个预防性修复，旨在解决 CI 中潜在的资源泄漏问题。当测试的 setUpClass 中途失败（如服务器启动超时或内存不足）时，Python 的 unittest 框架会跳过 tearDownClass，导致已分配的资源（如进程、端口）无法释放，可能引发后续测试的端口冲突。PR body 中强调：“这可以防止级联端口冲突”。

# 实现拆解
实现分为三个关键部分：

| 模块 | 文件 | 关键变更 | 说明 |
|------|------|----------|------|
| 测试工具 | `python/sglang/test/test_utils.py` | 在 `CustomTestCase` 类中添加 `__init_subclass__` 方法 | 包装 `setUpClass`，在异常时自动调用 `tearDownClass`，并处理多级继承的标记检查。代码片段：
```python
def safe_setUpClass(klass, _orig=setup):
    try:
        _orig.__func__(klass)
    except Exception:
        try:
            klass.tearDownClass()
        except Exception:
            pass
        raise
```
| 文档 | `.claude/skills/write-sglang-test/SKILL.md` | 更新测试编写指南 | 添加规则：始终使用 `CustomTestCase`，`tearDownClass` 必须防御性（使用 `hasattr` 检查）。 |
| 示例测试 | `test/registered/hicache/test_hicache_storage_file_backend.py` | 修改 `tearDownClass` 方法 | 使用 `hasattr` 检查 `cls.process` 和 `cls.temp_dir`，确保资源存在再清理。 |

# 评论区精华
PR 中没有 review 评论，表明变更可能被快速接受。但从提交历史可见，初始实现后通过提交“`[CI] Fix sentinel check for multi-level inheritance in CustomTestCase`”修复了标记检查问题，确保包装逻辑在子类继承链中正确工作。这揭示了设计时需考虑的边缘情况。

# 风险与影响
**风险**：
- 异常处理逻辑可能引入新 bug，如 tearDownClass 异常被抑制，但 PR 中已处理以优先传播原始异常。
- 防御性清理可能掩盖 setUpClass 中的初始化错误，但这是确保资源释放的必要权衡。
- 变更影响 217+ 测试类，需验证现有 CI 通过，PR 测试计划已涵盖 happy path 验证。

**影响**：
- **对系统**：提高 CI 作业稳定性，减少因资源泄漏导致的失败，间接提升开发效率。
- **对团队**：开发人员需遵循新文档编写防御性 tearDownClass，增加代码健壮性。
- **对用户**：无直接功能影响，但更可靠的 CI 有助于更快交付高质量代码。

# 关联脉络
从近期历史 PR 看，本 PR 是 CI 稳定性改进系列的一部分。例如：
- PR 21331 重写 `killall_sglang` 优化资源清理。
- PR 21345 改进 CI 请求效率。
- PR 21371 修复 HiCache 测试失败。
这些 PR 共同显示团队对测试基础设施的持续投入，本 PR 通过框架级修复预防资源泄漏，补充了现有 CI 优化工作。