1
0
Files
DiAL/openspec/specs/icmp-checker/spec.md
lanyuanxiaoyao 7a635a0a9f 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
2026-05-19 14:24:27 +08:00

11 KiB
Raw Blame History

Purpose

定义 ICMP/Ping checker 的配置格式、命令执行、跨平台输出解析、expect 校验、失败结构和状态摘要。

Requirements

Requirement: ping target 配置

系统 SHALL 支持 type: ping 的 target 配置,通过 ping.host 描述目标主机地址,并通过可选字段控制探测行为。

Scenario: 解析最简 ping target

  • WHEN YAML 中 target 配置 type: pingping.host: "10.0.0.1"
  • THEN 系统 SHALL 将其解析为 ping checker并填充 count=3packetSize=56、interval、timeout、group 和 expect 配置

Scenario: ping target 缺少 host

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

Scenario: ping host 类型非法

  • WHEN YAML 中 ping target 的 ping.host 不是非空字符串
  • THEN 系统 SHALL 以配置错误退出,提示 ping.host 必须为非空字符串

Scenario: ping count 配置

  • WHEN YAML 中 ping target 配置 ping.count: 5
  • THEN 系统 SHALL 使用 5 作为 ICMP 包发送数量

Scenario: ping count 非法

  • WHEN YAML 中 ping target 的 ping.count 不是 1 到 100 之间的正整数
  • THEN 系统 SHALL 以配置错误退出,提示 ping.count 必须为 1-100 的正整数

Scenario: ping packetSize 配置

  • WHEN YAML 中 ping target 配置 ping.packetSize: 1472
  • THEN 系统 SHALL 使用 1472 作为 ICMP 包大小bytes

Scenario: ping packetSize 非法

  • WHEN YAML 中 ping target 的 ping.packetSize 不是 1 到 65500 之间的正整数
  • THEN 系统 SHALL 以配置错误退出,提示 ping.packetSize 必须为 1-65500 的正整数

Scenario: ping 分组未知字段失败

  • WHEN YAML 中 ping target 的 ping 分组包含 timeout: 5 等未知字段
  • THEN 系统 SHALL 以配置错误退出,提示 ping 分组包含未知字段

Scenario: ping 序列化展示摘要

  • WHEN 系统同步 ping target 到 targets 表
  • THEN target 展示摘要 SHALL 为 ping <host>config JSON SHALL 包含 resolved 后的 host、count 和 packetSize

Requirement: ping checker 执行

系统 SHALL 通过调用系统 ping 命令执行 ICMP 探测,记录完整执行耗时,并在命令不可用、超时或解析失败时产生结构化失败信息。

Scenario: ping 命令构建Linux

  • WHEN 系统平台为 linuxping target 配置 host="10.0.0.1"、count=3、packetSize=56且外层 timeoutMs=10000
  • THEN 系统 SHALL 执行 ping -c 3 -s 56 -W 10 10.0.0.1-W 单位为秒,向上取整)

Scenario: ping 命令构建macOS

  • WHEN 系统平台为 darwinping target 配置 host="10.0.0.1"、count=3、packetSize=56且外层 timeoutMs=10000
  • THEN 系统 SHALL 执行 ping -c 3 -s 56 -W 10000 10.0.0.1-W 单位为毫秒)

Scenario: ping 命令构建Windows

  • WHEN 系统平台为 win32ping target 配置 host="10.0.0.1"、count=3、packetSize=56且外层 timeoutMs=10000
  • THEN 系统 SHALL 执行 ping -n 3 -l 56 -w 10000 10.0.0.1-w 单位为毫秒)

Scenario: ping 命令不存在

  • WHEN 系统未安装 ping 命令spawn 抛出 ENOENT
  • THEN 系统 SHALL 记录 matched=falsefailure 的 kind 为 errorphase 为 pingpath 为 spawnmessage 包含 "ping 命令不可用" 和原始错误信息

Scenario: ping 执行超时

  • WHEN 引擎注入的 ctx.signal 在 ping 命令执行过程中 abort
  • THEN 系统 SHALL 调用 proc.kill() 终止子进程,记录 matched=falsefailure 的 kind 为 errorphase 为 pingmessage 包含超时信息

