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// +build !js 6 7package net 8 9import ( 10 "flag" 11 "fmt" 12 "net/internal/socktest" 13 "os" 14 "runtime" 15 "sort" 16 "strings" 17 "sync" 18 "testing" 19) 20 21var ( 22 sw socktest.Switch 23 24 // uninstallTestHooks runs just before a run of benchmarks. 25 testHookUninstaller sync.Once 26) 27 28var ( 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 // If external IPv4 connectivity exists, we can try dialing 34 // non-node/interface local scope IPv4 addresses. 35 // On Windows, Lookup APIs may not return IPv4-related 36 // resource records when a node has no external IPv4 37 // connectivity. 38 testIPv4 = flag.Bool("ipv4", true, "assume external IPv4 connectivity exists") 39 40 // If external IPv6 connectivity exists, we can try dialing 41 // non-node/interface local scope IPv6 addresses. 42 // On Windows, Lookup APIs may not return IPv6-related 43 // resource records when a node has no external IPv6 44 // connectivity. 45 testIPv6 = flag.Bool("ipv6", false, "assume external IPv6 connectivity exists") 46) 47 48func 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 64type ipv6LinkLocalUnicastTest struct { 65 network, address string 66 nameLookup bool 67} 68 69var ( 70 ipv6LinkLocalUnicastTCPTests []ipv6LinkLocalUnicastTest 71 ipv6LinkLocalUnicastUDPTests []ipv6LinkLocalUnicastTest 72) 73 74func 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 // Issue 20911: don't return IPv4 addresses for 96 // Resolve*Addr calls of the IPv6 unspecified address. 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", "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 158func 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// runningGoroutines returns a list of remaining goroutines. 171func 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 ss := strings.SplitN(s, "\n", 2) 177 if len(ss) != 2 { 178 continue 179 } 180 stack := strings.TrimSpace(ss[1]) 181 if !strings.Contains(stack, "created by net") { 182 continue 183 } 184 gss = append(gss, stack) 185 } 186 sort.Strings(gss) 187 return gss 188} 189 190func printInflightSockets() { 191 sos := sw.Sockets() 192 if len(sos) == 0 { 193 return 194 } 195 fmt.Fprintf(os.Stderr, "Inflight sockets:\n") 196 for s, so := range sos { 197 fmt.Fprintf(os.Stderr, "%v: %v\n", s, so) 198 } 199 fmt.Fprintf(os.Stderr, "\n") 200} 201 202func printSocketStats() { 203 sts := sw.Stats() 204 if len(sts) == 0 { 205 return 206 } 207 fmt.Fprintf(os.Stderr, "Socket statistical information:\n") 208 for _, st := range sts { 209 fmt.Fprintf(os.Stderr, "%v\n", st) 210 } 211 fmt.Fprintf(os.Stderr, "\n") 212} 213