- 合并 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 审查提示文档
7.1 KiB
7.1 KiB
Purpose
定义 TCP checker 的配置格式、连接执行、banner 读取、expect 校验、失败结构和状态摘要。
Requirements
Requirement: tcp target 配置
系统 SHALL 支持 type: tcp 的 target 配置,通过 tcp.host 和 tcp.port 描述目标 TCP 地址,并通过可选字段控制 banner 读取行为。
Scenario: 解析最简 tcp target
- WHEN YAML 中 target 配置
type: tcp、tcp.host: "127.0.0.1"和tcp.port: 6379 - THEN 系统 SHALL 将其解析为 tcp checker,并填充
readBanner=false、bannerReadTimeout=2000、maxBannerBytes=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 序列化展示摘要
- WHEN 系统同步 tcp target 到 targets 表
- THEN
target展示摘要 SHALL 为<host>:<port>,configJSON SHALL 包含 resolved 后的 host、port、readBanner、bannerReadTimeout 和 maxBannerBytes
Requirement: tcp checker 执行
系统 SHALL 按 tcp target 配置建立 TCP 连接,记录完整执行耗时和 TCP observation,并在连接失败、超时或资源超限时产生结构化失败信息。
Scenario: TCP 连接成功
- WHEN tcp target 指向可连接的 TCP 服务,且未配置 expect 或
expect.connected为true - THEN 系统 SHALL 记录
matched=true、durationMs和包含 connected、connectTimeMs、banner 的 observation,并关闭 socket
Scenario: TCP 连接失败
- WHEN tcp target 指向不可连接的 host/port,且未配置 expect 或
expect.connected为true - THEN 系统 SHALL 记录
matched=false,observation SHALL 包含 connected=false 和错误信息,failure 的 kind 为error,phase 为connect,message 包含可读连接失败原因
Scenario: 期望端口不可达且连接失败
- WHEN tcp target 配置
expect.connected: false,且 TCP 连接失败 - THEN 系统 SHALL 记录
matched=true,observation SHALL 包含 connected=false 和实际连接失败原因,API detail SHALL 展示实际连接失败原因摘要
Scenario: 期望端口不可达但连接成功
- WHEN tcp target 配置
expect.connected: false,但 TCP 连接成功 - THEN 系统 SHALL 记录
matched=false,observation SHALL 包含 connected=true,failure 的 kind 为mismatch,phase 为connected
Scenario: TCP 执行超时
- WHEN 引擎注入的
ctx.signal在 TCP 连接或 banner 读取过程中 abort - THEN 系统 SHALL best-effort 关闭 socket,记录
matched=false,failure 的 kind 为error,phase 为connect或banner,message 包含超时信息,并在可收集时记录 observation
Scenario: duration 包含 banner 读取
- WHEN tcp target 开启
readBanner且服务端延迟发送 banner - THEN 结果中的
durationMsSHALL 覆盖连接建立、banner 等待、banner 读取和 expect 校验的完整耗时
Requirement: tcp banner 读取
系统 SHALL 仅在 tcp.readBanner: true 时读取服务端主动发送的 banner 数据,并同时受 bannerReadTimeout 和 maxBannerBytes 限制。
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 detail 截断展示
- WHEN tcp target 成功读取到较长 banner
- THEN observation.banner SHALL 保存截断后的 banner 摘要,API detail SHALL 展示截断后的 banner 摘要,避免 UI 展示过长文本
Requirement: tcp expect 校验
系统 SHALL 支持 tcp 专属 expect,包括 connected、banner 和 durationMs,并按 connected、banner、durationMs 的阶段顺序快速失败。connected SHALL 保持布尔状态语义,未配置时在 Resolved expect 中默认 true。banner MUST 使用共享 RawContentExpectations 数组输入并在运行期使用 ContentExpectations,且仅在 tcp.readBanner: true 时允许配置。durationMs SHALL 使用共享 RawValueExpectation 输入并在运行期使用 ValueExpectation 校验包含连接和 banner 读取在内的完整执行耗时。
Scenario: 默认 connected 成功语义
- WHEN tcp target 未显式配置
expect.connected - THEN 系统 SHALL 在 Resolved tcp expect 中使用默认
connected: true进行校验
Scenario: durationMs 校验
- WHEN tcp target 配置
expect.durationMs: {lte: 100},且完整执行耗时超过 100ms - THEN 系统 SHALL 返回
matched=false,failure 的 phase 为duration
Scenario: banner ContentExpectations 校验通过
- WHEN tcp target 配置
readBanner: true、expect.banner: [{contains: "ESMTP"}],且实际 banner 包含ESMTP - THEN 系统 SHALL 判定 banner 阶段通过
Scenario: banner regex 校验失败
- WHEN tcp target 配置
readBanner: true、expect.banner: [{regex: "^SSH-2\\.0"}],且实际 banner 不匹配该正则 - THEN 系统 SHALL 返回
matched=false,failure 的 kind 为mismatch,phase 为banner,path 指向失败的 banner expectation
Scenario: banner 多规则快速失败
- WHEN tcp target 配置两条 banner expectation 且第一条失败
- THEN 系统 SHALL 返回第一条失败 expectation 的 failure,并 MUST NOT 执行第二条 expectation
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 包含未知字段