feat: 新增 UDP checker,支持自定义 payload 请求-响应探测与断言
基于 Bun connected UDP socket 实现通用 UDP 拨测能力: - 支持 text/hex/base64 payload 编码与独立 responseEncoding 响应视图 - 支持 responded、response、responseSize、sourceHost、sourcePort、maxDurationMs 专属 expect - 单 datagram 发送,仅断言首个 UDP 响应 datagram - 通过 maxResponseBytes 和 flags.truncated 进行响应大小限制与截断保护 - payload 可选,省略时发送空 datagram - 自包含模块结构(types/schema/validate/expect/encoding/execute) - 新增 741 tests(含 unit、execute 集成、expect 和编码 roundtrip),全部通过
This commit is contained in:
@@ -5,9 +5,9 @@
|
||||
## Requirements
|
||||
|
||||
### Requirement: YAML 配置文件格式
|
||||
系统 SHALL 支持通过 YAML 配置文件定义全部运行参数,包括 server 配置、runtime 配置、可选的 variables 段、checker 默认值和 typed target 列表(含可选 group 字段)。target MUST 使用 `id` 字段作为唯一标识符,MUST 使用 `type` 字段声明 checker 类型,SHALL 支持可选的 `name` 字段作为展示名称元信息,SHALL 支持可选的 `description` 字段作为目标说明。`name` 和 `description` 均 SHALL 允许省略或显式配置为 `null`;省略或显式 null 时解析结果 SHALL 保留为 null。HTTP 领域字段 MUST 放在 `http` 分组,cmd 领域字段 MUST 放在 `cmd` 分组,db 领域字段 MUST 放在 `db` 分组,tcp 领域字段 MUST 放在 `tcp` 分组,ping 领域字段 MUST 放在 `ping` 分组。HTTP target 的 `http` 分组 SHALL 支持可选的 `ignoreSSL`(布尔值)和 `maxRedirects`(非负整数)字段。Db target 的 `db` 分组 SHALL 支持 `url`(必填)和 `query`(可选)字段。Tcp target 的 `tcp` 分组 SHALL 支持 `host`(必填)、`port`(必填)、`readBanner`(可选)、`bannerReadTimeout`(可选)和 `maxBannerBytes`(可选)字段。Ping target 的 `ping` 分组 SHALL 支持 `host`(必填)、`count`(可选,默认 3)和 `packetSize`(可选,默认 56)字段。
|
||||
系统 SHALL 支持通过 YAML 配置文件定义全部运行参数,包括 server 配置、runtime 配置、可选的 variables 段、checker 默认值和 typed target 列表(含可选 group 字段)。target MUST 使用 `id` 字段作为唯一标识符,MUST 使用 `type` 字段声明 checker 类型,SHALL 支持可选的 `name` 字段作为展示名称元信息,SHALL 支持可选的 `description` 字段作为目标说明。`name` 和 `description` 均 SHALL 允许省略或显式配置为 `null`;省略或显式 null 时解析结果 SHALL 保留为 null。HTTP 领域字段 MUST 放在 `http` 分组,cmd 领域字段 MUST 放在 `cmd` 分组,db 领域字段 MUST 放在 `db` 分组,tcp 领域字段 MUST 放在 `tcp` 分组,ping 领域字段 MUST 放在 `ping` 分组,udp 领域字段 MUST 放在 `udp` 分组。HTTP target 的 `http` 分组 SHALL 支持可选的 `ignoreSSL`(布尔值)和 `maxRedirects`(非负整数)字段。Db target 的 `db` 分组 SHALL 支持 `url`(必填)和 `query`(可选)字段。Tcp target 的 `tcp` 分组 SHALL 支持 `host`(必填)、`port`(必填)、`readBanner`(可选)、`bannerReadTimeout`(可选)和 `maxBannerBytes`(可选)字段。Ping target 的 `ping` 分组 SHALL 支持 `host`(必填)、`count`(可选,默认 3)和 `packetSize`(可选,默认 56)字段。Udp target 的 `udp` 分组 SHALL 支持 `host`(必填)、`port`(必填)、`payload`(可选,默认空字符串)、`encoding`(可选,默认 `text`)、`responseEncoding`(可选,默认 `text`)和 `maxResponseBytes`(可选,默认 4096)字段。
|
||||
|
||||
`defaults.http` 分组 SHALL 仅支持 `headers`(可选)和 `maxBodyBytes`(可选)字段。`defaults.http` 分组 MUST NOT 支持 `method` 字段。`defaults.tcp` 分组 SHALL 仅支持 `bannerReadTimeout`(可选)和 `maxBannerBytes`(可选)字段。
|
||||
`defaults.http` 分组 SHALL 仅支持 `headers`(可选)和 `maxBodyBytes`(可选)字段。`defaults.http` 分组 MUST NOT 支持 `method` 字段。`defaults.tcp` 分组 SHALL 仅支持 `bannerReadTimeout`(可选)和 `maxBannerBytes`(可选)字段。`defaults.udp` 分组 SHALL 仅支持 `encoding`(可选)、`responseEncoding`(可选)和 `maxResponseBytes`(可选)字段。
|
||||
|
||||
#### Scenario: 完整配置文件解析
|
||||
- **WHEN** 系统启动并读取包含 server、runtime、variables、defaults、targets(含 id、group 字段)的 YAML 配置文件
|
||||
@@ -61,6 +61,14 @@
|
||||
- **WHEN** 系统读取只包含一个 `type: ping` target(含 `id` 和 `ping.host`)的 YAML 配置文件
|
||||
- **THEN** 系统 SHALL 使用内置默认值填充未指定的字段(interval=30s, timeout=10s, group="default", ping.count=3, ping.packetSize=56),并保留 name=null、description=null
|
||||
|
||||
#### Scenario: 最简 udp 配置文件解析
|
||||
- **WHEN** 系统读取只包含一个 `type: udp` target(含 `id`、`udp.host` 和 `udp.port`)的 YAML 配置文件
|
||||
- **THEN** 系统 SHALL 使用内置默认值填充未指定的字段(interval=30s, timeout=10s, group="default", udp.payload="", udp.encoding="text", udp.responseEncoding="text", udp.maxResponseBytes=4096),并保留 name=null、description=null
|
||||
|
||||
#### Scenario: defaults.udp 配置默认值
|
||||
- **WHEN** YAML 配置中 defaults.udp 设置 `encoding`、`responseEncoding` 和 `maxResponseBytes`
|
||||
- **THEN** 未显式覆盖对应字段的 udp target SHALL 使用 defaults.udp 中的值
|
||||
|
||||
### Requirement: CLI 参数
|
||||
系统 SHALL 通过单一命令行参数接受 YAML 配置文件路径。
|
||||
|
||||
@@ -285,7 +293,7 @@
|
||||
- **THEN** 系统 SHALL 调用 `Bun.YAML.parse()` 将内容解析为配置对象
|
||||
|
||||
### Requirement: expect 配置增强
|
||||
系统 SHALL 支持 typed target 的领域专用 expect 配置,包括 HTTP 的 `status`(支持精确数字和范围模式)、`headers`、`body`,cmd 的 `exitCode`、`stdout`、`stderr`,tcp 的 `connected`、`banner`,以及 ping 的 `alive`、`maxPacketLoss`、`maxAvgLatencyMs`、`maxMaxLatencyMs`。内容类 expect MUST 使用数组表达配置顺序。
|
||||
系统 SHALL 支持 typed target 的领域专用 expect 配置,包括 HTTP 的 `status`(支持精确数字和范围模式)、`headers`、`body`,cmd 的 `exitCode`、`stdout`、`stderr`,tcp 的 `connected`、`banner`,ping 的 `alive`、`maxPacketLoss`、`maxAvgLatencyMs`、`maxMaxLatencyMs`,以及 udp 的 `responded`、`response`、`responseSize`、`sourceHost`、`sourcePort` 和 `maxDurationMs`。内容类 expect MUST 使用数组表达配置顺序。
|
||||
|
||||
#### Scenario: 解析 HTTP expect 配置
|
||||
- **WHEN** YAML 配置文件中 HTTP target 的 expect 包含 status、headers、body 规则数组及内部方法
|
||||
@@ -327,6 +335,14 @@
|
||||
- **WHEN** ping target 未配置任何 expect 规则
|
||||
- **THEN** 系统 SHALL 正常处理,expect 字段为 undefined,执行时使用默认 alive=true 语义
|
||||
|
||||
#### Scenario: 解析 udp expect 配置
|
||||
- **WHEN** YAML 配置文件中 udp target 的 expect 包含 responded、response、responseSize、sourceHost、sourcePort 和 maxDurationMs
|
||||
- **THEN** 系统 SHALL 正确解析并存储为 udp target 的 expect 字段
|
||||
|
||||
#### Scenario: 不配置 udp expect
|
||||
- **WHEN** udp target 未配置任何 expect 规则
|
||||
- **THEN** 系统 SHALL 正常处理,expect 字段为 undefined,执行时使用默认 responded=true 语义
|
||||
|
||||
### Requirement: 数据保留配置字段
|
||||
配置 schema 的 `runtime` 段 SHALL 支持 `retention` 字段,类型为字符串,格式为 `<数字><单位>`(单位:`d` 天、`h` 小时、`m` 分钟),用于指定历史数据保留时长。
|
||||
|
||||
|
||||
203
openspec/specs/udp-checker/spec.md
Normal file
203
openspec/specs/udp-checker/spec.md
Normal file
@@ -0,0 +1,203 @@
|
||||
## Purpose
|
||||
|
||||
定义 UDP checker 的 target 配置、defaults、执行语义、响应编码、expect 校验、失败结构和状态摘要。
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: udp target 配置
|
||||
系统 SHALL 支持 `type: udp` 的 target 配置,通过 `udp.host` 和 `udp.port` 描述目标 UDP 地址,并通过可选字段控制 payload、编码和响应大小限制。
|
||||
|
||||
#### Scenario: 解析最简 udp target
|
||||
- **WHEN** YAML 中 target 配置 `type: udp`、`udp.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 defaults 覆盖通用 UDP 参数
|
||||
- **WHEN** YAML 中配置 `defaults.udp.encoding: "hex"`、`defaults.udp.responseEncoding: "hex"` 和 `defaults.udp.maxResponseBytes: "8KB"`
|
||||
- **THEN** 未显式配置对应字段的 udp target SHALL 使用 defaults.udp 中的值
|
||||
|
||||
#### Scenario: per-target UDP 参数覆盖 defaults
|
||||
- **WHEN** defaults.udp 配置了 encoding、responseEncoding 或 maxResponseBytes,且某个 udp target 显式配置对应字段
|
||||
- **THEN** 该 target SHALL 使用自身 udp 分组中的值
|
||||
|
||||
#### Scenario: udp 分组未知字段失败
|
||||
- **WHEN** YAML 中 udp target 的 `udp` 分组包含 `dnsQuery`、`expectResponse` 或其他未知字段
|
||||
- **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.payload` 按 `udp.encoding` 解码为发送字节,编码类型限定为 `text`、`hex` 和 `base64`。
|
||||
|
||||
#### 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 必须为 `text`、`hex` 或 `base64`
|
||||
|
||||
#### Scenario: 非法 responseEncoding 失败
|
||||
- **WHEN** YAML 中 udp target 配置 `udp.responseEncoding: "json"`
|
||||
- **THEN** 系统 SHALL 以配置错误退出,提示 udp.responseEncoding 必须为 `text`、`hex` 或 `base64`
|
||||
|
||||
#### 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,记录完整执行耗时,并在发送失败、超时、资源超限或底层 socket 错误时产生结构化失败信息。
|
||||
|
||||
#### Scenario: UDP 请求响应成功
|
||||
- **WHEN** udp target 指向会返回 `PONG` 的 UDP 服务,且未配置 expect 或 `expect.responded` 为 `true`
|
||||
- **THEN** 系统 SHALL 记录 `matched=true`、`durationMs` 和包含响应大小的 `statusDetail`,并关闭 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.responded` 为 `true`
|
||||
- **THEN** 系统 SHALL 在 `ctx.signal` abort 后记录 `matched=false`,failure 的 kind 为 `error`,phase 为 `response`,message 包含超时或未响应信息
|
||||
|
||||
#### Scenario: 期望无响应且实际无响应
|
||||
- **WHEN** udp target 配置 `expect.responded: false`,且 timeout 内未收到 UDP datagram
|
||||
- **THEN** 系统 SHALL 记录 `matched=true`,statusDetail SHALL 表示未收到响应
|
||||
|
||||
#### Scenario: 期望无响应但实际收到响应
|
||||
- **WHEN** udp target 配置 `expect.responded: false`,但收到了 UDP datagram
|
||||
- **THEN** 系统 SHALL 记录 `matched=false`,failure 的 kind 为 `mismatch`,phase 为 `responded`
|
||||
|
||||
#### Scenario: UDP socket 底层错误
|
||||
- **WHEN** Bun UDP socket 在发送或接收过程中触发 error 事件
|
||||
- **THEN** 系统 SHALL best-effort 关闭 socket,并记录 `matched=false`、failure.kind=`error` 和可读错误信息
|
||||
|
||||
#### 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=false`,failure 的 kind 为 `error`,phase 为 `response`,message 包含响应超过大小限制的信息
|
||||
|
||||
#### Scenario: Bun 标记 datagram 被截断
|
||||
- **WHEN** Bun UDP data 回调中的 `flags.truncated` 为 `true`
|
||||
- **THEN** 系统 SHALL 返回 `matched=false`,failure 的 kind 为 `error`,phase 为 `response`,message 包含响应被截断的信息
|
||||
|
||||
#### Scenario: maxResponseBytes 格式非法
|
||||
- **WHEN** YAML 中 udp target 或 defaults.udp 的 `maxResponseBytes` 不是非负整数或合法 size string
|
||||
- **THEN** 系统 SHALL 以配置错误退出,提示 maxResponseBytes 格式错误
|
||||
|
||||
### Requirement: udp expect 校验
|
||||
系统 SHALL 支持 udp 专属 expect,包括 `responded`、`response`、`responseSize`、`sourceHost`、`sourcePort` 和 `maxDurationMs`,并按 responded、responseSize、response、sourceHost、sourcePort、duration 的阶段顺序快速失败。
|
||||
|
||||
#### Scenario: 默认 responded 成功语义
|
||||
- **WHEN** udp target 未显式配置 `expect.responded`
|
||||
- **THEN** 系统 SHALL 使用默认 `expect.responded: true` 进行校验
|
||||
|
||||
#### Scenario: response text rules 校验通过
|
||||
- **WHEN** udp target 配置 `expect.response: [{ contains: "PONG" }]`,且按 `responseEncoding` 转换后的响应文本包含 `PONG`
|
||||
- **THEN** 系统 SHALL 判定 response 阶段通过
|
||||
|
||||
#### Scenario: response text rules 校验失败
|
||||
- **WHEN** udp target 配置 `expect.response: [{ contains: "PONG" }]`,但按 `responseEncoding` 转换后的响应文本不包含 `PONG`
|
||||
- **THEN** 系统 SHALL 返回 `matched=false`,failure 的 kind 为 `mismatch`,phase 为 `response`,path 指向失败的 response 规则
|
||||
|
||||
#### Scenario: responseEncoding 为 hex
|
||||
- **WHEN** udp target 配置 `udp.responseEncoding: "hex"` 且收到字节内容 `PONG`
|
||||
- **THEN** 系统 SHALL 将响应转换为小写 hex 字符串 `504f4e47` 后执行 `expect.response` 规则
|
||||
|
||||
#### Scenario: responseEncoding 为 base64
|
||||
- **WHEN** udp target 配置 `udp.responseEncoding: "base64"` 且收到字节内容 `PONG`
|
||||
- **THEN** 系统 SHALL 将响应转换为 base64 字符串 `UE9ORw==` 后执行 `expect.response` 规则
|
||||
|
||||
#### Scenario: responseSize operator 校验通过
|
||||
- **WHEN** udp target 配置 `expect.responseSize: { gte: 4 }`,且实际响应为 4 字节
|
||||
- **THEN** 系统 SHALL 判定 responseSize 阶段通过
|
||||
|
||||
#### Scenario: responseSize operator 校验失败
|
||||
- **WHEN** udp target 配置 `expect.responseSize: { gte: 4 }`,但实际响应为 2 字节
|
||||
- **THEN** 系统 SHALL 返回 `matched=false`,failure 的 kind 为 `mismatch`,phase 为 `responseSize`
|
||||
|
||||
#### Scenario: sourceHost operator 校验
|
||||
- **WHEN** udp target 配置 `expect.sourceHost: { equals: "127.0.0.1" }`,且 Bun 回调中的来源地址为 `127.0.0.1`
|
||||
- **THEN** 系统 SHALL 判定 sourceHost 阶段通过
|
||||
|
||||
#### Scenario: sourcePort operator 校验
|
||||
- **WHEN** udp target 配置 `expect.sourcePort: { equals: 9000 }`,且 Bun 回调中的来源端口为 `9000`
|
||||
- **THEN** 系统 SHALL 判定 sourcePort 阶段通过
|
||||
|
||||
#### Scenario: maxDurationMs 校验
|
||||
- **WHEN** udp target 配置 `expect.maxDurationMs: 100`,且完整执行耗时超过 100ms
|
||||
- **THEN** 系统 SHALL 返回 `matched=false`,failure 的 phase 为 `duration`
|
||||
|
||||
#### Scenario: response 断言要求实际有响应
|
||||
- **WHEN** udp target 配置了 `expect.response` 或 `expect.responseSize`,但同时配置 `expect.responded: false`
|
||||
- **THEN** 系统 SHALL 在启动期配置校验失败,提示响应内容或大小断言需要 `expect.responded` 为 true
|
||||
|
||||
#### Scenario: source 断言要求实际有响应
|
||||
- **WHEN** udp target 配置了 `expect.sourceHost` 或 `expect.sourcePort`,但同时配置 `expect.responded: false`
|
||||
- **THEN** 系统 SHALL 在启动期配置校验失败,提示响应来源断言需要 `expect.responded` 为 true
|
||||
|
||||
#### Scenario: udp expect 未知字段失败
|
||||
- **WHEN** YAML 中 udp target 的 expect 包含 `status: [200]` 或其他非 udp expect 字段
|
||||
- **THEN** 系统 SHALL 以配置错误退出,提示 expect 包含未知字段
|
||||
|
||||
### Requirement: udp statusDetail 摘要
|
||||
系统 SHALL 在 udp 执行后生成简短 statusDetail 摘要,展示关键结果并避免写入过长响应内容。
|
||||
|
||||
#### Scenario: 收到响应的摘要
|
||||
- **WHEN** udp target 收到 4 字节响应且完整执行耗时为 12ms
|
||||
- **THEN** statusDetail SHALL 包含 `responded in 12ms` 和 `4 bytes`
|
||||
|
||||
#### Scenario: 未收到响应的摘要
|
||||
- **WHEN** udp target 配置 `expect.responded: false` 且 timeout 内未收到 UDP datagram
|
||||
- **THEN** statusDetail SHALL 包含 `no response` 和执行耗时
|
||||
|
||||
#### Scenario: 响应内容摘要截断
|
||||
- **WHEN** udp target 收到较长响应内容
|
||||
- **THEN** statusDetail SHALL 只展示按 `responseEncoding` 转换并截断后的响应摘要
|
||||
Reference in New Issue
Block a user