1
0
Files
DiAL/openspec/specs/udp-checker/spec.md
lanyuanxiaoyao cfca03b4d6 refactor: 规范审查与重组,合并细粒度规范,清理过时内容
- 合并 20+ 细粒度 spec 为粗粒度主题规范:dashboard、data-store、probe-engine、probe-api、probe-config 等
- 删除完全冗余规范:data-retention(被 probe-engine+data-store 覆盖)、backend-code-quality(DEVELOPMENT.md 已记录)
- 补充 http-checker 规范至完整标准(配置+执行+expect+校验+observation),匹配代码 440 行实现
- 清理 tcp/udp/llm checker 规范中已废弃 defaults 配置段的残留 Scenario
- 清理 checker-cohesion-structure 中的实现路径引用(src/server/...)
- 统一所有 spec 格式(## Purpose 开头,去除 # Capability/Title 形式)
- 更新 prompt-spec-review.md 审查提示文档
2026-05-22 18:55:18 +08:00

12 KiB
Raw Blame History

Purpose

定义 UDP checker 的 target 配置、defaults、执行语义、响应编码、expect 校验、失败结构和状态摘要。

Requirements

Requirement: udp target 配置

系统 SHALL 支持 type: udp 的 target 配置,通过 udp.hostudp.port 描述目标 UDP 地址,并通过可选字段控制 payload、编码和响应大小限制。

Scenario: 解析最简 udp target

  • WHEN YAML 中 target 配置 type: udpudp.host: "127.0.0.1"udp.port: 9000
  • THEN 系统 SHALL 将其解析为 udp checker并填充 payload=""encoding="text"responseEncoding="text"maxResponseBytes=4096、interval、timeout、group 和 expect 配置

Scenario: udp target 缺少 host

  • WHEN YAML 中 target 配置 type: udp 但缺少 udp.host
  • THEN 系统 SHALL 以配置错误退出,并提示该 target 缺少 udp.host 字段

Scenario: udp target 缺少 port

  • WHEN YAML 中 target 配置 type: udp 但缺少 udp.port
  • THEN 系统 SHALL 以配置错误退出,并提示该 target 缺少 udp.port 字段

Scenario: udp port 范围非法

  • WHEN YAML 中 udp target 的 udp.port 不是 1 到 65535 之间的整数
  • THEN 系统 SHALL 以配置错误退出,并提示 udp.port 必须为合法 UDP 端口

Scenario: 省略 payload 发送空 datagram

  • WHEN YAML 中 udp target 未配置 udp.payload
  • THEN 系统 SHALL 使用空字符串作为 payload并在执行时发送零长度 UDP datagram

Scenario: udp 分组未知字段失败

  • WHEN YAML 中 udp target 的 udp 分组包含 dnsQueryexpectResponse 或其他未知字段
  • THEN 系统 SHALL 以配置错误退出,提示 udp 分组包含未知字段

Scenario: udp 序列化展示摘要

  • WHEN 系统同步 udp target 到 targets 表
  • THEN target 展示摘要 SHALL 为 udp <host>:<port>config JSON SHALL 包含 resolved 后的 host、port、payload、encoding、responseEncoding 和 maxResponseBytes

Requirement: udp payload 编码

系统 SHALL 支持将 udp.payloadudp.encoding 解码为发送字节,编码类型限定为 texthexbase64

Scenario: text payload 编码

  • WHEN udp target 配置 udp.payload: "PING"udp.encoding 未配置或为 text
  • THEN 系统 SHALL 以 UTF-8 字节发送 PING

Scenario: hex payload 编码

  • WHEN udp target 配置 udp.payload: "50494e47"udp.encoding: "hex"
  • THEN 系统 SHALL 解码 hex 后发送字节内容 PING

Scenario: base64 payload 编码

  • WHEN udp target 配置 udp.payload: "UElORw=="udp.encoding: "base64"
  • THEN 系统 SHALL 解码 base64 后发送字节内容 PING

Scenario: 非法 encoding 失败

  • WHEN YAML 中 udp target 配置 udp.encoding: "json"
  • THEN 系统 SHALL 以配置错误退出,提示 udp.encoding 必须为 texthexbase64

Scenario: 非法 responseEncoding 失败

  • WHEN YAML 中 udp target 配置 udp.responseEncoding: "json"
  • THEN 系统 SHALL 以配置错误退出,提示 udp.responseEncoding 必须为 texthexbase64

Scenario: 非法 hex payload 失败

  • WHEN YAML 中 udp target 配置 udp.encoding: "hex"udp.payload 不是合法 hex 字符串
  • THEN 系统 SHALL 以配置错误退出,提示 udp.payload 与 udp.encoding 不匹配

Scenario: 非法 base64 payload 失败

  • WHEN YAML 中 udp target 配置 udp.encoding: "base64"udp.payload 不是合法 base64 字符串
  • THEN 系统 SHALL 以配置错误退出,提示 udp.payload 与 udp.encoding 不匹配

Requirement: udp checker 执行

系统 SHALL 使用 Bun connected UDP socket 向目标发送单个 datagram等待第一个 UDP 响应 datagram记录完整执行耗时和 UDP observation并在发送失败、超时、资源超限或底层 socket 错误时产生结构化失败信息。

Scenario: UDP 请求响应成功

  • WHEN udp target 指向会返回 PONG 的 UDP 服务,且未配置 expect 或 expect.respondedtrue
  • THEN 系统 SHALL 记录 matched=truedurationMs 和包含响应大小的 observation并关闭 socket

Scenario: 使用 hostname 执行 UDP 探测

  • WHEN udp target 的 udp.host 为可解析域名或 localhost
  • THEN 系统 SHALL 使用 Bun connected UDP socket 完成发送和接收,不要求配置 IP 地址

Scenario: 只处理第一个响应 datagram

  • WHEN UDP 服务对一次请求返回多个 datagram
  • THEN 系统 SHALL 仅使用第一个收到的 UDP datagram 执行 expect 校验,并关闭 socket

Scenario: UDP 无响应且默认期望响应

  • WHEN udp target 指向在 timeout 内不返回 UDP datagram 的服务,且未配置 expect 或 expect.respondedtrue
  • THEN 系统 SHALL 在 ctx.signal abort 后记录 matched=falseobservation SHALL 包含 responded=false 和 errorfailure 的 kind 为 errorphase 为 responsemessage 包含超时或未响应信息

Scenario: 期望无响应且实际无响应

  • WHEN udp target 配置 expect.responded: false,且 timeout 内未收到 UDP datagram
  • THEN 系统 SHALL 记录 matched=trueobservation SHALL 包含 responded=falseAPI detail SHALL 表示未收到响应

Scenario: 期望无响应但实际收到响应

  • WHEN udp target 配置 expect.responded: false,但收到了 UDP datagram
  • THEN 系统 SHALL 记录 matched=falseobservation SHALL 包含 responded=true 和响应摘要failure 的 kind 为 mismatchphase 为 responded

Scenario: UDP socket 底层错误

  • WHEN Bun UDP socket 在发送或接收过程中触发 error 事件
  • THEN 系统 SHALL best-effort 关闭 socket并记录 matched=false、failure.kind=error 和可读错误信息,并在可收集时记录 observation

Scenario: ICMP unreachable 不作为 UDP 响应

  • WHEN 底层系统因目标端口不可达产生 ICMP unreachable
  • THEN 系统 SHALL NOT 将其视为 responded=true 的 UDP datagram 响应

Scenario: UDP 执行超时关闭 socket

  • WHEN 引擎注入的 ctx.signal 在 UDP 发送或等待响应过程中 abort
  • THEN 系统 SHALL best-effort 关闭 UDP socket并记录结构化超时或未响应结果

Requirement: udp 响应大小限制

系统 SHALL 使用 udp.maxResponseBytes 限制单个 UDP 响应 datagram 的可处理字节数,默认值为 4096支持数字或 size string。

Scenario: 响应大小未超过限制

  • WHEN udp target 配置 udp.maxResponseBytes: 4096,且实际响应为 16 字节
  • THEN 系统 SHALL 允许后续 expect 校验继续执行

Scenario: 响应大小超过限制

  • WHEN udp target 配置 udp.maxResponseBytes: 4,且实际响应为 16 字节
  • THEN 系统 SHALL 返回 matched=falsefailure 的 kind 为 errorphase 为 responsemessage 包含响应超过大小限制的信息

Scenario: Bun 标记 datagram 被截断

  • WHEN Bun UDP data 回调中的 flags.truncatedtrue
  • THEN 系统 SHALL 返回 matched=falsefailure 的 kind 为 errorphase 为 responsemessage 包含响应被截断的信息

Scenario: maxResponseBytes 格式非法

  • WHEN YAML 中 udp target 的 maxResponseBytes 不是非负整数或合法 size string
  • THEN 系统 SHALL 以配置错误退出,提示 maxResponseBytes 格式错误

Requirement: udp expect 校验

系统 SHALL 支持 udp 专属 expect包括 respondedresponseresponseSizesourceHostsourcePortdurationMs,并按 responded、responseSize、response、sourceHost、sourcePort、durationMs 的阶段顺序快速失败。responded SHALL 保持布尔状态语义,未配置时在 Resolved expect 中默认 trueresponse MUST 使用共享 RawContentExpectations 数组输入并在运行期使用 ContentExpectations,且作用于按 udp.responseEncoding 转换后的响应文本。responseSizesourceHostsourcePortdurationMs SHALL 使用共享 RawValueExpectation 输入并在运行期使用 ValueExpectation

Scenario: 默认 responded 成功语义

  • WHEN udp target 未显式配置 expect.responded
  • THEN 系统 SHALL 在 Resolved udp expect 中使用默认 responded: true 进行校验

Scenario: response ContentExpectations 校验通过

  • WHEN udp target 配置 expect.response: [{ contains: "PONG" }],且按 responseEncoding 转换后的响应文本包含 PONG
  • THEN 系统 SHALL 判定 response 阶段通过

Scenario: response JSON 校验通过

  • WHEN udp target 收到文本响应 {"status":"ok"} 且配置 expect.response: [{json: {path: "$.status", equals: "ok"}}]
  • THEN 系统 SHALL 判定 response 阶段通过

Scenario: response ContentExpectations 校验失败

  • WHEN udp target 配置 expect.response: [{ contains: "PONG" }],但按 responseEncoding 转换后的响应文本不包含 PONG
  • THEN 系统 SHALL 返回 matched=falsefailure 的 kind 为 mismatchphase 为 responsepath 指向失败的 response expectation

Scenario: responseEncoding 为 hex

  • WHEN udp target 配置 udp.responseEncoding: "hex" 且收到字节内容 PONG
  • THEN 系统 SHALL 将响应转换为小写 hex 字符串 504f4e47 后执行 expect.response expectation

Scenario: responseSize matcher 校验通过

  • WHEN udp target 配置 expect.responseSize: { gte: 4 },且实际响应为 4 字节
  • THEN 系统 SHALL 判定 responseSize 阶段通过

Scenario: responseSize matcher 校验失败

  • WHEN udp target 配置 expect.responseSize: { gte: 4 },但实际响应为 2 字节
  • THEN 系统 SHALL 返回 matched=falsefailure 的 kind 为 mismatchphase 为 responseSize

Scenario: sourceHost matcher 校验

  • WHEN udp target 配置 expect.sourceHost: { equals: "127.0.0.1" },且 Bun 回调中的来源地址为 127.0.0.1
  • THEN 系统 SHALL 判定 sourceHost 阶段通过

Scenario: sourcePort matcher 校验

  • WHEN udp target 配置 expect.sourcePort: { equals: 9000 },且 Bun 回调中的来源端口为 9000
  • THEN 系统 SHALL 判定 sourcePort 阶段通过

Scenario: durationMs 校验

  • WHEN udp target 配置 expect.durationMs: {lte: 100},且完整执行耗时超过 100ms
  • THEN 系统 SHALL 返回 matched=falsefailure 的 phase 为 duration

Scenario: response 断言要求实际有响应

  • WHEN udp target 配置了 expect.responseexpect.responseSize,但同时配置 expect.responded: false
  • THEN 系统 SHALL 在启动期配置校验失败,提示响应内容或大小断言需要 expect.responded 为 true

Scenario: source 断言要求实际有响应

  • WHEN udp target 配置了 expect.sourceHostexpect.sourcePort,但同时配置 expect.responded: false
  • THEN 系统 SHALL 在启动期配置校验失败,提示响应来源断言需要 expect.responded 为 true

Scenario: udp expect 未知字段失败

  • WHEN YAML 中 udp target 的 expect 包含 status: [200]maxDurationMs: 1000 或其他非 udp expect 字段
  • THEN 系统 SHALL 以配置错误退出,提示 expect 包含未知字段

Requirement: udp detail 摘要

系统 SHALL 在 udp API 序列化时从 observation 动态生成简短 detail 摘要展示关键结果和执行耗时并避免返回过长响应内容。UDP observation SHALL 包含 durationMs 以支持 detail 构造。

Scenario: 收到响应的摘要

  • WHEN udp target 收到 4 字节响应且完整执行耗时为 12ms
  • THEN detail SHALL 包含 responded in 12ms4 bytes

Scenario: 未收到响应的摘要

  • WHEN udp target 配置 expect.responded: false 且 timeout 内未收到 UDP datagram
  • THEN detail SHALL 包含 no response 和执行耗时

Scenario: 响应内容摘要截断

  • WHEN udp target 收到较长响应内容
  • THEN detail SHALL 只展示按 responseEncoding 转换并截断后的响应摘要