main_test.go 7.1 KB

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