chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
7ad03ddc48
commit
94eef7d546
300
docs/zh-CN/ci.md
300
docs/zh-CN/ci.md
@ -1,75 +1,75 @@
|
||||
---
|
||||
read_when:
|
||||
- 你需要了解为什么 CI 作业运行了或没有运行
|
||||
- 你正在调试一个失败的 GitHub Actions 检查项
|
||||
- 你正在协调发布验证的运行或重新运行
|
||||
summary: 持续集成作业图、范围门禁、发布总括流程以及本地命令等效项
|
||||
- 你需要了解为什么某个 CI 作业运行了或没有运行
|
||||
- 你正在调试一个失败的 GitHub Actions 检查
|
||||
- 你正在协调一次发布验证运行或重新运行
|
||||
summary: CI 作业图、范围门禁、发布总括和本地命令等效项
|
||||
title: CI 流水线
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T18:11:04Z"
|
||||
generated_at: "2026-04-30T23:44:01Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: a24afc27606ac7f4e9ead89acdd319bffa23336610f8a6cd8b576ea1a5b233dd
|
||||
source_hash: 67bfe0245e2d78e88357f7068cc9bf9b99559655f87f9b65ffa89649b39bec44
|
||||
source_path: ci.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw CI 在每次推送到 `main` 以及每个拉取请求上运行。`preflight` 作业会分类差异,并在只有无关区域发生变化时关闭昂贵的验证线。手动 `workflow_dispatch` 运行会有意绕过智能作用域划分,并为发布候选版本和广泛验证展开完整图。Android 验证线通过 `include_android` 保持选择加入。仅发布使用的插件覆盖率位于单独的 [`插件预发布`](#plugin-prerelease) 工作流中,并且只会从 [`完整发布验证`](#full-release-validation) 或显式手动分发运行。
|
||||
OpenClaw CI 会在每次推送到 `main` 以及每个拉取请求时运行。`preflight` 任务会对差异进行分类,并在只有无关区域变更时关闭昂贵的任务通道。手动 `workflow_dispatch` 运行会有意绕过智能范围限定,并为候选发布版本和广泛验证展开完整图。Android 通道通过 `include_android` 保持选择加入。仅发布的插件覆盖位于单独的 [`Plugin Prerelease`](#plugin-prerelease) 工作流中,并且只会从 [`Full Release Validation`](#full-release-validation) 或显式手动触发运行。
|
||||
|
||||
## 流水线概览
|
||||
|
||||
| 作业 | 用途 | 运行时机 |
|
||||
| 任务 | 目的 | 运行时机 |
|
||||
| -------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------- |
|
||||
| `preflight` | 检测仅文档变更、已变更作用域、已变更插件,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `preflight` | 检测仅文档变更、变更范围、变更插件,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-scm-fast` | 通过 `zizmor` 进行私钥检测和工作流审计 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-dependency-audit` | 针对 npm advisories 进行无需依赖安装的生产 lockfile 审计 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-fast` | 快速安全作业的必需聚合项 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-dependency-audit` | 针对 npm 公告执行无依赖的生产 lockfile 审计 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-fast` | 快速安全任务的必需聚合项 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `check-dependencies` | 生产 Knip 仅依赖检查,以及未使用文件 allowlist 防护 | Node 相关变更 |
|
||||
| `build-artifacts` | 构建 `dist/`、Control UI、内置产物检查,以及可复用的下游产物 | Node 相关变更 |
|
||||
| `checks-fast-core` | 快速 Linux 正确性验证线,例如内置/插件契约/协议检查 | Node 相关变更 |
|
||||
| `build-artifacts` | 构建 `dist/`、Control UI、构建产物检查,以及可复用下游产物 | Node 相关变更 |
|
||||
| `checks-fast-core` | 快速 Linux 正确性通道,例如内置/插件契约/协议检查 | Node 相关变更 |
|
||||
| `checks-fast-contracts-channels` | 分片渠道契约检查,并提供稳定的聚合检查结果 | Node 相关变更 |
|
||||
| `checks-node-core-test` | 核心 Node 测试分片,不包括渠道、内置、契约和插件验证线 | Node 相关变更 |
|
||||
| `checks-node-core-test` | 核心 Node 测试分片,不包括渠道、内置、契约和插件通道 | Node 相关变更 |
|
||||
| `check` | 分片主本地门禁等价项:生产类型、lint、防护、测试类型和严格 smoke | Node 相关变更 |
|
||||
| `check-additional` | 架构、边界、插件表面防护、包边界,以及 gateway-watch 分片 | Node 相关变更 |
|
||||
| `check-additional` | 架构、边界、插件表面防护、包边界和 gateway-watch 分片 | Node 相关变更 |
|
||||
| `build-smoke` | 已构建 CLI smoke 测试和启动内存 smoke | Node 相关变更 |
|
||||
| `checks` | 已构建产物渠道测试的验证器 | Node 相关变更 |
|
||||
| `checks-node-compat-node22` | Node 22 兼容性构建和 smoke 验证线 | 发布用手动 CI 分发 |
|
||||
| `check-docs` | 文档格式、lint 和断链检查 | 文档已变更 |
|
||||
| `skills-python` | 针对 Python 支持的 Skills 运行 Ruff + pytest | Python Skills 相关变更 |
|
||||
| `checks-windows` | Windows 特定的进程/路径测试,以及共享运行时导入说明符回归 | Windows 相关变更 |
|
||||
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试验证线 | macOS 相关变更 |
|
||||
| `checks-node-compat-node22` | Node 22 兼容性构建和 smoke 通道 | 用于发布的手动 CI 触发 |
|
||||
| `check-docs` | 文档格式化、lint 和断链检查 | 文档已变更 |
|
||||
| `skills-python` | 面向 Python 支持的 Skills 的 Ruff + pytest | Python Skill 相关变更 |
|
||||
| `checks-windows` | Windows 特定进程/路径测试,以及共享运行时导入说明符回归 | Windows 相关变更 |
|
||||
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | macOS 相关变更 |
|
||||
| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | macOS 相关变更 |
|
||||
| `android` | 两种 flavor 的 Android 单元测试,以及一个 debug APK 构建 | Android 相关变更 |
|
||||
| `test-performance-agent` | 受信任活动后的每日 Codex 慢测试优化 | 主 CI 成功或手动分发 |
|
||||
| `android` | 两种 flavor 的 Android 单元测试,以及一次 debug APK 构建 | Android 相关变更 |
|
||||
| `test-performance-agent` | 受信任活动之后的每日 Codex 慢测试优化 | 主 CI 成功或手动触发 |
|
||||
|
||||
## 快速失败顺序
|
||||
|
||||
1. `preflight` 决定哪些验证线实际存在。`docs-scope` 和 `changed-scope` 逻辑是此作业中的步骤,而不是独立作业。
|
||||
2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,不等待更重的产物和平台矩阵作业。
|
||||
3. `build-artifacts` 与快速 Linux 验证线重叠运行,因此下游消费者可在共享构建就绪后立即开始。
|
||||
4. 更重的平台和运行时验证线随后展开:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`。
|
||||
1. `preflight` 决定哪些通道实际存在。`docs-scope` 和 `changed-scope` 逻辑是此任务内的步骤,而不是独立任务。
|
||||
2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,无需等待更重的产物和平台矩阵任务。
|
||||
3. `build-artifacts` 会与快速 Linux 通道重叠执行,因此下游消费者可以在共享构建准备好后立即开始。
|
||||
4. 更重的平台和运行时通道随后展开:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`。
|
||||
|
||||
当同一 PR 或 `main` ref 上有更新推送落地时,GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也失败,否则将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但不会在整个工作流已被取代后继续排队。自动 CI 并发键带有版本号(`CI-v7-*`),因此 GitHub 端旧队列组中的僵尸任务无法无限期阻塞更新的 main 运行。手动完整套件运行使用 `CI-manual-v1-*`,且不会取消进行中的运行。
|
||||
当同一 PR 或 `main` ref 上有更新推送落地时,GitHub 可能会将被取代的任务标记为 `cancelled`。除非同一 ref 的最新运行也失败,否则将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但不会在整个工作流已经被取代后继续排队。自动 CI 并发键带有版本号(`CI-v7-*`),因此 GitHub 侧旧队列组中的僵尸任务无法无限阻塞较新的 main 运行。手动完整套件运行使用 `CI-manual-v1-*`,并且不会取消正在进行的运行。
|
||||
|
||||
## 作用域和路由
|
||||
## 范围和路由
|
||||
|
||||
作用域逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动分发会跳过变更作用域检测,并让 preflight 清单表现得像每个作用域区域都发生了变化。
|
||||
范围逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动触发会跳过变更范围检测,并让 preflight 清单表现得像每个限定范围区域都已变更。
|
||||
|
||||
- **CI 工作流编辑**会验证 Node CI 图和工作流 lint,但本身不会强制运行 Windows、Android 或 macOS 原生构建;这些平台验证线仍限定于平台源代码变更。
|
||||
- **仅 CI 路由编辑、选定的低成本核心测试 fixture 编辑,以及窄范围插件契约辅助/测试路由编辑**会使用快速的仅 Node 清单路径:`preflight`、安全检查,以及单个 `checks-fast-core` 任务。当变更仅限于该快速任务直接覆盖的路由或辅助表面时,该路径会跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片以及额外防护矩阵。
|
||||
- **Windows Node 检查**的作用域限定于 Windows 特定的进程/路径包装器、npm/pnpm/UI runner 辅助、包管理器配置,以及执行该验证线的 CI 工作流表面;无关源代码、插件、install-smoke 和仅测试变更会保留在 Linux Node 验证线上。
|
||||
- **CI 工作流编辑**会验证 Node CI 图以及工作流 lint,但本身不会强制执行 Windows、Android 或 macOS 原生构建;这些平台通道仍限定于平台源代码变更。
|
||||
- **仅 CI 路由编辑、选定的廉价核心测试 fixture 编辑,以及窄范围插件契约 helper/测试路由编辑**会使用快速的仅 Node 清单路径:`preflight`、security,以及单个 `checks-fast-core` 任务。当变更仅限于该快速任务直接覆盖的路由或 helper 表面时,此路径会跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片和额外防护矩阵。
|
||||
- **Windows Node 检查**限定于 Windows 特定进程/路径包装器、npm/pnpm/UI runner helper、包管理器配置,以及执行该通道的 CI 工作流表面;无关源代码、插件、install-smoke 和仅测试变更会留在 Linux Node 通道上。
|
||||
|
||||
最慢的 Node 测试族会拆分或平衡,使每个作业保持较小规模而不过度预留 runner:渠道契约作为三个加权分片运行,小型核心单元验证线会配对,auto-reply 作为四个平衡 worker 运行(reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片),智能体式 Gateway 网关/插件配置会分布到现有的仅源代码智能体式 Node 作业中,而不是等待构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用其专用 Vitest 配置,而不是共享插件兜底配置。包含模式分片会使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分整个配置和过滤后的分片。`check-additional` 会将包边界编译/canary 工作放在一起,并将运行时拓扑架构与 gateway watch 覆盖率分离;边界防护分片会在一个作业内并发运行其小型独立防护。Gateway watch、渠道测试和核心支持边界分片会在 `dist/` 和 `dist-runtime/` 已构建后,在 `build-artifacts` 内并发运行。
|
||||
最慢的 Node 测试族会被拆分或均衡,让每个任务保持较小规模而不过度预留 runner:渠道契约作为三个加权分片运行,小型核心单元通道会配对,auto-reply 作为四个均衡 worker 运行(其中 reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片),agentic gateway/插件配置会分散到现有的仅源代码 agentic Node 任务中,而不是等待构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用各自专用的 Vitest 配置,而不是共享的插件兜底配置。include-pattern 分片会使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分整个配置和经过过滤的分片。`check-additional` 会将包边界编译/canary 工作放在一起,并将运行时拓扑架构与 gateway watch 覆盖分开;边界防护分片会在一个任务内并发运行其小型独立防护。Gateway watch、渠道测试和核心支持边界分片会在 `dist/` 和 `dist-runtime/` 已经构建完成后,于 `build-artifacts` 内并发运行。
|
||||
|
||||
Android CI 会同时运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,然后构建 Play debug APK。third-party flavor 没有单独的源集或清单;其单元测试验证线仍会使用 SMS/call-log BuildConfig 标志编译该 flavor,同时避免在每次 Android 相关推送上重复执行 debug APK 打包作业。
|
||||
Android CI 会运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,随后构建 Play debug APK。third-party flavor 没有单独的 source set 或 manifest;它的单元测试通道仍会使用 SMS/通话记录 BuildConfig 标志编译该 flavor,同时避免在每次 Android 相关推送上重复执行 debug APK 打包任务。
|
||||
|
||||
`check-dependencies` 分片运行 `pnpm deadcode:dependencies`(生产 Knip 仅依赖检查,固定到最新 Knip 版本,并在 `dlx` 安装时禁用 pnpm 的最小发布年龄)和 `pnpm deadcode:unused-files`,后者会将 Knip 的生产未使用文件发现结果与 `scripts/deadcode-unused-files.allowlist.mjs` 进行比较。当 PR 添加新的未经审查的未使用文件,或留下过期 allowlist 条目时,未使用文件防护会失败,同时保留 Knip 无法静态解析的有意动态插件、生成内容、构建内容、实时测试和包桥接表面。
|
||||
`check-dependencies` 分片运行 `pnpm deadcode:dependencies`(生产 Knip 仅依赖检查,固定到最新 Knip 版本,并为 `dlx` 安装禁用 pnpm 的最低发布年龄)和 `pnpm deadcode:unused-files`,后者会将 Knip 的生产未使用文件发现结果与 `scripts/deadcode-unused-files.allowlist.mjs` 对比。当 PR 添加新的未经审查未使用文件,或留下过期 allowlist 条目时,未使用文件防护会失败,同时保留 Knip 无法静态解析的有意动态插件、生成产物、构建、live-test 和包桥接表面。
|
||||
|
||||
## 手动分发
|
||||
## 手动触发
|
||||
|
||||
手动 CI 分发运行与普通 CI 相同的作业图,但会强制开启每个非 Android 作用域验证线:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、build smoke、文档检查、Python Skills、Windows、macOS 和 Control UI i18n。独立手动 CI 分发只有在 `include_android=true` 时才运行 Android;完整发布总入口会通过传递 `include_android=true` 来启用 Android。插件预发布静态检查、仅发布使用的 `agentic-plugins` 分片、完整插件批量扫描,以及插件预发布 Docker 验证线都排除在 CI 之外。Docker 预发布套件只会在 `Full Release Validation` 启用发布验证门禁并分发单独的 `Plugin Prerelease` 工作流时运行。
|
||||
手动 CI 触发运行与普通 CI 相同的任务图,但会强制开启每个非 Android 限定范围通道:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建 smoke、文档检查、Python Skills、Windows、macOS 和 Control UI i18n。独立手动 CI 触发仅在 `include_android=true` 时运行 Android;完整发布总入口会通过传递 `include_android=true` 启用 Android。插件预发布静态检查、仅发布的 `agentic-plugins` 分片、完整插件批量扫描和插件预发布 Docker 通道不包含在 CI 中。Docker 预发布套件仅在 `Full Release Validation` 使用已启用的 release-validation 门禁触发单独的 `Plugin Prerelease` 工作流时运行。
|
||||
|
||||
手动运行使用唯一并发组,因此发布候选完整套件不会被同一 ref 上的其他推送或 PR 运行取消。可选的 `target_ref` 输入允许受信任调用者在使用所选分发 ref 的工作流文件时,针对分支、标签或完整提交 SHA 运行该图。
|
||||
手动运行使用唯一并发组,因此候选发布版本完整套件不会被同一 ref 上的另一次推送或 PR 运行取消。可选的 `target_ref` 输入允许受信任调用方在使用所选触发 ref 中工作流文件的同时,针对分支、标签或完整提交 SHA 运行该图。
|
||||
|
||||
```bash
|
||||
gh workflow run ci.yml --ref release/YYYY.M.D
|
||||
@ -81,10 +81,10 @@ gh workflow run full-release-validation.yml --ref main -f ref=<branch-or-sha>
|
||||
|
||||
| 运行器 | 作业 |
|
||||
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `ubuntu-24.04` | `preflight`、快速安全作业和聚合(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速协议/契约/内置检查、分片的渠道契约检查、除 lint 之外的 `check` 分片、`check-additional` 分片和聚合、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-response;install-smoke 预检也使用 GitHub 托管的 Ubuntu,以便 Blacksmith 矩阵可以更早排队 |
|
||||
| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`、较低权重的插件分片、`checks-fast-core`、`checks-node-compat-node22`、`check-prod-types` 和 `check-test-types` |
|
||||
| `ubuntu-24.04` | `preflight`、快速安全作业和聚合项(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速协议/契约/内置检查、分片的渠道契约检查、除 lint 以外的 `check` 分片、`check-additional` 分片和聚合项、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-response;install-smoke 预检也使用 GitHub 托管的 Ubuntu,因此 Blacksmith 矩阵可以更早排队 |
|
||||
| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`、较低负载的插件分片、`checks-fast-core`、`checks-node-compat-node22`、`check-prod-types` 和 `check-test-types` |
|
||||
| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`、build-smoke、Linux Node 测试分片、内置插件测试分片、`android` |
|
||||
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(对 CPU 足够敏感,8 vCPU 节省的成本不抵其开销);install-smoke Docker 构建(32-vCPU 的排队时间成本不抵其节省) |
|
||||
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(对 CPU 足够敏感,8 vCPU 增加的成本超过了节省的成本);install-smoke Docker 构建(32-vCPU 队列时间增加的成本超过了节省的成本) |
|
||||
| `blacksmith-16vcpu-windows-2025` | `checks-windows` |
|
||||
| `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-node`;fork 回退到 `macos-latest` |
|
||||
| `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-swift`;fork 回退到 `macos-latest` |
|
||||
@ -117,19 +117,19 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac
|
||||
|
||||
## 完整发布验证
|
||||
|
||||
`Full Release Validation` 是用于“发布前运行所有内容”的手动总括工作流。它接受分支、标签或完整提交 SHA,使用该目标调度手动 `CI` 工作流,调度 `Plugin Prerelease` 以提供仅发布所需的插件/包/静态/Docker 证明,并调度 `OpenClaw Release Checks` 以运行安装烟测、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 线路。当提供已发布的包规范时,它还可以运行发布后的 `NPM Telegram Beta E2E` 工作流。
|
||||
`Full Release Validation` 是用于“发布前运行所有内容”的手动总括工作流。它接受分支、标签或完整提交 SHA,使用该目标分派手动 `CI` 工作流,为仅发布相关的插件/包/静态/Docker 证明分派 `Plugin Prerelease`,并为安装烟测、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab 一致性、Matrix 和 Telegram lane 分派 `OpenClaw Release Checks`。当提供已发布包规范时,它还可以运行发布后的 `NPM Telegram Beta E2E` 工作流。
|
||||
|
||||
`release_profile` 控制传入发布检查的 live/提供商覆盖范围:
|
||||
|
||||
- `minimum` 保留最快的 OpenAI/核心发布关键线路。
|
||||
- `stable` 添加稳定的提供商/后端集合。
|
||||
- `full` 运行广泛的 advisory 提供商/媒体矩阵。
|
||||
- `minimum` 保留最快的 OpenAI/core 发布关键 lane。
|
||||
- `stable` 添加稳定提供商/后端集合。
|
||||
- `full` 运行广泛的建议提供商/媒体矩阵。
|
||||
|
||||
总括工作流会记录已调度的子运行 ID,最终的 `Verify full validation` 作业会重新检查当前子运行结论,并为每个子运行追加最慢作业表。如果子工作流被重新运行并变绿,只需重新运行父验证器作业,以刷新总括结果和耗时摘要。
|
||||
总括工作流会记录已分派的子运行 ID,最终的 `Verify full validation` 作业会重新检查当前子运行结论,并为每个子运行追加最慢作业表。如果某个子工作流重新运行后变绿,只需重新运行父验证器作业,即可刷新总括结果和时间摘要。
|
||||
|
||||
对于恢复,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。对发布候选版本使用 `all`,只针对常规完整 CI 子项使用 `ci`,针对每个发布子项使用 `release-checks`,或在总括工作流上使用更窄的组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这样,在聚焦修复之后,失败的发布环境重跑会保持有界。
|
||||
对于恢复,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。发布候选版本使用 `all`,仅普通完整 CI 子项使用 `ci`,每个发布子项使用 `release-checks`,也可以在总括工作流上使用更窄的分组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这样可以在聚焦修复后将失败发布箱的重新运行限制在边界内。
|
||||
|
||||
`OpenClaw Release Checks` 使用受信任的工作流 ref 将所选 ref 解析一次为 `release-package-under-test` tarball,然后将该产物传递给 live/E2E 发布路径 Docker 工作流和包验收分片。这样可以让包字节在各个发布环境中保持一致,并避免在多个子作业中重新打包同一个候选版本。
|
||||
`OpenClaw Release Checks` 使用可信工作流引用将所选引用解析一次为 `release-package-under-test` tarball,然后将该构件传递给 live/E2E 发布路径 Docker 工作流和包验收分片。这样可以让发布箱之间的包字节保持一致,并避免在多个子作业中重复打包同一个候选版本。
|
||||
|
||||
## Live 和 E2E 分片
|
||||
|
||||
@ -137,7 +137,7 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac
|
||||
|
||||
- `native-live-src-agents`
|
||||
- `native-live-src-gateway-core`
|
||||
- 按提供商过滤的 `native-live-src-gateway-profiles` 作业
|
||||
- 提供商过滤的 `native-live-src-gateway-profiles` 作业
|
||||
- `native-live-src-gateway-backends`
|
||||
- `native-live-test`
|
||||
- `native-live-extensions-a-k`
|
||||
@ -145,57 +145,57 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac
|
||||
- `native-live-extensions-openai`
|
||||
- `native-live-extensions-o-z-other`
|
||||
- `native-live-extensions-xai`
|
||||
- 拆分的媒体音频/视频分片和按提供商过滤的音乐分片
|
||||
- 拆分的媒体音频/视频分片和提供商过滤的音乐分片
|
||||
|
||||
这会保持相同的文件覆盖范围,同时让缓慢的 live 提供商故障更容易重跑和诊断。聚合的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍然可用于手动一次性重跑。
|
||||
这在保持相同文件覆盖范围的同时,让较慢的 live 提供商失败更容易重新运行和诊断。聚合 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍然可用于手动一次性重新运行。
|
||||
|
||||
原生 live 媒体分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中运行,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预安装了 `ffmpeg` 和 `ffprobe`;媒体作业只在设置前验证这些二进制文件。将 Docker 支持的 live 套件保持在普通 Blacksmith 运行器上,容器作业不适合启动嵌套 Docker 测试。
|
||||
原生 live 媒体分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中运行,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预装 `ffmpeg` 和 `ffprobe`;媒体作业只在设置前验证二进制文件。将 Docker 支撑的 live 套件保留在普通 Blacksmith 运行器上,容器作业并不适合启动嵌套 Docker 测试。
|
||||
|
||||
Docker 支持的 live 模型/后端分片为每个所选提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像。live 发布工作流会构建并推送该镜像一次,然后 Docker live 模型、Gateway 网关、CLI 后端、ACP bind 和 Codex harness 分片会使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。如果这些分片各自独立重建完整源 Docker 目标,则说明发布运行配置错误,并会在重复镜像构建上浪费墙钟时间。
|
||||
Docker 支撑的 live 模型/后端分片会为每个所选提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像。live 发布工作流会构建并推送该镜像一次,然后 Docker live 模型、Gateway 网关、CLI 后端、ACP bind 和 Codex harness 分片会使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。如果这些分片各自独立重新构建完整源 Docker 目标,则说明发布运行配置错误,并会在重复镜像构建上浪费墙钟时间。
|
||||
|
||||
## 包验收
|
||||
|
||||
当问题是“这个可安装的 OpenClaw 包能否作为产品正常工作?”时,使用 `Package Acceptance`。它不同于普通 CI:普通 CI 验证源码树,而包验收通过用户在安装或更新后会使用的同一个 Docker E2E harness 来验证单个 tarball。
|
||||
当问题是“这个可安装的 OpenClaw 包作为产品是否可用?”时,使用 `Package Acceptance`。它不同于普通 CI:普通 CI 验证源代码树,而包验收通过用户在安装或更新后执行的同一个 Docker E2E harness 来验证单个 tarball。
|
||||
|
||||
### 作业
|
||||
|
||||
1. `resolve_package` 检出 `workflow_ref`,解析一个包候选,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将两者作为 `package-under-test` 产物上传,并在 GitHub 步骤摘要中打印来源、工作流 ref、包 ref、版本、SHA-256 和 profile。
|
||||
2. `docker_acceptance` 使用 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。可复用工作流会下载该产物,验证 tarball 清单,在需要时准备 package-digest Docker 镜像,并针对该包运行所选 Docker 线路,而不是打包工作流检出内容。当 profile 选择多个目标 `docker_lanes` 时,可复用工作流会准备一次包和共享镜像,然后将这些线路分发为并行的目标 Docker 作业,并使用唯一产物。
|
||||
3. `package_telegram` 可选地调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时运行;如果 Package Acceptance 解析了包,它会安装同一个 `package-under-test` 产物;独立的 Telegram 调度仍可安装已发布的 npm 规范。
|
||||
4. 如果包解析、Docker 验收或可选 Telegram 线路失败,`summary` 会使工作流失败。
|
||||
1. `resolve_package` 检出 `workflow_ref`,解析一个包候选,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将两者作为 `package-under-test` 构件上传,并在 GitHub 步骤摘要中打印来源、工作流引用、包引用、版本、SHA-256 和 profile。
|
||||
2. `docker_acceptance` 使用 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。可复用工作流会下载该构件,验证 tarball 清单,在需要时准备包摘要 Docker 镜像,并针对该包运行所选 Docker lane,而不是打包工作流检出内容。当某个 profile 选择多个目标 `docker_lanes` 时,可复用工作流会先准备一次包和共享镜像,然后将这些 lane 扇出为并行的目标 Docker 作业,并使用唯一构件。
|
||||
3. `package_telegram` 可选调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时运行;如果 Package Acceptance 解析了包,则安装同一个 `package-under-test` 构件;独立 Telegram 分派仍可安装已发布的 npm 规范。
|
||||
4. `summary` 会在包解析、Docker 验收或可选 Telegram lane 失败时使工作流失败。
|
||||
|
||||
### 候选来源
|
||||
|
||||
- `source=npm` 仅接受 `openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。将它用于已发布 beta/稳定版的验收。
|
||||
- `source=ref` 会打包受信任的 `package_ref` 分支、标签或完整提交 SHA。解析器会获取 OpenClaw 分支/标签,验证所选提交可从仓库分支历史或发布标签到达,在分离的工作树中安装依赖,并用 `scripts/package-openclaw-for-docker.mjs` 打包。
|
||||
- `source=npm` 仅接受 `openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。用它执行已发布 beta/稳定版验收。
|
||||
- `source=ref` 会打包受信任的 `package_ref` 分支、标签或完整提交 SHA。解析器会获取 OpenClaw 分支/标签,验证选定提交可从仓库分支历史或发布标签到达,在分离的工作树中安装依赖,并用 `scripts/package-openclaw-for-docker.mjs` 打包。
|
||||
- `source=url` 下载 HTTPS `.tgz`;必须提供 `package_sha256`。
|
||||
- `source=artifact` 从 `artifact_run_id` 和 `artifact_name` 下载一个 `.tgz`;`package_sha256` 可选,但应为对外共享的构件提供。
|
||||
- `source=artifact` 从 `artifact_run_id` 和 `artifact_name` 下载一个 `.tgz`;`package_sha256` 可选,但对外共享的构件应提供它。
|
||||
|
||||
将 `workflow_ref` 和 `package_ref` 分开。`workflow_ref` 是运行测试的受信任工作流/harness 代码。`package_ref` 是在 `source=ref` 时会被打包的源提交。这让当前测试 harness 能验证较旧的受信任源提交,而不运行旧工作流逻辑。
|
||||
保持 `workflow_ref` 和 `package_ref` 分离。`workflow_ref` 是运行测试的受信任工作流/测试框架代码。`package_ref` 是 `source=ref` 时会被打包的源提交。这样,当前测试框架就能验证较旧的受信任源提交,而不运行旧的工作流逻辑。
|
||||
|
||||
### 套件配置档
|
||||
### 套件配置
|
||||
|
||||
- `smoke` — `npm-onboard-channel-agent`、`gateway-network`、`config-reload`
|
||||
- `package` — `npm-onboard-channel-agent`、`doctor-switch`、`update-channel-switch`、`upgrade-survivor`、`bundled-channel-deps-compat`、`plugins-offline`、`plugin-update`
|
||||
- `package` — `npm-onboard-channel-agent`、`doctor-switch`、`update-channel-switch`、`upgrade-survivor`、`published-upgrade-survivor`、`bundled-channel-deps-compat`、`plugins-offline`、`plugin-update`
|
||||
- `product` — `package` 加上 `mcp-channels`、`cron-mcp-cleanup`、`openai-web-search-minimal`、`openwebui`
|
||||
- `full` — 带 OpenWebUI 的完整 Docker 发布路径分块
|
||||
- `custom` — 精确的 `docker_lanes`;当 `suite_profile=custom` 时必需
|
||||
|
||||
`package` 配置档使用离线插件覆盖,因此已发布包验证不会受实时 ClawHub 可用性限制。可选的 Telegram 通道会在 `NPM Telegram Beta E2E` 中复用 `package-under-test` 构件,同时为独立分发保留已发布 npm 规格路径。
|
||||
`package` 配置使用离线插件覆盖范围,因此已发布包验证不会受实时 ClawHub 可用性约束。可选的 Telegram 车道会在 `NPM Telegram Beta E2E` 中复用 `package-under-test` 构件,同时保留已发布 npm 规格路径用于独立调度。
|
||||
|
||||
发布检查会调用 Package Acceptance,并设置 `source=ref`、`package_ref=<release-ref>`、`workflow_ref=<release workflow ref>`、`suite_profile=custom`、`docker_lanes='bundled-channel-deps-compat plugins-offline'` 和 `telegram_mode=mock-openai`。发布路径 Docker 分块覆盖重叠的包/更新/插件通道;Package Acceptance 保留针对同一已解析包 tarball 的构件原生内置渠道兼容性、离线插件和 Telegram 证明。跨 OS 发布检查仍覆盖 OS 特定的新手引导、安装程序和平台行为;包/更新产品验证应从 Package Acceptance 开始。Windows 打包和安装程序全新通道还会验证已安装包可以从原始绝对 Windows 路径导入浏览器控制覆盖。OpenAI 跨 OS 智能体回合冒烟测试在设置时默认使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4-mini`,因此安装和 Gateway 网关证明保持快速且确定。
|
||||
发布检查使用 `source=ref`、`package_ref=<release-ref>`、`workflow_ref=<release workflow ref>`、`suite_profile=custom`、`docker_lanes='bundled-channel-deps-compat plugins-offline'` 和 `telegram_mode=mock-openai` 调用 Package Acceptance。发布路径 Docker 分块覆盖重叠的包/更新/插件车道;Package Acceptance 保留基于构件原生的内置渠道兼容、离线插件和 Telegram 证明,并针对同一个已解析的包 tarball。跨 OS 发布检查仍覆盖特定 OS 的新手引导、安装器和平台行为;包/更新产品验证应从 Package Acceptance 开始。Windows 打包和安装器全新车道还会验证已安装包能从原始绝对 Windows 路径导入浏览器控制覆盖。OpenAI 跨 OS agent-turn 冒烟测试在设置时默认使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4-mini`,因此安装和 Gateway 网关证明保持快速且确定。
|
||||
|
||||
### 旧版兼容窗口
|
||||
|
||||
Package Acceptance 对已发布包有有界的旧版兼容窗口。直到 `2026.4.25` 的包(包括 `2026.4.25-beta.*`)可以使用兼容路径:
|
||||
Package Acceptance 对已发布包有有界的旧版兼容窗口。到 `2026.4.25` 为止的包,包括 `2026.4.25-beta.*`,可以使用兼容路径:
|
||||
|
||||
- `dist/postinstall-inventory.json` 中已知的私有 QA 条目可以指向 tarball 省略的文件;
|
||||
- 当包未暴露 `gateway install --wrapper` 标志时,`doctor-switch` 可以跳过其持久化子用例;
|
||||
- `update-channel-switch` 可以从 tarball 派生的假 git fixture 中修剪缺失的 `pnpm.patchedDependencies`,并可以记录缺失的持久化 `update.channel`;
|
||||
- `update-channel-switch` 可以从 tarball 派生的假 git 夹具中修剪缺失的 `pnpm.patchedDependencies`,并可以记录缺失的持久化 `update.channel`;
|
||||
- 插件冒烟测试可以读取旧版安装记录位置,或接受缺失的 marketplace 安装记录持久化;
|
||||
- `plugin-update` 可以允许配置元数据迁移,同时仍要求安装记录和不重新安装行为保持不变。
|
||||
- `plugin-update` 可以允许配置元数据迁移,同时仍要求安装记录和不重装行为保持不变。
|
||||
|
||||
已发布的 `2026.4.26` 包也可以对已经发布的本地构建元数据戳文件发出警告。后续包必须满足现代契约;相同条件会失败,而不是警告或跳过。
|
||||
已发布的 `2026.4.26` 包也可以对已经发货的本地构建元数据戳文件发出警告。后续包必须满足现代契约;相同条件会失败,而不是警告或跳过。
|
||||
|
||||
### 示例
|
||||
|
||||
@ -238,152 +238,152 @@ gh workflow run package-acceptance.yml \
|
||||
-f docker_lanes='install-e2e plugin-update'
|
||||
```
|
||||
|
||||
调试失败的包验收运行时,先查看 `resolve_package` 摘要,以确认包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 构件:`.artifacts/docker-tests/**/summary.json`、`failures.json`、通道日志、阶段计时和重新运行命令。优先重新运行失败的包配置档或精确 Docker 通道,而不是重新运行完整发布验证。
|
||||
调试失败的包验收运行时,从 `resolve_package` 摘要开始,确认包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 构件:`.artifacts/docker-tests/**/summary.json`、`failures.json`、车道日志、阶段计时和重新运行命令。优先重新运行失败的包配置或精确 Docker 车道,而不是重新运行完整发布验证。
|
||||
|
||||
## 安装冒烟测试
|
||||
|
||||
单独的 `Install Smoke` 工作流通过自己的 `preflight` 作业复用相同的范围脚本。它将冒烟覆盖拆分为 `run_fast_install_smoke` 和 `run_full_install_smoke`。
|
||||
独立的 `Install Smoke` 工作流通过自己的 `preflight` 作业复用同一个范围脚本。它将冒烟覆盖拆分为 `run_fast_install_smoke` 和 `run_full_install_smoke`。
|
||||
|
||||
- **快速路径** 会针对触及 Docker/包表面、内置插件包/manifest 更改,或 Docker 冒烟作业会运行到的核心插件/渠道/Gateway 网关/插件 SDK 表面的拉取请求运行。仅源代码的内置插件更改、仅测试编辑和仅文档编辑不会预留 Docker worker。快速路径会构建一次根 Dockerfile 镜像,检查 CLI,运行 agents delete shared-workspace CLI 冒烟测试,运行容器 gateway-network e2e,验证内置 extension 构建参数,并在 240 秒聚合命令超时内运行有界的内置插件 Docker 配置档(每个场景的 Docker 运行分别设置上限)。
|
||||
- **完整路径** 为夜间定时运行、手动分发、workflow-call 发布检查,以及真正触及安装程序/包/Docker 表面的拉取请求保留 QR 包安装和安装程序 Docker/更新覆盖。在完整模式下,install-smoke 会准备或复用一个目标 SHA 的 GHCR 根 Dockerfile 冒烟镜像,然后将 QR 包安装、根 Dockerfile/Gateway 网关冒烟测试、安装程序/更新冒烟测试和快速内置插件 Docker E2E 作为单独作业运行,因此安装程序工作不会排在根镜像冒烟测试之后等待。
|
||||
- **快速路径**会在拉取请求触及 Docker/包表面、内置插件包/manifest 变更,或 Docker 冒烟作业覆盖的核心插件/渠道/Gateway 网关/插件 SDK 表面时运行。仅源代码的内置插件变更、仅测试编辑和仅文档编辑不会预留 Docker worker。快速路径会构建一次根 Dockerfile 镜像,检查 CLI,运行 agents delete shared-workspace CLI 冒烟测试,运行容器 gateway-network e2e,验证内置扩展构建参数,并在 240 秒聚合命令超时内运行有界内置插件 Docker 配置(每个场景的 Docker 运行单独限时)。
|
||||
- **完整路径**为夜间计划运行、手动调度、workflow-call 发布检查,以及确实触及安装器/包/Docker 表面的拉取请求保留 QR 包安装和安装器 Docker/更新覆盖。在完整模式下,install-smoke 会准备或复用一个目标 SHA GHCR 根 Dockerfile 冒烟镜像,然后将 QR 包安装、根 Dockerfile/Gateway 网关冒烟测试、安装器/更新冒烟测试,以及快速内置插件 Docker E2E 作为独立作业运行,避免安装器工作被阻塞在根镜像冒烟测试之后。
|
||||
|
||||
`main` 推送(包括合并提交)不会强制完整路径;当变更范围逻辑会在推送时请求完整覆盖时,工作流会保留快速 Docker 冒烟测试,并将完整安装冒烟测试留给夜间或发布验证。
|
||||
`main` 推送(包括合并提交)不会强制完整路径;当变更范围逻辑会在推送上请求完整覆盖时,工作流会保留快速 Docker 冒烟测试,并将完整安装冒烟测试留给夜间或发布验证。
|
||||
|
||||
较慢的 Bun 全局安装 image-provider 冒烟测试由 `run_bun_global_install_smoke` 单独控制。它会在夜间计划和发布检查工作流中运行,手动 `Install Smoke` 分发可以选择加入,但拉取请求和 `main` 推送不会运行它。QR 和安装程序 Docker 测试保留自己的安装专用 Dockerfile。
|
||||
慢速 Bun 全局安装 image-provider 冒烟测试由 `run_bun_global_install_smoke` 单独控制。它会在夜间计划和发布检查工作流中运行,手动 `Install Smoke` 调度也可以选择启用它,但拉取请求和 `main` 推送不会运行。QR 和安装器 Docker 测试保留各自面向安装的 Dockerfile。
|
||||
|
||||
## 本地 Docker E2E
|
||||
|
||||
`pnpm test:docker:all` 会预构建一个共享实时测试镜像,将 OpenClaw 打包一次为 npm tarball,并构建两个共享的 `scripts/e2e/Dockerfile` 镜像:
|
||||
`pnpm test:docker:all` 会预构建一个共享实时测试镜像,将 OpenClaw 打包一次为 npm tarball,并构建两个共享 `scripts/e2e/Dockerfile` 镜像:
|
||||
|
||||
- 用于安装程序/更新/插件依赖通道的裸 Node/Git 运行器;
|
||||
- 一个功能镜像,将同一个 tarball 安装到 `/app`,用于普通功能通道。
|
||||
- 用于安装器/更新/插件依赖车道的裸 Node/Git runner;
|
||||
- 一个功能镜像,将同一个 tarball 安装到 `/app`,用于普通功能车道。
|
||||
|
||||
Docker 通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,运行器只执行所选计划。调度器通过 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 为每个通道选择镜像,然后用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行通道。
|
||||
Docker 车道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,runner 只执行选定计划。调度器使用 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 为每条车道选择镜像,然后用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行车道。
|
||||
|
||||
### 可调参数
|
||||
|
||||
| 变量 | 默认值 | 用途 |
|
||||
| -------------------------------------- | ------- | --------------------------------------------------------------------------------------------- |
|
||||
| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 普通通道的主池槽位数。 |
|
||||
| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 对提供商敏感的尾部池槽位数。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 并发实时通道上限,避免提供商限流。 |
|
||||
| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 并发 npm 安装通道上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 并发多服务通道上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | 通道启动之间的错峰间隔,用于避免 Docker daemon 创建风暴;设为 `0` 表示不错峰。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每通道回退超时(120 分钟);选定的实时/尾部通道使用更严格的上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1` 会打印调度器计划而不运行通道。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANES` | unset | 逗号分隔的精确通道列表;跳过清理冒烟测试,使智能体可以复现一个失败通道。 |
|
||||
| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 普通车道的主池槽位数。 |
|
||||
| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 提供商敏感尾池槽位数。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 并发实时车道上限,避免提供商限流。 |
|
||||
| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 并发 npm 安装车道上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 并发多服务车道上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | 车道启动之间的错峰,避免 Docker daemon 创建风暴;设为 `0` 表示不交错。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每条车道的兜底超时(120 分钟);选定实时/尾部车道使用更紧的上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_DRY_RUN` | 未设置 | `1` 会打印调度器计划而不运行车道。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANES` | 未设置 | 逗号分隔的精确车道列表;跳过清理冒烟测试,以便智能体复现单个失败车道。 |
|
||||
|
||||
比其有效上限更重的通道仍可以从空池启动,然后独自运行直到释放容量。本地聚合会预检 Docker,移除陈旧的 OpenClaw E2E 容器,输出活动通道状态,持久化通道计时以进行最长优先排序,并默认在第一次失败后停止调度新的池化通道。
|
||||
比其有效上限更重的车道仍可从空池启动,然后独占运行,直到释放容量。本地聚合会预检 Docker,移除陈旧的 OpenClaw E2E 容器,输出活跃车道 Status,持久化车道计时以用于最长优先排序,并默认在首次失败后停止调度新的池化车道。
|
||||
|
||||
### 可复用的实时/E2E 工作流
|
||||
### 可复用实时/E2E 工作流
|
||||
|
||||
可复用的实时/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪种包、镜像类型、实时镜像、通道和凭证覆盖。随后 `scripts/docker-e2e.mjs` 会将该计划转换为 GitHub 输出和摘要。它要么通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw,要么下载当前运行的包构件,或从 `package_artifact_run_id` 下载包构件;验证 tarball inventory;当计划需要已安装包通道时,通过 Blacksmith 的 Docker 层缓存构建并推送带包摘要标签的裸/功能 GHCR Docker E2E 镜像;并复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有包摘要镜像,而不是重新构建。Docker 镜像拉取会用有界的每次 180 秒超时重试,因此卡住的 registry/cache 流会快速重试,而不是消耗大部分 CI 关键路径时间。
|
||||
可复用实时/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪个包、镜像类型、实时镜像、车道和凭证覆盖。`scripts/docker-e2e.mjs` 随后将该计划转换为 GitHub 输出和摘要。它会通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw,下载当前运行的包构件,或从 `package_artifact_run_id` 下载包构件;验证 tarball 清单;在计划需要已安装包车道时,通过 Blacksmith 的 Docker 层缓存构建并推送带包摘要标签的裸/功能 GHCR Docker E2E 镜像;并复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有的包摘要镜像,而不是重新构建。Docker 镜像拉取会使用有界的 180 秒单次尝试超时进行重试,因此卡住的 registry/cache 流会快速重试,而不是消耗大部分 CI 关键路径。
|
||||
|
||||
### 发布路径分块
|
||||
|
||||
发布 Docker 覆盖会用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行更小的分块作业,因此每个分块只拉取所需的镜像类型,并通过同一个加权调度器执行多个通道:
|
||||
发布 Docker 覆盖会使用较小的分块作业并设置 `OPENCLAW_SKIP_DOCKER_BUILD=1`,这样每个分块只拉取所需的镜像类型,并通过同一个加权调度器执行多条车道:
|
||||
|
||||
- `OPENCLAW_DOCKER_ALL_PROFILE=release-path`
|
||||
- `OPENCLAW_DOCKER_ALL_CHUNK=core | package-update-openai | package-update-anthropic | package-update-core | plugins-runtime-plugins | plugins-runtime-services | plugins-runtime-install-a..h | bundled-channels`
|
||||
|
||||
当前发布版 Docker 分块包括 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a` 到 `plugins-runtime-install-h`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-discord`、`bundled-channels-update-b` 和 `bundled-channels-contracts`。聚合的 `bundled-channels` 分块仍可用于手动一次性重新运行,`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍作为聚合的插件/运行时别名保留。`install-e2e` 通道别名仍是两个提供商安装器通道的聚合手动重新运行别名。`bundled-channels` 分块运行拆分后的 `bundled-channel-*` 和 `bundled-channel-update-*` 通道,而不是串行的全量一体式 `bundled-channel-deps` 通道。
|
||||
当前发布版 Docker 分块为 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a` 到 `plugins-runtime-install-h`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-discord`、`bundled-channels-update-b` 和 `bundled-channels-contracts`。聚合的 `bundled-channels` 分块仍可用于手动一次性重跑,`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍是聚合的插件/运行时别名。`install-e2e` 通道别名仍是两个提供商安装器通道的聚合手动重跑别名。`bundled-channels` 分块运行拆分后的 `bundled-channel-*` 和 `bundled-channel-update-*` 通道,而不是串行的一体化 `bundled-channel-deps` 通道。
|
||||
|
||||
当完整发布路径覆盖率请求它时,OpenWebUI 会合入 `plugins-runtime-services`,并且仅为只针对 OpenWebUI 的分发保留独立的 `openwebui` 分块。内置渠道更新通道会针对临时 npm 网络故障重试一次。
|
||||
当完整发布路径覆盖请求需要时,OpenWebUI 会并入 `plugins-runtime-services`,并且只有在仅 OpenWebUI 的调度中才保留独立的 `openwebui` 分块。内置渠道更新通道会针对临时 npm 网络故障重试一次。
|
||||
|
||||
每个分块都会上传 `.artifacts/docker-tests/`,其中包含通道日志、计时、`summary.json`、`failures.json`、阶段计时、调度器计划 JSON、慢通道表,以及每个通道的重新运行命令。工作流 `docker_lanes` 输入会针对已准备的镜像运行所选通道,而不是运行分块作业,这会把失败通道调试限制在一个有针对性的 Docker 作业内,并为该次运行准备、下载或复用包构件;如果所选通道是实时 Docker 通道,目标作业会在本地为该次重新运行构建实时测试镜像。生成的每通道 GitHub 重新运行命令在这些值存在时会包含 `package_artifact_run_id`、`package_artifact_name` 和已准备镜像输入,因此失败通道可以复用失败运行中的确切包和镜像。
|
||||
每个分块都会上传 `.artifacts/docker-tests/`,其中包含通道日志、耗时、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON、慢通道表,以及逐通道重跑命令。工作流 `docker_lanes` 输入会针对已准备好的镜像运行所选通道,而不是运行分块作业,这让失败通道调试被限制在一个有针对性的 Docker 作业内,并为该运行准备、下载或复用包工件;如果所选通道是实时 Docker 通道,则目标作业会在本地构建实时测试镜像以用于该次重跑。生成的逐通道 GitHub 重跑命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和已准备镜像输入,因此失败通道可以复用失败运行中的确切包和镜像。
|
||||
|
||||
```bash
|
||||
pnpm test:docker:rerun <run-id> # download Docker artifacts and print combined/per-lane targeted rerun commands
|
||||
pnpm test:docker:timings <summary> # slow-lane and phase critical-path summaries
|
||||
```
|
||||
|
||||
定时实时/E2E 工作流每天运行完整发布路径 Docker 套件。
|
||||
定时的实时/E2E 工作流每天运行完整发布路径 Docker 套件。
|
||||
|
||||
## 插件预发布
|
||||
|
||||
`Plugin Prerelease` 是成本更高的产品/包覆盖率检查,因此它是一个独立工作流,由 `Full Release Validation` 分发或由明确的操作员分发。普通拉取请求、`main` 推送和独立的手动 CI 分发会保持该套件关闭。它会把内置插件测试均衡分配到八个扩展工作器;这些扩展分片作业一次最多运行两个插件配置组,每组使用一个 Vitest 工作器和更大的 Node 堆,因此导入密集的插件批次不会创建额外的 CI 作业。
|
||||
`Plugin Prerelease` 是成本更高的产品/包覆盖,因此它是一个由 `Full Release Validation` 或显式操作员调度的独立工作流。普通拉取请求、`main` 推送以及独立的手动 CI 调度会保持该套件关闭。它会在八个扩展工作器之间均衡内置插件测试;这些扩展分片作业一次最多运行两个插件配置组,每个组使用一个 Vitest 工作器和更大的 Node 堆,因此导入密集型插件批次不会创建额外的 CI 作业。
|
||||
|
||||
## QA Lab
|
||||
|
||||
QA Lab 在主智能作用域工作流之外有专用 CI 通道。
|
||||
|
||||
- `Parity gate` 工作流会在匹配的 PR 变更和手动分发时运行;它会构建私有 QA 运行时,并比较模拟 GPT-5.5 和 Opus 4.6 智能体包。
|
||||
- `QA-Lab - All Lanes` 工作流会每晚在 `main` 上运行,也会在手动分发时运行;它会把模拟一致性门禁、实时 Matrix 通道、实时 Telegram 和 Discord 通道展开为并行作业。实时作业使用 `qa-live-shared` 环境,Telegram/Discord 使用 Convex 租约。
|
||||
- `Parity gate` 工作流会在匹配的 PR 变更和手动调度时运行;它会构建私有 QA 运行时,并比较模拟的 GPT-5.5 和 Opus 4.6 智能体包。
|
||||
- `QA-Lab - All Lanes` 工作流每晚在 `main` 上运行,也可手动调度;它会将模拟一致性门、实时 Matrix 通道,以及实时 Telegram 和 Discord 通道作为并行作业展开。实时作业使用 `qa-live-shared` 环境,Telegram/Discord 使用 Convex 租约。
|
||||
|
||||
发布检查会使用确定性的模拟提供商和模拟限定模型(`mock-openai/gpt-5.5` 与 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram 实时传输通道,因此渠道契约会与实时模型延迟和常规提供商插件启动隔离。实时传输 Gateway 网关会禁用记忆搜索,因为 QA 一致性会单独覆盖记忆行为;提供商连通性由单独的实时模型、原生提供商和 Docker 提供商套件覆盖。
|
||||
发布检查使用确定性的模拟提供商和模拟限定模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram 实时传输通道,因此渠道契约会与实时模型延迟和常规提供商插件启动隔离。实时传输 Gateway 网关会禁用记忆搜索,因为 QA 一致性会单独覆盖记忆行为;提供商连通性由单独的实时模型、原生提供商和 Docker 提供商套件覆盖。
|
||||
|
||||
Matrix 在定时门禁和发布门禁中使用 `--profile fast`,仅当检出的 CLI 支持时才添加 `--fail-fast`。CLI 默认值和手动工作流输入仍是 `all`;手动 `matrix_profile=all` 分发始终会把完整 Matrix 覆盖率分片成 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。
|
||||
Matrix 在定时和发布门中使用 `--profile fast`,只有在检出的 CLI 支持时才额外添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 调度始终会将完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。
|
||||
|
||||
`OpenClaw Release Checks` 还会在发布批准之前运行发布关键的 QA Lab 通道;它的 QA 一致性门禁会把候选包和基线包作为并行通道作业运行,然后把两个构件下载到一个小型报告作业中,用于最终一致性比较。
|
||||
`OpenClaw Release Checks` 还会在发布批准前运行发布关键的 QA Lab 通道;其 QA 一致性门会将候选包和基线包作为并行通道作业运行,然后将两个工件下载到一个小型报告作业中,用于最终一致性比较。
|
||||
|
||||
不要把 PR 合并路径放在 `Parity gate` 后面,除非该变更确实触及 QA 运行时、模型包一致性,或一致性工作流拥有的表面。对于普通渠道、配置、文档或单元测试修复,把它视为可选信号,并遵循作用域 CI/检查证据。
|
||||
不要把 PR 落地路径放到 `Parity gate` 后面,除非变更确实触及 QA 运行时、模型包一致性,或一致性工作流拥有的表面。对于常规渠道、配置、文档或单元测试修复,应将其视为可选信号,并遵循作用域化 CI/检查证据。
|
||||
|
||||
## CodeQL
|
||||
|
||||
`CodeQL` 工作流有意作为窄范围的一次性安全扫描器,而不是完整仓库扫描。每日、手动和非草稿拉取请求保护运行会扫描 Actions 工作流代码,以及风险最高的 JavaScript/TypeScript 表面,并使用高置信度安全查询,过滤到高/关键 `security-severity`。
|
||||
`CodeQL` 工作流有意作为窄范围的第一遍安全扫描器,而不是完整仓库扫描。每日、手动和非草稿拉取请求守护运行会扫描 Actions 工作流代码以及风险最高的 JavaScript/TypeScript 表面,并使用高置信度安全查询,筛选高/严重 `security-severity`。
|
||||
|
||||
拉取请求保护保持轻量:它只会因 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src` 下的变更启动,并且运行与定时工作流相同的高置信度安全矩阵。Android 和 macOS CodeQL 不纳入 PR 默认项。
|
||||
拉取请求守护保持轻量:它只会针对 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src` 下的变更启动,并运行与定时工作流相同的高置信度安全矩阵。Android 和 macOS CodeQL 不包含在 PR 默认项中。
|
||||
|
||||
### 安全类别
|
||||
|
||||
| 类别 | 表面 |
|
||||
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/codeql-security-high/core-auth-secrets` | 认证、密钥、沙箱、cron 和网关基线 |
|
||||
| `/codeql-security-high/core-auth-secrets` | 认证、密钥、沙箱、cron 和 Gateway 网关基线 |
|
||||
| `/codeql-security-high/channel-runtime-boundary` | 核心渠道实现契约,以及渠道插件运行时、Gateway 网关、插件 SDK、密钥、审计触点 |
|
||||
| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、网络防护、web-fetch 和插件 SDK SSRF 策略表面 |
|
||||
| `/codeql-security-high/mcp-process-tool-boundary` | MCP 服务器、进程执行辅助工具、出站投递和智能体工具执行门禁 |
|
||||
| `/codeql-security-high/plugin-trust-boundary` | 插件安装、加载器、manifest、注册表、运行时依赖暂存、源码加载和插件 SDK 包契约信任表面 |
|
||||
| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、网络守卫、web-fetch 和插件 SDK SSRF 策略表面 |
|
||||
| `/codeql-security-high/mcp-process-tool-boundary` | MCP 服务器、进程执行帮助器、出站投递和智能体工具执行门 |
|
||||
| `/codeql-security-high/plugin-trust-boundary` | 插件安装、加载器、清单、注册表、运行时依赖暂存、源码加载和插件 SDK 包契约信任表面 |
|
||||
|
||||
### 平台特定安全分片
|
||||
|
||||
- `CodeQL Android Critical Security` — 定时 Android 安全分片。在工作流完整性检查接受的最小 Blacksmith Linux 运行器上为 CodeQL 手动构建 Android 应用。上传到 `/codeql-critical-security/android` 下。
|
||||
- `CodeQL macOS Critical Security` — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上为 CodeQL 手动构建 macOS 应用,从上传的 SARIF 中过滤掉依赖构建结果,并上传到 `/codeql-critical-security/macos` 下。它保持在每日默认项之外,因为即使干净运行,macOS 构建也会主导运行时间。
|
||||
- `CodeQL Android Critical Security` — 定时 Android 安全分片。在工作流完整性检查接受的最小 Blacksmith Linux 运行器上手动构建 Android 应用以供 CodeQL 使用。上传到 `/codeql-critical-security/android` 下。
|
||||
- `CodeQL macOS Critical Security` — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上手动构建 macOS 应用以供 CodeQL 使用,从上传的 SARIF 中过滤掉依赖构建结果,并上传到 `/codeql-critical-security/macos` 下。它保持在每日默认项之外,因为即使在干净状态下,macOS 构建也会主导运行时间。
|
||||
|
||||
### 关键质量类别
|
||||
### Critical Quality 类别
|
||||
|
||||
`CodeQL Critical Quality` 是对应的非安全分片。它只在较小的 Blacksmith Linux 运行器上,对窄范围高价值表面运行错误严重级别的非安全 JavaScript/TypeScript 质量查询。它的拉取请求保护有意比定时配置更小:非草稿 PR 只会为智能体命令/模型/工具执行和回复分发代码、配置 schema/迁移/IO 代码、认证/密钥/沙箱/安全代码、核心渠道和内置渠道插件运行时、Gateway 网关协议/服务器方法、记忆运行时/SDK 粘合代码、MCP/进程/出站投递、提供商运行时/模型目录、会话诊断/投递队列、插件加载器、插件 SDK/包契约或插件 SDK 回复运行时变更,运行匹配的 `agent-runtime-boundary`、`config-boundary`、`core-auth-secrets`、`channel-runtime-boundary`、`gateway-runtime-boundary`、`memory-runtime-boundary`、`mcp-process-runtime-boundary`、`provider-runtime-boundary`、`session-diagnostics-boundary`、`plugin-boundary`、`plugin-sdk-package-contract` 和 `plugin-sdk-reply-runtime` 分片。CodeQL 配置和质量工作流变更会运行全部十二个 PR 质量分片。
|
||||
`CodeQL Critical Quality` 是对应的非安全分片。它只在较小的 Blacksmith Linux 运行器上,对窄范围高价值表面运行错误严重性、非安全 JavaScript/TypeScript 质量查询。它的拉取请求守护有意小于定时配置:非草稿 PR 只会针对智能体命令/模型/工具执行与回复调度代码、配置架构/迁移/IO 代码、认证/密钥/沙箱/安全代码、核心渠道与内置渠道插件运行时、Gateway 网关协议/服务器方法、记忆运行时/SDK 粘合层、MCP/进程/出站投递、提供商运行时/模型目录、会话诊断/投递队列、插件加载器、插件 SDK/包契约,或插件 SDK 回复运行时变更,运行匹配的 `agent-runtime-boundary`、`config-boundary`、`core-auth-secrets`、`channel-runtime-boundary`、`gateway-runtime-boundary`、`memory-runtime-boundary`、`mcp-process-runtime-boundary`、`provider-runtime-boundary`、`session-diagnostics-boundary`、`plugin-boundary`、`plugin-sdk-package-contract` 和 `plugin-sdk-reply-runtime` 分片。CodeQL 配置和质量工作流变更会运行全部十二个 PR 质量分片。
|
||||
|
||||
手动分发接受:
|
||||
手动调度接受:
|
||||
|
||||
```
|
||||
profile=all|agent-runtime-boundary|config-boundary|core-auth-secrets|channel-runtime-boundary|gateway-runtime-boundary|memory-runtime-boundary|mcp-process-runtime-boundary|plugin-boundary|plugin-sdk-package-contract|plugin-sdk-reply-runtime|provider-runtime-boundary|session-diagnostics-boundary
|
||||
```
|
||||
|
||||
窄范围配置是用于单独运行一个质量分片的教学/迭代钩子。
|
||||
窄配置是用于单独运行一个质量分片的教学/迭代钩子。
|
||||
|
||||
| 类别 | 表面 |
|
||||
| ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/codeql-critical-quality/core-auth-secrets` | 认证、密钥、沙箱、cron 和 Gateway 网关安全边界代码 |
|
||||
| `/codeql-critical-quality/config-boundary` | 配置 schema、迁移、规范化和 IO 契约 |
|
||||
| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议 schema 和服务器方法契约 |
|
||||
| `/codeql-critical-quality/channel-runtime-boundary` | 核心渠道和内置渠道插件实现契约 |
|
||||
| `/codeql-critical-quality/agent-runtime-boundary` | 命令执行、模型/提供商分发、自动回复分发与队列,以及 ACP 控制平面运行时契约 |
|
||||
| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 服务器和工具桥接、进程监控帮助函数,以及出站投递契约 |
|
||||
| `/codeql-critical-quality/memory-runtime-boundary` | 记忆主机 SDK、记忆运行时 facade、记忆插件 SDK 别名、记忆运行时激活胶水代码,以及记忆 Doctor 命令 |
|
||||
| `/codeql-critical-quality/session-diagnostics-boundary` | 回复队列内部机制、会话投递队列、出站会话绑定/投递帮助函数、诊断事件/日志包表面,以及会话 Doctor CLI 契约 |
|
||||
| `/codeql-critical-quality/plugin-sdk-reply-runtime` | 插件 SDK 入站回复分发、回复 payload/分块/运行时帮助函数、渠道回复选项、投递队列,以及会话/thread 绑定帮助函数 |
|
||||
| `/codeql-critical-quality/provider-runtime-boundary` | 模型目录规范化、提供商认证和设备发现、提供商运行时注册、提供商默认值/目录,以及 web/search/fetch/embedding 注册表 |
|
||||
| `/codeql-critical-quality/ui-control-plane` | 控制 UI 引导、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约 |
|
||||
| `/codeql-critical-quality/web-media-runtime-boundary` | 核心 web fetch/search、媒体 IO、媒体理解、图像生成,以及媒体生成运行时契约 |
|
||||
| `/codeql-critical-quality/plugin-boundary` | 加载器、注册表、公开表面,以及插件 SDK 入口点契约 |
|
||||
| `/codeql-critical-quality/plugin-sdk-package-contract` | 已发布的包侧插件 SDK 源码和插件包契约帮助函数 |
|
||||
| 类别 | 表面 |
|
||||
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/codeql-critical-quality/core-auth-secrets` | 凭证、密钥、沙箱、cron 和 Gateway 网关安全边界代码 |
|
||||
| `/codeql-critical-quality/config-boundary` | 配置 schema、迁移、规范化和 IO 契约 |
|
||||
| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议 schema 和服务器方法契约 |
|
||||
| `/codeql-critical-quality/channel-runtime-boundary` | 核心渠道和内置渠道插件实现契约 |
|
||||
| `/codeql-critical-quality/agent-runtime-boundary` | 命令执行、模型/提供商分发、自动回复分发与队列,以及 ACP 控制平面运行时契约 |
|
||||
| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 服务器和工具桥接、进程监管辅助工具,以及出站投递契约 |
|
||||
| `/codeql-critical-quality/memory-runtime-boundary` | Memory 主机 SDK、memory 运行时门面、memory 插件 SDK 别名、memory 运行时激活粘合层,以及 memory doctor 命令 |
|
||||
| `/codeql-critical-quality/session-diagnostics-boundary` | 回复队列内部机制、会话投递队列、出站会话绑定/投递辅助工具、诊断事件/日志包表面,以及会话 doctor CLI 契约 |
|
||||
| `/codeql-critical-quality/plugin-sdk-reply-runtime` | 插件 SDK 入站回复分发、回复载荷/分块/运行时辅助工具、渠道回复选项、投递队列,以及会话/线程绑定辅助工具 |
|
||||
| `/codeql-critical-quality/provider-runtime-boundary` | 模型目录规范化、提供商凭证和设备发现、提供商运行时注册、提供商默认值/目录,以及 web/search/fetch/embedding 注册表 |
|
||||
| `/codeql-critical-quality/ui-control-plane` | 控制 UI 启动、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约 |
|
||||
| `/codeql-critical-quality/web-media-runtime-boundary` | 核心 Web 抓取/搜索、媒体 IO、媒体理解、图像生成,以及媒体生成运行时契约 |
|
||||
| `/codeql-critical-quality/plugin-boundary` | 加载器、注册表、公共表面,以及插件 SDK 入口点契约 |
|
||||
| `/codeql-critical-quality/plugin-sdk-package-contract` | 已发布包侧插件 SDK 源码和插件包契约辅助工具 |
|
||||
|
||||
质量与安全保持分离,这样质量发现就可以被排期、度量、禁用或扩展,而不会遮蔽安全信号。Swift、Python 和内置插件 CodeQL 扩展只应在窄范围 profile 具有稳定运行时和信号之后,作为有作用域或分片的后续工作再加回来。
|
||||
质量与安全保持分离,这样质量发现就可以被排期、度量、禁用或扩展,而不会掩盖安全信号。只有在窄配置文件具备稳定运行时和稳定信号之后,才应将 Swift、Python 和内置插件 CodeQL 扩展作为有作用域或分片的后续工作加回。
|
||||
|
||||
## 维护工作流
|
||||
|
||||
### Docs Agent
|
||||
### 文档智能体
|
||||
|
||||
`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的变更保持一致。它没有纯定时计划:`main` 上一次成功的非 bot push CI 运行可以触发它,手动 dispatch 也可以直接运行它。当 `main` 已经向前移动,或过去一小时内已经创建过另一次未跳过的 Docs Agent 运行时,workflow-run 调用会跳过。运行时,它会审查从上一次未跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此一次每小时运行可以覆盖自上次文档检查以来累积的所有 main 变更。
|
||||
`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的变更保持一致。它没有纯定时计划:`main` 上一次成功的非 bot push CI 运行可以触发它,手动分发也可以直接运行它。当 `main` 已经前移,或者过去一小时内已经创建过另一个未跳过的 Docs Agent 运行时,workflow-run 调用会跳过。运行时,它会审查从上一个未跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此一次每小时运行可以覆盖自上次文档处理以来累积的所有 main 变更。
|
||||
|
||||
### Test Performance Agent
|
||||
### 测试性能智能体
|
||||
|
||||
`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于处理慢测试。它没有纯定时计划:`main` 上一次成功的非 bot push CI 运行可以触发它,但如果当天 UTC 已经有另一次 workflow-run 调用运行过或正在运行,它会跳过。手动 dispatch 会绕过这个每日活动门禁。该通道会构建完整套件分组 Vitest 性能报告,让 Codex 只做小范围、保留覆盖率的测试性能修复,而不是大规模重构,然后重新运行完整套件报告,并拒绝会减少通过基线测试数量的变更。如果基线有失败测试,Codex 只能修复明显的失败,并且 agent 后的完整套件报告必须通过,才会提交任何内容。当 `main` 在 bot push 落地前前进时,该通道会 rebase 已验证的补丁,重新运行 `pnpm check:changed`,并重试 push;有冲突的过期补丁会被跳过。它使用 GitHub 托管的 Ubuntu,因此 Codex action 可以保持与 docs agent 相同的 drop-sudo 安全姿态。
|
||||
`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于处理慢测试。它没有纯定时计划:`main` 上一次成功的非 bot push CI 运行可以触发它,但如果当天 UTC 已经有另一个 workflow-run 调用运行过或正在运行,它会跳过。手动分发会绕过这个每日活动门禁。该通道会构建完整套件分组 Vitest 性能报告,让 Codex 只做保留覆盖率的小型测试性能修复,而不是大范围重构,然后重新运行完整套件报告,并拒绝会降低通过基线测试数量的变更。如果基线存在失败测试,Codex 只能修复明显失败,并且 agent 后的完整套件报告必须通过,之后才会提交任何内容。当 `main` 在 bot push 落地前前移时,该通道会 rebase 已验证的补丁,重新运行 `pnpm check:changed`,并重试 push;存在冲突的过期补丁会被跳过。它使用 GitHub 托管的 Ubuntu,因此 Codex action 可以保持与 docs agent 相同的 drop-sudo 安全姿态。
|
||||
|
||||
### 合并后的重复 PR
|
||||
|
||||
`Duplicate PRs After Merge` 工作流是一个手动维护者工作流,用于落地后的重复项清理。它默认 dry-run,并且只有在 `apply=true` 时才会关闭明确列出的 PR。在修改 GitHub 之前,它会验证已落地 PR 已合并,并验证每个重复 PR 要么有共享引用的 issue,要么有重叠的变更 hunk。
|
||||
`Duplicate PRs After Merge` 工作流是一个手动维护者工作流,用于落地后的重复项清理。它默认 dry-run,并且只有在 `apply=true` 时才会关闭明确列出的 PR。在变更 GitHub 之前,它会验证已落地 PR 已合并,并且每个重复项都有共享的引用 issue 或重叠的变更 hunk。
|
||||
|
||||
```bash
|
||||
gh workflow run duplicate-after-merge.yml \
|
||||
@ -394,25 +394,25 @@ gh workflow run duplicate-after-merge.yml \
|
||||
|
||||
## 本地检查门禁和变更路由
|
||||
|
||||
本地 changed-lane 逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。该本地检查门禁在架构边界方面比宽泛的 CI 平台范围更严格:
|
||||
本地变更通道逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。这个本地检查门禁在架构边界方面比宽泛的 CI 平台范围更严格:
|
||||
|
||||
- 核心生产变更会运行核心 prod 和核心测试类型检查,以及核心 lint/guard;
|
||||
- 仅核心测试变更只运行核心测试类型检查和核心 lint;
|
||||
- 插件生产变更会运行插件 prod 和插件测试类型检查,以及插件 lint;
|
||||
- 仅插件测试变更会运行插件测试类型检查和插件 lint;
|
||||
- 公开插件 SDK 或插件契约变更会扩展到插件类型检查,因为插件依赖这些核心契约(Vitest 插件 sweep 仍然是显式测试工作);
|
||||
- 仅发布元数据的版本号 bump 会运行定向版本/config/root-dependency 检查;
|
||||
- 未知 root/config 变更会安全失败到所有检查通道。
|
||||
- 核心生产变更会运行核心生产和核心测试 typecheck,以及核心 lint/guard;
|
||||
- 仅核心测试变更只运行核心测试 typecheck 和核心 lint;
|
||||
- 插件生产变更会运行插件生产和插件测试 typecheck,以及插件 lint;
|
||||
- 仅插件测试变更会运行插件测试 typecheck 和插件 lint;
|
||||
- 公共插件 SDK 或插件契约变更会扩展到插件 typecheck,因为插件依赖这些核心契约(Vitest 插件扫描仍然是显式测试工作);
|
||||
- 仅发布元数据的版本号提升会运行定向版本/配置/根依赖检查;
|
||||
- 未知根目录/配置变更会故障安全地进入所有检查通道。
|
||||
|
||||
本地 changed-test 路由位于 `scripts/test-projects.test-support.mjs`,并且刻意比 `check:changed` 更便宜:直接测试编辑会运行自身,源码编辑优先使用显式映射,然后是同级测试和 import-graph 依赖项。共享 group-room 投递配置是显式映射之一:对 group visible-reply 配置、源回复投递模式或 message-tool 系统提示词的变更,会通过核心回复测试以及 Discord 和 Slack 投递回归测试进行路由,从而让共享默认值变更在第一次 PR push 之前失败。只有当变更足够 harness-wide,以至于廉价映射集合不是可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
本地变更测试路由位于 `scripts/test-projects.test-support.mjs`,并且有意比 `check:changed` 更便宜:直接测试编辑会运行自身,源码编辑优先使用显式映射,然后是同级测试和导入图依赖项。共享群组聊天室投递配置是显式映射之一:对群组可见回复配置、源回复投递模式或消息工具系统提示词的变更,会通过核心回复测试以及 Discord 和 Slack 投递回归测试路由,这样共享默认值变更会在第一次 PR push 前失败。只有当变更足够 harness-wide,以至于廉价映射集合不是可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
|
||||
## Testbox 验证
|
||||
|
||||
从仓库根目录运行 Testbox,并优先为宽范围证明使用新预热的 box。在一个复用、过期或刚报告异常大同步的 box 上投入慢门禁之前,先在该 box 内运行 `pnpm testbox:sanity`。
|
||||
从仓库根目录运行 Testbox,并且对宽泛证明优先使用新预热的 box。在复用、过期或刚刚报告异常大同步的 box 上花费慢门禁之前,先在 box 内运行 `pnpm testbox:sanity`。
|
||||
|
||||
当所需根文件(例如 `pnpm-lock.yaml`)消失,或 `git status --short` 显示至少 200 个已跟踪删除时,完整性检查会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;应停止该 box 并预热一个新的,而不是调试产品测试失败。对于有意的大量删除 PR,为该完整性检查运行设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。
|
||||
当所需根文件(例如 `pnpm-lock.yaml`)消失,或者 `git status --short` 显示至少 200 个已跟踪删除时,完整性检查会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;停止该 box 并预热一个新的,而不是调试产品测试失败。对于有意的大规模删除 PR,请为该完整性运行设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。
|
||||
|
||||
如果本地 Blacksmith CLI 调用在同步阶段停留超过五分钟且没有同步后输出,`pnpm testbox:run` 也会终止它。设置 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可禁用该保护,或为异常大的本地 diff 使用更大的毫秒值。
|
||||
`pnpm testbox:run` 也会终止在同步阶段停留超过五分钟且没有同步后输出的本地 Blacksmith CLI 调用。设置 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可禁用该保护,或者为异常大的本地 diff 使用更大的毫秒值。
|
||||
|
||||
## 相关
|
||||
|
||||
|
||||
@ -3,32 +3,32 @@ read_when:
|
||||
- 在本地或 CI 中运行测试
|
||||
- 为模型/提供商缺陷添加回归测试
|
||||
- 调试 Gateway 网关 + 智能体行为
|
||||
summary: 测试工具包:单元/e2e/真实环境测试套件、Docker 运行器,以及每项测试涵盖的内容
|
||||
summary: 测试工具包:单元/e2e/live 套件、Docker 运行器,以及每项测试覆盖的内容
|
||||
title: 测试
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T18:11:07Z"
|
||||
generated_at: "2026-04-30T23:44:08Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 470a96c6b47c2708950d05adc4a4efba5fe290f0675a131e2888d2d0032d5953
|
||||
source_hash: f663a4476a59e4ccc2a6ea5b43eb0079534945eac37374bec891d6cccb1e941c
|
||||
source_path: help/testing.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw 有三个 Vitest 测试套件(单元/集成、端到端、真实环境)和一小组 Docker 运行器。本文档是一份“我们如何测试”的指南:
|
||||
OpenClaw 有三个 Vitest 测试套件(单元/集成、E2E、实测)和一小组 Docker 运行器。本文是“我们如何测试”指南:
|
||||
|
||||
- 每个测试套件覆盖什么(以及它刻意_不_覆盖什么)。
|
||||
- 常见工作流(本地、推送前、调试)应该运行哪些命令。
|
||||
- 真实环境测试如何发现凭证并选择模型/提供商。
|
||||
- 如何为真实世界中的模型/提供商问题添加回归测试。
|
||||
- 每个套件覆盖什么(以及它刻意 _不_ 覆盖什么)。
|
||||
- 常见工作流应运行哪些命令(本地、推送前、调试)。
|
||||
- 实测测试如何发现凭证并选择模型/提供商。
|
||||
- 如何为真实世界的模型/提供商问题添加回归测试。
|
||||
|
||||
<Note>
|
||||
**QA 栈(qa-lab、qa-channel、真实传输通道)**单独记录在以下文档中:
|
||||
**QA 栈(qa-lab、qa-channel、实测传输通道)**单独记录在:
|
||||
|
||||
- [QA overview](/zh-CN/concepts/qa-e2e-automation) — 架构、命令表面、场景编写。
|
||||
- [QA overview](/zh-CN/concepts/qa-e2e-automation) — 架构、命令界面、场景编写。
|
||||
- [Matrix QA](/zh-CN/concepts/qa-matrix) — `pnpm openclaw qa matrix` 的参考。
|
||||
- [QA channel](/zh-CN/channels/qa-channel) — 由仓库支持的场景使用的合成传输插件。
|
||||
- [QA channel](/zh-CN/channels/qa-channel) — 仓库支持场景使用的合成传输插件。
|
||||
|
||||
本页覆盖常规测试套件以及 Docker/Parallels 运行器的运行方式。下面的 QA 专用运行器部分([QA 专用运行器](#qa-specific-runners))列出了具体的 `qa` 调用,并指回上面的参考资料。
|
||||
本页覆盖常规测试套件和 Docker/Parallels 运行器的运行方式。下面的 QA 专用运行器部分([QA 专用运行器](#qa-specific-runners))列出了具体的 `qa` 调用,并指回上面的参考文档。
|
||||
</Note>
|
||||
|
||||
## 快速开始
|
||||
@ -36,164 +36,150 @@ OpenClaw 有三个 Vitest 测试套件(单元/集成、端到端、真实环
|
||||
大多数时候:
|
||||
|
||||
- 完整门禁(推送前预期运行):`pnpm build && pnpm check && pnpm check:test-types && pnpm test`
|
||||
- 在资源充足的机器上更快地运行本地完整测试套件:`pnpm test:max`
|
||||
- 直接的 Vitest 监听循环:`pnpm test:watch`
|
||||
- 在资源充裕的机器上更快地运行本地完整套件:`pnpm test:max`
|
||||
- 直接 Vitest 监听循环:`pnpm test:watch`
|
||||
- 直接按文件定位现在也会路由插件/渠道路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts`
|
||||
- 当你在迭代单个失败时,优先使用定向运行。
|
||||
- 当你在迭代单个失败时,优先先运行有针对性的命令。
|
||||
- Docker 支持的 QA 站点:`pnpm qa:lab:up`
|
||||
- Linux VM 支持的 QA 通道:`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline`
|
||||
|
||||
当你改动测试或想要额外信心时:
|
||||
|
||||
- 覆盖率门禁:`pnpm test:coverage`
|
||||
- 端到端测试套件:`pnpm test:e2e`
|
||||
- E2E 套件:`pnpm test:e2e`
|
||||
|
||||
当调试真实提供商/模型时(需要真实凭证):
|
||||
调试真实提供商/模型时(需要真实凭证):
|
||||
|
||||
- 真实环境测试套件(模型 + Gateway 网关工具/图片探针):`pnpm test:live`
|
||||
- 安静地定位一个真实环境测试文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts`
|
||||
- Docker 真实环境模型扫描:`pnpm test:docker:live-models`
|
||||
- 每个选中的模型现在会运行一个文本轮次和一个小型文件读取风格探针。
|
||||
元数据声明支持 `image` 输入的模型还会运行一个微型图片轮次。
|
||||
在隔离提供商故障时,可用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` 或
|
||||
- 实测套件(模型 + Gateway 网关工具/图像探针):`pnpm test:live`
|
||||
- 静默定位一个实测文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts`
|
||||
- Docker 实测模型扫描:`pnpm test:docker:live-models`
|
||||
- 每个选中的模型现在会运行一个文本轮次,以及一个小型文件读取风格探针。
|
||||
元数据声明支持 `image` 输入的模型还会运行一个小型图像轮次。
|
||||
在隔离提供商失败时,可用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` 或
|
||||
`OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0` 禁用额外探针。
|
||||
- CI 覆盖范围:每日 `OpenClaw Scheduled Live And E2E Checks` 和手动
|
||||
`OpenClaw Release Checks` 都会调用可复用的真实环境/端到端工作流,并设置
|
||||
`include_live_suites: true`,其中包括按提供商分片的独立 Docker 真实环境模型
|
||||
- CI 覆盖:每日 `OpenClaw Scheduled Live And E2E Checks` 和手动
|
||||
`OpenClaw Release Checks` 都会调用可复用的实测/E2E 工作流,并设置
|
||||
`include_live_suites: true`,其中包含按提供商分片的独立 Docker 实测模型
|
||||
矩阵任务。
|
||||
- 对于聚焦的 CI 重跑,触发 `OpenClaw Live And E2E Checks (Reusable)`,
|
||||
并设置 `include_live_suites: true` 和 `live_models_only: true`。
|
||||
- 将新的高信号提供商密钥加入 `scripts/ci-hydrate-live-auth.sh`,
|
||||
- 将新的高信号提供商密钥添加到 `scripts/ci-hydrate-live-auth.sh`,
|
||||
以及 `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 和它的
|
||||
定时/发布调用方。
|
||||
- 原生 Codex 绑定聊天冒烟测试:`pnpm test:docker:live-codex-bind`
|
||||
- 针对 Codex 应用服务器路径运行 Docker 真实环境通道,绑定一个合成的
|
||||
Slack 私信和 `/codex bind`,执行 `/codex fast` 和
|
||||
`/codex permissions`,然后验证普通回复和图片附件
|
||||
通过原生插件绑定路由,而不是通过 ACP。
|
||||
- 针对 Codex 应用服务器路径运行 Docker 实测通道,使用 `/codex bind` 绑定一个合成
|
||||
Slack 私信,执行 `/codex fast` 和
|
||||
`/codex permissions`,然后验证普通回复和图像附件会通过原生插件绑定路由,而不是 ACP。
|
||||
- Codex 应用服务器 harness 冒烟测试:`pnpm test:docker:live-codex-harness`
|
||||
- 通过插件拥有的 Codex 应用服务器 harness 运行 Gateway 网关智能体轮次,
|
||||
验证 `/codex status` 和 `/codex models`,默认还会执行图片、
|
||||
cron MCP、子智能体和 Guardian 探针。在隔离其他 Codex
|
||||
应用服务器故障时,可用 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0`
|
||||
禁用子智能体探针。若要进行聚焦的子智能体检查,请禁用其他探针:
|
||||
- 通过插件拥有的 Codex 应用服务器 harness 运行 Gateway 网关 agent 轮次,
|
||||
验证 `/codex status` 和 `/codex models`,并默认执行图像、
|
||||
cron MCP、子 agent 和 Guardian 探针。在隔离其他 Codex
|
||||
应用服务器失败时,可用
|
||||
`OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0` 禁用子 agent 探针。要进行聚焦的子 agent 检查,请禁用其他探针:
|
||||
`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=1 pnpm test:docker:live-codex-harness`。
|
||||
除非设置了 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`,
|
||||
否则它会在子智能体探针后退出。
|
||||
除非设置了
|
||||
`OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`,否则它会在子 agent 探针之后退出。
|
||||
- Crestodian 救援命令冒烟测试:`pnpm test:live:crestodian-rescue-channel`
|
||||
- 对消息渠道救援命令表面的可选双重保险检查。
|
||||
它会执行 `/crestodian status`,排队一次持久模型
|
||||
- 可选的双保险检查,用于消息渠道救援命令界面。它会执行 `/crestodian status`,排队一个持久模型
|
||||
变更,回复 `/crestodian yes`,并验证审计/配置写入路径。
|
||||
- Crestodian planner Docker 冒烟测试:`pnpm test:docker:crestodian-planner`
|
||||
- 在无配置容器中运行 Crestodian,并在 `PATH`
|
||||
上提供一个假的 Claude CLI,验证模糊 planner 回退会转换为经过审计的类型化
|
||||
配置写入。
|
||||
- Crestodian 规划器 Docker 冒烟测试:`pnpm test:docker:crestodian-planner`
|
||||
- 在无配置容器中运行 Crestodian,`PATH` 上放置一个假的 Claude CLI,
|
||||
并验证模糊规划器回退会转化为一次经审计的类型化配置写入。
|
||||
- Crestodian 首次运行 Docker 冒烟测试:`pnpm test:docker:crestodian-first-run`
|
||||
- 从空的 OpenClaw 状态目录启动,将裸 `openclaw` 路由到
|
||||
Crestodian,应用设置/模型/智能体/Discord 插件 + SecretRef 写入,
|
||||
验证配置,并验证审计条目。相同的 Ring 0 设置路径
|
||||
也在 QA Lab 中由
|
||||
- 从空的 OpenClaw 状态目录开始,将裸 `openclaw` 路由到
|
||||
Crestodian,应用设置/模型/agent/Discord 插件 + SecretRef 写入,
|
||||
验证配置,并验证审计条目。同一 Ring 0 设置路径也在 QA Lab 中由
|
||||
`pnpm openclaw qa suite --scenario crestodian-ring-zero-setup` 覆盖。
|
||||
- Moonshot/Kimi 成本冒烟测试:设置 `MOONSHOT_API_KEY` 后,运行
|
||||
`openclaw models list --provider moonshot --json`,然后针对
|
||||
`moonshot/kimi-k2.6` 运行一个隔离的
|
||||
`openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json`。
|
||||
验证 JSON 报告 Moonshot/K2.6,并且助手转录记录存储了标准化的 `usage.cost`。
|
||||
验证 JSON 报告 Moonshot/K2.6,并且助手转录存储了规范化的 `usage.cost`。
|
||||
|
||||
<Tip>
|
||||
当你只需要一个失败用例时,优先通过下文描述的 allowlist 环境变量缩小真实环境测试范围。
|
||||
当你只需要一个失败用例时,优先通过下面描述的允许列表环境变量缩小实测测试范围。
|
||||
</Tip>
|
||||
|
||||
## QA 专用运行器
|
||||
|
||||
当你需要 QA-lab 的真实感时,这些命令与主测试套件并列使用:
|
||||
当你需要 QA-lab 真实度时,这些命令位于主测试套件旁边:
|
||||
|
||||
CI 在专用工作流中运行 QA Lab。`Parity gate` 在匹配的 PR 上运行,
|
||||
也可通过使用模拟提供商的手动触发运行。`QA-Lab - All Lanes` 每晚在
|
||||
`main` 上运行,也可通过手动触发运行,包含模拟 parity gate、真实 Matrix 通道、
|
||||
Convex 托管的真实 Telegram 通道,以及 Convex 托管的真实 Discord 通道,
|
||||
作为并行任务。定时 QA 和发布检查会显式传入 Matrix `--profile fast`,
|
||||
而 Matrix CLI 和手动工作流输入默认仍为 `all`;手动触发可以将 `all`
|
||||
分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep`
|
||||
和 `e2ee-cli` 任务。`OpenClaw Release Checks` 在发布批准前运行 parity
|
||||
以及 fast Matrix 和 Telegram 通道,发布传输检查使用
|
||||
`mock-openai/gpt-5.5`,以便保持确定性并避免普通提供商插件启动。
|
||||
这些真实传输 Gateway 网关会禁用记忆搜索;记忆行为仍由 QA parity 测试套件覆盖。
|
||||
CI 在专用工作流中运行 QA Lab。`Parity gate` 会在匹配的 PR 上运行,也可通过手动触发使用模拟提供商运行。`QA-Lab - All Lanes` 每晚在
|
||||
`main` 上运行,也可通过手动触发运行,并将模拟一致性门禁、实测 Matrix 通道、
|
||||
Convex 管理的实测 Telegram 通道,以及 Convex 管理的实测 Discord 通道作为
|
||||
并行任务。定时 QA 和发布检查会显式传递 Matrix `--profile fast`,
|
||||
而 Matrix CLI 和手动工作流输入默认仍为
|
||||
`all`;手动触发可将 `all` 分片为 `transport`、`media`、`e2ee-smoke`、
|
||||
`e2ee-deep` 和 `e2ee-cli` 任务。`OpenClaw Release Checks` 会在发布批准前运行一致性检查,以及快速 Matrix 和 Telegram 通道,并使用
|
||||
`mock-openai/gpt-5.5` 执行发布传输检查,使其保持确定性并避免常规提供商插件启动。这些实测传输 Gateway 网关会禁用记忆搜索;记忆行为仍由 QA 一致性套件覆盖。
|
||||
|
||||
完整发布真实媒体分片使用
|
||||
完整发布实测媒体分片使用
|
||||
`ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`,其中已经包含
|
||||
`ffmpeg` 和 `ffprobe`。Docker 真实环境模型/后端分片使用共享的
|
||||
`ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像,该镜像针对选中的
|
||||
提交只构建一次,然后用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 拉取,而不是在每个分片中重新构建。
|
||||
`ffmpeg` 和 `ffprobe`。Docker 实测模型/后端分片使用共享的
|
||||
`ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像,该镜像会为每个选中
|
||||
提交构建一次,然后使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 拉取它,而不是在每个分片内部重建。
|
||||
|
||||
- `pnpm openclaw qa suite`
|
||||
- 直接在宿主机上运行由仓库支持的 QA 场景。
|
||||
- 默认使用隔离的 Gateway 网关 worker 并行运行多个选中的场景。
|
||||
`qa-channel` 默认并发数为 4(受选中场景数量限制)。使用
|
||||
`--concurrency <count>` 调整 worker 数量,或使用 `--concurrency 1`
|
||||
运行旧的串行通道。
|
||||
- 任一场景失败时以非零退出。当你想要产物但不想要失败退出码时,
|
||||
使用 `--allow-failures`。
|
||||
- 直接在主机上运行仓库支持的 QA 场景。
|
||||
- 默认使用隔离的 Gateway 网关 worker 并行运行多个选中的场景。`qa-channel` 默认并发为 4(受
|
||||
选中场景数量限制)。使用 `--concurrency <count>` 调整 worker
|
||||
数量,或使用 `--concurrency 1` 运行较旧的串行通道。
|
||||
- 任何场景失败时以非零状态退出。当你想要产物但不想要失败退出码时,使用 `--allow-failures`。
|
||||
- 支持提供商模式 `live-frontier`、`mock-openai` 和 `aimock`。
|
||||
`aimock` 会启动一个本地 AIMock 支持的提供商服务器,用于实验性的
|
||||
fixture 和协议模拟覆盖,而不会替换场景感知的 `mock-openai` 通道。
|
||||
`aimock` 会启动一个本地 AIMock 支持的提供商服务器,用于实验性
|
||||
固件和协议模拟覆盖,而不会替代具备场景感知能力的
|
||||
`mock-openai` 通道。
|
||||
- `pnpm test:gateway:cpu-scenarios`
|
||||
- 运行 Gateway 网关启动基准测试和一个小型模拟 QA Lab 场景包
|
||||
- 运行 Gateway 网关启动基准,加上一小组模拟 QA Lab 场景包
|
||||
(`channel-chat-baseline`、`memory-failure-fallback`、
|
||||
`gateway-restart-inflight-run`),并在 `.artifacts/gateway-cpu-scenarios/`
|
||||
下写入合并后的 CPU 观察摘要。
|
||||
- 默认只标记持续的高 CPU 观察(`--cpu-core-warn`
|
||||
加 `--hot-wall-warn-ms`),因此短暂的启动突增会被记录为指标,
|
||||
而不会看起来像持续数分钟的 Gateway 网关占满 CPU 回归。
|
||||
- 使用已构建的 `dist` 产物;当检出目录中还没有新的运行时输出时,请先运行构建。
|
||||
下写入组合 CPU 观测摘要。
|
||||
- 默认只标记持续的高 CPU 观测(`--cpu-core-warn`
|
||||
加 `--hot-wall-warn-ms`),因此短暂启动峰值会记录为指标,而不会看起来像持续数分钟的 Gateway 网关占满回归。
|
||||
- 使用构建好的 `dist` 产物;当检出目录尚无新鲜运行时输出时,请先运行构建。
|
||||
- `pnpm openclaw qa suite --runner multipass`
|
||||
- 在一次性 Multipass Linux VM 中运行相同的 QA 测试套件。
|
||||
- 保持与宿主机上 `qa suite` 相同的场景选择行为。
|
||||
- 在一次性 Multipass Linux VM 内运行同一 QA 套件。
|
||||
- 保持与主机上 `qa suite` 相同的场景选择行为。
|
||||
- 复用与 `qa suite` 相同的提供商/模型选择标志。
|
||||
- 真实环境运行会转发适合 guest 使用的受支持 QA 认证输入:
|
||||
基于环境的提供商密钥、QA 真实环境提供商配置路径,以及存在时的 `CODEX_HOME`。
|
||||
- 输出目录必须保持在仓库根目录下,以便 guest 可以通过挂载的工作区写回。
|
||||
- 在 `.artifacts/qa-e2e/...` 下写入常规 QA 报告 + 摘要以及 Multipass 日志。
|
||||
- 实测运行会转发适合客户机的受支持 QA 认证输入:
|
||||
基于环境变量的提供商密钥、QA 实测提供商配置路径,以及存在时的 `CODEX_HOME`。
|
||||
- 输出目录必须保留在仓库根目录下,以便客户机可通过挂载的工作区写回。
|
||||
- 在 `.artifacts/qa-e2e/...` 下写入正常 QA 报告 + 摘要以及 Multipass 日志。
|
||||
- `pnpm qa:lab:up`
|
||||
- 启动 Docker 支持的 QA 站点,用于操作员风格的 QA 工作。
|
||||
- `pnpm test:docker:npm-onboard-channel-agent`
|
||||
- 从当前检出构建 npm tarball,在 Docker 中全局安装它,
|
||||
运行非交互式 OpenAI API key 新手引导,默认配置 Telegram,
|
||||
验证启用插件会按需安装运行时依赖,运行 Doctor,并针对模拟的 OpenAI
|
||||
端点运行一个本地智能体轮次。
|
||||
- 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 以 Discord 运行相同的打包安装通道。
|
||||
- 从当前检出构建 npm tarball,在 Docker 中全局安装,运行非交互式 OpenAI API 密钥新手引导,
|
||||
默认配置 Telegram,验证启用插件会按需安装运行时依赖,
|
||||
运行 Doctor,并针对模拟 OpenAI 端点运行一次本地 agent 轮次。
|
||||
- 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 可用 Discord 运行同一打包安装通道。
|
||||
- `pnpm test:docker:session-runtime-context`
|
||||
- 为嵌入式运行时上下文转录记录运行确定性的已构建应用 Docker 冒烟测试。
|
||||
它验证隐藏的 OpenClaw 运行时上下文会作为非显示自定义消息持久化,
|
||||
而不是泄漏到可见用户轮次中,然后植入一个受影响的损坏会话 JSONL,并验证
|
||||
`openclaw doctor --fix` 会将其重写到活动分支并生成备份。
|
||||
- 为嵌入式运行时上下文转录运行一个确定性的构建应用 Docker 冒烟测试。它验证隐藏的 OpenClaw 运行时上下文会作为
|
||||
非显示自定义消息持久化,而不是泄漏到可见用户轮次中,
|
||||
然后播种一个受影响的损坏会话 JSONL,并验证
|
||||
`openclaw doctor --fix` 会将其重写到当前分支且生成备份。
|
||||
- `pnpm test:docker:npm-telegram-live`
|
||||
- 在 Docker 中安装一个 OpenClaw 包候选版本,运行已安装包的
|
||||
新手引导,通过已安装的 CLI 配置 Telegram,然后复用真实 Telegram QA
|
||||
通道,并将该已安装包作为被测系统 Gateway 网关。
|
||||
- 默认使用 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`;设置
|
||||
- 在 Docker 中安装 OpenClaw 包候选,运行已安装包的新手引导,
|
||||
通过已安装的 CLI 配置 Telegram,然后复用实测 Telegram QA 通道,并将该已安装包作为被测系统 Gateway 网关。
|
||||
- 默认值为 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`;设置
|
||||
`OPENCLAW_NPM_TELEGRAM_PACKAGE_TGZ=/path/to/openclaw-current.tgz` 或
|
||||
`OPENCLAW_CURRENT_PACKAGE_TGZ`,即可测试已解析的本地 tarball,
|
||||
而不是从 registry 安装。
|
||||
- 使用与 `pnpm openclaw qa telegram` 相同的 Telegram 环境凭证或 Convex
|
||||
凭证来源。对于 CI/发布自动化,设置
|
||||
`OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`,并提供
|
||||
`OPENCLAW_QA_CONVEX_SITE_URL` 和角色密钥。如果 CI 中存在
|
||||
`OPENCLAW_QA_CONVEX_SITE_URL` 和 Convex 角色密钥,
|
||||
`OPENCLAW_CURRENT_PACKAGE_TGZ`,即可测试解析后的本地 tarball,而不是从注册表安装。
|
||||
- 使用与 `pnpm openclaw qa telegram` 相同的 Telegram 环境凭证或 Convex 凭证源。对于 CI/发布自动化,请设置
|
||||
`OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`,以及
|
||||
`OPENCLAW_QA_CONVEX_SITE_URL` 和角色密钥。如果
|
||||
`OPENCLAW_QA_CONVEX_SITE_URL` 和一个 Convex 角色密钥存在于 CI 中,
|
||||
Docker 包装器会自动选择 Convex。
|
||||
- `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 只为此通道覆盖共享的
|
||||
- `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 仅为此通道覆盖共享的
|
||||
`OPENCLAW_QA_CREDENTIAL_ROLE`。
|
||||
- GitHub Actions 将此通道暴露为手动维护者工作流
|
||||
- GitHub Actions 将此通道公开为手动维护者工作流
|
||||
`NPM Telegram Beta E2E`。它不会在合并时运行。该工作流使用
|
||||
`qa-live-shared` 环境和 Convex CI 凭证租约。
|
||||
- GitHub Actions 还暴露了 `Package Acceptance`,用于针对一个候选包进行旁路产品验证。
|
||||
它接受可信 ref、已发布的 npm spec、HTTPS tarball URL 加 SHA-256,
|
||||
或来自另一轮运行的 tarball 产物,上传标准化的 `openclaw-current.tgz`
|
||||
作为 `package-under-test`,然后使用 smoke、package、product、full
|
||||
或 custom 通道配置运行现有 Docker E2E 调度器。设置 `telegram_mode=mock-openai`
|
||||
或 `live-frontier`,即可针对同一个 `package-under-test` 产物运行
|
||||
Telegram QA 工作流。
|
||||
- 最新 beta 产品验证:
|
||||
- GitHub Actions 还公开了 `Package Acceptance`,用于针对一个候选包进行旁路运行的产品证明。
|
||||
它接受受信任的 ref、已发布的 npm 规格、
|
||||
HTTPS tarball URL 加 SHA-256,或来自另一运行的 tarball 产物,
|
||||
将规范化的 `openclaw-current.tgz` 作为 `package-under-test` 上传,然后使用冒烟、包、产品、完整或自定义
|
||||
通道配置文件运行现有 Docker E2E 调度器。设置 `telegram_mode=mock-openai` 或 `live-frontier` 可针对同一个
|
||||
`package-under-test` 产物运行 Telegram QA 工作流。
|
||||
- 最新 beta 产品证明:
|
||||
|
||||
```bash
|
||||
gh workflow run package-acceptance.yml --ref main \
|
||||
@ -203,7 +189,7 @@ gh workflow run package-acceptance.yml --ref main \
|
||||
-f telegram_mode=mock-openai
|
||||
```
|
||||
|
||||
- 精确 tarball URL 验证需要摘要:
|
||||
- 精确 tarball URL 证明需要摘要:
|
||||
|
||||
```bash
|
||||
gh workflow run package-acceptance.yml --ref main \
|
||||
@ -225,43 +211,43 @@ gh workflow run package-acceptance.yml --ref main \
|
||||
|
||||
- `pnpm test:docker:bundled-channel-deps`
|
||||
- 在 Docker 中打包并安装当前 OpenClaw 构建,启动已配置 OpenAI 的 Gateway 网关,然后通过配置编辑启用内置渠道/插件。
|
||||
- 验证设置发现会让未配置的插件运行时依赖保持缺失,首次配置的 Gateway 网关或 doctor 运行会按需安装每个内置插件的运行时依赖,并且第二次重启不会重新安装已经激活的依赖。
|
||||
- 还会安装一个已知的较旧 npm 基线,在运行 `openclaw update --tag <candidate>` 前启用 Telegram,并验证候选版本的更新后 doctor 会修复内置渠道运行时依赖,而不需要 harness 侧的 postinstall 修复。
|
||||
- 验证设置发现会保持未配置的插件运行时依赖缺失,第一个已配置的 Gateway 网关或 doctor 运行会按需安装每个内置插件的运行时依赖,并且第二次重启不会重新安装已经激活的依赖。
|
||||
- 还会安装一个已知的较旧 npm 基线,在运行 `openclaw update --tag <candidate>` 之前启用 Telegram,并验证候选版本的更新后 doctor 会修复内置渠道运行时依赖,而不需要 harness 侧 postinstall 修复。
|
||||
- `pnpm test:parallels:npm-update`
|
||||
- 跨 Parallels 客户机运行原生打包安装更新冒烟测试。每个选定平台都会先安装请求的基线包,然后在同一客户机中运行已安装的 `openclaw update` 命令,并验证已安装版本、更新 Status、Gateway 网关就绪状态,以及一次本地 agent 回合。
|
||||
- 在迭代单个客户机时使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要构件路径和每个 lane 的 Status。
|
||||
- OpenAI lane 默认使用 `openai/gpt-5.5` 进行实时 agent 回合证明。若要刻意验证另一个 OpenAI 模型,请传入 `--model <provider/model>` 或设置 `OPENCLAW_PARALLELS_OPENAI_MODEL`。
|
||||
- 用主机超时包装长时间本地运行,避免 Parallels 传输停滞耗尽剩余测试窗口:
|
||||
- 在 Parallels 客户机上运行原生打包安装更新 smoke。每个选定平台会先安装请求的基线包,然后在同一个客户机中运行已安装的 `openclaw update` 命令,并验证已安装版本、更新 Status、Gateway 网关就绪状态,以及一次本地智能体轮次。
|
||||
- 在迭代单个客户机时使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要构件路径和各泳道 Status。
|
||||
- OpenAI 泳道默认使用 `openai/gpt-5.5` 作为实时智能体轮次证明。若要有意验证另一个 OpenAI 模型,请传入 `--model <provider/model>` 或设置 `OPENCLAW_PARALLELS_OPENAI_MODEL`。
|
||||
- 用宿主机超时包装较长的本地运行,避免 Parallels 传输卡顿耗尽剩余测试窗口:
|
||||
|
||||
```bash
|
||||
timeout --foreground 150m pnpm test:parallels:npm-update -- --json
|
||||
timeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json
|
||||
```
|
||||
|
||||
- 该脚本会在 `/tmp/openclaw-parallels-npm-update.*` 下写入嵌套 lane 日志。在假定外层包装器卡住之前,先检查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`。
|
||||
- 在冷客户机上,Windows 更新可能会在更新后 doctor/运行时依赖修复中花费 10 到 15 分钟;只要嵌套的 npm 调试日志仍在推进,这仍然是健康状态。
|
||||
- 不要将这个聚合包装器与单独的 Parallels macOS、Windows 或 Linux 冒烟 lane 并行运行。它们共享 VM 状态,可能在快照恢复、包服务或客户机 Gateway 网关状态上发生冲突。
|
||||
- 更新后证明会运行正常的内置插件表面,因为语音、图像生成和媒体理解等能力 facade 会通过内置运行时 API 加载,即使 agent 回合本身只检查一个简单文本响应。
|
||||
- 脚本会在 `/tmp/openclaw-parallels-npm-update.*` 下写入嵌套泳道日志。先检查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`,再判断外层包装器是否卡住。
|
||||
- Windows 更新在冷启动客户机上可能会花 10 到 15 分钟进行更新后 doctor/运行时依赖修复;只要嵌套 npm debug 日志仍在推进,这仍属正常。
|
||||
- 不要将这个聚合包装器与单独的 Parallels macOS、Windows 或 Linux smoke 泳道并行运行。它们共享 VM 状态,可能在快照恢复、包服务或客户机 Gateway 网关状态上发生冲突。
|
||||
- 更新后证明会运行常规内置插件表面,因为即使智能体轮次本身只检查简单文本响应,语音、图像生成和媒体理解等能力外观也是通过内置运行时 API 加载的。
|
||||
|
||||
- `pnpm openclaw qa aimock`
|
||||
- 仅启动本地 AIMock 提供商服务器,用于直接协议冒烟测试。
|
||||
- 仅启动本地 AIMock 提供商服务器,用于直接协议 smoke 测试。
|
||||
- `pnpm openclaw qa matrix`
|
||||
- 针对一次性 Docker 支持的 Tuwunel homeserver 运行 Matrix 实时 QA lane。仅限源代码检出;打包安装不会附带 `qa-lab`。
|
||||
- 针对一次性 Docker 支持的 Tuwunel homeserver 运行 Matrix 实时 QA 泳道。仅限源码检出;打包安装不会随附 `qa-lab`。
|
||||
- 完整 CLI、profile/scenario 目录、环境变量和构件布局:[Matrix QA](/zh-CN/concepts/qa-matrix)。
|
||||
- `pnpm openclaw qa telegram`
|
||||
- 使用来自环境的 driver 和 SUT bot token,针对真实私有群组运行 Telegram 实时 QA lane。
|
||||
- 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。群组 ID 必须是数字 Telegram chat id。
|
||||
- 支持 `--credential-source convex` 以使用共享池化凭证。默认使用 env 模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 以选择加入池化租约。
|
||||
- 任一场景失败时会以非零状态退出。当你想获取构件但不想失败退出码时,使用 `--allow-failures`。
|
||||
- 需要同一个私有群组中的两个不同 bot,且 SUT bot 需公开 Telegram 用户名。
|
||||
- 为了稳定观察 bot 到 bot 的通信,请在 `@BotFather` 中为两个 bot 启用 Bot-to-Bot Communication Mode,并确保 driver bot 可以观察群组 bot 流量。
|
||||
- 在 `.artifacts/qa-e2e/...` 下写入 Telegram QA 报告、摘要和 observed-messages 构件。回复场景包含从 driver 发送请求到观察到 SUT 回复的 RTT。
|
||||
- 使用来自环境变量的驱动和 SUT 机器人 token,针对真实私有群组运行 Telegram 实时 QA 泳道。
|
||||
- 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。群组 ID 必须是数字形式的 Telegram chat id。
|
||||
- 支持 `--credential-source convex` 以使用共享池化凭证。默认使用环境变量模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 选择加入池化租约。
|
||||
- 任一场景失败时会以非零状态退出。若你希望获取构件但不产生失败退出码,请使用 `--allow-failures`。
|
||||
- 需要两个不同的机器人位于同一个私有群组中,且 SUT 机器人公开 Telegram 用户名。
|
||||
- 为了稳定观察机器人之间的通信,请在 `@BotFather` 中为两个机器人启用 Bot-to-Bot Communication Mode,并确保驱动机器人可以观察群组机器人流量。
|
||||
- 在 `.artifacts/qa-e2e/...` 下写入 Telegram QA 报告、摘要和 observed-messages 构件。回复场景包含从驱动发送请求到观察到 SUT 回复之间的 RTT。
|
||||
|
||||
实时传输 lane 共享一个标准契约,以避免新传输产生漂移;每个 lane 的覆盖矩阵位于 [QA overview → 实时传输覆盖范围](/zh-CN/concepts/qa-e2e-automation#live-transport-coverage)。`qa-channel` 是宽泛的合成套件,不属于该矩阵。
|
||||
实时传输泳道共享一套标准契约,因此新传输不会漂移;各泳道覆盖矩阵位于 [QA overview → 实时传输覆盖范围](/zh-CN/concepts/qa-e2e-automation#live-transport-coverage)。`qa-channel` 是宽泛的合成套件,不属于该矩阵。
|
||||
|
||||
### 通过 Convex 共享 Telegram 凭证(v1)
|
||||
|
||||
当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)时,QA 实验室会从 Convex 支持的池中获取独占租约,在 lane 运行期间为该租约发送 Heartbeat,并在关闭时释放租约。
|
||||
当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)时,QA lab 会从 Convex 支持的池中获取独占租约,在泳道运行期间对该租约发送 Heartbeat,并在关闭时释放租约。
|
||||
|
||||
参考 Convex 项目脚手架:
|
||||
|
||||
@ -270,12 +256,12 @@ gh workflow run package-acceptance.yml --ref main \
|
||||
必需环境变量:
|
||||
|
||||
- `OPENCLAW_QA_CONVEX_SITE_URL`(例如 `https://your-deployment.convex.site`)
|
||||
- 所选角色的一个密钥:
|
||||
- 所选角色的一个 secret:
|
||||
- `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` 用于 `maintainer`
|
||||
- `OPENCLAW_QA_CONVEX_SECRET_CI` 用于 `ci`
|
||||
- 凭证角色选择:
|
||||
- CLI:`--credential-role maintainer|ci`
|
||||
- 环境默认值:`OPENCLAW_QA_CREDENTIAL_ROLE`(CI 中默认为 `ci`,否则为 `maintainer`)
|
||||
- 环境变量默认值:`OPENCLAW_QA_CREDENTIAL_ROLE`(在 CI 中默认为 `ci`,否则为 `maintainer`)
|
||||
|
||||
可选环境变量:
|
||||
|
||||
@ -285,13 +271,13 @@ gh workflow run package-acceptance.yml --ref main \
|
||||
- `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS`(默认 `15000`)
|
||||
- `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX`(默认 `/qa-credentials/v1`)
|
||||
- `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(可选 trace id)
|
||||
- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许在仅本地开发中使用 loopback `http://` Convex URL。
|
||||
- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许用于仅本地开发的 loopback `http://` Convex URL。
|
||||
|
||||
正常运行中,`OPENCLAW_QA_CONVEX_SITE_URL` 应使用 `https://`。
|
||||
`OPENCLAW_QA_CONVEX_SITE_URL` 在正常运行中应使用 `https://`。
|
||||
|
||||
维护者管理命令(池 add/remove/list)明确需要 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。
|
||||
维护者管理命令(池添加/移除/列出)明确要求 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。
|
||||
|
||||
面向维护者的 CLI 辅助命令:
|
||||
维护者 CLI 辅助命令:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa credentials doctor
|
||||
@ -300,7 +286,7 @@ pnpm openclaw qa credentials list --kind telegram
|
||||
pnpm openclaw qa credentials remove --credential-id <credential-id>
|
||||
```
|
||||
|
||||
在实时运行前使用 `doctor` 检查 Convex 站点 URL、broker 密钥、端点前缀、HTTP 超时和 admin/list 可达性,且不会打印密钥值。在脚本和 CI 工具中使用 `--json` 获取机器可读输出。
|
||||
在实时运行前使用 `doctor` 检查 Convex site URL、broker secrets、endpoint prefix、HTTP timeout 和 admin/list 可达性,同时不会打印 secret 值。在脚本和 CI 工具中使用 `--json` 获取机器可读输出。
|
||||
|
||||
默认端点契约(`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`):
|
||||
|
||||
@ -314,79 +300,79 @@ pnpm openclaw qa credentials remove --credential-id <credential-id>
|
||||
- `POST /release`
|
||||
- 请求:`{ kind, ownerId, actorRole, credentialId, leaseToken }`
|
||||
- 成功:`{ status: "ok" }`(或空 `2xx`)
|
||||
- `POST /admin/add`(仅维护者密钥)
|
||||
- `POST /admin/add`(仅维护者 secret)
|
||||
- 请求:`{ kind, actorId, payload, note?, status? }`
|
||||
- 成功:`{ status: "ok", credential }`
|
||||
- `POST /admin/remove`(仅维护者密钥)
|
||||
- `POST /admin/remove`(仅维护者 secret)
|
||||
- 请求:`{ credentialId, actorId }`
|
||||
- 成功:`{ status: "ok", changed, credential }`
|
||||
- 活跃租约保护:`{ status: "error", code: "LEASE_ACTIVE", ... }`
|
||||
- `POST /admin/list`(仅维护者密钥)
|
||||
- `POST /admin/list`(仅维护者 secret)
|
||||
- 请求:`{ kind?, status?, includePayload?, limit? }`
|
||||
- 成功:`{ status: "ok", credentials, count }`
|
||||
|
||||
Telegram kind 的 payload 形状:
|
||||
|
||||
- `{ groupId: string, driverToken: string, sutToken: string }`
|
||||
- `groupId` 必须是数字 Telegram chat id 字符串。
|
||||
- `admin/add` 会针对 `kind: "telegram"` 验证此形状,并拒绝格式错误的 payload。
|
||||
- `groupId` 必须是数字形式的 Telegram chat id 字符串。
|
||||
- `admin/add` 会为 `kind: "telegram"` 验证此形状,并拒绝格式错误的 payload。
|
||||
|
||||
### 向 QA 添加渠道
|
||||
|
||||
新渠道适配器的架构和场景辅助器名称位于 [QA overview → 添加渠道](/zh-CN/concepts/qa-e2e-automation#adding-a-channel)。最低要求:在共享的 `qa-lab` host seam 上实现传输 runner,在插件 manifest 中声明 `qaRunners`,挂载为 `openclaw qa <runner>`,并在 `qa/scenarios/` 下编写场景。
|
||||
新渠道适配器的架构和场景辅助名称位于 [QA overview → 添加渠道](/zh-CN/concepts/qa-e2e-automation#adding-a-channel)。最低要求:在共享 `qa-lab` host seam 上实现传输运行器,在插件清单中声明 `qaRunners`,挂载为 `openclaw qa <runner>`,并在 `qa/scenarios/` 下编写场景。
|
||||
|
||||
## 测试套件(运行位置)
|
||||
## 测试套件(何处运行什么)
|
||||
|
||||
可以把这些套件理解为“真实度递增”(同时不稳定性/成本也递增):
|
||||
可以将这些套件理解为“逐步提高真实性”(同时也提高不稳定性/成本):
|
||||
|
||||
### 单元/集成(默认)
|
||||
### 单元 / 集成(默认)
|
||||
|
||||
- 命令:`pnpm test`
|
||||
- 配置:非定向运行使用 `vitest.full-*.config.ts` 分片集,并可能将多项目分片扩展为每个项目的配置以进行并行调度
|
||||
- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts` 和 `test/**/*.test.ts` 下的 core/unit 清单;UI 单元测试在专用的 `unit-ui` 分片中运行
|
||||
- 配置:非定向运行使用 `vitest.full-*.config.ts` 分片集,并且可能将多项目分片展开为按项目配置以进行并行调度
|
||||
- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts` 和 `test/**/*.test.ts` 下的核心/单元清单;UI 单元测试在专用 `unit-ui` 分片中运行
|
||||
- 范围:
|
||||
- 纯单元测试
|
||||
- 进程内集成测试(Gateway 网关认证、路由、工具、解析、配置)
|
||||
- 已知 bug 的确定性回归
|
||||
- 预期:
|
||||
- 进程内集成测试(Gateway 网关认证、路由、工具调用、解析、配置)
|
||||
- 已知 bug 的确定性回归测试
|
||||
- 期望:
|
||||
- 在 CI 中运行
|
||||
- 不需要真实 key
|
||||
- 不需要真实密钥
|
||||
- 应该快速且稳定
|
||||
- resolver 和公开表面 loader 测试必须用生成的微型插件 fixture 证明宽泛的 `api.js` 和 `runtime-api.js` fallback 行为,而不是使用真实的内置插件源码 API。真实插件 API 加载应放在插件所属的契约/集成套件中。
|
||||
- 解析器和公共表面加载器测试必须使用生成的微型插件 fixture 证明宽泛的 `api.js` 和 `runtime-api.js` fallback 行为,而不是使用真实内置插件源码 API。真实插件 API 加载属于插件拥有的契约/集成套件。
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="项目、分片和作用域 lane">
|
||||
<Accordion title="Projects, shards, and scoped lanes">
|
||||
|
||||
- 未指定目标的 `pnpm test` 会运行十二个更小的分片配置(`core-unit-fast`、`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是一个巨大的原生根项目进程。这会降低繁忙机器上的峰值 RSS,并避免自动回复/插件工作让无关套件得不到资源。
|
||||
- 非定向的 `pnpm test` 会运行十二个较小的分片配置(`core-unit-fast`、`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是一个巨大的原生根项目进程。这会降低繁忙机器上的峰值 RSS,并避免 auto-reply/插件工作让无关测试套件得不到资源。
|
||||
- `pnpm test --watch` 仍使用原生根 `vitest.config.ts` 项目图,因为多分片 watch 循环并不实用。
|
||||
- `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先将显式文件/目录目标路由到有作用域的 lane,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 能避免承担完整根项目启动开销。
|
||||
- `pnpm test:changed` 默认会把变更的 git 路径展开为低成本的有作用域 lane:直接测试编辑、同级 `*.test.ts` 文件、显式源文件映射,以及本地导入图依赖项。配置/setup/包编辑不会广泛运行测试,除非你显式使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
- `pnpm check:changed` 是窄范围工作的常规智能本地检查门禁。它会把 diff 分类到核心、核心测试、插件、插件测试、应用、文档、发布元数据、实时 Docker 工具和 tooling,然后运行匹配的类型检查、lint 和 guard 命令。它不会运行 Vitest 测试;如需测试证明,请调用 `pnpm test:changed` 或显式 `pnpm test <target>`。仅发布元数据的版本号更新会运行定向的版本/配置/根依赖检查,并带有一个 guard,用于拒绝顶层版本字段之外的包变更。
|
||||
- 实时 Docker ACP harness 编辑会运行聚焦检查:实时 Docker auth 脚本的 shell 语法检查,以及实时 Docker 调度器 dry-run。仅当 diff 限定在 `scripts["test:docker:live-*"]` 时,才会包含 `package.json` 变更;依赖、export、版本和其他包表面编辑仍使用更广的 guard。
|
||||
- 来自智能体、命令、插件、自动回复 helper、`plugin-sdk` 和类似纯工具区域的轻导入单元测试会路由到 `unit-fast` lane,该 lane 会跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件会留在现有 lane 上。
|
||||
- 选定的 `plugin-sdk` 和 `commands` helper 源文件也会把 changed-mode 运行映射到这些轻量 lane 中的显式同级测试,因此 helper 编辑可避免重新运行该目录的完整重型套件。
|
||||
- `auto-reply` 为顶层核心 helper、顶层 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树设置了专用 bucket。CI 还会把 reply 子树进一步拆分为 agent-runner、dispatch 和 commands/state-routing 分片,避免某个导入较重的 bucket 独占完整 Node 尾部耗时。
|
||||
- 常规 PR/main CI 会有意跳过插件批量 sweep 和仅发布使用的 `agentic-plugins` 分片。完整 Release Validation 会为发布候选版本调度独立的 `Plugin Prerelease` 子工作流,以运行这些插件/插件较重的套件。
|
||||
- `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先通过作用域 lane 路由显式文件/目录目标,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 可以避免支付完整根项目启动成本。
|
||||
- `pnpm test:changed` 默认会把变更的 git 路径展开为低成本的作用域 lane:直接测试编辑、同级 `*.test.ts` 文件、显式源码映射,以及本地导入图依赖项。Config/设置/包编辑不会广泛运行测试,除非你显式使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
- `pnpm check:changed` 是窄范围工作的常规智能本地检查门禁。它会将 diff 分类为 core、core tests、extensions、extension tests、apps、docs、release metadata、live Docker tooling 和 tooling,然后运行匹配的 typecheck、lint 与 guard 命令。它不会运行 Vitest 测试;如需测试证明,请调用 `pnpm test:changed` 或显式 `pnpm test <target>`。仅发布元数据的版本递增会运行定向版本/配置/根依赖检查,并带有一个 guard,用于拒绝顶层 version 字段以外的 package 变更。
|
||||
- Live Docker ACP harness 编辑会运行聚焦检查:live Docker 认证脚本的 shell 语法检查,以及 live Docker 调度器 dry-run。只有当 diff 限定在 `scripts["test:docker:live-*"]` 时,才会包含 `package.json` 变更;依赖、导出、版本和其他 package 表面编辑仍使用更广泛的 guard。
|
||||
- 来自 agents、commands、plugins、auto-reply helpers、`plugin-sdk` 和类似纯工具区域的轻导入单元测试会路由到 `unit-fast` lane,该 lane 会跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件仍保留在现有 lane 上。
|
||||
- 选定的 `plugin-sdk` 和 `commands` helper 源文件也会将 changed-mode 运行映射到这些轻量 lane 中的显式同级测试,因此 helper 编辑可以避免为该目录重新运行完整重型套件。
|
||||
- `auto-reply` 有专用 bucket,分别覆盖顶层 core helpers、顶层 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树。CI 会进一步将 reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片,避免一个导入较重的 bucket 占用完整 Node 尾部时间。
|
||||
- 常规 PR/main CI 会有意跳过插件批量扫描和仅发布用的 `agentic-plugins` 分片。完整发布验证会为发布候选触发单独的 `Plugin Prerelease` 子工作流,覆盖这些插件/扩展较重的套件。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="嵌入式 runner 覆盖率">
|
||||
<Accordion title="嵌入式运行器覆盖">
|
||||
|
||||
- 当你更改消息工具发现输入或压缩运行时上下文时,请保留两层覆盖率。
|
||||
- 为纯路由和规范化边界添加聚焦的 helper 回归测试。
|
||||
- 保持嵌入式 runner 集成套件健康:
|
||||
- 当你更改 message-tool 发现输入或 compaction 运行时上下文时,请保留两层覆盖。
|
||||
- 为纯路由与规范化边界添加聚焦的 helper 回归测试。
|
||||
- 保持嵌入式运行器集成套件健康:
|
||||
`src/agents/pi-embedded-runner/compact.hooks.test.ts`、
|
||||
`src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` 和
|
||||
`src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`。
|
||||
- 这些套件会验证有作用域的 id 和压缩行为仍通过真实的 `run.ts` / `compact.ts` 路径流动;仅 helper 测试不足以替代这些集成路径。
|
||||
- 这些套件会验证作用域 id 和 compaction 行为仍通过真实的 `run.ts` / `compact.ts` 路径流动;仅 helper 测试不足以替代这些集成路径。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Vitest pool 和隔离默认值">
|
||||
<Accordion title="Vitest 池和隔离默认值">
|
||||
|
||||
- 基础 Vitest 配置默认使用 `threads`。
|
||||
- 共享 Vitest 配置固定为 `isolate: false`,并在根项目、e2e 和实时配置中使用非隔离 runner。
|
||||
- 根 UI lane 保留其 `jsdom` setup 和 optimizer,但同样运行在共享非隔离 runner 上。
|
||||
- 共享 Vitest 配置固定 `isolate: false`,并在根项目、e2e 和 live 配置中使用非隔离运行器。
|
||||
- 根 UI lane 保留其 `jsdom` 设置和优化器,但同样运行在共享非隔离运行器上。
|
||||
- 每个 `pnpm test` 分片都会从共享 Vitest 配置继承相同的 `threads` + `isolate: false` 默认值。
|
||||
- `scripts/run-vitest.mjs` 默认会为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与原生 V8 行为对比。
|
||||
|
||||
@ -394,27 +380,27 @@ Telegram kind 的 payload 形状:
|
||||
|
||||
<Accordion title="快速本地迭代">
|
||||
|
||||
- `pnpm changed:lanes` 会显示一个 diff 触发哪些架构 lane。
|
||||
- pre-commit hook 仅做格式化。它会重新暂存格式化后的文件,不运行 lint、类型检查或测试。
|
||||
- 当你需要智能本地检查门禁时,请在 handoff 或 push 前显式运行 `pnpm check:changed`。
|
||||
- `pnpm test:changed` 默认会通过低成本的有作用域 lane 路由。仅当智能体判断 harness、配置、包或契约编辑确实需要更广的 Vitest 覆盖率时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
- `pnpm changed:lanes` 会显示一个 diff 触发了哪些架构 lane。
|
||||
- pre-commit hook 仅做格式化。它会重新暂存格式化后的文件,不运行 lint、typecheck 或测试。
|
||||
- 当你在交接或 push 前需要智能本地检查门禁时,请显式运行 `pnpm check:changed`。
|
||||
- `pnpm test:changed` 默认通过低成本作用域 lane 路由。仅当 agent 判定 harness、配置、包或契约编辑确实需要更广泛的 Vitest 覆盖时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
- `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的路由行为,只是 worker 上限更高。
|
||||
- 本地 worker 自动扩缩容刻意保持保守,并会在主机负载平均值已很高时退避,因此多个并发 Vitest 运行默认造成的影响更小。
|
||||
- 基础 Vitest 配置把项目/配置文件标记为 `forceRerunTriggers`,因此在测试 wiring 变化时,changed-mode 重新运行仍保持正确。
|
||||
- 配置会在受支持的主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你想为直接性能分析使用一个显式缓存位置,请设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。
|
||||
- 本地 worker 自动扩缩容有意保持保守,并会在主机负载平均值已经很高时退让,因此多个并发 Vitest 运行默认造成的影响更小。
|
||||
- 基础 Vitest 配置将项目/配置文件标记为 `forceRerunTriggers`,因此当测试接线更改时,changed-mode 重新运行仍保持正确。
|
||||
- 该配置会在支持的主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你想为直接 profiling 使用一个显式缓存位置,请设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="性能调试">
|
||||
|
||||
- `pnpm test:perf:imports` 会启用 Vitest 导入时长报告和导入拆分输出。
|
||||
- `pnpm test:perf:imports:changed` 会把相同的性能分析视图限定到自 `origin/main` 以来变更的文件。
|
||||
- 分片计时数据会写入 `.artifacts/vitest-shard-timings.json`。整配置运行使用配置路径作为键;include-pattern CI 分片会追加分片名称,因此过滤后的分片可以单独跟踪。
|
||||
- 当某个热点测试的大部分时间仍花在启动导入上时,请把重型依赖放在窄范围的本地 `*.runtime.ts` seam 后面,并直接 mock 该 seam,而不是深度导入运行时 helper 只是为了把它们传给 `vi.mock(...)`。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>` 会将路由后的 `test:changed` 与该已提交 diff 的原生根项目路径进行比较,并输出 wall time 与 macOS 最大 RSS。
|
||||
- `pnpm test:perf:changed:bench -- --worktree` 会通过把变更文件列表路由到 `scripts/test-projects.mjs` 和根 Vitest 配置,对当前 dirty tree 进行基准测试。
|
||||
- `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动和 transform 开销写入主线程 CPU profile。
|
||||
- `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为单元套件写入 runner CPU+heap profile。
|
||||
- `pnpm test:perf:imports` 会启用 Vitest 导入时长报告以及导入拆解输出。
|
||||
- `pnpm test:perf:imports:changed` 将相同的 profiling 视图限定到自 `origin/main` 以来变更的文件。
|
||||
- 分片计时数据会写入 `.artifacts/vitest-shard-timings.json`。整配置运行使用配置路径作为键;include-pattern CI 分片会追加分片名称,以便单独跟踪经过过滤的分片。
|
||||
- 当某个热门测试仍将大部分时间花在启动导入上时,请把重型依赖放在窄范围本地 `*.runtime.ts` 边界后面,并直接 mock 该边界,而不是为了通过 `vi.mock(...)` 传递它们而深度导入运行时 helpers。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>` 会将路由后的 `test:changed` 与该已提交 diff 的原生根项目路径进行比较,并打印 wall time 和 macOS 最大 RSS。
|
||||
- `pnpm test:perf:changed:bench -- --worktree` 会通过将变更文件列表路由到 `scripts/test-projects.mjs` 和根 Vitest 配置来基准测试当前脏工作树。
|
||||
- `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动与转换开销写入主线程 CPU profile。
|
||||
- `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下为单元套件写入 runner CPU+heap profiles。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -422,140 +408,141 @@ Telegram kind 的 payload 形状:
|
||||
### 稳定性(Gateway 网关)
|
||||
|
||||
- 命令:`pnpm test:stability:gateway`
|
||||
- 配置:`vitest.gateway.config.ts`,强制使用一个 worker
|
||||
- 配置:`vitest.gateway.config.ts`,强制为一个 worker
|
||||
- 范围:
|
||||
- 默认启动一个启用诊断的真实 loopback Gateway 网关
|
||||
- 通过诊断事件路径驱动合成的 Gateway 网关消息、记忆和大 payload churn
|
||||
- 默认启动一个启用 diagnostics 的真实 loopback Gateway 网关
|
||||
- 通过 diagnostic event path 驱动合成的 Gateway 网关 message、memory 和 large-payload churn
|
||||
- 通过 Gateway 网关 WS RPC 查询 `diagnostics.stability`
|
||||
- 覆盖诊断稳定性 bundle 持久化 helper
|
||||
- 断言 recorder 保持有界,合成 RSS 样本保持在压力预算以内,并且每个会话的队列深度会回落到零
|
||||
- 覆盖诊断稳定性 bundle 持久化 helpers
|
||||
- 断言 recorder 保持有界、合成 RSS 样本保持低于压力预算,并且每会话队列深度回落到零
|
||||
- 预期:
|
||||
- CI 安全且无需 key
|
||||
- 这是用于稳定性回归跟进的窄 lane,不能替代完整 Gateway 网关套件
|
||||
- CI 安全且无须密钥
|
||||
- 用于稳定性回归跟进的窄 lane,不是完整 Gateway 网关套件的替代品
|
||||
|
||||
### E2E(Gateway 网关 smoke)
|
||||
### E2E(Gateway 网关冒烟测试)
|
||||
|
||||
- 命令:`pnpm test:e2e`
|
||||
- 配置:`vitest.e2e.config.ts`
|
||||
- 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`,以及 `extensions/` 下的内置插件 E2E 测试
|
||||
- 运行时默认值:
|
||||
- 使用 Vitest `threads`,并设置 `isolate: false`,与仓库其余部分一致。
|
||||
- 使用自适应 worker(CI:最多 2 个;本地:默认 1 个)。
|
||||
- 默认以 silent 模式运行,以减少控制台 I/O 开销。
|
||||
- 常用覆盖:
|
||||
- `OPENCLAW_E2E_WORKERS=<n>` 用于强制指定 worker 数量(上限 16)。
|
||||
- `OPENCLAW_E2E_VERBOSE=1` 用于重新启用详细控制台输出。
|
||||
- 使用 Vitest `threads` 与 `isolate: false`,与仓库其余部分一致。
|
||||
- 使用自适应 workers(CI:最多 2 个,本地:默认 1 个)。
|
||||
- 默认以静默模式运行,以减少控制台 I/O 开销。
|
||||
- 有用的覆盖项:
|
||||
- `OPENCLAW_E2E_WORKERS=<n>` 强制 worker 数量(上限为 16)。
|
||||
- `OPENCLAW_E2E_VERBOSE=1` 重新启用详细控制台输出。
|
||||
- 范围:
|
||||
- 多实例 Gateway 网关端到端行为
|
||||
- WebSocket/HTTP 表面、节点配对和更重的网络功能
|
||||
- WebSocket/HTTP 表面、节点配对和更重的网络处理
|
||||
- 预期:
|
||||
- 在 CI 中运行(当 pipeline 启用时)
|
||||
- 不需要真实 key
|
||||
- 比单元测试有更多 moving parts(可能更慢)
|
||||
- 不需要真实密钥
|
||||
- 比单元测试有更多移动部件(可能更慢)
|
||||
|
||||
### E2E:OpenShell 后端 smoke
|
||||
### E2E:OpenShell 后端冒烟测试
|
||||
|
||||
- 命令:`pnpm test:e2e:openshell`
|
||||
- 文件:`extensions/openshell/src/backend.e2e.test.ts`
|
||||
- 范围:
|
||||
- 通过 Docker 在主机上启动隔离的 OpenShell gateway
|
||||
- 从临时本地 Dockerfile 创建沙箱
|
||||
- 通过 Docker 在主机上启动隔离的 OpenShell Gateway 网关
|
||||
- 从临时本地 Dockerfile 创建一个沙箱
|
||||
- 通过真实的 `sandbox ssh-config` + SSH exec 测试 OpenClaw 的 OpenShell 后端
|
||||
- 通过沙箱 fs bridge 验证 remote-canonical 文件系统行为
|
||||
- 通过沙箱 fs bridge 验证远端规范文件系统行为
|
||||
- 预期:
|
||||
- 仅 opt-in;不属于默认 `pnpm test:e2e` 运行的一部分
|
||||
- 需要本地 `openshell` CLI 以及可用的 Docker daemon
|
||||
- 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试 gateway 和沙箱
|
||||
- 常用覆盖:
|
||||
- `OPENCLAW_E2E_OPENSHELL=1` 用于在手动运行更广 e2e 套件时启用该测试
|
||||
- `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` 用于指向非默认 CLI binary 或 wrapper 脚本
|
||||
- 需要本地 `openshell` CLI 和正常工作的 Docker daemon
|
||||
- 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试 Gateway 网关和沙箱
|
||||
- 有用的覆盖项:
|
||||
- `OPENCLAW_E2E_OPENSHELL=1` 在手动运行更广泛的 e2e 套件时启用该测试
|
||||
- `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` 指向非默认 CLI 二进制文件或 wrapper script
|
||||
|
||||
### 实时(真实提供商 + 真实模型)
|
||||
### Live(真实提供商 + 真实模型)
|
||||
|
||||
- 命令:`pnpm test:live`
|
||||
- 配置:`vitest.live.config.ts`
|
||||
- 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的内置插件实时测试
|
||||
- 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的内置插件 live 测试
|
||||
- 默认值:由 `pnpm test:live` **启用**(设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- 范围:
|
||||
- “这个提供商/模型在 _今天_ 使用真实凭证时是否真的可用?”
|
||||
- 捕获提供商格式变化、tool-calling 怪癖、auth 问题和速率限制行为
|
||||
- 捕获提供商格式变更、tool-calling 特性、认证问题和速率限制行为
|
||||
- 预期:
|
||||
- 按设计不是 CI 稳定的(真实网络、真实提供商策略、配额、中断)
|
||||
- 会花钱/消耗速率限制
|
||||
- 优先运行缩小范围的子集,而不是“全部”
|
||||
- 实时运行会 source `~/.profile` 以获取缺失的 API key。
|
||||
- 默认情况下,实时运行仍会隔离 `HOME`,并把配置/auth 材料复制到临时测试 home,因此单元 fixture 不能修改你的真实 `~/.openclaw`。
|
||||
- 仅当你有意需要实时测试使用真实主目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。
|
||||
- `pnpm test:live` 现在默认使用更安静的模式:它保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静音 gateway bootstrap 日志/Bonjour chatter。如果你想恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。
|
||||
- API key 轮换(按提供商):设置带逗号/分号格式的 `*_API_KEYS` 或 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),或通过 `OPENCLAW_LIVE_*_KEY` 做每次实时运行覆盖;测试会在收到速率限制响应时重试。
|
||||
- 会花钱 / 使用速率限制额度
|
||||
- 更推荐运行缩窄后的子集,而不是“全部”
|
||||
- Live 运行会 source `~/.profile` 以获取缺失的 API key。
|
||||
- 默认情况下,live 运行仍会隔离 `HOME`,并将配置/认证材料复制到临时测试 home 中,因此单元 fixtures 无法修改你的真实 `~/.openclaw`。
|
||||
- 仅当你有意需要 live 测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。
|
||||
- `pnpm test:live` 现在默认使用更安静的模式:它保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静音 Gateway 网关 bootstrap 日志/Bonjour chatter。如果你想恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。
|
||||
- API key 轮换(按提供商):使用逗号/分号格式设置 `*_API_KEYS` 或 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),或通过 `OPENCLAW_LIVE_*_KEY` 设置每次 live 覆盖;测试会在速率限制响应时重试。
|
||||
- 进度/heartbeat 输出:
|
||||
- 实时套件现在会向 stderr 发出进度行,因此即使 Vitest 控制台捕获很安静,长时间提供商调用也能看出仍在活动。
|
||||
- `vitest.live.config.ts` 会禁用 Vitest 控制台拦截,因此提供商/gateway 进度行会在实时运行期间立即流式输出。
|
||||
- Live 套件现在会向 stderr 发送进度行,因此即使 Vitest 控制台捕获处于安静状态,长时间提供商调用也会显示为活跃。
|
||||
- `vitest.live.config.ts` 会禁用 Vitest 控制台拦截,因此提供商/Gateway 网关进度行会在 live 运行期间立即流式输出。
|
||||
- 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整 direct-model heartbeat。
|
||||
- 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 gateway/probe heartbeat。
|
||||
- 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关/probe heartbeat。
|
||||
|
||||
## 我应该运行哪个套件?
|
||||
|
||||
使用此决策表:
|
||||
|
||||
- 编辑逻辑/测试:运行 `pnpm test`(如果改动很多,也运行 `pnpm test:coverage`)
|
||||
- 触及 Gateway 网关网络 / WS 协议 / 配对:添加 `pnpm test:e2e`
|
||||
- 调试“我的机器人挂了”/ 提供商特定失败 / 工具调用:运行收窄范围的 `pnpm test:live`
|
||||
- 编辑逻辑/测试:运行 `pnpm test`(如果你改动很多,也运行 `pnpm test:coverage`)
|
||||
- 涉及 Gateway 网关网络 / WS 协议 / 配对:添加 `pnpm test:e2e`
|
||||
- 调试“我的机器人宕机了”/ 提供商特定失败 / 工具调用:运行收窄范围的 `pnpm test:live`
|
||||
|
||||
## 实时(触及网络的)测试
|
||||
## 真实(触网)测试
|
||||
|
||||
关于实时模型矩阵、CLI 后端冒烟测试、ACP 冒烟测试、Codex 应用服务器
|
||||
harness,以及所有媒体提供商实时测试(Deepgram、BytePlus、ComfyUI、图像、
|
||||
音乐、视频、媒体 harness)——再加上实时运行的凭证处理——请参阅
|
||||
[测试 — 实时套件](/zh-CN/help/testing-live)。
|
||||
关于真实模型矩阵、CLI 后端冒烟测试、ACP 冒烟测试、Codex 应用服务器
|
||||
harness,以及所有媒体提供商真实测试(Deepgram、BytePlus、ComfyUI、图像、
|
||||
音乐、视频、媒体 harness)——再加上真实运行的凭证处理——请参阅
|
||||
[测试——真实套件](/zh-CN/help/testing-live)。
|
||||
|
||||
## Docker 运行器(可选的“可在 Linux 中工作”检查)
|
||||
|
||||
这些 Docker 运行器分为两类:
|
||||
这些 Docker 运行器分成两类:
|
||||
|
||||
- 实时模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像内运行对应的 profile-key 实时文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),并挂载你的本地配置目录和工作区(如果已挂载,也会载入 `~/.profile`)。对应的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。
|
||||
- Docker 实时运行器默认使用较小的冒烟上限,让完整 Docker 扫描保持可行:
|
||||
`test:docker:live-models` 默认使用 `OPENCLAW_LIVE_MAX_MODELS=12`,并且
|
||||
- 真实模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像内运行各自匹配 profile-key 的真实文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),并挂载你的本地配置目录和工作区(如果已挂载,还会 source `~/.profile`)。匹配的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。
|
||||
- Docker 真实运行器默认使用较小的冒烟上限,让完整 Docker 扫描保持可行:
|
||||
`test:docker:live-models` 默认使用 `OPENCLAW_LIVE_MAX_MODELS=12`,而
|
||||
`test:docker:live-gateway` 默认使用 `OPENCLAW_LIVE_GATEWAY_SMOKE=1`、
|
||||
`OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`、
|
||||
`OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000` 和
|
||||
`OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你明确需要更大的穷尽式扫描时,可以覆盖这些环境变量。
|
||||
- `test:docker:all` 会通过 `test:docker:live-build` 构建一次实时 Docker 镜像,通过 `scripts/package-openclaw-for-docker.mjs` 将 OpenClaw 打包一次为 npm tarball,然后构建/复用两个 `scripts/e2e/Dockerfile` 镜像。裸镜像只是用于安装/更新/插件依赖 lane 的 Node/Git 运行器;这些 lane 会挂载预构建的 tarball。功能镜像会将同一个 tarball 安装到 `/app`,用于已构建应用的功能 lane。Docker lane 定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定的计划。聚合运行使用加权本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程槽位,而资源上限会防止重型实时、npm 安装和多服务 lane 同时全部启动。如果某个单独 lane 比活动上限更重,调度器仍可在池为空时启动它,然后让它单独运行,直到容量再次可用。默认值是 10 个槽位、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;只有在 Docker 主机有更多余量时,才调整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。运行器默认执行 Docker 预检,移除过时的 OpenClaw E2E 容器,每 30 秒打印一次 Status,将成功 lane 的耗时存储在 `.artifacts/docker-tests/lane-timings.json`,并在后续运行中使用这些耗时优先启动更长的 lane。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可在不构建或运行 Docker 的情况下打印加权 lane 清单,或使用 `node scripts/test-docker-all.mjs --plan-json` 打印所选 lane、包/镜像需求和凭证的 CI 计划。
|
||||
- `Package Acceptance` 是 GitHub 原生的包门禁,用来回答“这个可安装 tarball 作为产品是否可用?”它会从 `source=npm`、`source=ref`、`source=url` 或 `source=artifact` 解析一个候选包,将其上传为 `package-under-test`,然后对这个确切 tarball 运行可复用的 Docker E2E lane,而不是重新打包所选 ref。`workflow_ref` 选择受信任的工作流/harness 脚本,而 `package_ref` 在 `source=ref` 时选择要打包的源提交/分支/标签;这样当前验收逻辑就能验证较旧的受信任提交。Profile 按覆盖广度排序:`smoke` 是快速安装/渠道/智能体加 Gateway 网关/配置,`package` 是包/更新/插件合约,加无密钥 upgrade-survivor fixture,也是大多数 Parallels 包/更新覆盖的默认原生替代项,`product` 添加 MCP 渠道、cron/子智能体清理、OpenAI web 搜索和 OpenWebUI,`full` 则运行带 OpenWebUI 的发布路径 Docker 分块。发布验证会运行自定义包增量(`bundled-channel-deps-compat plugins-offline`),再加 Telegram 包 QA,因为发布路径 Docker 分块已经覆盖了重叠的包/更新/插件 lane。从工件生成的定向 GitHub Docker 重跑命令会在可用时包含先前的包工件和预备镜像输入,因此失败 lane 可以避免重新构建包和镜像。
|
||||
- 构建和发布检查会在 tsdown 之后运行 `scripts/check-cli-bootstrap-imports.mjs`。该保护会从 `dist/entry.js` 和 `dist/cli/run-main.js` 遍历静态构建图,如果分派前启动阶段在命令分派之前导入 Commander、prompt UI、undici 或日志等包依赖,就会失败;它还会将打包的 Gateway 网关运行分块保持在预算内,并拒绝对已知冷 Gateway 网关路径的静态导入。打包 CLI 冒烟测试还覆盖根帮助、新手引导帮助、Doctor 帮助、Status、配置 schema 和一个模型列表命令。
|
||||
- Package Acceptance 旧版兼容性上限为 `2026.4.25`(包含 `2026.4.25-beta.*`)。在该截止版本及之前,harness 仅容忍已发布包的元数据缺口:省略私有 QA 清单条目、缺少 `gateway install --wrapper`、tarball 派生的 git fixture 中缺少补丁文件、缺少持久化的 `update.channel`、旧版插件安装记录位置、缺少 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。对于 `2026.4.25` 之后的包,这些路径都是严格失败。
|
||||
- 容器冒烟运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:update-channel-switch`、`test:docker:upgrade-survivor`、`test:docker:session-runtime-context`、`test:docker:agents-delete-shared-workspace`、`test:docker:gateway-network`、`test:docker:browser-cdp-snapshot`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层的集成路径。
|
||||
`OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000`,以及
|
||||
`OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你明确需要更大的详尽扫描时,可以覆盖这些环境变量。
|
||||
- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次真实 Docker 镜像,通过 `scripts/package-openclaw-for-docker.mjs` 将 OpenClaw 打包一次为 npm tarball,然后构建/复用两个 `scripts/e2e/Dockerfile` 镜像。基础镜像只是用于安装/更新/插件依赖通道的 Node/Git 运行器;这些通道会挂载预构建的 tarball。功能镜像会把同一个 tarball 安装到 `/app`,用于已构建应用的功能通道。Docker 通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定计划。聚合运行使用加权本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程槽位,而资源上限会阻止重型真实、npm 安装和多服务通道同时全部启动。如果单个通道比当前上限更重,调度器仍可在池为空时启动它,并让它独占运行,直到容量再次可用。默认值为 10 个槽位、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;仅在 Docker 主机有更多余量时,才调优 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。运行器默认执行 Docker 预检,移除陈旧的 OpenClaw E2E 容器,每 30 秒打印一次状态,将成功通道耗时存储到 `.artifacts/docker-tests/lane-timings.json`,并在后续运行中使用这些耗时优先启动更长的通道。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可打印加权通道清单而不构建或运行 Docker,或使用 `node scripts/test-docker-all.mjs --plan-json` 打印所选通道、包/镜像需求和凭证的 CI 计划。
|
||||
- `Package Acceptance` 是 GitHub 原生的包门禁,用于验证“这个可安装 tarball 作为产品能否正常工作?”它会从 `source=npm`、`source=ref`、`source=url` 或 `source=artifact` 解析一个候选包,将其作为 `package-under-test` 上传,然后针对该精确 tarball 运行可复用的 Docker E2E 通道,而不是重新打包所选 ref。`workflow_ref` 选择受信任的 workflow/harness 脚本,而 `package_ref` 在 `source=ref` 时选择要打包的源提交/分支/标签;这让当前验收逻辑能够验证较旧的受信任提交。配置档按覆盖范围排序:`smoke` 是快速安装/渠道/智能体加 Gateway 网关/配置,`package` 是包/更新/插件契约加无密钥 upgrade-survivor fixture、已发布基线升级幸存者通道,以及多数 Parallels 包/更新覆盖的默认原生替代项,`product` 添加 MCP 渠道、cron/subagent 清理、OpenAI web search 和 OpenWebUI,`full` 使用 OpenWebUI 运行发布路径 Docker 分块。发布验证会运行自定义包增量(`bundled-channel-deps-compat plugins-offline`)以及 Telegram 包 QA,因为发布路径 Docker 分块已经覆盖重叠的包/更新/插件通道。从制品生成的定向 GitHub Docker 重跑命令会在可用时包含先前的包制品和已准备镜像输入,这样失败通道就能避免重建包和镜像。
|
||||
- 构建和发布检查会在 tsdown 之后运行 `scripts/check-cli-bootstrap-imports.mjs`。该守卫会从 `dist/entry.js` 和 `dist/cli/run-main.js` 遍历静态构建图,并在命令分派前的启动导入了 Commander、提示 UI、undici 或日志等包依赖时失败;它还会让打包的 Gateway 网关运行分块保持在预算内,并拒绝已知冷启动 Gateway 网关路径的静态导入。打包后的 CLI 冒烟测试还覆盖根帮助、新手引导帮助、Doctor 帮助、Status、配置 schema 和一个模型列表命令。
|
||||
- Package Acceptance 旧版兼容性上限为 `2026.4.25`(包括 `2026.4.25-beta.*`)。在该截止版本之前,harness 只容忍已发布包的元数据缺口:省略的私有 QA 清单条目、缺失的 `gateway install --wrapper`、tarball 派生 git fixture 中缺失的补丁文件、缺失的持久化 `update.channel`、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。对于 `2026.4.25` 之后的包,这些路径都是严格失败。
|
||||
- 容器冒烟运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:update-channel-switch`、`test:docker:upgrade-survivor`、`test:docker:published-upgrade-survivor`、`test:docker:session-runtime-context`、`test:docker:agents-delete-shared-workspace`、`test:docker:gateway-network`、`test:docker:browser-cdp-snapshot`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层级的集成路径。
|
||||
|
||||
实时模型 Docker 运行器还只会绑定挂载所需的 CLI 认证主目录(如果运行未收窄范围,则挂载所有受支持的主目录),然后在运行前将它们复制到容器主目录中,以便外部 CLI OAuth 可以刷新令牌,而不会修改主机认证存储:
|
||||
真实模型 Docker 运行器还只会 bind-mount 所需的 CLI 认证 home(如果运行未收窄,则挂载所有受支持的 home),然后在运行前把它们复制到容器 home 中,这样外部 CLI OAuth 就能刷新令牌,而不会修改主机认证存储:
|
||||
|
||||
- 直接模型:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`)
|
||||
- ACP 绑定冒烟测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`;默认覆盖 Claude、Codex 和 Gemini,并通过 `pnpm test:docker:live-acp-bind:droid` 与 `pnpm test:docker:live-acp-bind:opencode` 严格覆盖 Droid/OpenCode)
|
||||
- ACP 绑定冒烟测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`;默认覆盖 Claude、Codex 和 Gemini,并通过 `pnpm test:docker:live-acp-bind:droid` 和 `pnpm test:docker:live-acp-bind:opencode` 严格覆盖 Droid/OpenCode)
|
||||
- CLI 后端冒烟测试:`pnpm test:docker:live-cli-backend`(脚本:`scripts/test-live-cli-backend-docker.sh`)
|
||||
- Codex app-server harness 冒烟测试:`pnpm test:docker:live-codex-harness`(脚本:`scripts/test-live-codex-harness-docker.sh`)
|
||||
- Gateway 网关 + 开发智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`)
|
||||
- 可观测性冒烟测试:`pnpm qa:otel:smoke` 是一个私有 QA 源码签出通道。它有意不属于包 Docker 发布通道,因为 npm tarball 会省略 QA Lab。
|
||||
- 可观测性冒烟测试:`pnpm qa:otel:smoke` 是私有 QA 源码检出通道。它有意不属于包 Docker 发布通道,因为 npm tarball 会省略 QA 实验室。
|
||||
- Open WebUI 实时冒烟测试:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`)
|
||||
- 新手引导向导(TTY,完整脚手架):`pnpm test:docker:onboard`(脚本:`scripts/e2e/onboard-docker.sh`)
|
||||
- npm tarball 新手引导/渠道/智能体冒烟测试:`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装打包后的 OpenClaw tarball,通过 env-ref 新手引导配置 OpenAI,并默认配置 Telegram,验证 Doctor 已修复已激活插件的运行时依赖,并运行一个模拟的 OpenAI 智能体回合。使用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,使用 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机重新构建,或使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。
|
||||
- 更新渠道切换冒烟测试:`pnpm test:docker:update-channel-switch` 会在 Docker 中全局安装打包后的 OpenClaw tarball,从包 `stable` 切换到 git `dev`,验证持久化的渠道和插件更新后工作正常,然后切回包 `stable` 并检查更新状态。
|
||||
- 升级幸存者冒烟测试:`pnpm test:docker:upgrade-survivor` 会把打包后的 OpenClaw tarball 安装到一个脏的旧用户 fixture 上,其中包含智能体、渠道配置、插件允许列表、陈旧的插件运行时依赖状态,以及现有工作区/会话文件。它会在没有实时提供商或渠道密钥的情况下运行包更新和非交互式 Doctor,然后启动一个 loopback Gateway 网关,并检查配置/状态保留以及启动/Status 预算。
|
||||
- 会话运行时上下文冒烟测试:`pnpm test:docker:session-runtime-context` 会验证隐藏运行时上下文转录持久化,以及 Doctor 对受影响的重复 prompt-rewrite 分支的修复。
|
||||
- Bun 全局安装冒烟测试:`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前树,在隔离的 home 中用 `bun install -g` 安装,并验证 `openclaw infer image providers --json` 返回内置图片提供商而不是挂起。使用 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,使用 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳过主机构建,或使用 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 从已构建的 Docker 镜像复制 `dist/`。
|
||||
- 安装器 Docker 冒烟测试:`bash scripts/test-install-sh-docker.sh` 会在其 root、update 和 direct-npm 容器之间共享一个 npm 缓存。更新冒烟测试默认使用 npm `latest` 作为升级到候选 tarball 之前的稳定基线。本地用 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆盖,或在 GitHub 上用 Install Smoke 工作流的 `update_baseline_version` 输入覆盖。非 root 安装器检查会保留隔离的 npm 缓存,避免 root 拥有的缓存条目掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重跑之间复用 root/update/direct-npm 缓存。
|
||||
- Install Smoke CI 会用 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳过重复的 direct-npm 全局更新;需要覆盖直接 `npm install -g` 时,请在本地运行脚本且不设置该环境变量。
|
||||
- 智能体删除共享工作区 CLI 冒烟测试:`pnpm test:docker:agents-delete-shared-workspace`(脚本:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)默认构建根 Dockerfile 镜像,在隔离容器 home 中为两个智能体播种一个工作区,运行 `agents delete --json`,并验证有效 JSON 以及保留工作区行为。使用 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 复用 install-smoke 镜像。
|
||||
- Gateway 网关网络(两个容器,WS 凭证 + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`)
|
||||
- Browser CDP 快照冒烟测试:`pnpm test:docker:browser-cdp-snapshot`(脚本:`scripts/e2e/browser-cdp-snapshot-docker.sh`)会构建源码 E2E 镜像以及一个 Chromium 层,使用原始 CDP 启动 Chromium,运行 `browser doctor --deep`,并验证 CDP 角色快照覆盖链接 URL、游标提升的可点击元素、iframe 引用和 frame 元数据。
|
||||
- OpenAI Responses web_search 最小 reasoning 回归测试:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)会通过 Gateway 网关运行模拟的 OpenAI 服务器,验证 `web_search` 将 `reasoning.effort` 从 `minimal` 提升到 `low`,然后强制提供商 schema 拒绝,并检查原始详细信息出现在 Gateway 网关日志中。
|
||||
- npm tarball 新手引导/渠道/智能体冒烟测试:`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装打包后的 OpenClaw tarball,通过 env-ref 新手引导配置 OpenAI,并默认配置 Telegram,验证 Doctor 是否修复已激活插件运行时依赖,然后运行一次模拟的 OpenAI 智能体轮次。可用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,用 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机重建,或用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。
|
||||
- 更新渠道切换冒烟测试:`pnpm test:docker:update-channel-switch` 会在 Docker 中全局安装打包后的 OpenClaw tarball,从包 `stable` 切换到 git `dev`,验证持久化渠道和插件更新后工作正常,然后切回包 `stable` 并检查更新 Status。
|
||||
- 升级存活冒烟测试:`pnpm test:docker:upgrade-survivor` 会把打包后的 OpenClaw tarball 安装到带有脏旧用户夹具的环境上,该夹具包含智能体、渠道配置、插件 allowlist、过期的插件运行时依赖状态,以及既有工作区/会话文件。它会在没有实时提供商或渠道密钥的情况下运行包更新和非交互式 Doctor,然后启动一个 loopback Gateway 网关,并检查配置/状态保留以及启动/Status 预算。
|
||||
- 已发布版本升级存活冒烟测试:`pnpm test:docker:published-upgrade-survivor` 默认把 `openclaw@latest` 安装到同一个脏旧用户夹具上,将该已发布安装更新到候选 tarball,运行非交互式 Doctor,然后启动一个 loopback Gateway 网关,并检查相同的配置/状态保留以及启动/Status 预算。可用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆盖基线。
|
||||
- 会话运行时上下文冒烟测试:`pnpm test:docker:session-runtime-context` 验证隐藏运行时上下文转录持久化,以及 Doctor 对受影响的重复 prompt-rewrite 分支的修复。
|
||||
- Bun 全局安装冒烟测试:`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前树,在隔离 home 中用 `bun install -g` 安装它,并验证 `openclaw infer image providers --json` 返回内置图像提供商而不是挂起。可用 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,用 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳过主机构建,或用 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 从已构建的 Docker 镜像复制 `dist/`。
|
||||
- 安装器 Docker 冒烟测试:`bash scripts/test-install-sh-docker.sh` 会在其 root、update 和 direct-npm 容器之间共享一个 npm 缓存。更新冒烟测试默认使用 npm `latest` 作为升级到候选 tarball 之前的 stable 基线。本地可用 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆盖,或在 GitHub 上用 Install Smoke 工作流的 `update_baseline_version` 输入覆盖。非 root 安装器检查会保留隔离的 npm 缓存,避免 root 拥有的缓存条目掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重跑时复用 root/update/direct-npm 缓存。
|
||||
- Install Smoke CI 会用 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳过重复的 direct-npm 全局更新;需要覆盖直接 `npm install -g` 时,在本地运行脚本且不要设置该环境变量。
|
||||
- 智能体删除共享工作区 CLI 冒烟测试:`pnpm test:docker:agents-delete-shared-workspace`(脚本:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)默认构建根 Dockerfile 镜像,在隔离容器 home 中为两个智能体播种一个工作区,运行 `agents delete --json`,并验证 JSON 有效以及保留工作区行为。可用 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 复用 install-smoke 镜像。
|
||||
- Gateway 网关网络(两个容器,WS 认证 + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`)
|
||||
- 浏览器 CDP 快照冒烟测试:`pnpm test:docker:browser-cdp-snapshot`(脚本:`scripts/e2e/browser-cdp-snapshot-docker.sh`)构建源码 E2E 镜像和 Chromium 层,用原始 CDP 启动 Chromium,运行 `browser doctor --deep`,并验证 CDP 角色快照覆盖链接 URL、光标提升的可点击项、iframe 引用和 frame 元数据。
|
||||
- OpenAI Responses web_search minimal reasoning 回归测试:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)通过 Gateway 网关运行模拟的 OpenAI 服务器,验证 `web_search` 会把 `reasoning.effort` 从 `minimal` 提升到 `low`,然后强制提供商 schema 拒绝,并检查原始详情出现在 Gateway 网关日志中。
|
||||
- MCP 渠道桥接(已播种 Gateway 网关 + stdio bridge + 原始 Claude notification-frame 冒烟测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`)
|
||||
- Pi bundle MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi profile allow/deny 冒烟测试):`pnpm test:docker:pi-bundle-mcp-tools`(脚本:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`)
|
||||
- Cron/subagent MCP 清理(真实 Gateway 网关 + 隔离 cron 和一次性 subagent 运行后的 stdio MCP 子进程清理):`pnpm test:docker:cron-mcp-cleanup`(脚本:`scripts/e2e/cron-mcp-cleanup-docker.sh`)
|
||||
- Pi bundle MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi 配置文件允许/拒绝冒烟测试):`pnpm test:docker:pi-bundle-mcp-tools`(脚本:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`)
|
||||
- Cron/subagent MCP 清理(真实 Gateway 网关 + 在隔离 cron 和一次性 subagent 运行后拆除 stdio MCP 子进程):`pnpm test:docker:cron-mcp-cleanup`(脚本:`scripts/e2e/cron-mcp-cleanup-docker.sh`)
|
||||
- 插件(安装冒烟测试、ClawHub kitchen-sink 安装/卸载、marketplace 更新,以及 Claude-bundle 启用/检查):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`)
|
||||
设置 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可跳过 ClawHub 区块,或使用 `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` 和 `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID` 覆盖默认的 kitchen-sink package/runtime 组合。没有 `OPENCLAW_CLAWHUB_URL`/`CLAWHUB_URL` 时,测试会使用 hermetic 的本地 ClawHub fixture 服务器。
|
||||
设置 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可跳过 ClawHub 块,或用 `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` 和 `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID` 覆盖默认的 kitchen-sink 包/运行时组合。没有 `OPENCLAW_CLAWHUB_URL`/`CLAWHUB_URL` 时,测试会使用 hermetic 本地 ClawHub 夹具服务器。
|
||||
- 插件更新未变更冒烟测试:`pnpm test:docker:plugin-update`(脚本:`scripts/e2e/plugin-update-unchanged-docker.sh`)
|
||||
- 配置重载元数据冒烟测试:`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`)
|
||||
- 内置插件运行时依赖:`pnpm test:docker:bundled-channel-deps` 默认构建一个小型 Docker runner 镜像,在主机上构建并打包一次 OpenClaw,然后把该 tarball 挂载到每个 Linux 安装场景中。使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 复用镜像,在刚完成本地构建后用 `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` 跳过主机重新构建,或用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 指向现有 tarball。完整 Docker 聚合和发布路径 bundled-channel 分片会先预打包该 tarball 一次,然后将内置渠道检查分片到独立通道,包括 Telegram、Discord、Slack、Feishu、memory-lancedb 和 ACPX 的单独更新通道。发布分片会把渠道冒烟测试、更新目标以及设置/运行时契约拆分为 `bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-b` 和 `bundled-channels-contracts`;聚合 `bundled-channels` 分片仍可用于手动重跑。发布工作流还会拆分提供商安装器分片以及内置插件安装/卸载分片;旧版 `package-update`、`plugins-runtime` 和 `plugins-integrations` 分片仍保留为手动重跑的聚合别名。直接运行内置通道时,使用 `OPENCLAW_BUNDLED_CHANNELS=telegram,slack` 缩小渠道矩阵,或使用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx` 缩小更新场景。每个场景的 Docker 运行默认使用 `OPENCLAW_BUNDLED_CHANNEL_DOCKER_RUN_TIMEOUT=900s`;多目标更新场景默认使用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_DOCKER_RUN_TIMEOUT=2400s`。该通道还会验证 `channels.<id>.enabled=false` 和 `plugins.entries.<id>.enabled=false` 会抑制 Doctor/运行时依赖修复。
|
||||
- 迭代时可通过禁用不相关场景来缩小内置插件运行时依赖,例如:
|
||||
- 配置 reload 元数据冒烟测试:`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`)
|
||||
- 内置插件运行时依赖:`pnpm test:docker:bundled-channel-deps` 默认构建一个小型 Docker runner 镜像,在主机上构建并打包 OpenClaw 一次,然后把该 tarball 挂载到每个 Linux 安装场景中。可用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 复用镜像,在一次新的本地构建后用 `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` 跳过主机重建,或用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 指向既有 tarball。完整 Docker 聚合和发布路径的 bundled-channel 分块会先预打包此 tarball 一次,然后把内置渠道检查分片到独立通道中,包括 Telegram、Discord、Slack、Feishu、memory-lancedb 和 ACPX 的独立更新通道。发布分块会把渠道冒烟测试、更新目标以及设置/运行时合约拆分到 `bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-b` 和 `bundled-channels-contracts`;聚合 `bundled-channels` 分块仍可用于手动重跑。发布工作流还会拆分提供商安装器分块和内置插件安装/卸载分块;旧版 `package-update`、`plugins-runtime` 和 `plugins-integrations` 分块仍作为手动重跑的聚合别名保留。直接运行内置通道时,可用 `OPENCLAW_BUNDLED_CHANNELS=telegram,slack` 缩小渠道矩阵,或用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx` 缩小更新场景。每个场景的 Docker 运行默认使用 `OPENCLAW_BUNDLED_CHANNEL_DOCKER_RUN_TIMEOUT=900s`;多目标更新场景默认使用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_DOCKER_RUN_TIMEOUT=2400s`。该通道还会验证 `channels.<id>.enabled=false` 和 `plugins.entries.<id>.enabled=false` 会抑制 Doctor/运行时依赖修复。
|
||||
- 迭代时可通过禁用无关场景来缩小内置插件运行时依赖,例如:
|
||||
`OPENCLAW_BUNDLED_CHANNEL_SCENARIOS=0 OPENCLAW_BUNDLED_CHANNEL_UPDATE_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_ROOT_OWNED_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_SETUP_ENTRY_SCENARIO=0 pnpm test:docker:bundled-channel-deps`。
|
||||
|
||||
要手动预构建并复用共享功能镜像:
|
||||
@ -565,116 +552,114 @@ OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local pnpm test:docker:
|
||||
OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels
|
||||
```
|
||||
|
||||
设置后,`OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 等套件专用镜像覆盖项仍然优先。当 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向远程共享镜像时,如果本地还没有该镜像,脚本会拉取它。QR 和安装器 Docker 测试保留自己的 Dockerfile,因为它们验证的是包/安装行为,而不是共享的已构建应用运行时。
|
||||
设置了 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 等套件专用镜像覆盖项时,它们仍然优先。当 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向远程共享镜像时,如果该镜像尚不在本地,脚本会拉取它。QR 和安装器 Docker 测试会保留自己的 Dockerfile,因为它们验证的是包/安装行为,而不是共享的已构建应用运行时。
|
||||
|
||||
实时模型 Docker 运行器也会将当前检出目录以只读方式绑定挂载,并
|
||||
将其暂存到容器内的临时 workdir 中。这样可以保持运行时镜像精简,同时仍然用你的精确本地源代码/配置运行 Vitest。
|
||||
暂存步骤会跳过大型的仅本地缓存和应用构建输出,例如
|
||||
`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地的 `.build` 或
|
||||
Gradle 输出目录,因此 Docker 实时运行不会花费数分钟复制
|
||||
实时模型 Docker 运行器还会以只读方式绑定挂载当前检出内容,并将其
|
||||
暂存到容器内的临时工作目录。这样能保持运行时镜像精简,同时仍然用你的
|
||||
精确本地源代码/配置运行 Vitest。暂存步骤会跳过大型的仅本地缓存和应用构建输出,例如
|
||||
`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地 `.build` 或
|
||||
Gradle 输出目录,因此 Docker 实时运行不会花数分钟复制
|
||||
特定机器的产物。
|
||||
它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关实时探测就不会在容器内启动
|
||||
真实的 Telegram/Discord 等渠道 worker。
|
||||
`test:docker:live-models` 仍会运行 `pnpm test:live`,所以当你需要从该 Docker 通道收窄或排除 Gateway 网关
|
||||
实时覆盖范围时,也要传入
|
||||
它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,因此 Gateway 网关实时探测不会在
|
||||
容器内启动真实的 Telegram/Discord 等渠道 worker。
|
||||
`test:docker:live-models` 仍然运行 `pnpm test:live`,所以当你需要从该 Docker lane
|
||||
缩小或排除 Gateway 网关实时覆盖范围时,也要传入
|
||||
`OPENCLAW_LIVE_GATEWAY_*`。
|
||||
`test:docker:openwebui` 是更高层的兼容性冒烟测试:它会启动一个启用了
|
||||
OpenAI 兼容 HTTP 端点的
|
||||
OpenClaw Gateway 网关容器,
|
||||
再启动一个固定版本的 Open WebUI 容器并连接到该 Gateway 网关,通过
|
||||
Open WebUI 登录,验证 `/api/models` 暴露 `openclaw/default`,然后通过 Open WebUI 的
|
||||
`/api/chat/completions` 代理发送一个
|
||||
真实聊天请求。
|
||||
`test:docker:openwebui` 是更高层级的兼容性冒烟测试:它会启动一个启用了
|
||||
OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器,
|
||||
再启动一个固定版本的 Open WebUI 容器连接到该 Gateway 网关,通过
|
||||
Open WebUI 登录,验证 `/api/models` 暴露了 `openclaw/default`,然后通过
|
||||
Open WebUI 的 `/api/chat/completions` 代理发送真实聊天请求。
|
||||
首次运行可能明显更慢,因为 Docker 可能需要拉取
|
||||
Open WebUI 镜像,而 Open WebUI 可能需要完成自己的冷启动设置。
|
||||
该通道需要可用的实时模型密钥,`OPENCLAW_PROFILE_FILE`
|
||||
Open WebUI 镜像,而 Open WebUI 也可能需要完成自身的冷启动设置。
|
||||
此 lane 需要可用的实时模型密钥,`OPENCLAW_PROFILE_FILE`
|
||||
(默认是 `~/.profile`)是在 Docker 化运行中提供它的主要方式。
|
||||
成功运行会打印一个小型 JSON 载荷,例如 `{ "ok": true, "model":
|
||||
"openclaw/default", ... }`。
|
||||
`test:docker:mcp-channels` 是有意保持确定性的,不需要
|
||||
真实的 Telegram、Discord 或 iMessage 账号。它会启动一个已种子的 Gateway 网关
|
||||
容器,再启动第二个容器来生成 `openclaw mcp serve`,然后
|
||||
验证路由后的会话发现、转录读取、附件元数据、
|
||||
实时事件队列行为、出站发送路由,以及通过真实 stdio MCP 桥接传递的 Claude 风格渠道 +
|
||||
`test:docker:mcp-channels` 刻意设计为确定性的,不需要
|
||||
真实的 Telegram、Discord 或 iMessage 账号。它会启动一个带种子的 Gateway 网关
|
||||
容器,启动第二个容器来生成 `openclaw mcp serve`,然后
|
||||
验证已路由会话发现、转录读取、附件元数据、
|
||||
实时事件队列行为、出站发送路由,以及通过真实 stdio MCP bridge 发送的 Claude 风格渠道 +
|
||||
权限通知。通知检查会直接检查原始 stdio MCP 帧,因此该冒烟测试验证的是
|
||||
桥接实际发出的内容,而不只是某个特定客户端 SDK 恰好暴露的内容。
|
||||
bridge 实际发出的内容,而不只是某个特定客户端 SDK 恰好暴露的内容。
|
||||
`test:docker:pi-bundle-mcp-tools` 是确定性的,不需要实时
|
||||
模型密钥。它会构建仓库 Docker 镜像,在容器内启动真实 stdio MCP 探测服务器,
|
||||
通过嵌入式 Pi 包
|
||||
MCP 运行时物化该服务器,执行该工具,然后验证 `coding` 和 `messaging` 保留
|
||||
模型密钥。它会构建仓库 Docker 镜像,在容器内启动一个真实 stdio MCP 探测服务器,
|
||||
通过嵌入式 Pi bundle MCP 运行时物化该服务器,
|
||||
执行工具,然后验证 `coding` 和 `messaging` 会保留
|
||||
`bundle-mcp` 工具,而 `minimal` 和 `tools.deny: ["bundle-mcp"]` 会过滤它们。
|
||||
`test:docker:cron-mcp-cleanup` 是确定性的,不需要实时模型
|
||||
密钥。它会启动一个带有真实 stdio MCP 探测服务器的已种子 Gateway 网关,运行一个
|
||||
隔离的 cron 回合和一个 `/subagents spawn` 一次性子回合,然后验证
|
||||
密钥。它会启动一个带种子的 Gateway 网关和一个真实 stdio MCP 探测服务器,运行一次
|
||||
隔离的 cron turn 和一次 `/subagents spawn` 一次性子 turn,然后验证
|
||||
MCP 子进程会在每次运行后退出。
|
||||
|
||||
手动 ACP 自然语言线程冒烟测试(非 CI):
|
||||
|
||||
- `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...`
|
||||
- 保留此脚本用于回归/调试工作流。ACP 线程路由验证可能会再次需要它,因此不要删除它。
|
||||
- 保留此脚本用于回归/调试工作流。ACP 线程路由验证以后可能还会再次需要它,所以不要删除它。
|
||||
|
||||
有用的环境变量:
|
||||
|
||||
- `OPENCLAW_CONFIG_DIR=...`(默认:`~/.openclaw`)挂载到 `/home/node/.openclaw`
|
||||
- `OPENCLAW_WORKSPACE_DIR=...`(默认:`~/.openclaw/workspace`)挂载到 `/home/node/.openclaw/workspace`
|
||||
- `OPENCLAW_PROFILE_FILE=...`(默认:`~/.profile`)挂载到 `/home/node/.profile`,并在运行测试前 source
|
||||
- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 用于仅验证从 `OPENCLAW_PROFILE_FILE` source 的环境变量,使用临时配置/工作区目录且不挂载外部 CLI 认证
|
||||
- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内缓存的 CLI 安装
|
||||
- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 用于仅验证从 `OPENCLAW_PROFILE_FILE` source 的环境变量,使用临时配置/工作区目录,且不挂载外部 CLI 认证
|
||||
- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内缓存 CLI 安装
|
||||
- `$HOME` 下的外部 CLI 认证目录/文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...`
|
||||
- 默认目录:`.minimax`
|
||||
- 默认文件:`~/.codex/auth.json`、`~/.codex/config.toml`、`.claude.json`、`~/.claude/.credentials.json`、`~/.claude/settings.json`、`~/.claude/settings.local.json`
|
||||
- 收窄后的提供商运行只会挂载从 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录/文件
|
||||
- 缩小范围的提供商运行只会挂载从 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录/文件
|
||||
- 可用 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none`,或类似 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` 的逗号列表手动覆盖
|
||||
- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用于收窄运行范围
|
||||
- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用于缩小运行范围
|
||||
- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用于在容器内过滤提供商
|
||||
- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于在不需要重新构建的重复运行中复用现有的 `openclaw:local-live` 镜像
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭据来自 profile 存储(而非 env)
|
||||
- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于在不需要重新构建的重跑中复用现有 `openclaw:local-live` 镜像
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭据来自 profile 存储(而不是环境变量)
|
||||
- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关为 Open WebUI 冒烟测试暴露的模型
|
||||
- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试使用的 nonce 检查提示词
|
||||
- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试使用的 nonce 检查提示
|
||||
- `OPENWEBUI_IMAGE=...` 用于覆盖固定的 Open WebUI 镜像标签
|
||||
|
||||
## 文档完整性检查
|
||||
|
||||
文档编辑后运行文档检查:`pnpm check:docs`。
|
||||
当你还需要进行页内标题检查时,运行完整的 Mintlify 锚点验证:`pnpm docs:check-links:anchors`。
|
||||
当你还需要页内标题检查时,运行完整 Mintlify 锚点验证:`pnpm docs:check-links:anchors`。
|
||||
|
||||
## 离线回归(CI 安全)
|
||||
|
||||
这些是不使用真实提供商的“真实流水线”回归:
|
||||
这些是没有真实提供商的“真实流水线”回归:
|
||||
|
||||
- Gateway 网关工具调用(模拟 OpenAI,真实 Gateway 网关 + Agent loop):`src/gateway/gateway.test.ts`(用例:"runs a mock OpenAI tool call end-to-end via gateway agent loop")
|
||||
- Gateway 网关向导(WS `wizard.start`/`wizard.next`,写入配置 + 强制认证):`src/gateway/gateway.test.ts`(用例:"runs wizard over ws and writes auth token config")
|
||||
|
||||
## 智能体可靠性评测(Skills)
|
||||
## 智能体可靠性评估(Skills)
|
||||
|
||||
我们已经有一些 CI 安全测试,它们的行为类似“智能体可靠性评测”:
|
||||
我们已经有一些 CI 安全测试,它们的行为类似于“智能体可靠性评估”:
|
||||
|
||||
- 通过真实 Gateway 网关 + Agent loop 进行模拟工具调用(`src/gateway/gateway.test.ts`)。
|
||||
- 验证会话接线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。
|
||||
- 端到端向导流程,用于验证会话接线和配置效果(`src/gateway/gateway.test.ts`)。
|
||||
|
||||
Skills 仍然缺失的内容(参见 [Skills](/zh-CN/tools/skills)):
|
||||
Skills 仍然缺失的内容(见 [Skills](/zh-CN/tools/skills)):
|
||||
|
||||
- **决策:**当提示词中列出 Skills 时,智能体是否选择正确的 Skills(或避开无关项)?
|
||||
- **合规性:**智能体是否在使用前读取 `SKILL.md` 并遵循所需步骤/参数?
|
||||
- **工作流契约:**断言工具顺序、会话历史继承和沙箱边界的多轮场景。
|
||||
- **决策:** 当提示中列出 Skills 时,智能体是否选择正确的 Skills(或避开无关项)?
|
||||
- **合规:** 智能体是否在使用前读取 `SKILL.md`,并遵循必需步骤/参数?
|
||||
- **工作流契约:** 多轮场景,用于断言工具顺序、会话历史延续和沙箱边界。
|
||||
|
||||
未来评测应优先保持确定性:
|
||||
未来评估应优先保持确定性:
|
||||
|
||||
- 使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、Skill 文件读取和会话接线。
|
||||
- 一小组聚焦 Skill 的场景(使用与避开、门控、提示注入)。
|
||||
- 可选实时评测(选择启用、由环境变量门控)仅在 CI 安全套件就绪后再添加。
|
||||
- 使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、skill 文件读取和会话接线。
|
||||
- 一小组聚焦 Skills 的场景(使用 vs 避开、门控、提示注入)。
|
||||
- 仅在 CI 安全套件就位后,再添加可选实时评估(选择加入、由环境变量门控)。
|
||||
|
||||
## 契约测试(插件和渠道形状)
|
||||
|
||||
契约测试会验证每个已注册的插件和渠道都符合其
|
||||
接口契约。它们会遍历所有已发现的插件,并运行一套
|
||||
形状和行为断言。默认的 `pnpm test` 单元测试通道有意
|
||||
跳过这些共享衔接面和冒烟文件;当你触及共享渠道或提供商表面时,
|
||||
契约测试会验证每个已注册插件和渠道都符合其
|
||||
接口契约。它们会遍历所有发现的插件,并运行一套
|
||||
形状和行为断言。默认的 `pnpm test` 单元 lane 会刻意
|
||||
跳过这些共享 seam 和冒烟文件;当你触及共享渠道或提供商 surface 时,
|
||||
请显式运行契约命令。
|
||||
|
||||
### 命令
|
||||
|
||||
- 所有契约:`pnpm test:contracts`
|
||||
- 全部契约:`pnpm test:contracts`
|
||||
- 仅渠道契约:`pnpm test:contracts:channels`
|
||||
- 仅提供商契约:`pnpm test:contracts:plugins`
|
||||
|
||||
@ -682,14 +667,14 @@ Skills 仍然缺失的内容(参见 [Skills](/zh-CN/tools/skills)):
|
||||
|
||||
位于 `src/channels/plugins/contracts/*.contract.test.ts`:
|
||||
|
||||
- **plugin** - 基本插件形状(id、name、capabilities)
|
||||
- **plugin** - 基本插件形状(id、名称、能力)
|
||||
- **setup** - 设置向导契约
|
||||
- **session-binding** - 会话绑定行为
|
||||
- **outbound-payload** - 消息载荷结构
|
||||
- **inbound** - 入站消息处理
|
||||
- **actions** - 渠道操作处理器
|
||||
- **threading** - 线程 ID 处理
|
||||
- **directory** - 目录/名单 API
|
||||
- **directory** - 目录/名册 API
|
||||
- **group-policy** - 群组策略强制执行
|
||||
|
||||
### 提供商 Status 契约
|
||||
@ -718,20 +703,20 @@ Skills 仍然缺失的内容(参见 [Skills](/zh-CN/tools/skills)):
|
||||
- 添加或修改渠道或提供商插件后
|
||||
- 重构插件注册或发现后
|
||||
|
||||
契约测试会在 CI 中运行,不需要真实 API key。
|
||||
契约测试会在 CI 中运行,且不需要真实 API keys。
|
||||
|
||||
## 添加回归(指南)
|
||||
|
||||
当你修复在实时环境中发现的提供商/模型问题时:
|
||||
当你修复在实时中发现的提供商/模型问题时:
|
||||
|
||||
- 如果可能,添加 CI 安全回归(模拟/stub 提供商,或捕获精确的请求形状转换)
|
||||
- 如果它本质上只能实时测试(速率限制、认证策略),请保持实时测试收窄,并通过环境变量选择启用
|
||||
- 优先针对能捕获 bug 的最小层:
|
||||
- 提供商请求转换/回放 bug → 直接模型测试
|
||||
- 尽可能添加 CI 安全回归(模拟/stub 提供商,或捕获精确的请求形状转换)
|
||||
- 如果它本质上只能实时测试(速率限制、认证策略),请保持实时测试范围窄,并通过环境变量选择加入
|
||||
- 优先针对能捕获该 bug 的最小层级:
|
||||
- 提供商请求转换/重放 bug → 直接模型测试
|
||||
- Gateway 网关会话/历史/工具流水线 bug → Gateway 网关实时冒烟测试或 CI 安全 Gateway 网关模拟测试
|
||||
- SecretRef 遍历防护栏:
|
||||
- `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)为每个 SecretRef 类派生一个抽样目标,然后断言带遍历片段的 exec id 会被拒绝。
|
||||
- 如果你在 `src/secrets/target-registry-data.ts` 中添加新的 `includeInPlan` SecretRef 目标族,请更新该测试中的 `classifyTargetClass`。该测试会故意在未分类目标 id 上失败,确保新类不能被静默跳过。
|
||||
- SecretRef 遍历护栏:
|
||||
- `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)为每个 SecretRef 类派生一个抽样目标,然后断言 traversal-segment exec ids 会被拒绝。
|
||||
- 如果你在 `src/secrets/target-registry-data.ts` 中添加新的 `includeInPlan` SecretRef 目标家族,请更新该测试中的 `classifyTargetClass`。该测试会刻意在未分类目标 id 上失败,这样新类就不能被静默跳过。
|
||||
|
||||
## 相关
|
||||
|
||||
|
||||
@ -4,56 +4,57 @@ read_when:
|
||||
summary: 如何在本地运行测试(vitest),以及何时使用强制/覆盖率模式
|
||||
title: 测试
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T18:10:55Z"
|
||||
generated_at: "2026-04-30T23:43:52Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 131f2bad3b2806d28394213cec38d632d106ddbf8ff04d06345ab8046fb8bcf2
|
||||
source_hash: de18ac7d822055ee34885e5e897eff0fe7dde57c945a6b7f2c4bb2a29445c859
|
||||
source_path: reference/test.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
- 完整测试工具包(测试套件、实时测试、Docker):[测试](/zh-CN/help/testing)
|
||||
- 完整测试工具包(套件、真实环境测试、Docker):[测试](/zh-CN/help/testing)
|
||||
|
||||
- `pnpm test:force`:终止任何仍占用默认控制端口的 Gateway 网关进程,然后使用隔离的 Gateway 网关端口运行完整的 Vitest 套件,避免服务器测试与正在运行的实例冲突。当先前的 Gateway 网关运行留下端口 18789 被占用时使用此命令。
|
||||
- `pnpm test:coverage`:使用 V8 覆盖率运行单元套件(通过 `vitest.unit.config.ts`)。这是已加载文件的单元覆盖率门禁,不是全仓库所有文件覆盖率。阈值为行数/函数/语句 70%,分支 55%。因为 `coverage.all` 为 false,门禁衡量的是单元覆盖率套件加载的文件,而不是把每个拆分通道的源文件都视为未覆盖。
|
||||
- `pnpm test:coverage:changed`:仅对自 `origin/main` 以来更改的文件运行单元覆盖率。
|
||||
- `pnpm test:changed`:廉价的智能变更测试运行。它会从直接测试编辑、同级 `*.test.ts` 文件、显式源码映射和本地导入图运行精确目标。宽泛的配置/包更改会被跳过,除非它们能映射到精确测试。
|
||||
- `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`:显式的宽泛变更测试运行。当测试 harness/配置/包编辑应回退到 Vitest 更宽泛的变更测试行为时使用它。
|
||||
- `pnpm changed:lanes`:显示相对于 `origin/main` 的差异触发的架构通道。
|
||||
- `pnpm check:changed`:针对相对于 `origin/main` 的差异运行智能变更检查门禁。它会为受影响的架构通道运行类型检查、lint 和守卫命令,但不运行 Vitest 测试。测试证明请使用 `pnpm test:changed` 或显式的 `pnpm test <target>`。
|
||||
- `pnpm test`:通过限定范围的 Vitest 通道路由显式文件/目录目标。无目标运行会使用固定分片组,并展开到叶级配置以便本地并行执行;插件组始终展开为按插件划分的分片配置,而不是一个巨大的根项目进程。
|
||||
- 测试包装器运行会以简短的 `[test] passed|failed|skipped ... in ...` 摘要结束。Vitest 自身的耗时行仍保留为每个分片的详细信息。
|
||||
- 共享 OpenClaw 测试状态:当测试需要隔离的 `HOME`、`OPENCLAW_STATE_DIR`、`OPENCLAW_CONFIG_PATH`、配置夹具、工作区、智能体目录或 auth-profile 存储时,在 Vitest 中使用 `src/test-utils/openclaw-test-state.ts`。
|
||||
- 进程 E2E 助手:当 Vitest 进程级 E2E 测试需要一个正在运行的 Gateway 网关、CLI 环境、日志捕获和集中清理时,使用 `test/helpers/openclaw-test-instance.ts`。
|
||||
- Docker/Bash E2E 助手:source `scripts/lib/docker-e2e-image.sh` 的通道可以把 `docker_e2e_test_state_shell_b64 <label> <scenario>` 传入容器,并用 `scripts/lib/openclaw-e2e-instance.sh` 解码;多 home 脚本可以传入 `docker_e2e_test_state_function_b64`,并在每个流程中调用 `openclaw_test_state_create <label> <scenario>`。更底层的调用方可以使用 `scripts/lib/openclaw-test-state.mjs shell --label <name> --scenario <name>` 获取容器内 shell 片段,或使用 `node scripts/lib/openclaw-test-state.mjs -- create --label <name> --scenario <name> --env-file <path> --json` 获取可 source 的宿主环境文件。`create` 前的 `--` 可避免较新的 Node 运行时把 `--env-file` 当作 Node 标志处理。启动 Gateway 网关的 Docker/Bash 通道可以在容器内 source `scripts/lib/openclaw-e2e-instance.sh`,用于入口点解析、模拟 OpenAI 启动、Gateway 网关前台/后台启动、就绪探测、状态环境导出、日志转储和进程清理。
|
||||
- 完整、插件和 include-pattern 分片运行会更新 `.artifacts/vitest-shard-timings.json` 中的本地计时数据;之后的 whole-config 运行会使用这些计时来平衡慢分片和快分片。include-pattern CI 分片会把分片名称追加到计时键中,这样可以在不替换 whole-config 计时数据的情况下保留可见的过滤分片计时。设置 `OPENCLAW_TEST_PROJECTS_TIMINGS=0` 可忽略本地计时产物。
|
||||
- 选定的 `plugin-sdk` 和 `commands` 测试文件现在会通过专用轻量通道路由,这些通道只保留 `test/setup.ts`,而把运行时较重的用例留在其现有通道上。
|
||||
- 带有同级测试的源文件会先映射到该同级测试,然后再回退到更宽的目录 glob。`src/channels/plugins/contracts/test-helpers`、`src/plugin-sdk/test-helpers` 和 `src/plugins/contracts` 下的助手编辑会使用本地导入图来运行导入它们的测试,而不是在依赖路径精确时宽泛运行每个分片。
|
||||
- `auto-reply` 现在也拆分为三个专用配置(`core`、`top-level`、`reply`),因此 reply harness 不会支配更轻量的顶层状态/token/助手测试。
|
||||
- 基础 Vitest 配置现在默认使用 `pool: "threads"` 和 `isolate: false`,并在全仓库配置中启用共享的非隔离 runner。
|
||||
- `pnpm test:force`:终止任何仍占用默认控制端口的 Gateway 网关进程,然后使用隔离的 Gateway 网关端口运行完整 Vitest 套件,这样服务器测试就不会与正在运行的实例冲突。当先前的 Gateway 网关运行让端口 18789 被占用时使用此命令。
|
||||
- `pnpm test:coverage`:使用 V8 覆盖率运行单元套件(通过 `vitest.unit.config.ts`)。这是已加载文件的单元覆盖率门禁,不是整个仓库的全文件覆盖率。阈值为 70% 的行/函数/语句覆盖率和 55% 的分支覆盖率。因为 `coverage.all` 为 false,所以该门禁衡量的是单元覆盖率套件加载的文件,而不是把每个拆分通道源文件都视为未覆盖。
|
||||
- `pnpm test:coverage:changed`:仅对自 `origin/main` 以来变更的文件运行单元覆盖率。
|
||||
- `pnpm test:changed`:低成本的智能变更测试运行。它会从直接测试编辑、相邻的 `*.test.ts` 文件、显式源映射和本地导入图运行精确目标。宽泛/配置/package 变更会被跳过,除非它们映射到精确测试。
|
||||
- `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`:显式的宽泛变更测试运行。当测试 harness、配置或 package 编辑应回退到 Vitest 更宽泛的变更测试行为时使用它。
|
||||
- `pnpm changed:lanes`:显示相对于 `origin/main` 的 diff 触发的架构通道。
|
||||
- `pnpm check:changed`:对相对于 `origin/main` 的 diff 运行智能变更检查门禁。它会为受影响的架构通道运行 typecheck、lint 和 guard 命令,但不会运行 Vitest 测试。使用 `pnpm test:changed` 或显式的 `pnpm test <target>` 提供测试证明。
|
||||
- `pnpm test`:将显式文件/目录目标路由到有作用域的 Vitest 通道。无目标运行使用固定分片组,并展开为叶级配置以进行本地并行执行;插件组始终展开为按插件划分的分片配置,而不是一个巨大的根项目进程。
|
||||
- 测试包装器运行结束时会输出简短的 `[test] passed|failed|skipped ... in ...` 摘要。Vitest 自己的耗时行保留为每个分片的详细信息。
|
||||
- 共享 OpenClaw 测试状态:当测试需要隔离的 `HOME`、`OPENCLAW_STATE_DIR`、`OPENCLAW_CONFIG_PATH`、配置 fixture、工作区、智能体目录或 auth-profile 存储时,在 Vitest 中使用 `src/test-utils/openclaw-test-state.ts`。
|
||||
- 进程 E2E 辅助工具:当 Vitest 进程级 E2E 测试需要在一处完成运行中的 Gateway 网关、CLI 环境、日志捕获和清理时,使用 `test/helpers/openclaw-test-instance.ts`。
|
||||
- Docker/Bash E2E 辅助工具:source `scripts/lib/docker-e2e-image.sh` 的通道可以将 `docker_e2e_test_state_shell_b64 <label> <scenario>` 传入容器,并用 `scripts/lib/openclaw-e2e-instance.sh` 解码;多 home 脚本可以传入 `docker_e2e_test_state_function_b64`,并在每个流程中调用 `openclaw_test_state_create <label> <scenario>`。更底层的调用方可以使用 `scripts/lib/openclaw-test-state.mjs shell --label <name> --scenario <name>` 生成容器内 shell 片段,或使用 `node scripts/lib/openclaw-test-state.mjs -- create --label <name> --scenario <name> --env-file <path> --json` 生成可 source 的宿主环境文件。`create` 前面的 `--` 可防止较新的 Node 运行时把 `--env-file` 当作 Node 标志处理。启动 Gateway 网关的 Docker/Bash 通道可以在容器内 source `scripts/lib/openclaw-e2e-instance.sh`,用于入口点解析、模拟 OpenAI 启动、Gateway 网关前台/后台启动、就绪探测、状态环境导出、日志转储和进程清理。
|
||||
- 完整、插件和 include-pattern 分片运行会更新 `.artifacts/vitest-shard-timings.json` 中的本地计时数据;之后的整配置运行会使用这些计时来平衡慢分片和快分片。Include-pattern CI 分片会把分片名称追加到计时键中,这样筛选后的分片计时仍然可见,而不会替换整配置计时数据。设置 `OPENCLAW_TEST_PROJECTS_TIMINGS=0` 可忽略本地计时产物。
|
||||
- 选定的 `plugin-sdk` 和 `commands` 测试文件现在会通过专用轻量通道路由,这些通道只保留 `test/setup.ts`,而运行时较重的用例仍留在现有通道上。
|
||||
- 带有相邻测试的源文件会先映射到该相邻测试,然后再回退到更宽的目录 glob。`src/channels/plugins/contracts/test-helpers`、`src/plugin-sdk/test-helpers` 和 `src/plugins/contracts` 下的辅助工具编辑会使用本地导入图来运行导入它们的测试,而不是在依赖路径精确时宽泛运行每个分片。
|
||||
- `auto-reply` 现在也拆分为三个专用配置(`core`、`top-level`、`reply`),这样 reply harness 不会压过更轻量的顶层 status/token/helper 测试。
|
||||
- 基础 Vitest 配置现在默认使用 `pool: "threads"` 和 `isolate: false`,并在整个仓库配置中启用共享的非隔离 runner。
|
||||
- `pnpm test:channels` 运行 `vitest.channels.config.ts`。
|
||||
- `pnpm test:extensions` 和 `pnpm test extensions` 运行所有扩展/插件分片。重型渠道插件、浏览器插件和 OpenAI 会作为专用分片运行;其他插件组保持批处理。对单个内置插件通道使用 `pnpm test extensions/<id>`。
|
||||
- `pnpm test:perf:imports`:启用 Vitest 导入耗时 + 导入拆解报告,同时仍对显式文件/目录目标使用限定范围的通道路由。
|
||||
- `pnpm test:perf:imports:changed`:相同的导入分析,但仅针对自 `origin/main` 以来更改的文件。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>`:针对同一个已提交的 git 差异,对比经路由的 changed-mode 路径与原生根项目运行的基准。
|
||||
- `pnpm test:perf:changed:bench -- --worktree`:在无需先提交的情况下,对当前工作树变更集进行基准测试。
|
||||
- `pnpm test:extensions` 和 `pnpm test extensions` 运行所有插件分片。重型渠道插件、浏览器插件和 OpenAI 会作为专用分片运行;其他插件组保持批处理。使用 `pnpm test extensions/<id>` 运行一个内置插件通道。
|
||||
- `pnpm test:perf:imports`:启用 Vitest 导入耗时 + 导入拆分报告,同时仍对显式文件/目录目标使用有作用域的通道路由。
|
||||
- `pnpm test:perf:imports:changed`:相同的导入分析,但仅针对自 `origin/main` 以来变更的文件。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>` 会针对同一个已提交 git diff,对路由后的 changed-mode 路径与原生根项目运行进行基准测试。
|
||||
- `pnpm test:perf:changed:bench -- --worktree` 会在不先提交的情况下,对当前 worktree 变更集进行基准测试。
|
||||
- `pnpm test:perf:profile:main`:为 Vitest 主线程写入 CPU profile(`.artifacts/vitest-main-profile`)。
|
||||
- `pnpm test:perf:profile:runner`:为单元 runner 写入 CPU + heap profile(`.artifacts/vitest-runner-profile`)。
|
||||
- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`:串行运行每个 full-suite Vitest 叶级配置,并写入分组耗时数据以及每个配置的 JSON/日志产物。Test Performance Agent 在尝试修复慢测试之前,会使用它作为基线。
|
||||
- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`:在以性能为重点的变更后比较分组报告。
|
||||
- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`:串行运行每个完整套件 Vitest 叶级配置,并写入分组耗时数据以及每配置 JSON/日志产物。Test Performance Agent 在尝试修复慢测试前会使用它作为基线。
|
||||
- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`:在面向性能的变更后比较分组报告。
|
||||
- Gateway 网关集成:通过 `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` 或 `pnpm test:gateway` 选择启用。
|
||||
- `pnpm test:e2e`:运行 Gateway 网关端到端冒烟测试(多实例 WS/HTTP/node 配对)。默认在 `vitest.e2e.config.ts` 中使用 `threads` + `isolate: false` 和自适应 worker;用 `OPENCLAW_E2E_WORKERS=<n>` 调整,并设置 `OPENCLAW_E2E_VERBOSE=1` 获取详细日志。
|
||||
- `pnpm test:live`:运行提供商 live 测试(minimax/zai)。需要 API key 和 `LIVE=1`(或提供商专用的 `*_LIVE_TEST=1`)才能取消跳过。
|
||||
- `pnpm test:docker:all`:构建共享 live-test 镜像,将 OpenClaw 打包一次为 npm tarball,构建/复用一个裸 Node/Git runner 镜像,以及一个把该 tarball 安装到 `/app` 的功能镜像,然后通过加权调度器使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行 Docker 冒烟通道。裸镜像(`OPENCLAW_DOCKER_E2E_BARE_IMAGE`)用于安装器/更新/插件依赖通道;这些通道会挂载预构建 tarball,而不是使用复制的仓库源码。功能镜像(`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`)用于普通 built-app 功能通道。`scripts/package-openclaw-for-docker.mjs` 是唯一的本地/CI 包打包器,会在 Docker 使用前验证 tarball 和 `dist/postinstall-inventory.json`。Docker 通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定计划。`node scripts/test-docker-all.mjs --plan-json` 会输出调度器拥有的 CI 计划,包含选定通道、镜像类型、包/live-image 需求、状态场景和凭据检查,而不会构建或运行 Docker。`OPENCLAW_DOCKER_ALL_PARALLELISM=<n>` 控制进程槽位,默认值为 10;`OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=<n>` 控制对提供商敏感的尾部池,默认值为 10。重型通道上限默认是 `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;提供商上限默认通过 `OPENCLAW_DOCKER_ALL_LIVE_CLAUDE_LIMIT=4`、`OPENCLAW_DOCKER_ALL_LIVE_CODEX_LIMIT=4` 和 `OPENCLAW_DOCKER_ALL_LIVE_GEMINI_LIMIT=4` 为每个提供商保留一个重型通道。对更大的宿主机使用 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。如果某个通道在低并行度宿主机上超过有效权重或资源上限,它仍可以从空池启动,并会独占运行直到释放容量。默认情况下,通道启动会错开 2 秒,以避免本地 Docker daemon 创建风暴;可用 `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=<ms>` 覆盖。runner 默认会预检 Docker,清理陈旧的 OpenClaw E2E 容器,每 30 秒输出活动通道状态,在兼容通道之间共享提供商 CLI 工具缓存,默认对瞬时 live-provider 失败重试一次(`OPENCLAW_DOCKER_ALL_LIVE_RETRIES=<n>`),并将通道计时存储在 `.artifacts/docker-tests/lane-timings.json` 中,以便后续运行按最长优先排序。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可在不运行 Docker 的情况下打印通道清单,使用 `OPENCLAW_DOCKER_ALL_STATUS_INTERVAL_MS=<ms>` 可调整状态输出,或使用 `OPENCLAW_DOCKER_ALL_TIMINGS=0` 禁用计时复用。使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=skip` 仅运行确定性/本地通道,或使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=only` 仅运行 live-provider 通道;包别名是 `pnpm test:docker:local:all` 和 `pnpm test:docker:live:all`。live-only 模式会把 main 和 tail live 通道合并到一个最长优先池中,这样提供商桶可以把 Claude、Codex 和 Gemini 工作一起打包。除非设置 `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`,否则 runner 会在首次失败后停止调度新的池化通道;每个通道都有 120 分钟的回退超时,可用 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖;选定的 live/tail 通道使用更严格的逐通道上限。CLI 后端 Docker 设置命令有自己的超时,通过 `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS` 设置(默认 180)。逐通道日志、`summary.json`、`failures.json` 和阶段计时会写入 `.artifacts/docker-tests/<run-id>/`;使用 `pnpm test:docker:timings <summary.json>` 检查慢通道,使用 `pnpm test:docker:rerun <run-id|summary.json|failures.json>` 打印廉价的定向重运行命令。
|
||||
- `pnpm test:docker:browser-cdp-snapshot`:构建基于 Chromium 的源码 E2E 容器,启动原始 CDP 和隔离的 Gateway 网关,运行 `browser doctor --deep`,并验证 CDP 角色快照包含链接 URL、光标提升的可点击项、iframe ref 和 frame 元数据。
|
||||
- CLI 后端 live Docker 探测可以作为聚焦通道运行,例如 `pnpm test:docker:live-cli-backend:codex`、`pnpm test:docker:live-cli-backend:codex:resume` 或 `pnpm test:docker:live-cli-backend:codex:mcp`。Claude 和 Gemini 有匹配的 `:resume` 和 `:mcp` 别名。
|
||||
- `pnpm test:docker:openwebui`:启动 Docker 化的 OpenClaw + Open WebUI,通过 Open WebUI 登录,检查 `/api/models`,然后通过 `/api/chat/completions` 运行真实的代理聊天。需要可用的 live 模型 key(例如 `~/.profile` 中的 OpenAI),会拉取外部 Open WebUI 镜像,并且不预期像普通 unit/e2e 套件一样具备 CI 稳定性。
|
||||
- `pnpm test:docker:mcp-channels`:启动一个已种子化的 Gateway 网关容器,以及第二个会生成 `openclaw mcp serve` 的客户端容器,然后验证路由会话发现、transcript 读取、附件元数据、live 事件队列行为、出站发送路由,以及通过真实 stdio bridge 发送的 Claude 风格渠道 + 权限通知。Claude 通知断言会直接读取原始 stdio MCP frame,因此该冒烟测试反映 bridge 实际发出的内容。
|
||||
- `pnpm test:docker:upgrade-survivor`:在脏的旧用户测试夹具上安装打包好的 OpenClaw tar 归档包,在没有实时提供商或渠道密钥的情况下运行包更新和非交互式 Doctor,然后启动一个回环 Gateway 网关,并检查智能体、渠道配置、插件允许列表、工作区/会话文件、过期的插件 runtime-deps 状态、启动流程和 RPC 状态是否都能保留下来。
|
||||
- `pnpm test:e2e`:运行 Gateway 网关端到端冒烟测试(多实例 WS/HTTP/node 配对)。默认使用 `threads` + `isolate: false`,并在 `vitest.e2e.config.ts` 中使用自适应 worker;用 `OPENCLAW_E2E_WORKERS=<n>` 调整,并设置 `OPENCLAW_E2E_VERBOSE=1` 输出详细日志。
|
||||
- `pnpm test:live`:运行提供商 live 测试(minimax/zai)。需要 API keys 和 `LIVE=1`(或提供商特定的 `*_LIVE_TEST=1`)才能取消跳过。
|
||||
- `pnpm test:docker:all`:构建共享 live-test 镜像,将 OpenClaw 一次打包为 npm tarball,构建/复用一个裸 Node/Git runner 镜像以及一个把该 tarball 安装到 `/app` 的功能镜像,然后通过加权调度器用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行 Docker 冒烟通道。裸镜像(`OPENCLAW_DOCKER_E2E_BARE_IMAGE`)用于 installer/update/plugin-dependency 通道;这些通道挂载预构建 tarball,而不是使用复制的仓库源。功能镜像(`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`)用于普通内置应用功能通道。`scripts/package-openclaw-for-docker.mjs` 是唯一的本地/CI package packer,并会在 Docker 使用前校验 tarball 和 `dist/postinstall-inventory.json`。Docker 通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;planner 逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定计划。`node scripts/test-docker-all.mjs --plan-json` 会为选定通道、镜像类型、package/live-image 需求、状态场景和凭证检查输出由调度器拥有的 CI 计划,而不构建或运行 Docker。`OPENCLAW_DOCKER_ALL_PARALLELISM=<n>` 控制进程槽位,默认值为 10;`OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=<n>` 控制提供商敏感的尾部池,默认值为 10。重型通道上限默认为 `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;提供商上限默认通过 `OPENCLAW_DOCKER_ALL_LIVE_CLAUDE_LIMIT=4`、`OPENCLAW_DOCKER_ALL_LIVE_CODEX_LIMIT=4` 和 `OPENCLAW_DOCKER_ALL_LIVE_GEMINI_LIMIT=4` 为每个提供商设置一个重型通道。更大的宿主机可使用 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。如果某个通道在低并行度宿主机上超过有效权重或资源上限,它仍可从空池启动,并会独自运行,直到释放容量。默认情况下通道启动会错开 2 秒,以避免本地 Docker daemon 出现创建风暴;可用 `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=<ms>` 覆盖。runner 默认会预检 Docker、清理陈旧的 OpenClaw E2E 容器、每 30 秒输出活动通道状态、在兼容通道之间共享提供商 CLI 工具缓存、默认重试一次暂时性的 live-provider 失败(`OPENCLAW_DOCKER_ALL_LIVE_RETRIES=<n>`),并将通道计时存储到 `.artifacts/docker-tests/lane-timings.json`,供后续运行按最长优先排序。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可打印通道清单而不运行 Docker,使用 `OPENCLAW_DOCKER_ALL_STATUS_INTERVAL_MS=<ms>` 可调整状态输出,或使用 `OPENCLAW_DOCKER_ALL_TIMINGS=0` 禁用计时复用。使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=skip` 仅运行确定性/本地通道,或使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=only` 仅运行 live-provider 通道;package 别名为 `pnpm test:docker:local:all` 和 `pnpm test:docker:live:all`。Live-only 模式会把 main 和 tail live 通道合并为一个最长优先池,这样提供商桶可以把 Claude、Codex 和 Gemini 工作打包在一起。除非设置了 `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`,runner 会在第一次失败后停止调度新的池化通道,并且每个通道都有 120 分钟的兜底超时,可用 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖;选定的 live/tail 通道使用更严格的按通道上限。CLI 后端 Docker 设置命令有自己的超时,通过 `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS` 配置(默认 180)。每通道日志、`summary.json`、`failures.json` 和阶段计时会写入 `.artifacts/docker-tests/<run-id>/` 下;使用 `pnpm test:docker:timings <summary.json>` 检查慢通道,使用 `pnpm test:docker:rerun <run-id|summary.json|failures.json>` 打印低成本的定向重跑命令。
|
||||
- `pnpm test:docker:browser-cdp-snapshot`:构建一个基于 Chromium 的 source E2E 容器,启动原始 CDP 加隔离的 Gateway 网关,运行 `browser doctor --deep`,并验证 CDP role 快照包含链接 URL、光标提升的可点击项、iframe refs 和 frame 元数据。
|
||||
- CLI 后端 live Docker 探针可以作为聚焦通道运行,例如 `pnpm test:docker:live-cli-backend:codex`、`pnpm test:docker:live-cli-backend:codex:resume` 或 `pnpm test:docker:live-cli-backend:codex:mcp`。Claude 和 Gemini 有匹配的 `:resume` 和 `:mcp` 别名。
|
||||
- `pnpm test:docker:openwebui`:启动 Docker 化的 OpenClaw + Open WebUI,通过 Open WebUI 登录,检查 `/api/models`,然后通过 `/api/chat/completions` 运行一次真实的代理聊天。需要可用的 live 模型 key(例如 `~/.profile` 中的 OpenAI),会拉取外部 Open WebUI 镜像,且不期望像普通 unit/e2e 套件一样具备 CI 稳定性。
|
||||
- `pnpm test:docker:mcp-channels`:启动一个已种子的 Gateway 网关容器和第二个客户端容器,后者会启动 `openclaw mcp serve`,然后通过真实 stdio bridge 验证路由后的对话发现、transcript 读取、附件元数据、live 事件队列行为、出站发送路由,以及 Claude 风格的渠道 + permission 通知。Claude 通知断言会直接读取原始 stdio MCP 帧,因此该冒烟测试反映的是 bridge 实际发出的内容。
|
||||
- `pnpm test:docker:upgrade-survivor`:将打包好的 OpenClaw tar 包安装到脏的旧用户夹具上,运行包更新以及不需要实时提供商或渠道密钥的非交互式 Doctor,然后启动回环 Gateway 网关,并检查智能体、渠道配置、插件允许列表、工作区/会话文件、过期的插件 runtime-deps 状态、启动和 RPC Status 是否保留下来。
|
||||
- `pnpm test:docker:published-upgrade-survivor`:默认将 `openclaw@latest` 安装到脏的旧用户夹具上,将该已发布安装更新为打包好的 OpenClaw tar 包,然后运行相同的 Doctor、Gateway 网关启动和 RPC 保留断言。可使用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆盖基线。
|
||||
|
||||
## 本地 PR 门禁
|
||||
|
||||
对于本地 PR 合入/门禁检查,运行:
|
||||
对于本地 PR 落地/门禁检查,运行:
|
||||
|
||||
- `pnpm check:changed`
|
||||
- `pnpm check`
|
||||
@ -62,7 +63,7 @@ x-i18n:
|
||||
- `pnpm test`
|
||||
- `pnpm check:docs`
|
||||
|
||||
如果 `pnpm test` 在负载较高的主机上偶发失败,先重跑一次,再将其视为回归问题,然后用 `pnpm test <path/to/test>` 隔离定位。对于内存受限主机,使用:
|
||||
如果 `pnpm test` 在负载较高的主机上出现偶发失败,先重跑一次,再将其视为回归问题,然后用 `pnpm test <path/to/test>` 隔离问题。对于内存受限的主机,使用:
|
||||
|
||||
- `OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test`
|
||||
- `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-vitest-cache pnpm test:changed`
|
||||
@ -75,12 +76,12 @@ x-i18n:
|
||||
|
||||
- `source ~/.profile && pnpm tsx scripts/bench-model.ts --runs 10`
|
||||
- 可选环境变量:`MINIMAX_API_KEY`、`MINIMAX_BASE_URL`、`MINIMAX_MODEL`、`ANTHROPIC_API_KEY`
|
||||
- 默认提示词:“Reply with a single word: ok. No punctuation or extra text.”
|
||||
- 默认提示词:“只回复一个单词:ok。不要标点或额外文本。”
|
||||
|
||||
上次运行(2025-12-31,20 次运行):
|
||||
|
||||
- minimax 中位数 1279ms(最小值 1114,最大值 2431)
|
||||
- opus 中位数 2454ms(最小值 1224,最大值 3170)
|
||||
- minimax 中位数 1279 ms(最小 1114,最大 2431)
|
||||
- opus 中位数 2454 ms(最小 1224,最大 3170)
|
||||
|
||||
## CLI 启动基准测试
|
||||
|
||||
@ -110,41 +111,41 @@ x-i18n:
|
||||
- `real`:`health`、`status`、`status --json`、`sessions`、`sessions --json`、`tasks --json`、`tasks list --json`、`tasks audit --json`、`agents list --json`、`gateway status`、`gateway status --json`、`gateway health --json`、`config get gateway.port`
|
||||
- `all`:两个预设
|
||||
|
||||
输出包含每条命令的 `sampleCount`、平均值、p50、p95、最小/最大值、退出码/信号分布,以及最大 RSS 摘要。可选的 `--cpu-prof-dir` / `--heap-prof-dir` 会为每次运行写入 V8 profile,因此计时和 profile 捕获会使用同一个 harness。
|
||||
输出包括 `sampleCount`、平均值、p50、p95、最小/最大值、退出码/信号分布,以及每条命令的最大 RSS 摘要。可选的 `--cpu-prof-dir` / `--heap-prof-dir` 会为每次运行写入 V8 配置文件,使计时和配置文件捕获使用同一套测试框架。
|
||||
|
||||
已保存输出约定:
|
||||
|
||||
- `pnpm test:startup:bench:smoke` 将目标 smoke artifact 写入 `.artifacts/cli-startup-bench-smoke.json`
|
||||
- `pnpm test:startup:bench:save` 使用 `runs=5` 和 `warmup=1` 将全套 artifact 写入 `.artifacts/cli-startup-bench-all.json`
|
||||
- `pnpm test:startup:bench:update` 使用 `runs=5` 和 `warmup=1` 刷新已检入的 baseline fixture:`test/fixtures/cli-startup-bench.json`
|
||||
- `pnpm test:startup:bench:smoke` 将定向烟雾测试产物写入 `.artifacts/cli-startup-bench-smoke.json`
|
||||
- `pnpm test:startup:bench:save` 使用 `runs=5` 和 `warmup=1` 将完整套件产物写入 `.artifacts/cli-startup-bench-all.json`
|
||||
- `pnpm test:startup:bench:update` 使用 `runs=5` 和 `warmup=1` 刷新已签入的基线夹具 `test/fixtures/cli-startup-bench.json`
|
||||
|
||||
已检入 fixture:
|
||||
已签入夹具:
|
||||
|
||||
- `test/fixtures/cli-startup-bench.json`
|
||||
- 使用 `pnpm test:startup:bench:update` 刷新
|
||||
- 使用 `pnpm test:startup:bench:check` 将当前结果与 fixture 比较
|
||||
- 使用 `pnpm test:startup:bench:check` 将当前结果与夹具比较
|
||||
|
||||
## 新手引导 E2E(Docker)
|
||||
|
||||
Docker 是可选的;只有容器化新手引导 smoke 测试才需要它。
|
||||
Docker 是可选的;仅容器化新手引导烟雾测试需要它。
|
||||
|
||||
在干净的 Linux 容器中运行完整冷启动流程:
|
||||
在干净 Linux 容器中的完整冷启动流程:
|
||||
|
||||
```bash
|
||||
scripts/e2e/onboard-docker.sh
|
||||
```
|
||||
|
||||
此脚本通过伪终端驱动交互式向导,验证配置/工作区/会话文件,然后启动 Gateway 网关并运行 `openclaw health`。
|
||||
此脚本通过伪 tty 驱动交互式向导,验证配置/工作区/会话文件,然后启动 Gateway 网关并运行 `openclaw health`。
|
||||
|
||||
## QR 导入 smoke(Docker)
|
||||
## QR 导入烟雾测试(Docker)
|
||||
|
||||
确保维护中的 QR 运行时 helper 能在受支持的 Docker Node 运行时下加载(Node 24 默认,Node 22 兼容):
|
||||
确保维护的 QR 运行时辅助工具可在支持的 Docker Node 运行时下加载(默认 Node 24,兼容 Node 22):
|
||||
|
||||
```bash
|
||||
pnpm test:docker:qr
|
||||
```
|
||||
|
||||
## 相关内容
|
||||
## 相关
|
||||
|
||||
- [测试](/zh-CN/help/testing)
|
||||
- [实时测试](/zh-CN/help/testing-live)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user