Failnow Goroutine

ID

go.failnow_goroutine

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Go

Tags

concurrency, reliability

Description

Reports a t.FailNow() or t.SkipNow() call placed inside the body of a goroutine started with go func() { …​ }().

Rationale

FailNow and SkipNow (and the Fatal/Fatalf helpers built on them) stop the test by calling runtime.Goexit on the current goroutine. When they run inside a goroutine other than the one running the test, only that goroutine is terminated; the test goroutine keeps going and the failure may be silently lost — the test can even report success. The reporting methods Error, Errorf and Log are safe to call from any goroutine.

go func() {
    t.FailNow()      // FLAW — terminates only this goroutine
}()

go func() {
    t.Errorf("bad")  // OK — Errorf is goroutine-safe
}()

t.FailNow()          // OK — runs on the test goroutine

Remediation

Inside a goroutine, report the failure with t.Error/t.Errorf and return, or signal the test goroutine (for example over a channel) and call FailNow there.