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