From e924732a02161102374d87aa9230615c446e293a Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Sat, 16 May 2026 21:45:08 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=20defaults.http.?= =?UTF-8?q?method=20=E9=85=8D=E7=BD=AE=EF=BC=8C=E7=AE=80=E5=8C=96=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=E4=BD=93=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - HTTP checker defaults schema 不再支持 method 字段 - resolve 逻辑从三级 fallback 简化为两级(target -> 内置默认) - 配置文件中出现 defaults.http.method 将触发未知字段校验错误 - per-target http.method 覆盖功能保持不变 - 同步更新示例配置、README 文档和测试用例 --- README.md | 17 ++++++------ openspec/specs/probe-config/spec.md | 14 ++++++++++ probe-config.schema.json | 32 ---------------------- probes.example.yaml | 1 - src/server/checker/runner/http/execute.ts | 4 +-- src/server/checker/runner/http/schema.ts | 1 - tests/server/checker/config-loader.test.ts | 11 ++++---- 7 files changed, 29 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 86d77f1..78fe682 100644 --- a/README.md +++ b/README.md @@ -142,15 +142,14 @@ targets: #### defaults — 全局默认值(均可省略) -| 字段 | 说明 | 默认值 | -| -------------------- | -------------------------------------------------------------------- | ------- | -| `interval` | 拨测间隔 | `30s` | -| `timeout` | 超时时间 | `10s` | -| `http.method` | HTTP 方法,支持 `GET`/`HEAD`/`POST`/`PUT`/`PATCH`/`DELETE`/`OPTIONS` | `GET` | -| `http.maxBodyBytes` | 响应体最大字节数 | `100MB` | -| `http.headers` | 默认请求头(target 中的 headers 会合并覆盖同名头) | — | -| `cmd.maxOutputBytes` | 输出最大字节数 | `100MB` | -| `cmd.cwd` | 默认工作目录(相对于配置文件所在目录) | `.` | +| 字段 | 说明 | 默认值 | +| -------------------- | -------------------------------------------------- | ------- | +| `interval` | 拨测间隔 | `30s` | +| `timeout` | 超时时间 | `10s` | +| `http.maxBodyBytes` | 响应体最大字节数 | `100MB` | +| `http.headers` | 默认请求头(target 中的 headers 会合并覆盖同名头) | — | +| `cmd.maxOutputBytes` | 输出最大字节数 | `100MB` | +| `cmd.cwd` | 默认工作目录(相对于配置文件所在目录) | `.` | #### targets — 拨测目标列表(必填) diff --git a/openspec/specs/probe-config/spec.md b/openspec/specs/probe-config/spec.md index 324b0ac..37203e5 100644 --- a/openspec/specs/probe-config/spec.md +++ b/openspec/specs/probe-config/spec.md @@ -7,6 +7,8 @@ ### Requirement: YAML 配置文件格式 系统 SHALL 支持通过 YAML 配置文件定义全部运行参数,包括 server 配置、runtime 配置、checker 默认值和 typed target 列表(含可选 group 字段)。target MUST 使用 `type` 字段声明 checker 类型,HTTP 领域字段 MUST 放在 `http` 分组,cmd 领域字段 MUST 放在 `cmd` 分组,db 领域字段 MUST 放在 `db` 分组。HTTP target 的 `http` 分组 SHALL 支持可选的 `ignoreSSL`(布尔值)和 `maxRedirects`(非负整数)字段。Db target 的 `db` 分组 SHALL 支持 `url`(必填)和 `query`(可选)字段。 +`defaults.http` 分组 SHALL 仅支持 `headers`(可选)和 `maxBodyBytes`(可选)字段。`defaults.http` 分组 MUST NOT 支持 `method` 字段。 + #### Scenario: 完整配置文件解析 - **WHEN** 系统启动并读取包含 server、runtime、defaults、targets(含 group 字段)的 YAML 配置文件 - **THEN** 系统 SHALL 正确解析所有字段并用于初始化服务、调度引擎和对应 checker runner @@ -35,6 +37,18 @@ - **WHEN** 系统读取只包含一个 `type: db` target 和 `db.url` 的 YAML 配置文件 - **THEN** 系统 SHALL 使用内置默认值填充未指定的字段(interval=30s, timeout=10s, group="default") +#### Scenario: defaults.http.method 触发校验错误 +- **WHEN** 配置文件中出现 `defaults.http.method` 字段 +- **THEN** 系统 SHALL 以配置错误退出,提示 defaults.http 中存在未知字段 method + +#### Scenario: per-target http.method 仍然有效 +- **WHEN** HTTP target 配置 `http.method: POST` +- **THEN** 系统 SHALL 使用 POST 作为该 target 的请求方法 + +#### Scenario: 未配置 http.method 使用内置默认值 +- **WHEN** HTTP target 未配置 `http.method` 且 defaults.http 中无 method 字段 +- **THEN** 系统 SHALL 使用内置默认值 GET 作为该 target 的请求方法 + ### Requirement: CLI 参数 系统 SHALL 通过单一命令行参数接受 YAML 配置文件路径。 diff --git a/probe-config.schema.json b/probe-config.schema.json index 1d4e583..43a0700 100644 --- a/probe-config.schema.json +++ b/probe-config.schema.json @@ -35,38 +35,6 @@ "type": "integer" } ] - }, - "method": { - "anyOf": [ - { - "const": "DELETE", - "type": "string" - }, - { - "const": "GET", - "type": "string" - }, - { - "const": "HEAD", - "type": "string" - }, - { - "const": "OPTIONS", - "type": "string" - }, - { - "const": "PATCH", - "type": "string" - }, - { - "const": "POST", - "type": "string" - }, - { - "const": "PUT", - "type": "string" - } - ] } } }, diff --git a/probes.example.yaml b/probes.example.yaml index a082492..a4a4f77 100644 --- a/probes.example.yaml +++ b/probes.example.yaml @@ -10,7 +10,6 @@ defaults: interval: "30s" timeout: "10s" http: - method: GET maxBodyBytes: "10MB" cmd: maxOutputBytes: "1MB" diff --git a/src/server/checker/runner/http/execute.ts b/src/server/checker/runner/http/execute.ts index 7af183a..5f39f76 100644 --- a/src/server/checker/runner/http/execute.ts +++ b/src/server/checker/runner/http/execute.ts @@ -105,9 +105,9 @@ export class HttpChecker implements CheckerDefinition { const t = target as RawTargetConfig & { http: HttpTargetConfig; type: "http" }; const httpDefaults = context.defaults["http"] as | undefined - | { headers?: Record; maxBodyBytes?: string; method?: string }; + | { headers?: Record; maxBodyBytes?: string }; - const method = t.http.method ?? httpDefaults?.method ?? "GET"; + const method = t.http.method ?? "GET"; const maxBodyBytes = parseSize(t.http.maxBodyBytes ?? httpDefaults?.maxBodyBytes ?? "100MB"); return { diff --git a/src/server/checker/runner/http/schema.ts b/src/server/checker/runner/http/schema.ts index 6f5ce50..da8f2f1 100644 --- a/src/server/checker/runner/http/schema.ts +++ b/src/server/checker/runner/http/schema.ts @@ -28,7 +28,6 @@ export const httpCheckerSchemas: CheckerSchemas = { { headers: Type.Optional(stringMapSchema), maxBodyBytes: Type.Optional(sizeSchema), - method: Type.Optional(httpMethodSchema), }, { additionalProperties: false }, ), diff --git a/tests/server/checker/config-loader.test.ts b/tests/server/checker/config-loader.test.ts index 52e0203..b5d140c 100644 --- a/tests/server/checker/config-loader.test.ts +++ b/tests/server/checker/config-loader.test.ts @@ -173,7 +173,6 @@ defaults: interval: "15s" timeout: "5s" http: - method: "POST" headers: Authorization: "Bearer token" maxBodyBytes: "50MB" @@ -186,6 +185,7 @@ targets: interval: "1m" http: url: "http://example.com" + method: "POST" ignoreSSL: true maxRedirects: 5 expect: @@ -255,7 +255,6 @@ targets: interval: "30s" timeout: "10s" http: - method: "GET" maxBodyBytes: "10MB" targets: - name: "override-all" @@ -1038,19 +1037,19 @@ targets: ); }); - test("defaults.http.method 小写输入失败", async () => { + test("defaults.http.method 触发未知字段错误", async () => { await expectConfigError( - "lowercase-default-method.yaml", + "unknown-default-method.yaml", `defaults: http: - method: post + method: POST targets: - name: "test" type: http http: url: "http://example.com" `, - "defaults.http.method 不在允许范围内", + "defaults.http.method 是未知字段", ); });