SuperAPI AI 工具集

fix-project-leak-from-tc-report

测试与质量

查看项目

更新于 10-15 23:31

技能介绍

用途:修复 TeamCity 报告中的 _LastInSuiteTest.testProjectLeak 项目泄漏失败,覆盖从诊断到反复验证的完整流程。仅做调查(定位、复现、分析)的任务由同源的 leaking-test-investigation-by-tc-report 技能覆盖,本技能在其阶段 1–3 基础上增加阶段 4(应用修复)与阶段 5(验证)。

主要能力与流程:

  1. 从 TC 报告定位肇事测试。泄漏的 Project 名称是最强信号,ProjectRule() 中项目名默认取测试类简单名,可在报告中查找 Instance: Project(name=<TestClassSimpleName>, containerState=DISPOSE_COMPLETED, …),用 ijproxy 的 search_symbol / search_file 定位文件,并记录测试模块(testSrc/ 旁的 .iml)作为 tests.cmd 的 --module。
  2. 本地复现 10 次。testProjectLeak 被排除在模式发现之外,其执行由 JUnit5TestSessionListener.testPlanExecutionFinished 触发,条件是 UsefulTestCase.IS_UNDER_TEAMCITY == true(即 TEAMCITY_VERSION != null)。本地需设置 TEAMCITY_VERSION 并让 TEAMCITY_BUILD_PROPERTIES_FILE 指向一个两行 stub 属性文件,然后运行捆绑脚本:"${CLAUDE_SKILL_DIR}/scripts/leak-loop.sh" --module <test-module-iml-name> --test <test-FQN> --runs 10 --archive /tmp/<name>-leak-runs。脚本会设置环境变量、循环运行、归档堆转储与 stdout。快速退出约定:若第 1 次运行未产生堆转储,脚本以退出码 3 中止,不再排队剩余运行;退出码 0 表示 N 次全部泄漏。
  3. 分析所有唯一保留链。运行 "${CLAUDE_SKILL_DIR}/scripts/summarize-runs.sh" /tmp/<name>-leak-runs 生成 SUMMARY.md,再手写 ANALYSIS.md,覆盖复现情况、每条唯一保留链(本地与 CI 报告)、根因(用 search_symbol 定位并引用 file:line-range)及推荐修复。
  4. 应用修复。强制先检查:保留类是否为通过 <projectService> 或 @Service(Level.PROJECT) 注册且实现 Disposable 的项目服务。若是,容器已通过 ServiceInstanceInitializer.kt:61-62 注册、ComponentManagerImpl.kt:904-905 调用 Disposer.dispose(instance) 处理,构造函数中的 Disposer.register(this, child) 是正确写法,不应改动;若链仍显示服务为 Disposer ROOT,应排查框架路径、构造与容器注册顺序、light-project 重置路径、leak-hunter 时序及 IJPL-247543 相关提交。若否,按根因分类处理:类别 A(按设计长于 Project 的应用级缓存、消息总线、扩展点、线程本地、静态字段)应断开保留;类别 B2(不应长于 Project 且未接入服务容器)应正确注册、迁移为 @Service(Level.PROJECT)、经 Disposer.dispose(...) 释放、补 parentDisposable 或在 projectClosed 时清理。
  5. 验证:在打补丁的代码树上重跑 leak-hunter 循环,确认不再触发。

限制与反模式:不要用 WeakReference 包装服务自身的 myProject 字段来“修复”泄漏,这只会掩盖释放缺陷,服务实例仍被泄漏,消息总线订阅仍会触发,且 GC 后可能从意外路径抛 NPE;也不要把 Disposable 服务构造函数中的 Disposer.register(this, child) 改为 Disposer.register(project, child) 来压平 Disposer 树,这不会把服务从 ObjectTree 移除。捆绑脚本自包含,不要引用其他技能的副本。首次冷 Bazel 编译加 JBR 下载约需 4–5 分钟,后续运行约 30–60 秒。