- 引入共享 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
11 KiB
11 KiB
Purpose
定义 ICMP/Ping checker 的配置格式、命令执行、跨平台输出解析、expect 校验、失败结构和状态摘要。
Requirements
Requirement: ping target 配置
系统 SHALL 支持 type: ping 的 target 配置,通过 ping.host 描述目标主机地址,并通过可选字段控制探测行为。
Scenario: 解析最简 ping target
- WHEN YAML 中 target 配置
type: ping和ping.host: "10.0.0.1" - THEN 系统 SHALL 将其解析为 ping checker,并填充
count=3、packetSize=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>,configJSON SHALL 包含 resolved 后的 host、count 和 packetSize
Requirement: ping checker 执行
系统 SHALL 通过调用系统 ping 命令执行 ICMP 探测,记录完整执行耗时,并在命令不可用、超时或解析失败时产生结构化失败信息。
Scenario: ping 命令构建(Linux)
- WHEN 系统平台为 linux,ping 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 系统平台为 darwin,ping 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 系统平台为 win32,ping 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=false,failure 的 kind 为error,phase 为ping,path 为spawn,message 包含 "ping 命令不可用" 和原始错误信息
Scenario: ping 执行超时
- WHEN 引擎注入的
ctx.signal在 ping 命令执行过程中 abort - THEN 系统 SHALL 调用
proc.kill()终止子进程,记录matched=false,failure 的 kind 为error,phase 为ping,message 包含超时信息
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 结果中的
durationMsSHALL 覆盖从 spawn 到进程退出的完整耗时
Requirement: 跨平台 ping 输出解析
系统 SHALL 实现跨平台 ping 输出解析器,支持 Linux、macOS 和 Windows(含多语言 locale),从 stdout 中提取 transmitted、received、packetLoss、minLatencyMs、avgLatencyMs、maxLatencyMs。
Scenario: 解析 Linux ping 输出
- WHEN 平台为 linux,stdout 包含 "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 平台为 darwin,stdout 包含 "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 平台为 win32,stdout 包含 "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 平台为 win32,stdout 包含 "数据包: 已发送 = 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=false,failure 的 kind 为error,phase 为ping,path 为parse,message 包含 "无法解析 ping 输出"
Requirement: ping expect 校验
系统 SHALL 支持 ping 专属 expect,包括 alive、packetLossPercent、avgLatencyMs、maxLatencyMs 和 durationMs,并按 alive、packetLossPercent、avgLatencyMs、maxLatencyMs、durationMs 的阶段顺序快速失败。alive SHALL 保持布尔状态语义,未配置时默认 true。packetLossPercent SHALL 表示 0 到 100 的丢包率百分比,并使用共享 ValueMatcher。avgLatencyMs、maxLatencyMs 和 durationMs 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=false,failure 的 kind 为mismatch,phase 为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=false,failure 的 kind 为mismatch,phase 为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=false,failure 的 kind 为mismatch,phase 为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=false,failure 的 kind 为mismatch,phase 为maxLatency
Scenario: durationMs 校验
- WHEN ping target 配置
expect.durationMs: {lte: 5000},且完整执行耗时超过 5000ms - THEN 系统 SHALL 返回
matched=false,failure 的 phase 为duration
Scenario: alive=false 时跳过延迟断言
- WHEN ping target 配置
expect.alive: true和expect.avgLatencyMs: {lte: 100},且目标不可达 - THEN 系统 SHALL 在 alive 阶段即返回失败,不执行后续延迟断言
Scenario: ping expect 未知字段失败
- WHEN YAML 中 ping target 的 expect 包含
status: [200]、maxPacketLoss、maxAvgLatencyMs、maxMaxLatencyMs、maxDurationMs或其他非 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)