1
0

refactor: 统一 expect 断言体系,引入共享 ValueMatcher/ContentRules/KeyValueExpect 模型

- 引入共享 ValueMatcher(equals/contains/regex/exists/empty/gt/gte/lt/lte)
- 引入共享 ContentRules 数组(direct/json/css/xpath 提取器)
- 引入共享 KeyValueExpect(动态键值断言,字面量等价 equals)
- maxDurationMs → durationMs: ValueMatcher(所有 checker)
- match → regex(固定无 flags)
- Ping max* → packetLossPercent/avgLatencyMs/maxLatencyMs(ValueMatcher)
- LLM finishReason/rawFinishReason → ValueMatcher
- DB 新增 result: ContentRules
- TCP banner → ContentRules 数组
- 删除旧模块:operator.ts、validate-operator.ts、duration.ts、body.ts、text.ts、output.ts
- 更新全部 checker schema/validate/expect/execute
- 更新 probe-config.schema.json、probes.example.yaml
- 更新 README.md、DEVELOPMENT.md(含 expect 字段选择规范)
- 同步 10 个 delta specs 到主 specs,归档 change
This commit is contained in:
2026-05-19 14:24:27 +08:00
parent 349896bd02
commit 7a635a0a9f
85 changed files with 4290 additions and 2028 deletions

View File

