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.