1
0
Files
DiAL/openspec/specs/expect-body-checkers/spec.md
lanyuanxiaoyao bce0f8e7a8 feat: 增强 HTTP checker 鲁棒性 — 严格配置校验、完整耗时、流式body、重定向与编码完善
启动期校验: 新增 validate.ts 对 HTTP config/expect/body rule/operator 全方位严格校验
执行语义: body 改为 Web Stream 流式超限中止,durationMs 覆盖完整执行
错误归属: status/header 失败不读 body,phase 分层 request/body,early duration skip body
重定向: 跟随前释放 body,POST/303 改 GET 清理 header,跨 origin 剥离敏感 header
编码: 支持 quoted charset,未知编码返回结构化解码错误
文档: README match→regex+durationMs,DEVELOPMENT 执行流程与错误归属
测试: +63 测试覆盖全部新增场景,325 pass 0 fail
规格: 同步 probe-config/probe-engine/expect-body-checkers 3 个 delta spec
2026-05-13 08:00:05 +08:00

11 KiB
Raw Blame History

Purpose

定义 HTTP 拨测中响应体校验方法集contains/regex/json/css/xpath、操作符系统和响应头校验的行为规范。

Requirements

Requirement: 响应体多种校验方法

系统 SHALL 支持对 HTTP 响应体进行五种可组合的校验方法contains子串、regex正则、jsonJSONPath、cssCSS 选择器、xpathXPath。这些方法 MUST 配置在 expect.body 有序数组中。

Scenario: contains 子串匹配

  • WHEN HTTP target 配置 expect.body: [{contains: "healthy"}],且响应体包含 "healthy"
  • THEN 系统 SHALL 判定该 body 规则通过

Scenario: contains 不匹配

  • WHEN HTTP target 配置 expect.body: [{contains: "healthy"}],且响应体不包含该文本
  • THEN 系统 SHALL 判定 matched 为 false并记录该规则的 failure.path

Scenario: regex 正则匹配

  • WHEN HTTP target 配置 expect.body: [{regex: '"status"\\s*:\\s*"ok"'}],且响应体匹配该正则
  • THEN 系统 SHALL 判定该 body 规则通过

Scenario: regex 不匹配

  • WHEN HTTP target 配置 regex body 规则,且响应体不匹配该正则
  • THEN 系统 SHALL 判定 matched 为 false并记录该规则的 failure.path

Scenario: json JSONPath 等值匹配

  • WHEN HTTP target 配置 expect.body: [{json: {path: "$.status", equals: "ok"}}],且响应 JSON 中 $.status 值为 "ok"
  • THEN 系统 SHALL 判定该 body 规则通过

Scenario: json JSONPath 值不匹配

  • WHEN HTTP target 配置 json body 规则,且提取值不符合期望
  • THEN 系统 SHALL 判定 matched 为 false并记录包含 JSONPath 的 failure.path

Scenario: json 解析失败

  • WHEN HTTP target 配置了 json body 规则但响应体不是合法 JSON
  • THEN 系统 SHALL 判定 matched 为 false

Scenario: css 选择器匹配

  • WHEN HTTP target 配置 expect.body: [{css: {selector: "div#health", equals: "OK"}}],且 HTML 中存在 div#health 元素文本为 "OK"
  • THEN 系统 SHALL 判定该 body 规则通过

Scenario: css 选择器匹配属性值

  • WHEN HTTP target 配置 css 规则带 attr: "content" 用于提取属性,且属性值匹配期望
  • THEN 系统 SHALL 判定该 body 规则通过

Scenario: css 选择器无匹配元素

  • WHEN HTTP target 配置了 css 选择器但 HTML 中无匹配元素
  • THEN 系统 SHALL 判定 matched 为 false

Scenario: xpath 表达式匹配

  • WHEN HTTP target 配置 expect.body: [{xpath: {path: "/root/status/text()", equals: "ok"}}],且 XML 中 /root/status 节点文本为 "ok"
  • THEN 系统 SHALL 判定该 body 规则通过

Scenario: xpath 表达式无匹配节点

  • WHEN HTTP target 配置了 xpath 表达式但 XML 中无匹配节点
  • THEN 系统 SHALL 判定 matched 为 false

Requirement: 多种 body 校验方法 AND 组合

系统 SHALL 支持在 expect.body 数组中同时配置多种 body 校验方法,所有方法均通过时 matched 方为 true。

