]> Cypherpunks.ru repositories - gostls13.git/blob - src/net/main_test.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / src / net / main_test.go
1 // Copyright 2015 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.
4
5 package net
6
7 import (
8         "flag"
9         "fmt"
10         "net/internal/socktest"
11         "os"
12         "runtime"
13         "sort"
14         "strings"
15         "sync"
16         "testing"
17         "time"
18 )
19
20 var (
21         sw socktest.Switch
22
23         // uninstallTestHooks runs just before a run of benchmarks.
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         // If external IPv4 connectivity exists, we can try dialing
33         // non-node/interface local scope IPv4 addresses.
34         // On Windows, Lookup APIs may not return IPv4-related
35         // resource records when a node has no external IPv4
36         // connectivity.
37         testIPv4 = flag.Bool("ipv4", true, "assume external IPv4 connectivity exists")
38
39         // If external IPv6 connectivity exists, we can try dialing
40         // non-node/interface local scope IPv6 addresses.
41         // On Windows, Lookup APIs may not return IPv6-related
42         // resource records when a node has no external IPv6
43         // connectivity.
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 // mustSetDeadline calls the bound method m to set a deadline on a Conn.
64 // If the call fails, mustSetDeadline skips t if the current GOOS is believed
65 // not to support deadlines, or fails the test otherwise.
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                 // Issue 20911: don't return IPv4 addresses for
109                 // Resolve*Addr calls of the IPv6 unspecified address.
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 // runningGoroutines returns a list of remaining goroutines.
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         sort.Strings(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 }