...

Source file src/net/main_test.go

Documentation: net

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

View as plain text