Source file
src/net/main_test.go
Documentation: net
1
2
3
4
5
6
7
8 package net
9
10 import (
11 "flag"
12 "fmt"
13 "net/internal/socktest"
14 "os"
15 "runtime"
16 "sort"
17 "strings"
18 "sync"
19 "testing"
20 )
21
22 var (
23 sw socktest.Switch
24
25
26 testHookUninstaller sync.Once
27 )
28
29 var (
30 testTCPBig = flag.Bool("tcpbig", false, "whether to test massive size of data per read or write call on TCP connection")
31
32 testDNSFlood = flag.Bool("dnsflood", false, "whether to test DNS query flooding")
33
34
35
36
37
38
39 testIPv4 = flag.Bool("ipv4", true, "assume external IPv4 connectivity exists")
40
41
42
43
44
45
46 testIPv6 = flag.Bool("ipv6", false, "assume external IPv6 connectivity exists")
47 )
48
49 func TestMain(m *testing.M) {
50 setupTestData()
51 installTestHooks()
52
53 st := m.Run()
54
55 testHookUninstaller.Do(uninstallTestHooks)
56 if testing.Verbose() {
57 printRunningGoroutines()
58 printInflightSockets()
59 printSocketStats()
60 }
61 forceCloseSockets()
62 os.Exit(st)
63 }
64
65 type ipv6LinkLocalUnicastTest struct {
66 network, address string
67 nameLookup bool
68 }
69
70 var (
71 ipv6LinkLocalUnicastTCPTests []ipv6LinkLocalUnicastTest
72 ipv6LinkLocalUnicastUDPTests []ipv6LinkLocalUnicastTest
73 )
74
75 func setupTestData() {
76 if supportsIPv4() {
77 resolveTCPAddrTests = append(resolveTCPAddrTests, []resolveTCPAddrTest{
78 {"tcp", "localhost:1", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 1}, nil},
79 {"tcp4", "localhost:2", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 2}, nil},
80 }...)
81 resolveUDPAddrTests = append(resolveUDPAddrTests, []resolveUDPAddrTest{
82 {"udp", "localhost:1", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 1}, nil},
83 {"udp4", "localhost:2", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 2}, nil},
84 }...)
85 resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{
86 {"ip", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
87 {"ip4", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
88 }...)
89 }
90
91 if supportsIPv6() {
92 resolveTCPAddrTests = append(resolveTCPAddrTests, resolveTCPAddrTest{"tcp6", "localhost:3", &TCPAddr{IP: IPv6loopback, Port: 3}, nil})
93 resolveUDPAddrTests = append(resolveUDPAddrTests, resolveUDPAddrTest{"udp6", "localhost:3", &UDPAddr{IP: IPv6loopback, Port: 3}, nil})
94 resolveIPAddrTests = append(resolveIPAddrTests, resolveIPAddrTest{"ip6", "localhost", &IPAddr{IP: IPv6loopback}, nil})
95
96
97
98 resolveTCPAddrTests = append(resolveTCPAddrTests, resolveTCPAddrTest{"tcp", "[::]:4", &TCPAddr{IP: IPv6unspecified, Port: 4}, nil})
99 resolveUDPAddrTests = append(resolveUDPAddrTests, resolveUDPAddrTest{"udp", "[::]:4", &UDPAddr{IP: IPv6unspecified, Port: 4}, nil})
100 resolveIPAddrTests = append(resolveIPAddrTests, resolveIPAddrTest{"ip", "::", &IPAddr{IP: IPv6unspecified}, nil})
101 }
102
103 ifi := loopbackInterface()
104 if ifi != nil {
105 index := fmt.Sprintf("%v", ifi.Index)
106 resolveTCPAddrTests = append(resolveTCPAddrTests, []resolveTCPAddrTest{
107 {"tcp6", "[fe80::1%" + ifi.Name + "]:1", &TCPAddr{IP: ParseIP("fe80::1"), Port: 1, Zone: zoneCache.name(ifi.Index)}, nil},
108 {"tcp6", "[fe80::1%" + index + "]:2", &TCPAddr{IP: ParseIP("fe80::1"), Port: 2, Zone: index}, nil},
109 }...)
110 resolveUDPAddrTests = append(resolveUDPAddrTests, []resolveUDPAddrTest{
111 {"udp6", "[fe80::1%" + ifi.Name + "]:1", &UDPAddr{IP: ParseIP("fe80::1"), Port: 1, Zone: zoneCache.name(ifi.Index)}, nil},
112 {"udp6", "[fe80::1%" + index + "]:2", &UDPAddr{IP: ParseIP("fe80::1"), Port: 2, Zone: index}, nil},
113 }...)
114 resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{
115 {"ip6", "fe80::1%" + ifi.Name, &IPAddr{IP: ParseIP("fe80::1"), Zone: zoneCache.name(ifi.Index)}, nil},
116 {"ip6", "fe80::1%" + index, &IPAddr{IP: ParseIP("fe80::1"), Zone: index}, nil},
117 }...)
118 }
119
120 addr := ipv6LinkLocalUnicastAddr(ifi)
121 if addr != "" {
122 if runtime.GOOS != "dragonfly" {
123 ipv6LinkLocalUnicastTCPTests = append(ipv6LinkLocalUnicastTCPTests, []ipv6LinkLocalUnicastTest{
124 {"tcp", "[" + addr + "%" + ifi.Name + "]:0", false},
125 }...)
126 ipv6LinkLocalUnicastUDPTests = append(ipv6LinkLocalUnicastUDPTests, []ipv6LinkLocalUnicastTest{
127 {"udp", "[" + addr + "%" + ifi.Name + "]:0", false},
128 }...)
129 }
130 ipv6LinkLocalUnicastTCPTests = append(ipv6LinkLocalUnicastTCPTests, []ipv6LinkLocalUnicastTest{
131 {"tcp6", "[" + addr + "%" + ifi.Name + "]:0", false},
132 }...)
133 ipv6LinkLocalUnicastUDPTests = append(ipv6LinkLocalUnicastUDPTests, []ipv6LinkLocalUnicastTest{
134 {"udp6", "[" + addr + "%" + ifi.Name + "]:0", false},
135 }...)
136 switch runtime.GOOS {
137 case "darwin", "ios", "dragonfly", "freebsd", "openbsd", "netbsd":
138 ipv6LinkLocalUnicastTCPTests = append(ipv6LinkLocalUnicastTCPTests, []ipv6LinkLocalUnicastTest{
139 {"tcp", "[localhost%" + ifi.Name + "]:0", true},
140 {"tcp6", "[localhost%" + ifi.Name + "]:0", true},
141 }...)
142 ipv6LinkLocalUnicastUDPTests = append(ipv6LinkLocalUnicastUDPTests, []ipv6LinkLocalUnicastTest{
143 {"udp", "[localhost%" + ifi.Name + "]:0", true},
144 {"udp6", "[localhost%" + ifi.Name + "]:0", true},
145 }...)
146 case "linux":
147 ipv6LinkLocalUnicastTCPTests = append(ipv6LinkLocalUnicastTCPTests, []ipv6LinkLocalUnicastTest{
148 {"tcp", "[ip6-localhost%" + ifi.Name + "]:0", true},
149 {"tcp6", "[ip6-localhost%" + ifi.Name + "]:0", true},
150 }...)
151 ipv6LinkLocalUnicastUDPTests = append(ipv6LinkLocalUnicastUDPTests, []ipv6LinkLocalUnicastTest{
152 {"udp", "[ip6-localhost%" + ifi.Name + "]:0", true},
153 {"udp6", "[ip6-localhost%" + ifi.Name + "]:0", true},
154 }...)
155 }
156 }
157 }
158
159 func printRunningGoroutines() {
160 gss := runningGoroutines()
161 if len(gss) == 0 {
162 return
163 }
164 fmt.Fprintf(os.Stderr, "Running goroutines:\n")
165 for _, gs := range gss {
166 fmt.Fprintf(os.Stderr, "%v\n", gs)
167 }
168 fmt.Fprintf(os.Stderr, "\n")
169 }
170
171
172 func runningGoroutines() []string {
173 var gss []string
174 b := make([]byte, 2<<20)
175 b = b[:runtime.Stack(b, true)]
176 for _, s := range strings.Split(string(b), "\n\n") {
177 ss := strings.SplitN(s, "\n", 2)
178 if len(ss) != 2 {
179 continue
180 }
181 stack := strings.TrimSpace(ss[1])
182 if !strings.Contains(stack, "created by net") {
183 continue
184 }
185 gss = append(gss, stack)
186 }
187 sort.Strings(gss)
188 return gss
189 }
190
191 func printInflightSockets() {
192 sos := sw.Sockets()
193 if len(sos) == 0 {
194 return
195 }
196 fmt.Fprintf(os.Stderr, "Inflight sockets:\n")
197 for s, so := range sos {
198 fmt.Fprintf(os.Stderr, "%v: %v\n", s, so)
199 }
200 fmt.Fprintf(os.Stderr, "\n")
201 }
202
203 func printSocketStats() {
204 sts := sw.Stats()
205 if len(sts) == 0 {
206 return
207 }
208 fmt.Fprintf(os.Stderr, "Socket statistical information:\n")
209 for _, st := range sts {
210 fmt.Fprintf(os.Stderr, "%v\n", st)
211 }
212 fmt.Fprintf(os.Stderr, "\n")
213 }
214
View as plain text