Skip to content
Testing

blockingtest

Checks cancellation ownership for blocking test channels.

AvailabilityOpt-in
Fix offeredNo

What it detects

Reports blocking channel receives and selects in test code when they have no cancellation or timer escape. It also reports unguarded sends in context-aware test helpers.

Checks

Check What it detects
send*
Reports unguarded channel sends in context-aware test code.
receive*
Reports blocking channel receives in tests without a cancellation escape.
select*
Reports blocking selects in tests without a cancellation escape.

* Opt-in; requires explicit selection.

Why this is flagged

An unconditional wait can leave a test stuck forever when the expected event never happens. A cancellation or timeout path lets the test stop promptly and report a useful failure instead of hanging the entire test run.

Further reading: Go concurrency patterns: Pipelines and cancellation, Timing out, moving on.

How to fix it

Wait with a select that also listens for the test context or a bounded timeout. If cancellation wins, stop the test with a message that explains what it was waiting for.

Examples

Flagged code

func waitForEvent(t *testing.T, events <-chan Event) Event {
// gohawk: blocking channel receive in test code requires cancellation-aware select
return <-events
}

Accepted code

func waitForEventSafely(t *testing.T, events <-chan Event) Event {
t.Helper()
select {
case event := <-events:
return event
case <-t.Context().Done():
t.Fatal("timed out waiting for event")
return Event{}
}
}