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 }()