mirror of
https://github.com/RuoJi6/ARTEX.git
synced 2026-10-27 17:03:49 +08:00
fix(db): 修正公司 ICP 归属用例连接关闭顺序导致的资产残留
清理注册在 t.Cleanup 里,而连接关闭用的是 defer d.Close()。defer 在函数 返回时先执行、t.Cleanup 在其后,于是两条 DELETE 全部落在**已关闭的连接** 上,错误又被 `_, _ =` 丢弃,测试资产与公司因此永久残留在库里。 该用例用 MAX(companies.id)+1 当假 TaskID 给资产打标。残留本身不会立刻报错, 但一旦这个数字与其他用例的任务 id 相撞,那个按「恰好 N 个资产」断言的用例 就会失败,而现象(某个无关测试的资产计数不对)与原因(另一个测试的连接 关闭顺序)相距极远,排查成本很高。 改为关闭连接也走 t.Cleanup 并注册在清理之前(t.Cleanup 后进先出,保证清理 先跑),同时让清理失败显式报错而不是被吞掉。 注:同一模式(defer d.Close() + 在 t.Cleanup 里写库)在 db 包另有十余处, 本次只修被实证触发的那一处。 Co-Authored-By: Claude Code <[email protected]>
This commit is contained in:
1 parent
50b7b2a05b
commit
18589b270e
1 file changed
+16
-3
@@ -233,7 +233,15 @@ func TestCompanyICPAttribution(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Skipf("postgres unavailable (%v) — skipping", err)
|
||||
}
|
||||
defer d.Close()
|
||||
// 关连接必须走 t.Cleanup 且**注册在清理之前**:t.Cleanup 是后进先出,
|
||||
// 先注册关闭 → 关闭最后执行,下面的数据清理才连得上库。
|
||||
// 原先这里是 `defer d.Close()`:defer 在函数返回时先跑,t.Cleanup 在那之后
|
||||
// 才执行,于是清理语句全落在**已关闭的连接**上、错误又被 `_, _ =` 丢弃,
|
||||
// 资产与公司就永久残留在库里。残留本身不会立刻报错,但本用例用
|
||||
// `MAX(companies.id)+1` 当假 TaskID 给资产打标(见下方 suffix),
|
||||
// 一旦这个数字与别的用例的任务 id 撞上,那个用例按「恰好 N 个资产」的断言
|
||||
// 就会莫名失败——排查成本极高。
|
||||
t.Cleanup(func() { d.Close() })
|
||||
|
||||
var suffix int64
|
||||
if err := d.QueryRow(`SELECT COALESCE(MAX(id),0)+1 FROM companies`).Scan(&suffix); err != nil {
|
||||
@@ -246,8 +254,13 @@ func TestCompanyICPAttribution(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
_, _ = d.Exec(`DELETE FROM assets WHERE task_ids @> ARRAY[$1]::bigint[]`, suffix)
|
||||
_, _ = d.Exec(`DELETE FROM companies WHERE id=$1`, companyID)
|
||||
// 不吞错误:清理失败会污染后续用例,必须让它在本次运行里显形。
|
||||
if _, err := d.Exec(`DELETE FROM assets WHERE task_ids @> ARRAY[$1]::bigint[]`, suffix); err != nil {
|
||||
t.Errorf("清理测试资产失败: %v", err)
|
||||
}
|
||||
if _, err := d.Exec(`DELETE FROM companies WHERE id=$1`, companyID); err != nil {
|
||||
t.Errorf("清理测试公司失败: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
// A keyword can guide an Agent, but must never claim an asset by its name.
|
||||
|
||||
Reference in new issue
Block a user