1
0
Files
DiAL/openspec/specs/tcp-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

7.1 KiB
Raw Blame History

Purpose

定义 TCP checker 的配置格式、连接执行、banner 读取、expect 校验、失败结构和状态摘要。

Requirements

Requirement: tcp target 配置

系统 SHALL 支持 type: tcp 的 target 配置,通过 tcp.hosttcp.port 描述目标 TCP 地址,并通过可选字段控制 banner 读取行为。

Scenario: 解析最简 tcp target

  • WHEN YAML 中 target 配置 type: tcptcp.host: "127.0.0.1"tcp.port: 6379
  • THEN 系统 SHALL 将其解析为 tcp checker并填充 readBanner=falsebannerReadTimeout=2000maxBannerBytes=4096、interval、timeout、group 和 expect 配置

Scenario: tcp target 缺少 host

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

Scenario: tcp target 缺少 port

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

Scenario: tcp port 范围非法

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

Scenario: tcp defaults 覆盖 banner 参数

  • WHEN YAML 中配置 defaults.tcp.bannerReadTimeout: 1000defaults.tcp.maxBannerBytes: "8KB"
  • THEN 未显式配置对应字段的 tcp target SHALL 使用 defaults.tcp 中的值

Scenario: per-target banner 参数覆盖 defaults

  • WHEN defaults.tcp 配置了 banner 参数,且某个 tcp target 显式配置 tcp.bannerReadTimeouttcp.maxBannerBytes
  • THEN 该 target SHALL 使用自身 tcp 分组中的值

Scenario: tcp 序列化展示摘要

  • WHEN 系统同步 tcp target 到 targets 表
  • THEN target 展示摘要 SHALL 为 <host>:<port>config JSON SHALL 包含 resolved 后的 host、port、readBanner、bannerReadTimeout 和 maxBannerBytes

Requirement: tcp checker 执行

系统 SHALL 按 tcp target 配置建立 TCP 连接,记录完整执行耗时,并在连接失败、超时或资源超限时产生结构化失败信息。

Scenario: TCP 连接成功

  • WHEN tcp target 指向可连接的 TCP 服务,且未配置 expect 或 expect.connectedtrue
  • THEN 系统 SHALL 记录 matched=truedurationMsstatusDetail,并关闭 socket

Scenario: TCP 连接失败

  • WHEN tcp target 指向不可连接的 host/port且未配置 expect 或 expect.connectedtrue
  • THEN 系统 SHALL 记录 matched=falsefailure 的 kind 为 errorphase 为 connectmessage 包含可读连接失败原因

Scenario: 期望端口不可达且连接失败

  • WHEN tcp target 配置 expect.connected: false,且 TCP 连接失败
  • THEN 系统 SHALL 记录 matched=truestatusDetail SHALL 展示实际连接失败原因摘要

Scenario: 期望端口不可达但连接成功

  • WHEN tcp target 配置 expect.connected: false,但 TCP 连接成功
  • THEN 系统 SHALL 记录 matched=falsefailure 的 kind 为 mismatchphase 为 connected

Scenario: TCP 执行超时

  • WHEN 引擎注入的 ctx.signal 在 TCP 连接或 banner 读取过程中 abort
  • THEN 系统 SHALL best-effort 关闭 socket记录 matched=falsefailure 的 kind 为 errorphase 为 connectbannermessage 包含超时信息

Scenario: duration 包含 banner 读取

  • WHEN tcp target 开启 readBanner 且服务端延迟发送 banner
  • THEN 结果中的 durationMs SHALL 覆盖连接建立、banner 等待、banner 读取和 expect 校验的完整耗时

Requirement: tcp banner 读取

系统 SHALL 仅在 tcp.readBanner: true 时读取服务端主动发送的 banner 数据,并同时受 bannerReadTimeoutmaxBannerBytes 限制。

Scenario: 默认不读取 banner

  • WHEN tcp target 未配置 readBanner 或配置为 false
  • THEN 系统 SHALL 在连接建立后立即进入 connected 和 duration 校验,不等待服务端数据

Scenario: 读取服务端 banner

  • WHEN tcp target 配置 readBanner: true,且服务端连接后发送 220 smtp.example.com ESMTP
  • THEN 系统 SHALL 收集 banner 文本,并允许后续 expect.banner 对该文本执行 operator 断言

Scenario: banner 等待超时无数据

  • WHEN tcp target 配置 readBanner: true,但服务端在 bannerReadTimeout 内未发送任何数据
  • THEN 系统 SHALL 将 banner 视为空字符串并继续执行 expect 校验,不将无 banner 本身作为连接错误

Scenario: banner 读取超过最大字节数

  • WHEN 服务端发送的 banner 数据超过 maxBannerBytes
  • THEN 系统 SHALL 停止读取并记录 matched=false、failure.kind=error、failure.phase=banner 的结构化错误

Scenario: banner statusDetail 截断展示

  • WHEN tcp target 成功读取到较长 banner
  • THEN statusDetail SHALL 展示截断后的 banner 摘要,避免 UI 和历史记录写入过长文本

Requirement: tcp expect 校验

系统 SHALL 支持 tcp 专属 expect包括 connectedbannerdurationMs,并按 connected、banner、durationMs 的阶段顺序快速失败。connected SHALL 保持布尔状态语义,未配置时默认 truebanner MUST 使用共享 ContentRules 数组,并仅在 tcp.readBanner: true 时允许配置。durationMs SHALL 使用共享 ValueMatcher 校验包含连接和 banner 读取在内的完整执行耗时。

Scenario: 默认 connected 成功语义

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

Scenario: durationMs 校验

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

Scenario: banner ContentRules 校验通过

  • WHEN tcp target 配置 readBanner: trueexpect.banner: [{contains: "ESMTP"}],且实际 banner 包含 ESMTP
  • THEN 系统 SHALL 判定 banner 阶段通过

Scenario: banner regex 校验失败

  • WHEN tcp target 配置 readBanner: trueexpect.banner: [{regex: "^SSH-2\\.0"}],且实际 banner 不匹配该正则
  • THEN 系统 SHALL 返回 matched=falsefailure 的 kind 为 mismatchphase 为 bannerpath 指向失败的 banner 规则

Scenario: banner 多规则快速失败

  • WHEN tcp target 配置两条 banner 规则且第一条失败
  • THEN 系统 SHALL 返回第一条失败规则的 failure并 MUST NOT 执行第二条规则

Scenario: expect.banner 未开启 readBanner

  • WHEN tcp target 配置 expect.banner,但 tcp.readBanner 未配置为 true
  • THEN 系统 SHALL 在启动期配置校验失败,提示 banner 断言需要启用 tcp.readBanner

Scenario: tcp expect 未知字段失败

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