Scenario: 多种方法全部通过

  • WHEN HTTP target 的 expect.body 数组依次配置 contains、json、regex且全部通过
  • THEN 系统 SHALL 判定 matched 为 true

Scenario: 多种方法任一失败

  • WHEN HTTP target 的 expect.body 数组第一条 contains 不通过,后续还有 json 规则
  • THEN 系统 SHALL 判定 matched 为 false且不再检查后续 json 规则

Requirement: 操作符系统

系统 SHALL 支持对提取值和文本值使用以下操作符进行比较equals默认等值、contains子串包含、match正则匹配、empty空值判断、exists存在性判断、gte/lte/gt/lt数值比较

Scenario: 标量值隐式 equals

  • WHEN 配置的期望值为标量(字符串/数字/布尔/nullequals: "ok"
  • THEN 系统 SHALL 使用 equals 操作符,对实际值做严格相等比较

Scenario: 显式 contains 操作符

  • WHEN 配置 {contains: "success"},且实际值包含 "success"
  • THEN 系统 SHALL 判定该规则通过

Scenario: 显式 match 操作符

  • WHEN 配置 {match: '\\d+\\.\\d+\\.\\d+'},且实际值匹配该正则
  • THEN 系统 SHALL 判定该规则通过

Scenario: empty 操作符判断为空

  • WHEN 配置 {empty: true},且实际值为空数组 []
  • THEN 系统 SHALL 判定该规则通过

Scenario: empty 操作符判断非空

  • WHEN 配置 {empty: false},且实际值为 [1, 2]
  • THEN 系统 SHALL 判定该规则通过

Scenario: exists 操作符判断存在

  • WHEN 配置 {exists: false},且实际值不存在
  • THEN 系统 SHALL 判定该规则通过

Scenario: gte 数值比较

  • WHEN 配置 {gte: 10},且实际值为 15(数字)
  • THEN 系统 SHALL 判定该规则通过

Scenario: gt/lt 数值比较

  • WHEN 配置 {gt: 0, lt: 1000},且实际值为 500
  • THEN 系统 SHALL 对同一字段进行多操作符复合比较,全部通过则该规则通过

Requirement: 响应头校验

系统 SHALL 支持通过 expect.headers 配置对 HTTP 响应头进行键值规则校验header 名称匹配 MUST 不区分大小写。

Scenario: 响应头匹配

  • WHEN HTTP target 配置 expect.headers: {"Content-Type": {contains: "application/json"}},且响应包含该 header 且值匹配
  • THEN 系统 SHALL 判定 headers 阶段通过

Scenario: 响应头不匹配

  • WHEN HTTP target 配置 expect.headers: {"Content-Type": {equals: "application/json"}},且响应 header 值为 "text/html"
  • THEN 系统 SHALL 判定 matched 为 false

Scenario: 响应头缺失

  • WHEN HTTP target 配置了某个 header 但响应中不存在该 header
  • THEN 系统 SHALL 判定 matched 为 false

Requirement: 结构化 expect 失败信息

系统 SHALL 在任一 expect 规则失败时生成结构化 failure用于标识失败阶段、规则路径、期望值、实际值和可读错误信息。

Scenario: body 规则失败信息

  • WHEN HTTP target 的 expect.body[1].json 规则失败
  • THEN failure SHALL 包含 kind=mismatch、phase=body、path 指向 expect.body[1],并包含 message

Scenario: actual 值截断

  • WHEN 失败规则的实际值超过系统允许记录的摘要长度
  • THEN 系统 MUST 截断 actual 摘要,而不是持久化完整响应体或命令输出

Requirement: 状态码范围匹配

系统 SHALL 支持在 expect.status 数组中使用范围模式字符串("1xx""2xx""3xx""4xx""5xx"),与精确数字混合使用。范围模式 SHALL 匹配对应百位段内的所有状态码。其他范围模式 SHALL 在启动期配置校验失败。

Scenario: 1xx 范围匹配

  • WHEN HTTP target 配置 expect.status: ["1xx"],且响应状态码为 101
  • THEN 系统 SHALL 判定状态码匹配

Scenario: 2xx 范围匹配

  • WHEN HTTP target 配置 expect.status: ["2xx"],且响应状态码为 200
  • THEN 系统 SHALL 判定状态码匹配

Scenario: 2xx 范围匹配 204

  • WHEN HTTP target 配置 expect.status: ["2xx"],且响应状态码为 204
  • THEN 系统 SHALL 判定状态码匹配

Scenario: 2xx 范围不匹配 301

  • WHEN HTTP target 配置 expect.status: ["2xx"],且响应状态码为 301
  • THEN 系统 SHALL 判定状态码不匹配

Scenario: 混合精确值与范围模式

  • WHEN HTTP target 配置 expect.status: ["2xx", 301],且响应状态码为 301
  • THEN 系统 SHALL 判定状态码匹配(精确值 301 匹配)

Scenario: 混合精确值与范围模式范围命中

  • WHEN HTTP target 配置 expect.status: ["2xx", 301],且响应状态码为 204
  • THEN 系统 SHALL 判定状态码匹配2xx 范围命中)

