|
| 1 | +<!-- SPDX-FileCopyrightText: © 2026 Phala Network <dstack@phala.network> --> |
| 2 | +<!-- SPDX-License-Identifier: Apache-2.0 --> |
| 3 | + |
| 4 | +<a id="dstack-test-methodology"></a> |
| 5 | +# dstack 测试方法 |
| 6 | + |
| 7 | +本文规定 dstack 版本测试从需求分析、风险建模、用例设计、环境执行、证据采集到发布判定的统一方法。具体用例格式见[测试用例编写规范](test-case-authoring-spec.md#dstack-test-case-authoring-spec),执行产物格式见[测试报告输出规范](test-report-output-spec.md#dstack-test-report-output-spec)。 |
| 8 | + |
| 9 | +<a id="methodology-goals"></a> |
| 10 | +## 1. 目标 |
| 11 | + |
| 12 | +测试应当提供可重复、可审计且可追踪的发布证据,而不只是证明某个脚本曾经退出为零。任一结论都应能从需求或风险追踪到用例、步骤、命令原文、观察结果和附件。 |
| 13 | + |
| 14 | +测试工作的完成条件是: |
| 15 | + |
| 16 | +1. 版本变化、产品需求和主要风险均有明确测试覆盖; |
| 17 | +2. 测试规格可由不了解实现细节的执行者独立复现; |
| 18 | +3. 每一步实际执行的命令、退出码、标准输出和标准错误均保存; |
| 19 | +4. 模拟测试和真实硬件测试分别报告,不能互相替代; |
| 20 | +5. 汇总状态可由工具从原子结果重新计算; |
| 21 | +6. 报告中的引用、附件摘要和统计均可机器校验。 |
| 22 | + |
| 23 | +<a id="methodology-artifacts"></a> |
| 24 | +## 2. 测试资料分层 |
| 25 | + |
| 26 | +测试资料分为四类,禁止混写: |
| 27 | + |
| 28 | +| 资料 | 作用 | 是否随执行变化 | |
| 29 | +|---|---|---| |
| 30 | +| 测试说明 `README.md` | 范围、环境配置、公共前置条件、执行与清理方法 | 否 | |
| 31 | +| 测试索引 `index.json` | 章、节、用例顺序及机器可读引用 | 否 | |
| 32 | +| 用例规格 `case.md` | 单条用例的目标、前置条件、数据、步骤和预期结果 | 否 | |
| 33 | +| 执行结果 `results/<run-id>/` | 实际版本、命令证据、观察结果、附件和状态 | 是 | |
| 34 | + |
| 35 | +测试规格是只读输入。执行器只能在 `results/` 下创建当前 run 的产物,不得根据执行结果反向修改预期结果。 |
| 36 | + |
| 37 | +<a id="methodology-organization"></a> |
| 38 | +## 3. 组织结构 |
| 39 | + |
| 40 | +测试计划固定使用“章/节/用例”三个层级。每条用例必须拥有独立目录,便于附带 fixture、脚本和多次执行结果。 |
| 41 | + |
| 42 | +```text |
| 43 | +<plan>/ |
| 44 | +├── index.json |
| 45 | +├── README.md |
| 46 | +├── schemas/ |
| 47 | +├── results/<run-id>/run.json |
| 48 | +└── <chapter>/ |
| 49 | + └── <section>/ |
| 50 | + └── <case-id>/ |
| 51 | + ├── case.md |
| 52 | + ├── fixtures/ # 可选 |
| 53 | + ├── scripts/ # 可选 |
| 54 | + └── results/<run-id>/ |
| 55 | +``` |
| 56 | + |
| 57 | +目录名建议使用两位数字前缀维持人工浏览顺序;权威执行顺序仍来自 `index.json`,执行器不得通过文件名猜测顺序。 |
| 58 | + |
| 59 | +<a id="methodology-input-analysis"></a> |
| 60 | +## 4. 测试输入分析 |
| 61 | + |
| 62 | +在编写用例前,测试负责人应收集并冻结: |
| 63 | + |
| 64 | +- 上一个发布版本及本次候选 revision; |
| 65 | +- change log、PR、schema、RPC 和配置变化; |
| 66 | +- 产品需求及用户场景; |
| 67 | +- 安全不变量和信任边界; |
| 68 | +- 已知缺陷、迁移约束和运维方式; |
| 69 | +- 可用的真实硬件、模拟器与外部服务。 |
| 70 | + |
| 71 | +每项变化至少回答:谁使用它、正常行为是什么、错误输入如何处理、升级时如何兼容、失败后如何恢复、会影响哪些旧功能。 |
| 72 | + |
| 73 | +<a id="methodology-traceability"></a> |
| 74 | +## 5. 追踪与覆盖 |
| 75 | + |
| 76 | +每条用例应引用至少一个需求或风险。推荐维护以下关系: |
| 77 | + |
| 78 | +```text |
| 79 | +Change / Requirement / Risk |
| 80 | + ↓ |
| 81 | + Test case |
| 82 | + ↓ |
| 83 | + Step |
| 84 | + ↓ |
| 85 | + Command and output |
| 86 | + ↓ |
| 87 | + Assertion/result |
| 88 | +``` |
| 89 | + |
| 90 | +覆盖审计至少包含: |
| 91 | + |
| 92 | +1. 新增和改变的功能; |
| 93 | +2. 受影响功能的回归; |
| 94 | +3. 新旧组件组合兼容; |
| 95 | +4. 配置和 API 的合法、边界及错误输入; |
| 96 | +5. 有状态组件的创建、运行、停止、重启、升级、回滚和恢复; |
| 97 | +6. 安全策略的允许、拒绝及恢复; |
| 98 | +7. 并发、隔离、幂等和重试; |
| 99 | +8. 资源耗尽、依赖不可用和网络故障; |
| 100 | +9. 可观测性、错误信息及审计记录。 |
| 101 | + |
| 102 | +覆盖数量不是质量指标。一个包含多个独立断言的大用例应拆为若干原子用例,否则失败无法定位,结果也无法准确统计。 |
| 103 | + |
| 104 | +<a id="methodology-environments"></a> |
| 105 | +## 6. 环境等级 |
| 106 | + |
| 107 | +执行报告必须标记环境等级: |
| 108 | + |
| 109 | +| 等级 | 说明 | |
| 110 | +|---|---| |
| 111 | +| `UNIT` | 单进程或模块测试 | |
| 112 | +| `INTEGRATION` | 多组件集成,但不使用模拟硬件证据代替真实平台 | |
| 113 | +| `SIMULATED` | mock attestation、no-TEE、swtpm 等模拟环境 | |
| 114 | +| `REAL_SGX` | 真实 SGX enclave | |
| 115 | +| `REAL_TDX` | 真实 TDX CVM | |
| 116 | +| `REAL_PLATFORM` | 指定 NVIDIA、GCP、AWS、SEV-SNP 等真实平台 | |
| 117 | + |
| 118 | +用例规格必须声明最低环境。若只在较低等级执行,原用例保持 `NOT_RUN` 或 `BLOCKED`,模拟结果应记录在单独用例中。 |
| 119 | + |
| 120 | +<a id="methodology-status"></a> |
| 121 | +## 7. 状态与判定 |
| 122 | + |
| 123 | +状态枚举固定为: |
| 124 | + |
| 125 | +- `PASS`:所有步骤的实际结果完全满足预期; |
| 126 | +- `FAIL`:至少一步实际结果不完全满足预期; |
| 127 | +- `BLOCKED`:外部环境或前置条件阻止被测行为开始; |
| 128 | +- `NOT_RUN`:尚未执行; |
| 129 | +- `SKIPPED`:预先定义的适用条件不成立。 |
| 130 | + |
| 131 | +单个用例不使用 `PARTIAL`。若一部分断言通过、一部分未执行,应拆分用例或将该用例判为非 `PASS`。顶层汇总必须由用例结果计算,不能手工覆盖。 |
| 132 | + |
| 133 | +<a id="methodology-execution"></a> |
| 134 | +## 8. 标准执行流程 |
| 135 | + |
| 136 | +AI或人工执行器应按以下顺序工作: |
| 137 | + |
| 138 | +1. 阅读顶层 `README.md`; |
| 139 | +2. 读取并校验 `index.json`、schema、路径、锚点和引用; |
| 140 | +3. 创建唯一 `run_id`,记录执行器、公共版本和环境; |
| 141 | +4. 按索引顺序逐章、逐节、逐用例读取 `case.md`; |
| 142 | +5. 为每条用例启动独立AI会话,验证前置条件并执行各步骤; |
| 143 | +6. runner将Agent原生JSONL事件流直接保存为`session.jsonl`,其中包含实际tool call、命令和原始输出; |
| 144 | +7. 将观察结果与预期逐项比较,结束前原子写入浅层`result.json`; |
| 145 | +8. 执行用例后置条件,记录未能清理的资源; |
| 146 | +9. 全部完成后重新校验会话、结果、附件摘要、引用和统计; |
| 147 | +10. 生成顶层`run.json`、`SHA256SUMS`,再打包上传或渲染HTML。 |
| 148 | + |
| 149 | +AI执行器必须记录实际提供方、产品和模型名称;无法从运行环境确认模型时填写 `unknown`,不得猜测。 |
| 150 | + |
| 151 | +<a id="methodology-evidence"></a> |
| 152 | +## 9. 证据原则 |
| 153 | + |
| 154 | +每一步至少包含一条实际执行的命令证据。命令和输出由Agent原生 |
| 155 | +`session.jsonl`保存,不要求AI再次复制或转义。会话应包含: |
| 156 | + |
| 157 | +- 未经改写的命令字符串和工作目录; |
| 158 | +- 已脱敏的环境变量; |
| 159 | +- UTC开始、结束时间和退出码; |
| 160 | +- stdout、stderr原文; |
| 161 | +- 从原文提取的结构化 observed 值; |
| 162 | +- 截图、日志或二进制捕获附件及 SHA-256。 |
| 163 | + |
| 164 | +额外的截图、长日志或二进制捕获写入`artifacts/`并由`result.json`引用; |
| 165 | +`result.json`只保存逐步观察总结,不嵌入大段输出。密钥、token、私钥和用户数据 |
| 166 | +不得进入会话或附件;脱敏必须保留字段存在性和数据形状,且在报告中声明。 |
| 167 | + |
| 168 | +<a id="methodology-versioning"></a> |
| 169 | +## 10. 版本与环境记录 |
| 170 | + |
| 171 | +公共被测版本只在 run 顶层记录一次,包括 Git revision、binary SHA-256、container digest 和 guest image digest。单个用例只在使用旧版或特殊构件时设置 `version_overrides`。 |
| 172 | + |
| 173 | +环境记录至少包括:主机标识、内核、CPU架构、TEE能力、模拟标志、关键外部服务及配置摘要。路径和主机名如涉及隐私,可使用稳定别名,但必须足以复现拓扑。 |
| 174 | + |
| 175 | +<a id="methodology-release-decision"></a> |
| 176 | +## 11. 发布判定 |
| 177 | + |
| 178 | +发布结论应直接引用未通过的 P0/P1 用例及未覆盖需求。以下情况不得表述为“全量通过”: |
| 179 | + |
| 180 | +- P0 用例为 `FAIL`、`BLOCKED` 或 `NOT_RUN`; |
| 181 | +- 真实硬件要求仅由模拟测试覆盖; |
| 182 | +- 关键附件缺失或摘要不匹配; |
| 183 | +- 结果引用失效; |
| 184 | +- 执行偏离规格且未记录 deviation; |
| 185 | +- 公共版本未固定到可追溯 digest。 |
| 186 | + |
| 187 | +<a id="methodology-rendering"></a> |
| 188 | +## 12. 打包和展示 |
| 189 | + |
| 190 | +规范 Plan目录是平台和本地渲染器的唯一输入。推荐命令: |
| 191 | + |
| 192 | +```bash |
| 193 | +dstack-test render \ |
| 194 | + --plan path/to/plan \ |
| 195 | + --run-id run-20260723-001 \ |
| 196 | + --output report.html |
| 197 | +``` |
| 198 | + |
| 199 | +渲染前必须完成结构、引用、状态、统计和附件摘要校验。生成的 HTML应内联样式、脚本、JSON、文本、图片和可下载附件,不依赖网络资源。 |
0 commit comments