Testing
blockingtest
Checks cancellation ownership for blocking test channels.
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{} }}