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
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:
parent
26e9f158c6
commit
d60da43cd7
@ -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)
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user