package httpapi import ( "context" "testing" "time" "github.com/jackc/pgx/v5/pgxpool" ) type acceptanceStatusSnapshot struct { ID string Status string } type acceptanceUserGroupSnapshot struct { ID string RateLimitPolicy []byte } // isolateHTTPAcceptanceState lets a stress test disable unrelated runtime // resources without leaking those mutations into later integration tests that // intentionally share the same dedicated test database. func isolateHTTPAcceptanceState( t *testing.T, ctx context.Context, pool *pgxpool.Pool, includeStorage bool, ) func() { t.Helper() startedAt := time.Now() platforms := readAcceptanceStatusSnapshots(t, ctx, pool, ` SELECT id::text, status FROM integration_platforms WHERE deleted_at IS NULL`) userGroups := make([]acceptanceUserGroupSnapshot, 0) rows, err := pool.Query(ctx, ` SELECT id::text, rate_limit_policy FROM gateway_user_groups`) if err != nil { t.Fatalf("snapshot acceptance user groups: %v", err) } for rows.Next() { var item acceptanceUserGroupSnapshot if err := rows.Scan(&item.ID, &item.RateLimitPolicy); err != nil { rows.Close() t.Fatalf("scan acceptance user group snapshot: %v", err) } userGroups = append(userGroups, item) } if err := rows.Err(); err != nil { rows.Close() t.Fatalf("read acceptance user group snapshots: %v", err) } rows.Close() storageChannels := []acceptanceStatusSnapshot(nil) if includeStorage { storageChannels = readAcceptanceStatusSnapshots(t, ctx, pool, ` SELECT id::text, status FROM file_storage_channels WHERE deleted_at IS NULL`) } if _, err := pool.Exec(ctx, ` UPDATE integration_platforms SET status = 'disabled' WHERE deleted_at IS NULL`); err != nil { t.Fatalf("isolate acceptance platforms: %v", err) } if includeStorage { if _, err := pool.Exec(ctx, ` UPDATE file_storage_channels SET status = 'disabled' WHERE deleted_at IS NULL`); err != nil { t.Fatalf("isolate acceptance storage channels: %v", err) } } return func() { restoreCtx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() tx, err := pool.Begin(restoreCtx) if err != nil { t.Errorf("begin acceptance state restore: %v", err) return } defer func() { _ = tx.Rollback(restoreCtx) }() for _, item := range platforms { if _, err := tx.Exec(restoreCtx, ` UPDATE integration_platforms SET status = $2 WHERE id = $1::uuid`, item.ID, item.Status); err != nil { t.Errorf("restore acceptance platform %s: %v", item.ID, err) return } } if _, err := tx.Exec(restoreCtx, ` UPDATE integration_platforms SET status = 'disabled' WHERE created_at >= $1 AND deleted_at IS NULL`, startedAt); err != nil { t.Errorf("disable acceptance-created platforms: %v", err) return } for _, item := range userGroups { if _, err := tx.Exec(restoreCtx, ` UPDATE gateway_user_groups SET rate_limit_policy = $2::jsonb WHERE id = $1::uuid`, item.ID, string(item.RateLimitPolicy)); err != nil { t.Errorf("restore acceptance user group %s: %v", item.ID, err) return } } if includeStorage { for _, item := range storageChannels { if _, err := tx.Exec(restoreCtx, ` UPDATE file_storage_channels SET status = $2 WHERE id = $1::uuid`, item.ID, item.Status); err != nil { t.Errorf("restore acceptance storage channel %s: %v", item.ID, err) return } } if _, err := tx.Exec(restoreCtx, ` UPDATE file_storage_channels SET status = 'disabled' WHERE created_at >= $1 AND deleted_at IS NULL`, startedAt); err != nil { t.Errorf("disable acceptance-created storage channels: %v", err) return } } if err := tx.Commit(restoreCtx); err != nil { t.Errorf("commit acceptance state restore: %v", err) } } } func readAcceptanceStatusSnapshots( t *testing.T, ctx context.Context, pool *pgxpool.Pool, query string, ) []acceptanceStatusSnapshot { t.Helper() rows, err := pool.Query(ctx, query) if err != nil { t.Fatalf("snapshot acceptance statuses: %v", err) } defer rows.Close() items := make([]acceptanceStatusSnapshot, 0) for rows.Next() { var item acceptanceStatusSnapshot if err := rows.Scan(&item.ID, &item.Status); err != nil { t.Fatalf("scan acceptance status snapshot: %v", err) } items = append(items, item) } if err := rows.Err(); err != nil { t.Fatalf("read acceptance status snapshots: %v", err) } return items }