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