@@ -55,7 +55,7 @@
- **THEN** 系统 MUST 停止收集输出并终止该检查,记录 `matched=false`,并在 failure 中写入输出超限信息
### Requirement: cmd expect 校验
系统 SHALL 支持 cmd 专用 expect包括 `exitCode``stdout``stderr`,并按 exitCode、duration、stdout、stderr 的阶段顺序快速失败。
系统 SHALL 支持 cmd 专用 expect包括 `exitCode``durationMs``stdout``stderr`,并按 exitCode、durationMs、stdout、stderr 的阶段顺序快速失败。`exitCode` SHALL 保持有限整数数组语义,未配置时默认 `[0]``durationMs` SHALL 使用共享 `ValueMatcher` 校验完整命令执行耗时。`stdout``stderr` MUST 使用共享 `ContentRules` 数组,直接 matcher 作用于对应输出文本,`json` extractor SHALL 支持对 JSON CLI 输出执行 JSONPath 断言。
#### Scenario: 默认 exitCode 成功语义
- **WHEN** cmd target 未显式配置 `expect.exitCode`
@@ -67,75 +67,67 @@
#### Scenario: exitCode 不匹配快速失败
- **WHEN** cmd target 配置 `expect.exitCode: [0]` 且实际 exit code 为 1
- **THEN** 系统 SHALL 立即返回 `matched=false`,并在 failure 中写入 phase=`exitCode`、path=`expect.exitCode`、expected 和 actual
- **THEN** 系统 SHALL 立即返回 `matched=false`,并在 failure 中写入 phase=`exitCode`、path=`exitCode`、expected 和 actual
#### Scenario: durationMs 校验
- **WHEN** cmd target 配置 `expect.durationMs: {lte: 1000}` 且实际执行耗时为 1500ms
- **THEN** 系统 SHALL 返回 `matched=false`failure 的 phase 为 `duration`
#### Scenario: stdout 按配置顺序校验
- **WHEN** cmd target 配置 `expect.stdout` 为两个规则,第一条通过且第二条失败
- **THEN** 系统 SHALL 先执行第一条 stdout 规则,再执行第二条,并将 failure.path 指向失败的 `expect.stdout[1]`
- **WHEN** cmd target 配置 `expect.stdout` 为两个 ContentRules,第一条通过且第二条失败
- **THEN** 系统 SHALL 先执行第一条 stdout 规则,再执行第二条,并将 failure.path 指向失败的 `stdout[1]`
#### Scenario: stderr 校验为空
- **WHEN** cmd target 配置 `expect.stderr: [{empty: true}]` 且实际 stderr 为空字符串
- **THEN** 系统 SHALL 判定 stderr 阶段通过
#### Scenario: stdout JSON 输出校验
- **WHEN** cmd target 输出 stdout 为 `{"status":"ok"}` 且配置 `expect.stdout: [{json: {path: "$.status", equals: "ok"}}]`
- **THEN** 系统 SHALL 判定 stdout 阶段通过
#### Scenario: stdout 失败后不检查 stderr
- **WHEN** cmd target 同时配置 stdout 和 stderr 规则,且 stdout 规则失败
- **THEN** 系统 SHALL 快速失败并 MUST NOT 继续执行 stderr 规则
### Requirement: cmd checker 启动期配置校验
系统 SHALL 在启动期对 cmd checker 的配置契约和语义执行严格校验。Cmd target 的 `cmd` 分组 SHALL 只允许 `exec``args``cwd``env``maxOutputBytes` 字段Cmd expect SHALL 只允许 `exitCode``maxDurationMs``stdout``stderr` 字段。未知字段、非法类型不可编译正则 MUST 导致启动期配置错误。`expect.exitCode` SHALL 保留原有有限整数数组语义,不限制到特定平台范围。
系统 SHALL 在启动期对 cmd checker 的配置契约和语义执行严格校验。Cmd target 的 `cmd` 分组 SHALL 只允许 `exec``args``cwd``env``maxOutputBytes` 字段Cmd expect SHALL 只允许 `exitCode``durationMs``stdout``stderr` 字段。未知字段、非法类型不可编译正则和 ReDoS 风险正则 MUST 导致启动期配置错误。`expect.exitCode` SHALL 保留原有有限整数数组语义,不限制到特定平台范围。
#### Scenario: cmd args 类型非法
- **WHEN** YAML 中 cmd target 配置 `cmd.args` 不是字符串数组
- **THEN** 系统 SHALL 以配置错误退出,提示 cmd.args 格式错误
#### Scenario: cmd cwd 类型非法
- **WHEN** YAML 中 cmd target 配置 `cmd.cwd` 不是字符串
- **THEN** 系统 SHALL 以配置错误退出,提示 cmd.cwd 必须为字符串
#### Scenario: cmd env 值类型非法
- **WHEN** YAML 中 cmd target 配置 `cmd.env`,且任一环境变量值不是字符串
- **THEN** 系统 SHALL 以配置错误退出,提示 cmd.env 对应变量值必须为字符串
#### Scenario: cmd maxOutputBytes 非法
- **WHEN** YAML 中 cmd target 或 defaults.cmd 配置的 `maxOutputBytes` 不是合法 size 值
- **THEN** 系统 SHALL 以配置错误退出,提示 maxOutputBytes 格式错误
#### Scenario: cmd 分组未知字段失败
- **WHEN** YAML 中 cmd target 的 `cmd` 分组包含 `shell: true` 等未知字段
- **THEN** 系统 SHALL 以配置错误退出,提示 cmd 分组包含未知字段
#### Scenario: cmd expect exitCode 类型非法
- **WHEN** YAML 中 cmd target 配置 `expect.exitCode` 不是整数数组
- **THEN** 系统 SHALL 以配置错误退出,提示 expect.exitCode 必须为整数数组
#### Scenario: cmd expect exitCode 不限制平台范围
- **WHEN** YAML 中 cmd target 配置 `expect.exitCode` 为有限整数数组
- **THEN** 系统 SHALL 接受该数组,不额外限制为 0-255 等平台相关范围
#### Scenario: cmd expect durationMs 非法
- **WHEN** YAML 中 cmd target 配置 `expect.durationMs` 不是合法 `ValueMatcher`
- **THEN** 系统 SHALL 以配置错误退出,提示 expect.durationMs 格式错误
#### Scenario: cmd expect maxDurationMs 非法
- **WHEN** YAML 中 cmd target 配置 `expect.maxDurationMs` 不是非负有限数字
- **THEN** 系统 SHALL 以配置错误退出,提示 expect.maxDurationMs 格式错误
#### Scenario: stdout 必须为规则数组
#### Scenario: stdout 必须为 ContentRules 数组
- **WHEN** YAML 中 cmd target 配置 `expect.stdout` 但其值不是数组
- **THEN** 系统 SHALL 以配置错误退出,提示 expect.stdout 必须为数组
#### Scenario: stderr 必须为规则数组
#### Scenario: stderr 必须为 ContentRules 数组
- **WHEN** YAML 中 cmd target 配置 `expect.stderr` 但其值不是数组
- **THEN** 系统 SHALL 以配置错误退出,提示 expect.stderr 必须为数组
#### Scenario: stdout text rule 空对象非法
- **WHEN** YAML 中 cmd target 配置 `expect.stdout: [{}]`
- **THEN** 系统 SHALL 以配置错误退出,提示 stdout 规则必须包含至少一个合法 operator
- **THEN** 系统 SHALL 以配置错误退出,提示 stdout 规则必须包含至少一个合法 matcher 或 extractor
#### Scenario: stderr text rule 未知字段非法
- **WHEN** YAML 中 cmd target 配置 `expect.stderr: [{foo: "bar"}]`
- **THEN** 系统 SHALL 以配置错误退出,提示 stderr 规则包含未知 operator
- **THEN** 系统 SHALL 以配置错误退出,提示 stderr 规则包含未知 matcher 或未知 extractor
#### Scenario: stdout match 正则非法
- **WHEN** YAML 中 cmd target 配置 `expect.stdout: [{match: "[invalid"}]`
#### Scenario: stdout regex 正则非法
- **WHEN** YAML 中 cmd target 配置 `expect.stdout: [{regex: "[invalid"}]`
- **THEN** 系统 SHALL 在启动期配置校验失败,而不是延迟到运行期抛错
#### Scenario: cmd expect 未知字段失败
- **WHEN** YAML 中 cmd target 的 expect 包含 `status: [200]` 或其他非 cmd expect 字段
- **WHEN** YAML 中 cmd target 的 expect 包含 `status: [200]``maxDurationMs: 1000` 或其他非 cmd expect 字段
- **THEN** 系统 SHALL 以配置错误退出,提示 expect 包含未知字段