1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
18 func TestMain(m
*testing
.M
) {
20 if v
== 0 && goroutineLeaked() {
26 func interestingGoroutines() (gs
[]string) {
27 buf
:= make([]byte, 2<<20)
28 buf
= buf
[:runtime
.Stack(buf
, true)]
29 for _
, g
:= range strings
.Split(string(buf
), "\n\n") {
30 sl
:= strings
.SplitN(g
, "\n", 2)
34 stack
:= strings
.TrimSpace(sl
[1])
36 strings
.Contains(stack
, "created by net.startServer") ||
37 strings
.Contains(stack
, "created by testing.RunTests") ||
38 strings
.Contains(stack
, "closeWriteAndWait") ||
39 strings
.Contains(stack
, "testing.Main(") ||
40 // These only show up with GOTRACEBACK=2; Issue 5005 (comment 28)
41 strings
.Contains(stack
, "runtime.goexit") ||
42 strings
.Contains(stack
, "created by runtime.gc") ||
43 strings
.Contains(stack
, "net/http_test.interestingGoroutines") ||
44 strings
.Contains(stack
, "runtime.MHeap_Scavenger") {
47 gs
= append(gs
, stack
)
53 // Verify the other tests didn't leave any goroutines running.
54 func goroutineLeaked() bool {
56 // not counting goroutines for leakage in -short mode
59 gs
:= interestingGoroutines()
62 stackCount
:= make(map[string]int)
63 for _
, g
:= range gs
{
71 fmt
.Fprintf(os
.Stderr
, "Too many goroutines running after net/http test(s).\n")
72 for stack
, count
:= range stackCount
{
73 fmt
.Fprintf(os
.Stderr
, "%d instances of:\n%s\n", count
, stack
)
78 func afterTest(t
*testing
.T
) {
79 http
.DefaultTransport
.(*http
.Transport
).CloseIdleConnections()
84 badSubstring
:= map[string]string{
85 ").readLoop(": "a Transport",
86 ").writeLoop(": "a Transport",
87 "created by net/http/httptest.(*Server).Start": "an httptest.Server",
88 "timeoutHandler": "a TimeoutHandler",
89 "net.(*netFD).connect(": "a timing out dial",
90 ").noteClientGone(": "a closenotifier sender",
93 for i
:= 0; i
< 4; i
++ {
95 stacks
= strings
.Join(interestingGoroutines(), "\n\n")
96 for substr
, what
:= range badSubstring
{
97 if strings
.Contains(stacks
, substr
) {
104 // Bad stuff found, but goroutines might just still be
105 // shutting down, so give it some time.
106 time
.Sleep(250 * time
.Millisecond
)
108 t
.Errorf("Test appears to have leaked %s:\n%s", bad
, stacks
)