fix(test): finish v9 postgres gate coverage
Staging Backend Quality Gate / validate (push) Successful in 12m9s
Staging Backend Quality Gate / publish (push) Successful in 8m42s

This commit is contained in:
Jesse_Chen
2026-08-11 19:57:28 +08:00
parent 48a4240bdf
commit 1e8fc6c208
2 changed files with 13 additions and 13 deletions
+4 -4
View File
@@ -2851,7 +2851,7 @@
## BUG-166 | V9 Docker DB 测试在 staging gate 失败:service 连接池未按 URL 关闭 + fixture 种子角色越权
- 状态:investigating(本地已修复 + 非 Docker 单测通过;Gitea Docker gate 复跑确认前不标记 resolved
- 状态:resolved(本地 Docker PostgreSQL fixture 复跑通过,待 Gitea gate
- 首次发现:2026-08-11Gitea staging gate run 1732
- 最近更新:2026-08-11
- 影响面:`frontend/tests/rectification-v9-database.test.ts``frontend/src/lib/db/local-postgres-client-core.ts` 的按 URL 连接池生命周期
@@ -2859,13 +2859,13 @@
- 触发条件:在 CIDocker fixture)中运行 `rectification-v9-database.test.ts`
- 根因(脱敏):
1. 两个测试创建了 `createLocalPostgresDataClient` 的 service 客户端后没有关闭其全局按 URL 缓存的连接池;`fixture.stop()` 先销毁 PostgreSQL,池的异步终止随后触发 57P01terminating connection)类报错。不能全局关闭所有池(node:test 的 DB 用例可能并发),必须按各自 service URL 关闭,且任何情况下 `fixture.stop()` 都要执行。
2. 最后一个 “v9 agent api migration…” 测试用 `identity_runtime` 角色向 `public.profiles/chat_sessions/agentic_rectification_cases/agentic_rectification_turns` 播种 fixture 行;生产最小权限正确拒绝了这些写入。
2. 最后一个 “v9 agent api migration…” 测试用 `identity_runtime` 角色向 `public.profiles/chat_sessions/agentic_rectification_cases/agentic_rectification_turns` 播种 fixture 行;生产最小权限正确拒绝了这些写入。该用例还重复插入由 identity→auth→profile 触发器已自动创建的 profile,把 JavaScript `.repeat()` 写进 SQL,并错误期待未 grounded 的 consent quote 进入候选查询。
- 修复:
1. 审查并保留新增的 `closeLocalPostgresDataPool(connectionString)`:先按 key 从全局缓存删除再 `pool.end()`,未知 key 与重复关闭均为安全 no-op,删除后再注册同名 key 可创建新池,与全局 `closeLocalPostgresDataPools` 并发/先后调用无冲突(end 幂等)。
2. `rectification-v9-database.test.ts` 中所有创建 service 客户端的测试(open / profile gating / evidence / backfill / agent api,共 5 个)在 `finally` 中先 `await closeLocalPostgresDataPool(service_url)``fixture.stop()`,嵌套 try/finally 保证池关闭失败时 fixture 仍会停止;纯迁移测试无需关闭。
3. 最后一个测试的 fixture 行改为:先经合法的 `identity_runtime` 播种 `identity.users`(同步到 `auth.users` 以满足 profiles FK,与文件内其它测试一致),再通过 `fixture.psql`postgres admin)播种 `public.*` 行,保留生产最小权限,不改任何 grant、不改迁移。
3. 最后一个测试先经合法的 `identity_runtime` 播种 `identity.users`,再由 postgres admin 更新触发器自动创建的 profile 并播种其它 `public.*` 行;同时改用模板中的既有 fingerprint,并按 RPC 真实合同断言 consent grounding 失败。保留生产最小权限,不改任何 grant、不改迁移。
4. 新增非 Docker 单测 `tests/local-postgres-pool-close.test.ts`4 项):未知 key no-op、按 key 关闭互不影响、关闭后同 key 可重建、全局关闭后再按 key 关闭 no-op。
- 验证(本地可执行部分)`local-postgres-pool-close.test.ts` 4/4 通过;目标 ESLint 0 error`git diff --check` 通过;tsc 对触碰文件无新错误。本机无 DockerDocker fixture 套件无法本地执行 —— 真实 Docker 复跑证据待 Gitea gate 下一次运行提供,故状态保持 investigating
- 验证:`local-postgres-pool-close.test.ts` 4/4 通过;本地 Docker PostgreSQL fixture 的 `rectification-v9-database.test.ts` 6/6 通过;目标 ESLint 0 error`git diff --check` 通过。Gitea gate 仍需对最终提交复跑
- 防复发:任何测试创建本地数据客户端必须在 `fixture.stop()` 之前按自身 service URL 关闭连接池;测试不得用 `identity_runtime``public.*` 播种 fixture 行(一律走 postgres admin 的 `fixture.psql`);禁止为测试放宽运行时 grant 或改迁移。
- 相关记录:BUG-163、BUG-164、BUG-165
- 修复版本:本地 staging 候选(未 push / deploy
@@ -824,10 +824,12 @@ test("v9 agent api migration applies, seeds the runtime flag and guards consent"
values ('66666666-6666-4666-8666-666666666666', 'V9 Agent API Fixture', 'v9-agent-api-fixture@example.com', true, now())
`);
fixture.psql(`
insert into public.profiles (id, birth_date, reported_birth_time, active_birth_time, birth_time_source,
uncertainty_before_minutes, uncertainty_after_minutes, latitude, longitude, timezone_offset)
values ('66666666-6666-4666-8666-666666666666', '1997-08-08', '05:00', null, 'family_exact',
10, 10, 36.420487, 114.209936, 8);
update public.profiles
set birth_date = '1997-08-08', reported_birth_time = '05:00', active_birth_time = null,
birth_time_source = 'family_exact', uncertainty_before_minutes = 10,
uncertainty_after_minutes = 10, latitude = 36.420487,
longitude = 114.209936, timezone_offset = 8
where id = '66666666-6666-4666-8666-666666666666';
`);
fixture.psql(`
insert into public.chat_sessions (id, user_id, title, theme, session_type, messages)
@@ -840,7 +842,7 @@ test("v9 agent api migration applies, seeds the runtime flag and guards consent"
) values (
'11111111-1111-4111-8111-111111111111', '66666666-6666-4666-8666-666666666666',
'22222222-2222-4222-8222-222222222222', 'draft', 'jyotish-birth-time-rectification', '9.0.0',
'a'.repeat(64),
'${fingerprint}',
'{"birth_date":"1997-08-08","latitude":36.420487,"longitude":114.209936,"timezone_offset":8,"birth_time_source":"family_exact"}'::jsonb,
'{"start_time":"04:50","end_time":"05:10"}'::jsonb
);
@@ -885,7 +887,7 @@ test("v9 agent api migration applies, seeds the runtime flag and guards consent"
assert.equal(receiptRow.status, "completed");
assert.equal(receiptRow.skill_version, "9.0.0");
// Consent-less confirmation is rejected even with a confirmable result.
// Consent must be grounded in the source turn before candidate lookup.
const consent = await service.rpc("confirm_agentic_rectification_birth_time", {
p_user_id: "66666666-6666-4666-8666-666666666666",
p_case_id: "11111111-1111-4111-8111-111111111111",
@@ -894,9 +896,7 @@ test("v9 agent api migration applies, seeds the runtime flag and guards consent"
p_consent_quote: "就用05:02",
p_source_turn_id: "33333333-3333-4333-8333-333333333333",
});
assert.equal(consent.error, null);
const consentRow = consent.data as { error?: unknown };
assert.equal(consentRow.error, "agentic_rectification_candidate_not_found");
assert.match(rpcError(consent.error), /agentic_rectification_consent_not_grounded/);
} finally {
try {
await closeLocalPostgresDataPool(