runtime-llt-generator
为 CANN Runtime 的指定接口、函数、分支、缺陷或当前代码变更设计、编写并验证 LLT,支持通过 coverage_threshold 指定覆盖率门槛,未指定时默认 80%。用户要求“写对应的 LLT”“生成对应的 LLT”“补充或新增 LLT/单测”“为缺陷写回归用例”时使用;不用于仅筛选、运行、复跑、解释或审查已有 LLT、生成 gtest_filter 或只查看既有覆盖率报告。
SKILL.mdruntime/runtime-llt-generator/SKILL.md
GitHubRuntime LLT 用例生成
任务边界
- 负责从目标行为出发设计测试点,编写或补齐 Runtime LLT、必要的 stub/data/helper 和精确 CMake 挂载,并完成生成范围内的构建、执行、覆盖率与测试审计。
- 只处理以新增或修改测试代码为主要目标的请求;仅筛选、运行、复跑、解释或审查已有 LLT、生成
gtest_filter、读取既有报告不属于本 Skill 范围。 - 用户只要求方案、测试点或分析时保持只读。用户要求生成时,只修改目标测试及其必要构建资产;不得顺带提交、推送或修改远端状态。
- 测试暴露产品缺陷时,记录失败结果并停止。除非用户同时要求修复产品代码,否则不得为了让 LLT 通过而改产品实现、放宽断言或忽略错误。
- 测试范围已经跨模块、依赖真实设备或完整异步链路时,说明为什么应使用 ST/HLT,不把跨层场景强塞进 LLT。
输入与前置条件
- 从用户请求、指定符号/文件、当前 diff、Issue 或设计文档中确定被测行为。可从工作区查到的信息不向用户重复询问。
- 只有目标行为、目标平台或预期结果存在会改变测试结论的歧义时才提问。
- 开始前记录工作区基线,保留用户修改,新增测试只限于本次任务。
- 可选入参
coverage_threshold表示目标范围的行覆盖率门槛,接受80、80%、87.5%等百分数写法;用户用自然语言明确指定覆盖率时按同一入参处理。 - 用户未指定
coverage_threshold时,请求门槛默认为 80%。参数解析、有效范围以及仓库强制门槛的优先级按references/coverage-policy.md执行,并在开始生成前明确本次实际生效值。
信息来源
按内容读取以下来源,区分需求、当前实现、测试结果和推断:
- 用户指定的需求、Issue、设计文档和公开 API/ABI 要求。
- 仓库
AGENTS.md、当前 workflow、repo memory,以及目标头文件、源码、平台实现和调用路径。存在.codegraph/时先用 CodeGraph,再用rg补充磁盘核查。 - 全部 Runtime UT 中对目标符号、动态类型和同语义行为的已有测试,以及目标附近 fixture、stub/data/helper、
tests/depends/和精确 CMake target。不能只搜最先命中的平台目录。 - 输出测试方案或编写测试前,先读取
Runtime UT guidelines 路径,再从目标 CANN Runtime 仓根目录解析其中列出的规范文件;需要选择 mock、fixture、stub 或新增文件挂载时,按该 reference 的条件再读取测试框架指南。 - 输出覆盖率验证方案、生成覆盖用例或验收覆盖率时读取
覆盖率政策。
来源冲突时先指出冲突,不得静默选择最容易通过测试的一方。
工作流程
1. 建立被测范围
- 定位声明、实现、真实生产入口、动态分发、平台变体、失败返回和资源生命周期。
- 在整个
tests/ut/runtime/搜索目标符号、动态类型、同语义方法和已有断言,判断是新增用例、扩展现有用例,还是已有用例已经完整覆盖。把命中的测试文件、用例名和已覆盖行为列出来后,才能提出修改。 - 已有用例已覆盖目标行为时,不新增重复 LLT;只有确认存在独立的未覆盖行为时才补用例。
- 确认 LLT 所属产品和构建目标;V201、David、XPU、910B 等独立实现必须使用各自真实 fixture/target,不能用通用目标代替。
- 平台归属由生产类型、现有同平台 fixture 和 CMake owner 共同确定。某平台 target 偶然链接了目标源码,不代表该平台拥有这个测试;例如 David 专用对象不得仅因能链接而放进 910B 测试目录。
输出:目标符号、行为边界、生产路径、测试文件、fixture、CMake target 和尚未覆盖的行为。
2. 设计行为矩阵
在写代码前列出适用测试点,至少检查:
- 成功主路径及关键出参、状态和副作用;
- 空指针、非法枚举、越界、零值、最小/最大值、空/单个/多个对象;
- 依赖失败、提前返回、资源申请/释放、重复调用和失败清理;
- 全局状态、单例、环境变量、回调、并发或异步生命周期;
- 受影响的不同平台、编译宏、driver 能力和不支持路径;
- 缺陷修复对应的稳定 reproducer。
只选择与源码行为相关的测试点,不为覆盖率制造不可能出现的状态。每个用例聚焦一个可观察行为;同一行为的真实输入矩阵优先使用参数化测试。
输出:场景、前置条件/输入、stub 或 mock、动作、预期结果、可观察副作用、目标平台和覆盖行/分支。
3. 选择放置位置和构建挂载
- 优先追加到最近的现有测试文件并复用 fixture;只有职责边界或 target 不同才新增文件。
- 新文件必须加入准确的
CMakeLists.txt源文件列表;新增模块或子模块且需要通过tests/build_ut.sh -u <name>独立执行时,才修改脚本的ut_path_map/target 映射。 - 新增文件名、suite 和 case 名沿用同目录风格,并表达被测对象、触发场景和预期行为。
- 不盲目修改
TEST_PLAN.md。先检查它是否被 Git 跟踪、是否属于当前分支基线,再按仓库 workflow 处理计数。
4. 编写 LLT
- 每个测试至少包含一条有效
EXPECT_*或ASSERT_*;只有后续继续执行不安全时使用ASSERT_*。 - 除返回码外,校验适用的出参、对象状态、副作用、回调、资源释放以及 mock 参数和调用次数。
- gmock/mockcpp 只隔离真实外部依赖。行为默认值使用 stub/
ON_CALL;只有依赖调用本身需要验证时才使用EXPECT_CALL或精确次数期望。 - 在
TearDown或等价收口点 verify/reset mock,并恢复 SoC、device、环境变量、单例、静态缓存和全局指针。临时文件和资源必须独立命名并清理。 - 优先通过公开生命周期和可观察行为构造状态;只要公开申请、回收、reset 等操作能够到达目标状态,就不得直接写 private 字段。先复用 helper/stub/accessor,确实无替代时才使用
private public、protected public或-fno-access-control,并在方案中说明必要性。 - Bug 修复先写能稳定复现的失败用例,再修改产品代码;仅生成测试时不得改产品代码掩盖失败。
- 不删除、禁用或放宽已有测试来换取通过,不写只验证“不崩溃”或只执行无断言的用例。
输出:最小测试 diff,以及必要的 CMake/stub/data/helper diff。
5. 构建、运行和覆盖率
- 增量格式化新增或修改的测试代码,检查 diff 未改动无关行。
- 先读取当前
tests/build_ut.sh --help或仓库原生测试说明,再原样采用当前参数语法;不得凭记忆拼接命令。构建准确的测试 target,并直接运行包含新用例的 gtest binary。必须证明筛选后实际执行了大于 0 个用例,且无失败、超时或未归因异常。 - 平台专用用例向运行工具显式传入准确 target;不要依赖只覆盖通用目标的自动选择。
- 按
references/coverage-policy.md采集覆盖率并与本次有效覆盖率门槛核对。不得把构建脚本的总体PASS、全仓聚合覆盖率或“代码看起来经过了”当作目标范围的覆盖率结果。 - 测试源码发生变化时,按目标仓 workflow 完成要求的单元测试审计和代码审查。用户明确缩小或跳过验证时,准确记录未执行项,不虚构通过结果。
如果失败,先区分产品、测试、构建挂载和环境问题。修复测试问题后重跑;单次复跑通过仍需标记为可能不稳定,并保留首次失败记录。
覆盖率完成标准
- 按
references/coverage-policy.md确定统计范围,行覆盖率不得低于本次有效门槛。 - 所有可达的新建或修改判断结果、错误路径和边界行为都有直接测试,即使行覆盖率已经达到有效门槛。
- 覆盖报告必须写明请求门槛及其来源、实际生效门槛、基线、范围、指标、命令、工具和报告路径,并列出未覆盖与无法映射的行。目标范围没有可执行行时只报告
N/A,不得宣称达到有效门槛。 - 无法采集或无法可靠映射覆盖率时,状态只能是“用例已生成/已运行,覆盖率未验证”,不得宣称完成覆盖率门槛。
交付与停止条件
完成时报告:
- 新增或修改的测试、CMake、stub/data/helper 文件;
- 每个用例保护的行为以及避免了哪些重复测试;
- 精确 target、执行用例数、通过/失败结果和日志路径;
- 请求门槛及其来源、实际生效门槛、覆盖范围、实际结果、未覆盖/未知行;
- 未执行的全量验证、平台路径和剩余风险。
仅在测试代码已落地、准确 target 构建通过、相关用例真实执行通过、覆盖率满足本次有效门槛且仓库要求的测试审计完成后,才能宣称任务完成。出现以下情况时停止并说明原因:预期行为冲突、目标平台无法确定、测试稳定复现产品缺陷、必要环境或依赖缺失、用户已有改动与目标文件无法安全合并。
已知陷阱
- 不假设
tests/build_ut.sh会把--后的gtest_filter透传给二进制;先检查当前脚本,必要时直接运行发现到的 gtest binary。 - 不用全仓覆盖率掩盖目标改动未覆盖,也不把行覆盖率当作断言有效性的替代品。
- 不把一个平台 fixture 的通过结果外推为所有平台已覆盖。
- 一次失败后,仅靠单次重跑通过不能判定用例稳定。
- MockCpp 的 receiver 静态类型、参数和返回对象底层类型必须与目标签名精确匹配。
评测资源
evals/ 仅用于维护本 Skill 的正向、近邻负向、行为、失败和安全评测,不在普通 LLT 生成任务中加载。