github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/src/net/main_test.go (about) 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 ) 18 19 var ( 20 sw socktest.Switch 21 22 // uninstallTestHooks runs just before a run of benchmarks. 23 testHookUninstaller sync.Once 24 ) 25 26 var ( 27 testDNSFlood = flag.Bool("dnsflood", false, "whether to test DNS query flooding") 28 29 // If external IPv4 connectivity exists, we can try dialing 30 // non-node/interface local scope IPv4 addresses. 31 // On Windows, Lookup APIs may not return IPv4-related 32 // resource records when a node has no external IPv4 33 // connectivity. 34 testIPv4 = flag.Bool("ipv4", true, "assume external IPv4 connectivity exists") 35 36 // If external IPv6 connectivity exists, we can try dialing 37 // non-node/interface local scope IPv6 addresses. 38 // On Windows, Lookup APIs may not return IPv6-related 39 // resource records when a node has no external IPv6 40 // connectivity. 41 testIPv6 = flag.Bool("ipv6", false, "assume external IPv6 connectivity exists") 42 ) 43 44 func TestMain(m *testing.M) { 45 setupTestData() 46 installTestHooks() 47 48 st := m.Run() 49 50 testHookUninstaller.Do(uninstallTestHooks) 51 if testing.Verbose() { 52 printRunningGoroutines() 53 printInflightSockets() 54 printSocketStats() 55 } 56 forceCloseSockets() 57 os.Exit(st) 58 } 59 60 type ipv6LinkLocalUnicastTest struct { 61 network, address string 62 nameLookup bool 63 } 64 65 var ( 66 ipv6LinkLocalUnicastTCPTests []ipv6LinkLocalUnicastTest 67 ipv6LinkLocalUnicastUDPTests []ipv6LinkLocalUnicastTest 68 ) 69 70 func setupTestData() { 71 if supportsIPv4 { 72 resolveTCPAddrTests = append(resolveTCPAddrTests, []resolveTCPAddrTest{ 73 {"tcp", "localhost:1", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 1}, nil}, 74 {"tcp4", "localhost:2", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 2}, nil}, 75 }...) 76 resolveUDPAddrTests = append(resolveUDPAddrTests, []resolveUDPAddrTest{ 77 {"udp", "localhost:1", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 1}, nil}, 78 {"udp4", "localhost:2", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 2}, nil}, 79 }...) 80 resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{ 81 {"ip", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, 82 {"ip4", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, 83 }...) 84 } 85 86 if supportsIPv6 { 87 resolveTCPAddrTests = append(resolveTCPAddrTests, resolveTCPAddrTest{"tcp6", "localhost:3", &TCPAddr{IP: IPv6loopback, Port: 3}, nil}) 88 resolveUDPAddrTests = append(resolveUDPAddrTests, resolveUDPAddrTest{"udp6", "localhost:3", &UDPAddr{IP: IPv6loopback, Port: 3}, nil}) 89 resolveIPAddrTests = append(resolveIPAddrTests, resolveIPAddrTest{"ip6", "localhost", &IPAddr{IP: IPv6loopback}, nil}) 90 } 91 92 ifi := loopbackInterface() 93 if ifi != nil { 94 index := fmt.Sprintf("%v", ifi.Index) 95 resolveTCPAddrTests = append(resolveTCPAddrTests, []resolveTCPAddrTest{ 96 {"tcp6", "[fe80::1%" + ifi.Name + "]:1", &TCPAddr{IP: ParseIP("fe80::1"), Port: 1, Zone: zoneToString(ifi.Index)}, nil}, 97 {"tcp6", "[fe80::1%" + index + "]:2", &TCPAddr{IP: ParseIP("fe80::1"), Port: 2, Zone: index}, nil}, 98 }...) 99 resolveUDPAddrTests = append(resolveUDPAddrTests, []resolveUDPAddrTest{ 100 {"udp6", "[fe80::1%" + ifi.Name + "]:1", &UDPAddr{IP: ParseIP("fe80::1"), Port: 1, Zone: zoneToString(ifi.Index)}, nil}, 101 {"udp6", "[fe80::1%" + index + "]:2", &UDPAddr{IP: ParseIP("fe80::1"), Port: 2, Zone: index}, nil}, 102 }...) 103 resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{ 104 {"ip6", "fe80::1%" + ifi.Name, &IPAddr{IP: ParseIP("fe80::1"), Zone: zoneToString(ifi.Index)}, nil}, 105 {"ip6", "fe80::1%" + index, &IPAddr{IP: ParseIP("fe80::1"), Zone: index}, nil}, 106 }...) 107 } 108 109 addr := ipv6LinkLocalUnicastAddr(ifi) 110 if addr != "" { 111 if runtime.GOOS != "dragonfly" { 112 ipv6LinkLocalUnicastTCPTests = append(ipv6LinkLocalUnicastTCPTests, []ipv6LinkLocalUnicastTest{ 113 {"tcp", "[" + addr + "%" + ifi.Name + "]:0", false}, 114 }...) 115 ipv6LinkLocalUnicastUDPTests = append(ipv6LinkLocalUnicastUDPTests, []ipv6LinkLocalUnicastTest{ 116 {"udp", "[" + addr + "%" + ifi.Name + "]:0", false}, 117 }...) 118 } 119 ipv6LinkLocalUnicastTCPTests = append(ipv6LinkLocalUnicastTCPTests, []ipv6LinkLocalUnicastTest{ 120 {"tcp6", "[" + addr + "%" + ifi.Name + "]:0", false}, 121 }...) 122 ipv6LinkLocalUnicastUDPTests = append(ipv6LinkLocalUnicastUDPTests, []ipv6LinkLocalUnicastTest{ 123 {"udp6", "[" + addr + "%" + ifi.Name + "]:0", false}, 124 }...) 125 switch runtime.GOOS { 126 case "darwin", "dragonfly", "freebsd", "openbsd", "netbsd": 127 ipv6LinkLocalUnicastTCPTests = append(ipv6LinkLocalUnicastTCPTests, []ipv6LinkLocalUnicastTest{ 128 {"tcp", "[localhost%" + ifi.Name + "]:0", true}, 129 {"tcp6", "[localhost%" + ifi.Name + "]:0", true}, 130 }...) 131 ipv6LinkLocalUnicastUDPTests = append(ipv6LinkLocalUnicastUDPTests, []ipv6LinkLocalUnicastTest{ 132 {"udp", "[localhost%" + ifi.Name + "]:0", true}, 133 {"udp6", "[localhost%" + ifi.Name + "]:0", true}, 134 }...) 135 case "linux": 136 ipv6LinkLocalUnicastTCPTests = append(ipv6LinkLocalUnicastTCPTests, []ipv6LinkLocalUnicastTest{ 137 {"tcp", "[ip6-localhost%" + ifi.Name + "]:0", true}, 138 {"tcp6", "[ip6-localhost%" + ifi.Name + "]:0", true}, 139 }...) 140 ipv6LinkLocalUnicastUDPTests = append(ipv6LinkLocalUnicastUDPTests, []ipv6LinkLocalUnicastTest{ 141 {"udp", "[ip6-localhost%" + ifi.Name + "]:0", true}, 142 {"udp6", "[ip6-localhost%" + ifi.Name + "]:0", true}, 143 }...) 144 } 145 } 146 } 147 148 func printRunningGoroutines() { 149 gss := runningGoroutines() 150 if len(gss) == 0 { 151 return 152 } 153 fmt.Fprintf(os.Stderr, "Running goroutines:\n") 154 for _, gs := range gss { 155 fmt.Fprintf(os.Stderr, "%v\n", gs) 156 } 157 fmt.Fprintf(os.Stderr, "\n") 158 } 159 160 // runningGoroutines returns a list of remaining goroutines. 161 func runningGoroutines() []string { 162 var gss []string 163 b := make([]byte, 2<<20) 164 b = b[:runtime.Stack(b, true)] 165 for _, s := range strings.Split(string(b), "\n\n") { 166 ss := strings.SplitN(s, "\n", 2) 167 if len(ss) != 2 { 168 continue 169 } 170 stack := strings.TrimSpace(ss[1]) 171 if !strings.Contains(stack, "created by net") { 172 continue 173 } 174 gss = append(gss, stack) 175 } 176 sort.Strings(gss) 177 return gss 178 } 179 180 func printInflightSockets() { 181 sos := sw.Sockets() 182 if len(sos) == 0 { 183 return 184 } 185 fmt.Fprintf(os.Stderr, "Inflight sockets:\n") 186 for s, so := range sos { 187 fmt.Fprintf(os.Stderr, "%v: %v\n", s, so) 188 } 189 fmt.Fprintf(os.Stderr, "\n") 190 } 191 192 func printSocketStats() { 193 sts := sw.Stats() 194 if len(sts) == 0 { 195 return 196 } 197 fmt.Fprintf(os.Stderr, "Socket statistical information:\n") 198 for _, st := range sts { 199 fmt.Fprintf(os.Stderr, "%v\n", st) 200 } 201 fmt.Fprintf(os.Stderr, "\n") 202 }