fix(handlers): add timeouts to all DB operations in integration tests
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 9s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 11s
CI / Detect changes (pull_request) Successful in 27s
E2E API Smoke Test / detect-changes (pull_request) Successful in 28s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 30s
Harness Replays / detect-changes (pull_request) Successful in 27s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 32s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 12s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 26s
sop-checklist / all-items-acked (pull_request) [soft-fail tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: 2
qa-review / approved (pull_request) Failing after 13s
sop-checklist-gate / gate (pull_request) Successful in 14s
security-review / approved (pull_request) Failing after 15s
gate-check-v3 / gate-check (pull_request) Successful in 20s
CI / Canvas (Next.js) (pull_request) Successful in 4s
sop-tier-check / tier-check (pull_request) Successful in 11s
CI / Python Lint & Test (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 5s
Harness Replays / Harness Replays (pull_request) Successful in 5s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 12s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 6s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 39s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Failing after 1m11s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m20s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m26s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m33s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Failing after 3m13s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Failing after 3m17s
CI / Platform (Go) (pull_request) Failing after 5m27s
CI / all-required (pull_request) Failing after 1s

Add 10s timeouts to integrationDB and setupIntegrationFixtures DB
operations, and a 5s timeout to the cleanup DELETEs. The raw TCP
mock server was confirmed working (tests pass in 5-8s when they pass),
but some CI runs hang for 2+ minutes. Adding timeouts ensures that if
DB operations block, the test fails cleanly with a timeout message
rather than hanging the CI job. This also makes the tests more
resilient to transient postgres slowness under CI runner load.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Molecule AI · core-be 2026-05-12 15:58:38 +00:00
parent 26e9f158c6
commit d60da43cd7
2 changed files with 22 additions and 9 deletions

View File

@ -163,6 +163,7 @@ func buildHTTPResponse(statusCode int, body string) []byte {
// Returns a cleanup function the test should defer.
func setupIntegrationFixtures(t *testing.T, conn *sql.DB) func() {
t.Helper()
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
for _, ws := range []struct {
id string
name string
@ -171,10 +172,11 @@ func setupIntegrationFixtures(t *testing.T, conn *sql.DB) func() {
{testSourceID, "test-source", nil},
{testTargetID, "test-target", nil},
} {
if _, err := conn.ExecContext(context.Background(),
if _, err := conn.ExecContext(ctx,
`INSERT INTO workspaces (id, name, parent_id) VALUES ($1::uuid, $2, $3) ON CONFLICT (id) DO NOTHING`,
ws.id, ws.name, ws.parentID,
); err != nil {
cancel()
t.Fatalf("seed workspace %s: %v", ws.id, err)
}
}
@ -183,31 +185,36 @@ func setupIntegrationFixtures(t *testing.T, conn *sql.DB) func() {
"delegation_id": testDelegationID,
"task": "do work",
})
if _, err := conn.ExecContext(context.Background(), `
if _, err := conn.ExecContext(ctx, `
INSERT INTO activity_logs
(workspace_id, activity_type, method, source_id, target_id, request_body, status)
VALUES ($1, 'delegate', 'delegate', $1, $2, $3::jsonb, 'pending')
ON CONFLICT DO NOTHING
`, testSourceID, testTargetID, string(reqBody)); err != nil {
cancel()
t.Fatalf("seed activity_logs: %v", err)
}
if _, err := conn.ExecContext(context.Background(), `
if _, err := conn.ExecContext(ctx, `
INSERT INTO delegations
(delegation_id, caller_id, callee_id, task_preview, status)
VALUES ($1, $2::uuid, $3::uuid, 'do work', 'queued')
ON CONFLICT (delegation_id) DO NOTHING
`, testDelegationID, testSourceID, testTargetID); err != nil {
cancel()
t.Fatalf("seed delegations: %v", err)
}
cancel()
return func() {
conn.ExecContext(context.Background(),
ctx2, cancel2 := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel2()
conn.ExecContext(ctx2,
`DELETE FROM activity_logs WHERE workspace_id = $1 AND request_body->>'delegation_id' = $2`,
testSourceID, testDelegationID)
conn.ExecContext(context.Background(),
conn.ExecContext(ctx2,
`DELETE FROM delegations WHERE delegation_id = $1`, testDelegationID)
conn.ExecContext(context.Background(),
conn.ExecContext(ctx2,
`DELETE FROM workspaces WHERE id IN ($1, $2)`, testSourceID, testTargetID)
}
}
@ -216,8 +223,10 @@ func setupIntegrationFixtures(t *testing.T, conn *sql.DB) func() {
// delegation, or fails the test if the row is not found.
func readDelegationRow(t *testing.T, conn *sql.DB) (status, preview, errorDetail string) {
t.Helper()
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
var prev, errDet sql.NullString
err := conn.QueryRowContext(context.Background(),
err := conn.QueryRowContext(ctx,
`SELECT status, result_preview, error_detail FROM delegations WHERE delegation_id = $1`,
testDelegationID,
).Scan(&status, &prev, &errDet)

View File

@ -64,12 +64,16 @@ func integrationDB(t *testing.T) *sql.DB {
if err != nil {
t.Fatalf("open: %v", err)
}
if err := conn.Ping(); err != nil {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := conn.PingContext(ctx); err != nil {
t.Fatalf("ping: %v", err)
}
// Each test gets a fresh table state — fail loud if cleanup fails so
// a bad test doesn't pollute the next one.
if _, err := conn.ExecContext(context.Background(), `DELETE FROM delegations`); err != nil {
ctx2, cancel2 := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel2()
if _, err := conn.ExecContext(ctx2, `DELETE FROM delegations`); err != nil {
t.Fatalf("cleanup: %v", err)
}
// Wire the package-level db.DB so production helpers (recordLedgerInsert,