github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/src/net/platform_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  	"os"
     9  	"runtime"
    10  	"strings"
    11  	"testing"
    12  )
    13  
    14  // testableNetwork reports whether network is testable on the current
    15  // platform configuration.
    16  func testableNetwork(network string) bool {
    17  	ss := strings.Split(network, ":")
    18  	switch ss[0] {
    19  	case "ip+nopriv":
    20  		switch runtime.GOOS {
    21  		case "nacl":
    22  			return false
    23  		}
    24  	case "ip", "ip4", "ip6":
    25  		switch runtime.GOOS {
    26  		case "nacl", "plan9":
    27  			return false
    28  		default:
    29  			if os.Getuid() != 0 {
    30  				return false
    31  			}
    32  		}
    33  	case "unix", "unixgram":
    34  		switch runtime.GOOS {
    35  		case "android", "nacl", "plan9", "windows":
    36  			return false
    37  		}
    38  		// iOS does not support unix, unixgram.
    39  		if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
    40  			return false
    41  		}
    42  	case "unixpacket":
    43  		switch runtime.GOOS {
    44  		case "android", "darwin", "nacl", "plan9", "windows":
    45  			fallthrough
    46  		case "freebsd": // FreeBSD 8 and below don't support unixpacket
    47  			return false
    48  		}
    49  	}
    50  	switch ss[0] {
    51  	case "tcp4", "udp4", "ip4":
    52  		if !supportsIPv4 {
    53  			return false
    54  		}
    55  	case "tcp6", "udp6", "ip6":
    56  		if !supportsIPv6 {
    57  			return false
    58  		}
    59  	}
    60  	return true
    61  }
    62  
    63  // testableAddress reports whether address of network is testable on
    64  // the current platform configuration.
    65  func testableAddress(network, address string) bool {
    66  	switch ss := strings.Split(network, ":"); ss[0] {
    67  	case "unix", "unixgram", "unixpacket":
    68  		// Abstract unix domain sockets, a Linux-ism.
    69  		if address[0] == '@' && runtime.GOOS != "linux" {
    70  			return false
    71  		}
    72  	}
    73  	return true
    74  }
    75  
    76  // testableListenArgs reports whether arguments are testable on the
    77  // current platform configuration.
    78  func testableListenArgs(network, address, client string) bool {
    79  	if !testableNetwork(network) || !testableAddress(network, address) {
    80  		return false
    81  	}
    82  
    83  	var err error
    84  	var addr Addr
    85  	switch ss := strings.Split(network, ":"); ss[0] {
    86  	case "tcp", "tcp4", "tcp6":
    87  		addr, err = ResolveTCPAddr("tcp", address)
    88  	case "udp", "udp4", "udp6":
    89  		addr, err = ResolveUDPAddr("udp", address)
    90  	case "ip", "ip4", "ip6":
    91  		addr, err = ResolveIPAddr("ip", address)
    92  	default:
    93  		return true
    94  	}
    95  	if err != nil {
    96  		return false
    97  	}
    98  	var ip IP
    99  	var wildcard bool
   100  	switch addr := addr.(type) {
   101  	case *TCPAddr:
   102  		ip = addr.IP
   103  		wildcard = addr.isWildcard()
   104  	case *UDPAddr:
   105  		ip = addr.IP
   106  		wildcard = addr.isWildcard()
   107  	case *IPAddr:
   108  		ip = addr.IP
   109  		wildcard = addr.isWildcard()
   110  	}
   111  
   112  	// Test wildcard IP addresses.
   113  	if wildcard && (testing.Short() || !*testExternal) {
   114  		return false
   115  	}
   116  
   117  	// Test functionality of IPv4 communication using AF_INET and
   118  	// IPv6 communication using AF_INET6 sockets.
   119  	if !supportsIPv4 && ip.To4() != nil {
   120  		return false
   121  	}
   122  	if !supportsIPv6 && ip.To16() != nil && ip.To4() == nil {
   123  		return false
   124  	}
   125  	cip := ParseIP(client)
   126  	if cip != nil {
   127  		if !supportsIPv4 && cip.To4() != nil {
   128  			return false
   129  		}
   130  		if !supportsIPv6 && cip.To16() != nil && cip.To4() == nil {
   131  			return false
   132  		}
   133  	}
   134  
   135  	// Test functionality of IPv4 communication using AF_INET6
   136  	// sockets.
   137  	if !supportsIPv4map && supportsIPv4 && (network == "tcp" || network == "udp" || network == "ip") && wildcard {
   138  		// At this point, we prefer IPv4 when ip is nil.
   139  		// See favoriteAddrFamily for further information.
   140  		if ip.To16() != nil && ip.To4() == nil && cip.To4() != nil { // a pair of IPv6 server and IPv4 client
   141  			return false
   142  		}
   143  		if (ip.To4() != nil || ip == nil) && cip.To16() != nil && cip.To4() == nil { // a pair of IPv4 server and IPv6 client
   144  			return false
   145  		}
   146  	}
   147  
   148  	return true
   149  }
   150  
   151  var condFatalf = func() func(*testing.T, string, ...interface{}) {
   152  	// A few APIs, File, Read/WriteMsg{UDP,IP}, are not
   153  	// implemented yet on both Plan 9 and Windows.
   154  	switch runtime.GOOS {
   155  	case "plan9", "windows":
   156  		return (*testing.T).Logf
   157  	}
   158  	return (*testing.T).Fatalf
   159  }()