Scenario: ping 目标可达

  • WHEN ping target 指向可达主机,且 ping 命令正常返回
  • THEN 系统 SHALL 解析 stdout 获取统计数据,并按断言链执行 expect 校验

Scenario: ping 目标不可达

  • WHEN ping target 指向不可达主机,且 ping 命令返回 100% packet loss
  • THEN 系统 SHALL 解析 stdout 获取统计数据,alive 为 false延迟字段为 null

Scenario: duration 覆盖完整执行

  • WHEN ping 命令执行完成
  • THEN 结果中的 durationMs SHALL 覆盖从 spawn 到进程退出的完整耗时

Requirement: 跨平台 ping 输出解析

系统 SHALL 实现跨平台 ping 输出解析器,支持 Linux、macOS 和 Windows含多语言 locale从 stdout 中提取 transmitted、received、packetLoss、minLatencyMs、avgLatencyMs、maxLatencyMs。

Scenario: 解析 Linux ping 输出

  • WHEN 平台为 linuxstdout 包含 "3 packets transmitted, 3 received, 0% packet loss" 和 "rtt min/avg/max/mdev = 1.234/2.345/3.456/0.567 ms"
  • THEN 系统 SHALL 解析为 transmitted=3, received=3, packetLoss=0, minLatencyMs=1.234, avgLatencyMs=2.345, maxLatencyMs=3.456

Scenario: 解析 macOS ping 输出

  • WHEN 平台为 darwinstdout 包含 "3 packets transmitted, 3 packets received, 0.0% packet loss" 和 "round-trip min/avg/max/stddev = 1.234/2.345/3.456/0.567 ms"
  • THEN 系统 SHALL 解析为 transmitted=3, received=3, packetLoss=0, minLatencyMs=1.234, avgLatencyMs=2.345, maxLatencyMs=3.456

Scenario: 解析 Windows 英文 ping 输出

  • WHEN 平台为 win32stdout 包含 "Packets: Sent = 3, Received = 3, Lost = 0 (0% loss)" 和 "Minimum = 1ms, Maximum = 3ms, Average = 2ms"
  • THEN 系统 SHALL 解析为 transmitted=3, received=3, packetLoss=0, minLatencyMs=1, avgLatencyMs=2, maxLatencyMs=3

Scenario: 解析 Windows 中文 ping 输出

  • WHEN 平台为 win32stdout 包含 "数据包: 已发送 = 3已接收 = 3丢失 = 0 (0% 丢失)" 和 "最短 = 1ms最长 = 3ms平均 = 2ms"
  • THEN 系统 SHALL 解析为 transmitted=3, received=3, packetLoss=0, minLatencyMs=1, avgLatencyMs=2, maxLatencyMs=3

Scenario: 解析全部丢包(无延迟行)

  • WHEN stdout 包含丢包统计行但无延迟统计行100% packet loss
  • THEN 系统 SHALL 解析为 alive=false延迟字段min/avg/max均为 null

Scenario: 输出无法解析

  • WHEN stdout 不匹配任何已知的统计行格式
  • THEN 系统 SHALL 记录 matched=falsefailure 的 kind 为 errorphase 为 pingpath 为 parsemessage 包含 "无法解析 ping 输出"

Requirement: ping expect 校验

系统 SHALL 支持 ping 专属 expect包括 alivepacketLossPercentavgLatencyMsmaxLatencyMsdurationMs,并按 alive、packetLossPercent、avgLatencyMs、maxLatencyMs、durationMs 的阶段顺序快速失败。alive SHALL 保持布尔状态语义,未配置时默认 truepacketLossPercent SHALL 表示 0 到 100 的丢包率百分比,并使用共享 ValueMatcheravgLatencyMsmaxLatencyMsdurationMs SHALL 使用共享 ValueMatcher

Scenario: 默认 alive 成功语义

  • WHEN ping target 未显式配置 expect.alive
  • THEN 系统 SHALL 使用默认 expect.alive: true 进行校验

