1package dns
2
3import (
4	"fmt"
5	"os"
6	"runtime"
7	"sort"
8	"strings"
9	"testing"
10	"time"
11)
12
13// copied from net/http/main_test.go
14
15func interestingGoroutines() (gs []string) {
16	buf := make([]byte, 2<<20)
17	buf = buf[:runtime.Stack(buf, true)]
18	for _, g := range strings.Split(string(buf), "\n\n") {
19		sl := strings.SplitN(g, "\n", 2)
20		if len(sl) != 2 {
21			continue
22		}
23		stack := strings.TrimSpace(sl[1])
24		if stack == "" ||
25			strings.Contains(stack, "testing.(*M).before.func1") ||
26			strings.Contains(stack, "os/signal.signal_recv") ||
27			strings.Contains(stack, "created by net.startServer") ||
28			strings.Contains(stack, "created by testing.RunTests") ||
29			strings.Contains(stack, "closeWriteAndWait") ||
30			strings.Contains(stack, "testing.Main(") ||
31			strings.Contains(stack, "testing.(*T).Run(") ||
32			strings.Contains(stack, "created by net/http.(*http2Transport).newClientConn") ||
33			// These only show up with GOTRACEBACK=2; Issue 5005 (comment 28)
34			strings.Contains(stack, "runtime.goexit") ||
35			strings.Contains(stack, "created by runtime.gc") ||
36			strings.Contains(stack, "dns.interestingGoroutines") ||
37			strings.Contains(stack, "runtime.MHeap_Scavenger") {
38			continue
39		}
40		gs = append(gs, stack)
41	}
42	sort.Strings(gs)
43	return
44}
45
46func goroutineLeaked() error {
47	if testing.Short() {
48		// Don't worry about goroutine leaks in -short mode or in
49		// benchmark mode. Too distracting when there are false positives.
50		return nil
51	}
52
53	var stackCount map[string]int
54	for i := 0; i < 5; i++ {
55		n := 0
56		stackCount = make(map[string]int)
57		gs := interestingGoroutines()
58		for _, g := range gs {
59			stackCount[g]++
60			n++
61		}
62		if n == 0 {
63			return nil
64		}
65		// Wait for goroutines to schedule and die off:
66		time.Sleep(100 * time.Millisecond)
67	}
68	for stack, count := range stackCount {
69		fmt.Fprintf(os.Stderr, "%d instances of:\n%s\n", count, stack)
70	}
71	return fmt.Errorf("too many goroutines running after dns test(s)")
72}
73