Scenario: 5xx 范围匹配

  • WHEN HTTP target 配置 expect.status: ["5xx"],且响应状态码为 503
  • THEN 系统 SHALL 判定状态码匹配

Scenario: 非 HTTP 范围模式启动失败

  • WHEN HTTP target 配置 expect.status: ["6xx"]
  • THEN 系统 SHALL 在启动期配置校验失败

Requirement: HTTP expect 规则启动期校验

系统 SHALL 在启动期校验 HTTP expect 中已支持字段的类型、格式和可编译表达式。未知字段 SHALL 被忽略,但每个规则对象 MUST 至少包含可产生有效断言的支持字段。

Scenario: body rule 使用 regex 字段

  • WHEN HTTP target 配置 expect.body: [{regex: "ok|healthy"}] 且 regex 可编译
  • THEN 系统 SHALL 接受该配置,并在运行期按 regex body 规则匹配响应体

Scenario: body rule 不支持 match 字段

  • WHEN HTTP target 配置 expect.body: [{match: "ok"}] 且该规则没有 contains、regex、json、css、xpath 任一支持字段
  • THEN 系统 SHALL 在启动期配置校验失败

Scenario: body rule 忽略未知字段

  • WHEN HTTP target 配置 expect.body: [{contains: "ok", note: "ignored"}]
  • THEN 系统 SHALL 忽略 note 字段并按 contains 规则校验响应体

Scenario: body rule 多支持字段非法

  • WHEN HTTP target 的同一条 body rule 同时配置 contains 和 regex
  • THEN 系统 SHALL 在启动期配置校验失败

Scenario: operator match 正则非法

  • WHEN HTTP target 的 expect.headers、json、css 或 xpath operator 配置了不可编译的 match 正则
  • THEN 系统 SHALL 在启动期配置校验失败

Scenario: operator 数值比较类型非法

  • WHEN HTTP target 的 expect operator 配置 gt、gte、lt 或 lte且对应值不是有限数字
  • THEN 系统 SHALL 在启动期配置校验失败

Scenario: operator 布尔类型非法

  • WHEN HTTP target 的 expect operator 配置 empty 或 exists且对应值不是布尔值
  • THEN 系统 SHALL 在启动期配置校验失败

Scenario: JSONPath 子集非法

  • WHEN HTTP target 的 json body rule path 不符合系统支持的 JSONPath 子集
  • THEN 系统 SHALL 在启动期配置校验失败

Requirement: HTTP body 运行期失败结构化

系统 SHALL 将 HTTP body 运行期失败记录为结构化 CheckFailure并保留与具体规则相关的 phase 和 path。响应内容不符合配置 SHALL 记录为 mismatch响应内容无法按配置解析或解码 SHALL 记录为 error。

Scenario: JSON 响应不是合法 JSON

  • WHEN HTTP target 配置 json body rule但响应体不是合法 JSON
  • THEN 系统 SHALL 记录 failure.kind="error"failure.phase="body",且 failure.path SHALL 指向对应 json 规则

Scenario: CSS selector 无匹配元素

  • WHEN HTTP target 配置 css body rule但响应 HTML 中无匹配元素
  • THEN 系统 SHALL 记录 failure.kind="mismatch"failure.phase="body",且 failure.path SHALL 指向对应 css 规则

Scenario: XPath 无匹配节点

  • WHEN HTTP target 配置 xpath body rule但响应 XML/HTML 中无匹配节点
  • THEN 系统 SHALL 记录 failure.kind="mismatch"failure.phase="body",且 failure.path SHALL 指向对应 xpath 规则