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