- 引入共享 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
9.1 KiB
Purpose
定义 db 类型拨测目标的配置格式、执行逻辑、expect 断言规则和启动期校验。
Requirements
Requirement: db target 配置
系统 SHALL 支持 type: db 的 target 配置,通过 db.url 描述数据库连接字符串(遵循 Bun SQL 支持的格式),通过可选的 db.query 描述待执行的 SQL 语句。
Scenario: 解析仅连接的 db target
- WHEN YAML 中 target 配置
type: db和db.url: "postgres://user:pass@localhost:5432/mydb",未配置db.query - THEN 系统 SHALL 将其解析为 db checker,仅执行连通性检测
Scenario: 解析带查询的 db target
- WHEN YAML 中 target 配置
type: db、db.url: "mysql://user:pass@host:3306/app"和db.query: "SELECT count(*) as cnt FROM users" - THEN 系统 SHALL 将其解析为 db checker,执行连通性检测后执行指定 SQL 并进入 expect 校验
Scenario: db target 缺少 url
- WHEN YAML 中 target 配置
type: db但缺少db.url - THEN 系统 SHALL 以配置错误退出,并提示该 target 缺少 db.url 字段
Scenario: db.url 为空字符串
- WHEN YAML 中 target 配置
db.url: "" - THEN 系统 SHALL 以配置错误退出,并提示 db.url 不能为空
Scenario: db.query 为空字符串
- WHEN YAML 中 target 配置
db.query: "" - THEN 系统 SHALL 以配置错误退出,并提示 db.query 不能为空字符串(如不需要查询则不配置该字段)
Scenario: db 分组未知字段失败
- WHEN YAML 中 db target 的
db分组包含timeout: 5等未知字段 - THEN 系统 SHALL 以配置错误退出,提示 db 分组包含未知字段
Scenario: SQLite 连接字符串
- WHEN YAML 中 target 配置
db.url: "sqlite:///data/app.db" - THEN 系统 SHALL 将其解析为 db checker,使用 SQLite 文件数据库
Scenario: url 格式由 Bun 运行时校验
- WHEN YAML 中 target 配置
db.url为 Bun 不支持的格式 - THEN 系统 SHALL 在执行阶段捕获连接错误并作为 phase="connect" 的 failure 返回,而非在启动期校验 URL 格式
Requirement: db checker 执行
系统 SHALL 按 db target 配置连接数据库并执行查询,每次执行都新建连接并在完成后关闭。连接能力本身作为监控指标。
Scenario: 仅连接测试成功
- WHEN db target 未配置
db.query且数据库连接成功 - THEN 系统 SHALL 内部执行
SELECT 1验证连通性,记录matched=true和durationMs
Scenario: 连接失败
- WHEN db target 的数据库连接失败(网络不通、认证错误、数据库不存在等)
- THEN 系统 SHALL 记录
matched=false,failure 的 phase 为"connect",message 包含可读错误信息
Scenario: 查询执行成功
- WHEN db target 配置了
db.query且 SQL 执行成功返回结果集 - THEN 系统 SHALL 记录
durationMs(从连接开始到查询完成),并进入 expect 校验
Scenario: 查询执行失败
- WHEN db target 配置了
db.query且 SQL 执行报错(语法错误、权限不足、表不存在等) - THEN 系统 SHALL 记录
matched=false,failure 的 phase 为"query",message 包含数据库返回的错误信息
Scenario: 执行超时
- WHEN db target 在 timeout 时间内未完成(连接或查询)
- THEN 系统 SHALL 关闭连接,记录
matched=false,failure 的 phase 为"connect"或"query"(取决于超时发生的阶段),message 包含超时信息
Scenario: 每次执行新建连接
- WHEN db target 被引擎调度执行
- THEN 系统 SHALL 创建新的 SQL 连接实例(max: 1),执行完成后立即关闭连接(close timeout: 0)
Scenario: 使用 unsafe 执行用户 SQL
- WHEN db target 配置了
db.query - THEN 系统 SHALL 使用
sql.unsafe(query)执行用户配置的 SQL 文本,不限制 SQL 类型
Scenario: 响应 abort signal
- WHEN 引擎注入的
ctx.signal被 abort - THEN 系统 SHALL 立即关闭数据库连接
Requirement: db expect 校验
系统 SHALL 支持 db 专用 expect,包括 durationMs、rowCount、rows 和 result,按 durationMs、rowCount、rows、result 的阶段顺序快速失败。durationMs 和 rowCount SHALL 使用共享 ValueMatcher。rows SHALL 保留按行索引匹配列值的语义,类型为 Array<KeyValueExpect>(外层数组按行索引,内层每个元素为一个 KeyValueExpect 表达该行的列值断言),每个行规则中列值字面量等价于 {equals: <literal>}。result MUST 使用共享 ContentRules 数组,对查询结果对象 { rows, rowCount } 执行断言。
Scenario: durationMs 校验
- WHEN db target 配置
expect.durationMs: {lte: 3000}且实际执行耗时 4000ms - THEN 系统 SHALL 返回
matched=false,failure 的 phase 为duration
Scenario: rowCount 校验通过
- WHEN db target 配置
expect.rowCount: { gte: 1 }且查询返回 5 行 - THEN 系统 SHALL 判定 rowCount 阶段通过,继续后续 expect 阶段
Scenario: rowCount 校验失败
- WHEN db target 配置
expect.rowCount: { gte: 1 }且查询返回 0 行 - THEN 系统 SHALL 返回
matched=false,failure 的 phase 为rowCount,path 为rowCount,expected 为{ gte: 1 },actual 为 0
Scenario: rows 按索引匹配列值 matcher 形式
- WHEN db target 配置
expect.rows: [{ cnt: { gte: 100 } }]且查询首行 cnt 列值为 50 - THEN 系统 SHALL 返回
matched=false,failure 的 phase 为row,path 为rows[0].cnt
Scenario: rows 按索引匹配列值字面量形式
- WHEN db target 配置
expect.rows: [{ status: "active" }]且查询首行 status 列值为"active" - THEN 系统 SHALL 判定该行该列通过(字面量等价于
{ equals: "active" })
Scenario: rows 只检查声明的列
- WHEN db target 配置
expect.rows: [{ cnt: { gte: 1 } }]且查询首行包含 cnt、name、age 三列 - THEN 系统 SHALL 仅检查 cnt 列,忽略 name 和 age 列
Scenario: rows 结果行数不足
- WHEN db target 配置
expect.rows包含 3 个元素但查询仅返回 2 行 - THEN 系统 SHALL 返回
matched=false,failure 的 phase 为row,message 说明结果行数不足
Scenario: result JSONPath 校验
- WHEN db target 查询返回首行
{status: "active"}且配置expect.result: [{json: {path: "$.rows[0].status", equals: "active"}}] - THEN 系统 SHALL 基于
{rows, rowCount}结果对象执行 JSONPath,并判定 result 阶段通过
Scenario: result rowCount 校验
- WHEN db target 查询返回 2 行且配置
expect.result: [{json: {path: "$.rowCount", equals: 2}}] - THEN 系统 SHALL 判定 result 阶段通过
Scenario: 无 query 时结果类 expect 被忽略
- WHEN db target 未配置
db.query但配置了expect.rowCount、expect.rows或expect.result - THEN 系统 SHALL 忽略这些查询结果断言(仅
durationMs生效)
Scenario: 快速失败顺序
- WHEN db target 同时配置 durationMs、rowCount、rows 和 result
- THEN 系统 SHALL 按 durationMs → rowCount → rows → result 顺序校验,任一阶段失败立即返回
Requirement: db checker 启动期配置校验
系统 SHALL 在启动期对 db checker 的配置契约和语义执行严格校验。Db target 的 db 分组 SHALL 只允许 url 和 query 字段。Db expect SHALL 只允许 durationMs、rowCount、rows 和 result 字段。未知字段、非法 matcher、非法 ContentRules、非法 regex 和 ReDoS 风险正则 MUST 导致启动期配置错误。
Scenario: db expect durationMs 非法
- WHEN YAML 中 db target 配置
expect.durationMs不是合法ValueMatcher - THEN 系统 SHALL 以配置错误退出,提示 expect.durationMs 格式错误
Scenario: db expect rowCount 非法
- WHEN YAML 中 db target 配置
expect.rowCount不是合法ValueMatcher - THEN 系统 SHALL 以配置错误退出,提示 expect.rowCount 格式错误
Scenario: db expect rows 非法
- WHEN YAML 中 db target 配置
expect.rows不是对象数组 - THEN 系统 SHALL 以配置错误退出,提示 expect.rows 必须为对象数组
Scenario: db expect rows 元素列值非法
- WHEN YAML 中 db target 配置
expect.rows: [{ cnt: { foo: 1 } }],其中 foo 不是合法 matcher - THEN 系统 SHALL 以配置错误退出,提示 rows 中包含未知 matcher
Scenario: db expect result 非法
- WHEN YAML 中 db target 配置
expect.result不是合法 ContentRules 数组 - THEN 系统 SHALL 以配置错误退出,提示 expect.result 格式错误
Scenario: db expect 未知字段失败
- WHEN YAML 中 db target 的 expect 包含
status: [200]、maxDurationMs: 1000或其他非 db expect 字段 - THEN 系统 SHALL 以配置错误退出,提示 expect 包含未知字段
Scenario: db expect rows 中 regex 正则非法
- WHEN YAML 中 db target 配置
expect.rows: [{ name: { regex: "[invalid" } }] - THEN 系统 SHALL 在启动期配置校验失败,而不是延迟到运行期抛错