Scenario: alive 校验通过

  • WHEN ping target 配置 expect.alive: true,且目标主机可达
  • THEN 系统 SHALL 判定 alive 阶段通过

Scenario: alive 校验失败

  • WHEN ping target 配置 expect.alive: true,且目标主机不可达
  • THEN 系统 SHALL 返回 matched=falsefailure 的 kind 为 mismatchphase 为 alive

Scenario: 反向 alive 断言

  • WHEN ping target 配置 expect.alive: false,且目标主机不可达
  • THEN 系统 SHALL 判定 alive 阶段通过(matched=true

Scenario: packetLossPercent 校验通过

  • WHEN ping target 配置 expect.packetLossPercent: {lte: 10},且实际丢包率为 0%
  • THEN 系统 SHALL 判定 packetLossPercent 阶段通过

Scenario: packetLossPercent 校验失败

  • WHEN ping target 配置 expect.packetLossPercent: {lte: 10},且实际丢包率为 33%
  • THEN 系统 SHALL 返回 matched=falsefailure 的 kind 为 mismatchphase 为 packetLoss

Scenario: avgLatencyMs 校验通过

  • WHEN ping target 配置 expect.avgLatencyMs: {lte: 200},且实际平均延迟为 12ms
  • THEN 系统 SHALL 判定 avgLatency 阶段通过

Scenario: avgLatencyMs 校验失败

  • WHEN ping target 配置 expect.avgLatencyMs: {lte: 100},且实际平均延迟为 156ms
  • THEN 系统 SHALL 返回 matched=falsefailure 的 kind 为 mismatchphase 为 avgLatency

Scenario: maxLatencyMs 校验通过

  • WHEN ping target 配置 expect.maxLatencyMs: {lte: 500},且实际最大延迟为 340ms
  • THEN 系统 SHALL 判定 maxLatency 阶段通过

Scenario: maxLatencyMs 校验失败

  • WHEN ping target 配置 expect.maxLatencyMs: {lte: 200},且实际最大延迟为 340ms
  • THEN 系统 SHALL 返回 matched=falsefailure 的 kind 为 mismatchphase 为 maxLatency

Scenario: durationMs 校验

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

Scenario: alive=false 时跳过延迟断言

  • WHEN ping target 配置 expect.alive: trueexpect.avgLatencyMs: {lte: 100},且目标不可达
  • THEN 系统 SHALL 在 alive 阶段即返回失败,不执行后续延迟断言

Scenario: ping expect 未知字段失败

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

Scenario: packetLossPercent 类型非法

  • WHEN YAML 中 ping target 的 expect.packetLossPercent 不是合法 ValueMatcher,或其数值范围无法用于 0 到 100 的百分比断言
  • THEN 系统 SHALL 以配置错误退出,提示 expect.packetLossPercent 格式错误

Scenario: avgLatencyMs 类型非法

  • WHEN YAML 中 ping target 的 expect.avgLatencyMs 不是合法 ValueMatcher
  • THEN 系统 SHALL 以配置错误退出,提示 expect.avgLatencyMs 格式错误

Scenario: maxLatencyMs 类型非法

  • WHEN YAML 中 ping target 的 expect.maxLatencyMs 不是合法 ValueMatcher
  • THEN 系统 SHALL 以配置错误退出,提示 expect.maxLatencyMs 格式错误

Requirement: ping statusDetail 摘要

系统 SHALL 在 ping 执行成功后生成结构化 statusDetail 摘要,展示关键指标。

Scenario: 目标可达无丢包

  • WHEN ping 结果为 alive=true, avg=12ms, packetLoss=0%, transmitted=3, received=3
  • THEN statusDetail SHALL 为 alive, avg 12ms, loss 0% (3/3)

Scenario: 目标可达有丢包

  • WHEN ping 结果为 alive=true, avg=156ms, max=340ms, packetLoss=33%, transmitted=3, received=2
  • THEN statusDetail SHALL 包含 avg、max 和 loss 信息

Scenario: 目标不可达

  • WHEN ping 结果为 alive=false, transmitted=3, received=0
  • THEN statusDetail SHALL 为 unreachable (0/3 received)