diff options
Diffstat (limited to 'src/net/platform_test.go')
-rw-r--r-- | src/net/platform_test.go | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/src/net/platform_test.go b/src/net/platform_test.go new file mode 100644 index 0000000..2da23de --- /dev/null +++ b/src/net/platform_test.go @@ -0,0 +1,191 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package net + +import ( + "internal/testenv" + "os" + "os/exec" + "runtime" + "strconv" + "strings" + "testing" +) + +var unixEnabledOnAIX bool + +func init() { + if runtime.GOOS == "aix" { + // Unix network isn't properly working on AIX 7.2 with + // Technical Level < 2. + // The information is retrieved only once in this init() + // instead of everytime testableNetwork is called. + out, _ := exec.Command("oslevel", "-s").Output() + if len(out) >= len("7200-XX-ZZ-YYMM") { // AIX 7.2, Tech Level XX, Service Pack ZZ, date YYMM + aixVer := string(out[:4]) + tl, _ := strconv.Atoi(string(out[5:7])) + unixEnabledOnAIX = aixVer > "7200" || (aixVer == "7200" && tl >= 2) + } + } +} + +// testableNetwork reports whether network is testable on the current +// platform configuration. +func testableNetwork(network string) bool { + ss := strings.Split(network, ":") + switch ss[0] { + case "ip+nopriv": + case "ip", "ip4", "ip6": + switch runtime.GOOS { + case "plan9": + return false + default: + if os.Getuid() != 0 { + return false + } + } + case "unix", "unixgram": + switch runtime.GOOS { + case "android", "plan9", "windows": + return false + case "aix": + return unixEnabledOnAIX + } + // iOS does not support unix, unixgram. + if iOS() { + return false + } + case "unixpacket": + switch runtime.GOOS { + case "aix", "android", "darwin", "ios", "plan9", "windows": + return false + case "netbsd": + // It passes on amd64 at least. 386 fails (Issue 22927). arm is unknown. + if runtime.GOARCH == "386" { + return false + } + } + } + switch ss[0] { + case "tcp4", "udp4", "ip4": + if !supportsIPv4() { + return false + } + case "tcp6", "udp6", "ip6": + if !supportsIPv6() { + return false + } + } + return true +} + +func iOS() bool { + return runtime.GOOS == "ios" +} + +// testableAddress reports whether address of network is testable on +// the current platform configuration. +func testableAddress(network, address string) bool { + switch ss := strings.Split(network, ":"); ss[0] { + case "unix", "unixgram", "unixpacket": + // Abstract unix domain sockets, a Linux-ism. + if address[0] == '@' && runtime.GOOS != "linux" { + return false + } + } + return true +} + +// testableListenArgs reports whether arguments are testable on the +// current platform configuration. +func testableListenArgs(network, address, client string) bool { + if !testableNetwork(network) || !testableAddress(network, address) { + return false + } + + var err error + var addr Addr + switch ss := strings.Split(network, ":"); ss[0] { + case "tcp", "tcp4", "tcp6": + addr, err = ResolveTCPAddr("tcp", address) + case "udp", "udp4", "udp6": + addr, err = ResolveUDPAddr("udp", address) + case "ip", "ip4", "ip6": + addr, err = ResolveIPAddr("ip", address) + default: + return true + } + if err != nil { + return false + } + var ip IP + var wildcard bool + switch addr := addr.(type) { + case *TCPAddr: + ip = addr.IP + wildcard = addr.isWildcard() + case *UDPAddr: + ip = addr.IP + wildcard = addr.isWildcard() + case *IPAddr: + ip = addr.IP + wildcard = addr.isWildcard() + } + + // Test wildcard IP addresses. + if wildcard && !testenv.HasExternalNetwork() { + return false + } + + // Test functionality of IPv4 communication using AF_INET and + // IPv6 communication using AF_INET6 sockets. + if !supportsIPv4() && ip.To4() != nil { + return false + } + if !supportsIPv6() && ip.To16() != nil && ip.To4() == nil { + return false + } + cip := ParseIP(client) + if cip != nil { + if !supportsIPv4() && cip.To4() != nil { + return false + } + if !supportsIPv6() && cip.To16() != nil && cip.To4() == nil { + return false + } + } + + // Test functionality of IPv4 communication using AF_INET6 + // sockets. + if !supportsIPv4map() && supportsIPv4() && (network == "tcp" || network == "udp" || network == "ip") && wildcard { + // At this point, we prefer IPv4 when ip is nil. + // See favoriteAddrFamily for further information. + if ip.To16() != nil && ip.To4() == nil && cip.To4() != nil { // a pair of IPv6 server and IPv4 client + return false + } + if (ip.To4() != nil || ip == nil) && cip.To16() != nil && cip.To4() == nil { // a pair of IPv4 server and IPv6 client + return false + } + } + + return true +} + +func condFatalf(t *testing.T, network string, format string, args ...interface{}) { + t.Helper() + // A few APIs like File and Read/WriteMsg{UDP,IP} are not + // fully implemented yet on Plan 9 and Windows. + switch runtime.GOOS { + case "windows": + if network == "file+net" { + t.Logf(format, args...) + return + } + case "plan9": + t.Logf(format, args...) + return + } + t.Fatalf(format, args...) +} |