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