Skip to content

Commit b7428b7

Browse files
author
Bryan C. Mills
committed
net/http: only report the first leak of each test run
We don't have a way to terminate the leaked goroutines, and we can't wait forever for them to exit (or else we would risk timing out the test and losing the log line describing what exactly leaked). So we have reason to believe that they will remain leaked while we run the next test, and we don't want the goroutines from the first leak to generate a spurious error when the second test completes. This also removes a racy Parallel call I added in CL 476036, which was flagged by the race detector in the duplicate-suppression check. (I hadn't considered the potential interaction with the leak checker.) For #59526. Updates #56421. Change-Id: Ib1f759f102fb41ece114401680cd728343e58545 Reviewed-on: https://go-review.googlesource.com/c/go/+/483896 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com> Auto-Submit: Bryan Mills <bcmills@google.com> Run-TryBot: Bryan Mills <bcmills@google.com>
1 parent 4b154e5 commit b7428b7

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

Diff for: src/net/http/main_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,30 @@ func runningBenchmarks() bool {
108108
return false
109109
}
110110

111+
var leakReported bool
112+
111113
func afterTest(t testing.TB) {
112114
http.DefaultTransport.(*http.Transport).CloseIdleConnections()
113115
if testing.Short() {
114116
return
115117
}
118+
if leakReported {
119+
// To avoid confusion, only report the first leak of each test run.
120+
// After the first leak has been reported, we can't tell whether the leaked
121+
// goroutines are a new leak from a subsequent test or just the same
122+
// goroutines from the first leak still hanging around, and we may add a lot
123+
// of latency waiting for them to exit at the end of each test.
124+
return
125+
}
126+
127+
// We shouldn't be running the leak check for parallel tests, because we might
128+
// report the goroutines from a test that is still running as a leak from a
129+
// completely separate test that has just finished. So we use non-atomic loads
130+
// and stores for the leakReported variable, and store every time we start a
131+
// leak check so that the race detector will flag concurrent leak checks as a
132+
// race even if we don't detect any leaks.
133+
leakReported = true
134+
116135
var bad string
117136
badSubstring := map[string]string{
118137
").readLoop(": "a Transport",
@@ -132,6 +151,7 @@ func afterTest(t testing.TB) {
132151
}
133152
}
134153
if bad == "" {
154+
leakReported = false
135155
return
136156
}
137157
// Bad stuff found, but goroutines might just still be

Diff for: src/net/http/serve_test.go

-3
Original file line numberDiff line numberDiff line change
@@ -5519,9 +5519,6 @@ func testServerShutdownStateNew(t *testing.T, mode testMode) {
55195519
if testing.Short() {
55205520
t.Skip("test takes 5-6 seconds; skipping in short mode")
55215521
}
5522-
// The run helper runs the test in parallel only in short mode by default.
5523-
// Since this test has a very long latency, always run it in parallel.
5524-
t.Parallel()
55255522

55265523
var connAccepted sync.WaitGroup
55275524
ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {

0 commit comments

Comments
 (0)