From: Mikio Hara Date: Thu, 26 Mar 2015 14:26:45 +0000 (+0900) Subject: net: simplify test helpers X-Git-Tag: go1.5beta1~1403 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=7b2b45e544140aa51d335b09f11b4baf84e3be18;p=gostls13.git net: simplify test helpers This change consolidates test helpers that test platform capabilities. testNetwork, testAddress and testListenArgs report whether given ariguments are testable on the current platform configuration to mitigate to receive weird test results. Change-Id: Ie1ed568a1f9cc50f3155945ea01562904bc2c389 Reviewed-on: https://go-review.googlesource.com/8076 Reviewed-by: Ian Lance Taylor --- diff --git a/src/net/conn_test.go b/src/net/conn_test.go index b86ef437fb..912c084c70 100644 --- a/src/net/conn_test.go +++ b/src/net/conn_test.go @@ -9,7 +9,6 @@ package net import ( "os" - "runtime" "testing" "time" ) @@ -30,23 +29,9 @@ const someTimeout = 10 * time.Second func TestConnAndListener(t *testing.T) { for _, tt := range connTests { - switch tt.net { - case "unix": - switch runtime.GOOS { - case "nacl", "plan9", "windows": - continue - } - // iOS does not support unix domain sockets - if runtime.GOOS == "darwin" && runtime.GOARCH == "arm" { - continue - } - case "unixpacket": - switch runtime.GOOS { - case "android", "darwin", "nacl", "openbsd", "plan9", "windows": - continue - case "freebsd": // FreeBSD 8 doesn't support unixpacket - continue - } + if !testableNetwork(tt.net) { + t.Logf("skipping %s test", tt.net) + continue } ln, err := Listen(tt.net, tt.addr) diff --git a/src/net/file_test.go b/src/net/file_test.go index 6fab06a9c6..609efb232e 100644 --- a/src/net/file_test.go +++ b/src/net/file_test.go @@ -27,10 +27,6 @@ type connFile interface { } func testFileListener(t *testing.T, net, laddr string) { - switch net { - case "tcp", "tcp4", "tcp6": - laddr += ":0" // any available port - } l, err := Listen(net, laddr) if err != nil { t.Fatalf("Listen failed: %v", err) @@ -59,32 +55,30 @@ func testFileListener(t *testing.T, net, laddr string) { var fileListenerTests = []struct { net string laddr string - ipv6 bool // test with underlying AF_INET6 socket - linux bool // test with abstract unix domain socket, a Linux-ism }{ - {net: "tcp", laddr: ""}, - {net: "tcp", laddr: "0.0.0.0"}, - {net: "tcp", laddr: "[::ffff:0.0.0.0]"}, - {net: "tcp", laddr: "[::]", ipv6: true}, + {net: "tcp", laddr: ":0"}, + {net: "tcp", laddr: "0.0.0.0:0"}, + {net: "tcp", laddr: "[::ffff:0.0.0.0]:0"}, + {net: "tcp", laddr: "[::]:0"}, - {net: "tcp", laddr: "127.0.0.1"}, - {net: "tcp", laddr: "[::ffff:127.0.0.1]"}, - {net: "tcp", laddr: "[::1]", ipv6: true}, + {net: "tcp", laddr: "127.0.0.1:0"}, + {net: "tcp", laddr: "[::ffff:127.0.0.1]:0"}, + {net: "tcp", laddr: "[::1]:0"}, - {net: "tcp4", laddr: ""}, - {net: "tcp4", laddr: "0.0.0.0"}, - {net: "tcp4", laddr: "[::ffff:0.0.0.0]"}, + {net: "tcp4", laddr: ":0"}, + {net: "tcp4", laddr: "0.0.0.0:0"}, + {net: "tcp4", laddr: "[::ffff:0.0.0.0]:0"}, - {net: "tcp4", laddr: "127.0.0.1"}, - {net: "tcp4", laddr: "[::ffff:127.0.0.1]"}, + {net: "tcp4", laddr: "127.0.0.1:0"}, + {net: "tcp4", laddr: "[::ffff:127.0.0.1]:0"}, - {net: "tcp6", laddr: "", ipv6: true}, - {net: "tcp6", laddr: "[::]", ipv6: true}, + {net: "tcp6", laddr: ":0"}, + {net: "tcp6", laddr: "[::]:0"}, - {net: "tcp6", laddr: "[::1]", ipv6: true}, + {net: "tcp6", laddr: "[::1]:0"}, - {net: "unix", laddr: "@gotest/net", linux: true}, - {net: "unixpacket", laddr: "@gotest/net", linux: true}, + {net: "unix", laddr: "@gotest/net"}, + {net: "unixpacket", laddr: "@gotest/net"}, } func TestFileListener(t *testing.T) { @@ -94,10 +88,8 @@ func TestFileListener(t *testing.T) { } for _, tt := range fileListenerTests { - if skipServerTest(tt.net, "unix", tt.laddr, tt.ipv6, false, tt.linux) { - continue - } - if skipServerTest(tt.net, "unixpacket", tt.laddr, tt.ipv6, false, tt.linux) { + if !testableListenArgs(tt.net, tt.laddr, "") { + t.Logf("skipping %s test", tt.net+":"+tt.laddr+"->") continue } testFileListener(t, tt.net, tt.laddr) @@ -130,10 +122,6 @@ func testFilePacketConn(t *testing.T, pcf packetConnFile, listen bool) { } func testFilePacketConnListen(t *testing.T, net, laddr string) { - switch net { - case "udp", "udp4", "udp6": - laddr += ":0" // any available port - } l, err := ListenPacket(net, laddr) if err != nil { t.Fatalf("ListenPacket failed: %v", err) @@ -145,10 +133,6 @@ func testFilePacketConnListen(t *testing.T, net, laddr string) { } func testFilePacketConnDial(t *testing.T, net, raddr string) { - switch net { - case "udp", "udp4", "udp6": - raddr += ":12345" - } c, err := Dial(net, raddr) if err != nil { t.Fatalf("Dial failed: %v", err) @@ -160,23 +144,21 @@ func testFilePacketConnDial(t *testing.T, net, raddr string) { } var filePacketConnTests = []struct { - net string - addr string - ipv6 bool // test with underlying AF_INET6 socket - linux bool // test with abstract unix domain socket, a Linux-ism + net string + addr string }{ - {net: "udp", addr: "127.0.0.1"}, - {net: "udp", addr: "[::ffff:127.0.0.1]"}, - {net: "udp", addr: "[::1]", ipv6: true}, + {net: "udp", addr: "127.0.0.1:0"}, + {net: "udp", addr: "[::ffff:127.0.0.1]:0"}, + {net: "udp", addr: "[::1]:0"}, - {net: "udp4", addr: "127.0.0.1"}, - {net: "udp4", addr: "[::ffff:127.0.0.1]"}, + {net: "udp4", addr: "127.0.0.1:0"}, + {net: "udp4", addr: "[::ffff:127.0.0.1]:0"}, - {net: "udp6", addr: "[::1]", ipv6: true}, + {net: "udp6", addr: "[::1]:0"}, {net: "ip4:icmp", addr: "127.0.0.1"}, - {net: "unixgram", addr: "@gotest3/net", linux: true}, + {net: "unixgram", addr: "@gotest3/net"}, } func TestFilePacketConn(t *testing.T) { @@ -186,7 +168,8 @@ func TestFilePacketConn(t *testing.T) { } for _, tt := range filePacketConnTests { - if skipServerTest(tt.net, "unixgram", tt.addr, tt.ipv6, false, tt.linux) { + if !testableListenArgs(tt.net, tt.addr, "") { + t.Logf("skipping %s test", tt.net+":"+tt.addr+"->") continue } if os.Getuid() != 0 && tt.net == "ip4:icmp" { @@ -194,12 +177,16 @@ func TestFilePacketConn(t *testing.T) { continue } testFilePacketConnListen(t, tt.net, tt.addr) - switch tt.addr { - case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]": - default: - if tt.net != "unixgram" { - testFilePacketConnDial(t, tt.net, tt.addr) + switch tt.net { + case "udp", "udp4", "udp6": + host, _, err := SplitHostPort(tt.addr) + if err != nil { + t.Error(err) + continue } + testFilePacketConnDial(t, tt.net, JoinHostPort(host, "12345")) + case "ip4:icmp": + testFilePacketConnDial(t, tt.net, tt.addr) } } } diff --git a/src/net/ipraw_test.go b/src/net/ipraw_test.go index 7bf95e1213..f93b9ef0b0 100644 --- a/src/net/ipraw_test.go +++ b/src/net/ipraw_test.go @@ -6,9 +6,7 @@ package net import ( "fmt" - "os" "reflect" - "runtime" "testing" ) @@ -64,9 +62,8 @@ func init() { } func TestResolveIPAddr(t *testing.T) { - switch runtime.GOOS { - case "nacl": - t.Skipf("skipping test on %q", runtime.GOOS) + if !testableNetwork("ip+nopriv") { + t.Skip("ip+nopriv test") } for _, tt := range resolveIPAddrTests { @@ -89,16 +86,11 @@ var ipConnLocalNameTests = []struct { } func TestIPConnLocalName(t *testing.T) { - switch runtime.GOOS { - case "nacl", "plan9", "windows": - t.Skipf("skipping test on %q", runtime.GOOS) - default: - if os.Getuid() != 0 { - t.Skip("skipping test; must be root") - } - } - for _, tt := range ipConnLocalNameTests { + if !testableNetwork(tt.net) { + t.Logf("skipping %s test", tt.net) + continue + } c, err := ListenIP(tt.net, tt.laddr) if err != nil { t.Fatalf("ListenIP failed: %v", err) @@ -111,13 +103,8 @@ func TestIPConnLocalName(t *testing.T) { } func TestIPConnRemoteName(t *testing.T) { - switch runtime.GOOS { - case "plan9", "windows": - t.Skipf("skipping test on %q", runtime.GOOS) - default: - if os.Getuid() != 0 { - t.Skip("skipping test; must be root") - } + if !testableNetwork("ip:tcp") { + t.Skip("ip:tcp test") } raddr := &IPAddr{IP: IPv4(127, 0, 0, 1).To4()} diff --git a/src/net/iprawsock.go b/src/net/iprawsock.go index 5cc361390f..1e53ab2847 100644 --- a/src/net/iprawsock.go +++ b/src/net/iprawsock.go @@ -23,6 +23,13 @@ func (a *IPAddr) String() string { return a.IP.String() } +func (a *IPAddr) isWildcard() bool { + if a == nil || a.IP == nil { + return true + } + return a.IP.IsUnspecified() +} + func (a *IPAddr) toAddr() Addr { if a == nil { return nil diff --git a/src/net/iprawsock_posix.go b/src/net/iprawsock_posix.go index e11eacec6a..94db068d7c 100644 --- a/src/net/iprawsock_posix.go +++ b/src/net/iprawsock_posix.go @@ -43,13 +43,6 @@ func (a *IPAddr) family() int { return syscall.AF_INET6 } -func (a *IPAddr) isWildcard() bool { - if a == nil || a.IP == nil { - return true - } - return a.IP.IsUnspecified() -} - func (a *IPAddr) sockaddr(family int) (syscall.Sockaddr, error) { if a == nil { return nil, nil diff --git a/src/net/net_test.go b/src/net/net_test.go index acf9ee5a35..5a88363eb6 100644 --- a/src/net/net_test.go +++ b/src/net/net_test.go @@ -63,14 +63,10 @@ func TestShutdown(t *testing.T) { } func TestShutdownUnix(t *testing.T) { - switch runtime.GOOS { - case "nacl", "plan9", "windows": - t.Skipf("skipping test on %q", runtime.GOOS) - case "darwin": - if runtime.GOARCH == "arm" { - t.Skipf("skipping test on %s/%s", runtime.GOOS, runtime.GOARCH) - } + if !testableNetwork("unix") { + t.Skip("unix test") } + f, err := ioutil.TempFile("", "go_net_unixtest") if err != nil { t.Fatalf("TempFile: %s", err) diff --git a/src/net/packetconn_test.go b/src/net/packetconn_test.go index 72bdb49196..31e050f6d3 100644 --- a/src/net/packetconn_test.go +++ b/src/net/packetconn_test.go @@ -9,8 +9,6 @@ package net import ( "os" - "runtime" - "strings" "testing" "time" ) @@ -21,24 +19,11 @@ import ( // golang.org/x/net/ipv6 // golang.org/x/net/icmp -func packetConnTestData(t *testing.T, net string, i int) ([]byte, func()) { - switch net { - case "udp": - return []byte("UDP PACKETCONN TEST"), nil - case "unixgram": - switch runtime.GOOS { - case "nacl", "plan9", "windows": - return nil, func() { - t.Logf("skipping %q test on %q", net, runtime.GOOS) - } - default: - return []byte("UNIXGRAM PACKETCONN TEST"), nil - } - default: - return nil, func() { - t.Logf("skipping %q test", net) - } +func packetConnTestData(t *testing.T, network string) ([]byte, func()) { + if !testableNetwork(network) { + return nil, func() { t.Logf("skipping %s test", network) } } + return []byte("PACKETCONN TEST"), nil } var packetConnTests = []struct { @@ -51,9 +36,6 @@ var packetConnTests = []struct { } func TestPacketConn(t *testing.T) { - if runtime.GOOS == "darwin" && runtime.GOARCH == "arm" { - t.Skip("skipping test on darwin/arm") - } closer := func(c PacketConn, net, addr1, addr2 string) { c.Close() switch net { @@ -63,9 +45,8 @@ func TestPacketConn(t *testing.T) { } } - for i, tt := range packetConnTests { - netstr := strings.Split(tt.net, ":") - wb, skipOrFatalFn := packetConnTestData(t, netstr[0], i) + for _, tt := range packetConnTests { + wb, skipOrFatalFn := packetConnTestData(t, tt.net) if skipOrFatalFn != nil { skipOrFatalFn() continue @@ -75,7 +56,7 @@ func TestPacketConn(t *testing.T) { if err != nil { t.Fatalf("ListenPacket failed: %v", err) } - defer closer(c1, netstr[0], tt.addr1, tt.addr2) + defer closer(c1, tt.net, tt.addr1, tt.addr2) c1.LocalAddr() c1.SetDeadline(time.Now().Add(500 * time.Millisecond)) c1.SetReadDeadline(time.Now().Add(500 * time.Millisecond)) @@ -85,7 +66,7 @@ func TestPacketConn(t *testing.T) { if err != nil { t.Fatalf("ListenPacket failed: %v", err) } - defer closer(c2, netstr[0], tt.addr1, tt.addr2) + defer closer(c2, tt.net, tt.addr1, tt.addr2) c2.LocalAddr() c2.SetDeadline(time.Now().Add(500 * time.Millisecond)) c2.SetReadDeadline(time.Now().Add(500 * time.Millisecond)) @@ -109,9 +90,6 @@ func TestPacketConn(t *testing.T) { } func TestConnAndPacketConn(t *testing.T) { - if runtime.GOOS == "darwin" && runtime.GOARCH == "arm" { - t.Skip("skipping test on darwin/arm") - } closer := func(c PacketConn, net, addr1, addr2 string) { c.Close() switch net { @@ -121,10 +99,9 @@ func TestConnAndPacketConn(t *testing.T) { } } - for i, tt := range packetConnTests { + for _, tt := range packetConnTests { var wb []byte - netstr := strings.Split(tt.net, ":") - wb, skipOrFatalFn := packetConnTestData(t, netstr[0], i) + wb, skipOrFatalFn := packetConnTestData(t, tt.net) if skipOrFatalFn != nil { skipOrFatalFn() continue @@ -134,7 +111,7 @@ func TestConnAndPacketConn(t *testing.T) { if err != nil { t.Fatalf("ListenPacket failed: %v", err) } - defer closer(c1, netstr[0], tt.addr1, tt.addr2) + defer closer(c1, tt.net, tt.addr1, tt.addr2) c1.LocalAddr() c1.SetDeadline(time.Now().Add(500 * time.Millisecond)) c1.SetReadDeadline(time.Now().Add(500 * time.Millisecond)) @@ -159,9 +136,7 @@ func TestConnAndPacketConn(t *testing.T) { t.Fatalf("PacketConn.ReadFrom failed: %v", err) } var dst Addr - switch netstr[0] { - case "ip": - dst = &IPAddr{IP: IPv4(127, 0, 0, 1)} + switch tt.net { case "unixgram": continue default: diff --git a/src/net/platform_test.go b/src/net/platform_test.go new file mode 100644 index 0000000000..a1e766dbcd --- /dev/null +++ b/src/net/platform_test.go @@ -0,0 +1,137 @@ +// 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 ( + "os" + "runtime" + "strings" + "testing" +) + +// testableNetwork reports whether network is testable on the current +// platform configuration. +func testableNetwork(network string) bool { + switch ss := strings.Split(network, ":"); ss[0] { + case "ip+nopriv": + switch runtime.GOOS { + case "nacl": + return false + } + case "ip", "ip4", "ip6": + switch runtime.GOOS { + case "nacl", "plan9": + return false + default: + if os.Getuid() != 0 { + return false + } + } + case "unix", "unixgram": + switch runtime.GOOS { + case "nacl", "plan9", "windows": + return false + } + // iOS does not support unix, unixgram. + if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + return false + } + case "unixpacket": + switch runtime.GOOS { + case "android", "darwin", "nacl", "openbsd", "plan9", "windows": + fallthrough + case "freebsd": // FreeBSD 8 and below don't support unixpacket + return false + } + } + return true +} + +// 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 && (testing.Short() || !*testExternal) { + return false + } + + // Test functionality of IPv6 communication using AF_INET6 + // sockets. + if !supportsIPv6 && ip.To16() != nil && ip.To4() == nil { + return false + } + + // Test functionality of IPv4 communication using AF_INET6 + // sockets. + cip := ParseIP(client) + if !supportsIPv4map && (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 +} + +var condFatalf = func() func(*testing.T, string, ...interface{}) { + // A few APIs, File, Read/WriteMsg{UDP,IP}, are not + // implemented yet on both Plan 9 and Windows. + switch runtime.GOOS { + case "plan9", "windows": + return (*testing.T).Logf + } + return (*testing.T).Fatalf +}() diff --git a/src/net/protoconn_test.go b/src/net/protoconn_test.go index 18ac4a6bdf..3a16ec5bc0 100644 --- a/src/net/protoconn_test.go +++ b/src/net/protoconn_test.go @@ -35,15 +35,6 @@ func testUnixAddr() string { return addr } -var condFatalf = func() func(*testing.T, string, ...interface{}) { - // A few APIs are not implemented yet on both Plan 9 and Windows. - switch runtime.GOOS { - case "plan9", "windows": - return (*testing.T).Logf - } - return (*testing.T).Fatalf -}() - func TestTCPListenerSpecificMethods(t *testing.T) { switch runtime.GOOS { case "plan9": @@ -218,13 +209,8 @@ func TestIPConnSpecificMethods(t *testing.T) { } func TestUnixListenerSpecificMethods(t *testing.T) { - switch runtime.GOOS { - case "nacl", "plan9", "windows": - t.Skipf("skipping test on %q", runtime.GOOS) - case "darwin": - if runtime.GOARCH == "arm" { - t.Skipf("skipping test on %s/%s", runtime.GOOS, runtime.GOARCH) - } + if !testableNetwork("unix") { + t.Skip("unix test") } addr := testUnixAddr() @@ -264,13 +250,8 @@ func TestUnixListenerSpecificMethods(t *testing.T) { } func TestUnixConnSpecificMethods(t *testing.T) { - switch runtime.GOOS { - case "nacl", "plan9", "windows": - t.Skipf("skipping test on %q", runtime.GOOS) - case "darwin": - if runtime.GOARCH == "arm" { - t.Skipf("skipping test on %s/%s", runtime.GOOS, runtime.GOARCH) - } + if !testableNetwork("unixgram") { + t.Skip("unixgram test") } addr1, addr2, addr3 := testUnixAddr(), testUnixAddr(), testUnixAddr() diff --git a/src/net/server_test.go b/src/net/server_test.go index c29468fda4..479c181248 100644 --- a/src/net/server_test.go +++ b/src/net/server_test.go @@ -8,105 +8,66 @@ import ( "flag" "io" "os" - "runtime" "testing" "time" ) -func skipServerTest(net, unixsotype, addr string, ipv6, ipv4map, linuxOnly bool) bool { - switch runtime.GOOS { - case "linux": - case "nacl", "plan9", "windows": - // "unix" sockets are not supported on Windows and Plan 9. - if net == unixsotype { - return true - } - case "darwin": - if net == unixsotype { - if runtime.GOARCH == "arm" || linuxOnly { - return true - } - } - default: - if net == unixsotype && linuxOnly { - return true - } - } - switch addr { - case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]": - if testing.Short() || !*testExternal { - return true - } - } - if ipv6 && !supportsIPv6 { - return true - } - if ipv4map && !supportsIPv4map { - return true - } - return false -} - var streamConnServerTests = []struct { - snet string // server side - saddr string - cnet string // client side - caddr string - ipv6 bool // test with underlying AF_INET6 socket - ipv4map bool // test with IPv6 IPv4-mapping functionality - empty bool // test with empty data - linuxOnly bool // test with abstract unix domain socket, a Linux-ism + snet string // server side + saddr string + cnet string // client side + caddr string + empty bool // test with empty data }{ - {snet: "tcp", saddr: "", cnet: "tcp", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "[::]", cnet: "tcp", caddr: "[::1]", ipv6: true}, + {snet: "tcp", saddr: ":0", cnet: "tcp", caddr: "127.0.0.1"}, + {snet: "tcp", saddr: "0.0.0.0:0", cnet: "tcp", caddr: "127.0.0.1"}, + {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", cnet: "tcp", caddr: "127.0.0.1"}, + {snet: "tcp", saddr: "[::]:0", cnet: "tcp", caddr: "::1"}, - {snet: "tcp", saddr: "", cnet: "tcp", caddr: "[::1]", ipv4map: true}, - {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp", caddr: "[::1]", ipv4map: true}, - {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp", caddr: "[::1]", ipv4map: true}, - {snet: "tcp", saddr: "[::]", cnet: "tcp", caddr: "127.0.0.1", ipv4map: true}, + {snet: "tcp", saddr: ":0", cnet: "tcp", caddr: "::1"}, + {snet: "tcp", saddr: "0.0.0.0:0", cnet: "tcp", caddr: "::1"}, + {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", cnet: "tcp", caddr: "::1"}, + {snet: "tcp", saddr: "[::]:0", cnet: "tcp", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "[::]", cnet: "tcp6", caddr: "[::1]", ipv6: true}, + {snet: "tcp", saddr: ":0", cnet: "tcp4", caddr: "127.0.0.1"}, + {snet: "tcp", saddr: "0.0.0.0:0", cnet: "tcp4", caddr: "127.0.0.1"}, + {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", cnet: "tcp4", caddr: "127.0.0.1"}, + {snet: "tcp", saddr: "[::]:0", cnet: "tcp6", caddr: "::1"}, - {snet: "tcp", saddr: "", cnet: "tcp6", caddr: "[::1]", ipv4map: true}, - {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp6", caddr: "[::1]", ipv4map: true}, - {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp6", caddr: "[::1]", ipv4map: true}, - {snet: "tcp", saddr: "[::]", cnet: "tcp4", caddr: "127.0.0.1", ipv4map: true}, + {snet: "tcp", saddr: ":0", cnet: "tcp6", caddr: "::1"}, + {snet: "tcp", saddr: "0.0.0.0:0", cnet: "tcp6", caddr: "::1"}, + {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", cnet: "tcp6", caddr: "::1"}, + {snet: "tcp", saddr: "[::]:0", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "127.0.0.1", cnet: "tcp", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "[::ffff:127.0.0.1]", cnet: "tcp", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "[::1]", cnet: "tcp", caddr: "[::1]", ipv6: true}, + {snet: "tcp", saddr: "127.0.0.1:0", cnet: "tcp", caddr: "127.0.0.1"}, + {snet: "tcp", saddr: "[::ffff:127.0.0.1]:0", cnet: "tcp", caddr: "127.0.0.1"}, + {snet: "tcp", saddr: "[::1]:0", cnet: "tcp", caddr: "::1"}, - {snet: "tcp4", saddr: "", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp4", saddr: "0.0.0.0", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp4", saddr: "[::ffff:0.0.0.0]", cnet: "tcp4", caddr: "127.0.0.1"}, + {snet: "tcp4", saddr: ":0", cnet: "tcp4", caddr: "127.0.0.1"}, + {snet: "tcp4", saddr: "0.0.0.0:0", cnet: "tcp4", caddr: "127.0.0.1"}, + {snet: "tcp4", saddr: "[::ffff:0.0.0.0]:0", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp4", saddr: "127.0.0.1", cnet: "tcp4", caddr: "127.0.0.1"}, + {snet: "tcp4", saddr: "127.0.0.1:0", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp6", saddr: "", cnet: "tcp6", caddr: "[::1]", ipv6: true}, - {snet: "tcp6", saddr: "[::]", cnet: "tcp6", caddr: "[::1]", ipv6: true}, + {snet: "tcp6", saddr: ":0", cnet: "tcp6", caddr: "::1"}, + {snet: "tcp6", saddr: "[::]:0", cnet: "tcp6", caddr: "::1"}, - {snet: "tcp6", saddr: "[::1]", cnet: "tcp6", caddr: "[::1]", ipv6: true}, + {snet: "tcp6", saddr: "[::1]:0", cnet: "tcp6", caddr: "::1"}, {snet: "unix", saddr: testUnixAddr(), cnet: "unix", caddr: testUnixAddr()}, - {snet: "unix", saddr: "@gotest2/net", cnet: "unix", caddr: "@gotest2/net.local", linuxOnly: true}, + {snet: "unix", saddr: "@gotest2/net", cnet: "unix", caddr: "@gotest2/net.local"}, } func TestStreamConnServer(t *testing.T) { for _, tt := range streamConnServerTests { - if skipServerTest(tt.snet, "unix", tt.saddr, tt.ipv6, tt.ipv4map, tt.linuxOnly) { + if !testableListenArgs(tt.snet, tt.saddr, tt.caddr) { + t.Logf("skipping %s test", tt.snet+":"+tt.saddr+"->"+tt.caddr) continue } listening := make(chan string) done := make(chan int) switch tt.snet { - case "tcp", "tcp4", "tcp6": - tt.saddr += ":0" case "unix": os.Remove(tt.saddr) os.Remove(tt.caddr) @@ -121,7 +82,7 @@ func TestStreamConnServer(t *testing.T) { if err != nil { t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err) } - taddr = tt.caddr + ":" + port + taddr = JoinHostPort(tt.caddr, port) } runStreamConnClient(t, tt.cnet, taddr, tt.empty) @@ -136,26 +97,19 @@ func TestStreamConnServer(t *testing.T) { } var seqpacketConnServerTests = []struct { - net string - saddr string // server address - caddr string // client address - empty bool // test with empty data - linuxOnly bool // test with abstract unix domain socket, a Linux-ism + net string + saddr string // server address + caddr string // client address + empty bool // test with empty data }{ {net: "unixpacket", saddr: testUnixAddr(), caddr: testUnixAddr()}, - {net: "unixpacket", saddr: "@gotest4/net", caddr: "@gotest4/net.local", linuxOnly: true}, + {net: "unixpacket", saddr: "@gotest4/net", caddr: "@gotest4/net.local"}, } func TestSeqpacketConnServer(t *testing.T) { - switch runtime.GOOS { - case "darwin", "nacl", "openbsd", "plan9", "windows": - fallthrough - case "freebsd": // FreeBSD 8 doesn't support unixpacket - t.Skipf("skipping test on %q", runtime.GOOS) - } - for _, tt := range seqpacketConnServerTests { - if runtime.GOOS != "linux" && tt.linuxOnly { + if !testableListenArgs(tt.net, tt.saddr, tt.caddr) { + t.Logf("skipping %s test", tt.net+":"+tt.saddr+"->"+tt.caddr) continue } listening := make(chan string) @@ -254,65 +208,62 @@ func runStreamConnClient(t *testing.T, net, taddr string, isEmpty bool) { var testDatagram = flag.Bool("datagram", false, "whether to test udp and unixgram") var datagramPacketConnServerTests = []struct { - snet string // server side - saddr string - cnet string // client side - caddr string - ipv6 bool // test with underlying AF_INET6 socket - ipv4map bool // test with IPv6 IPv4-mapping functionality - dial bool // test with Dial or DialUnix - empty bool // test with empty data - linuxOnly bool // test with abstract unix domain socket, a Linux-ism + snet string // server side + saddr string + cnet string // client side + caddr string + dial bool // test with Dial or DialUnix + empty bool // test with empty data }{ - {snet: "udp", saddr: "", cnet: "udp", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "0.0.0.0", cnet: "udp", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "[::]", cnet: "udp", caddr: "[::1]", ipv6: true}, + {snet: "udp", saddr: ":0", cnet: "udp", caddr: "127.0.0.1"}, + {snet: "udp", saddr: "0.0.0.0:0", cnet: "udp", caddr: "127.0.0.1"}, + {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", cnet: "udp", caddr: "127.0.0.1"}, + {snet: "udp", saddr: "[::]:0", cnet: "udp", caddr: "::1"}, - {snet: "udp", saddr: "", cnet: "udp", caddr: "[::1]", ipv4map: true}, - {snet: "udp", saddr: "0.0.0.0", cnet: "udp", caddr: "[::1]", ipv4map: true}, - {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp", caddr: "[::1]", ipv4map: true}, - {snet: "udp", saddr: "[::]", cnet: "udp", caddr: "127.0.0.1", ipv4map: true}, + {snet: "udp", saddr: ":0", cnet: "udp", caddr: "::1"}, + {snet: "udp", saddr: "0.0.0.0:0", cnet: "udp", caddr: "::1"}, + {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", cnet: "udp", caddr: "::1"}, + {snet: "udp", saddr: "[::]:0", cnet: "udp", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "0.0.0.0", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "[::]", cnet: "udp6", caddr: "[::1]", ipv6: true}, + {snet: "udp", saddr: ":0", cnet: "udp4", caddr: "127.0.0.1"}, + {snet: "udp", saddr: "0.0.0.0:0", cnet: "udp4", caddr: "127.0.0.1"}, + {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", cnet: "udp4", caddr: "127.0.0.1"}, + {snet: "udp", saddr: "[::]:0", cnet: "udp6", caddr: "::1"}, - {snet: "udp", saddr: "", cnet: "udp6", caddr: "[::1]", ipv4map: true}, - {snet: "udp", saddr: "0.0.0.0", cnet: "udp6", caddr: "[::1]", ipv4map: true}, - {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp6", caddr: "[::1]", ipv4map: true}, - {snet: "udp", saddr: "[::]", cnet: "udp4", caddr: "127.0.0.1", ipv4map: true}, + {snet: "udp", saddr: ":0", cnet: "udp6", caddr: "::1"}, + {snet: "udp", saddr: "0.0.0.0:0", cnet: "udp6", caddr: "::1"}, + {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", cnet: "udp6", caddr: "::1"}, + {snet: "udp", saddr: "[::]:0", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "[::ffff:127.0.0.1]", cnet: "udp", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true}, + {snet: "udp", saddr: "127.0.0.1:0", cnet: "udp", caddr: "127.0.0.1"}, + {snet: "udp", saddr: "[::ffff:127.0.0.1]:0", cnet: "udp", caddr: "127.0.0.1"}, + {snet: "udp", saddr: "[::1]:0", cnet: "udp", caddr: "::1"}, - {snet: "udp4", saddr: "", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp4", saddr: "0.0.0.0", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp4", saddr: "[::ffff:0.0.0.0]", cnet: "udp4", caddr: "127.0.0.1"}, + {snet: "udp4", saddr: ":0", cnet: "udp4", caddr: "127.0.0.1"}, + {snet: "udp4", saddr: "0.0.0.0:0", cnet: "udp4", caddr: "127.0.0.1"}, + {snet: "udp4", saddr: "[::ffff:0.0.0.0]:0", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp4", saddr: "127.0.0.1", cnet: "udp4", caddr: "127.0.0.1"}, + {snet: "udp4", saddr: "127.0.0.1:0", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp6", saddr: "", cnet: "udp6", caddr: "[::1]", ipv6: true}, - {snet: "udp6", saddr: "[::]", cnet: "udp6", caddr: "[::1]", ipv6: true}, + {snet: "udp6", saddr: ":0", cnet: "udp6", caddr: "::1"}, + {snet: "udp6", saddr: "[::]:0", cnet: "udp6", caddr: "::1"}, - {snet: "udp6", saddr: "[::1]", cnet: "udp6", caddr: "[::1]", ipv6: true}, + {snet: "udp6", saddr: "[::1]:0", cnet: "udp6", caddr: "::1"}, - {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", dial: true}, - {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", empty: true}, - {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", dial: true, empty: true}, + {snet: "udp", saddr: "127.0.0.1:0", cnet: "udp", caddr: "127.0.0.1", dial: true}, + {snet: "udp", saddr: "127.0.0.1:0", cnet: "udp", caddr: "127.0.0.1", empty: true}, + {snet: "udp", saddr: "127.0.0.1:0", cnet: "udp", caddr: "127.0.0.1", dial: true, empty: true}, - {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, dial: true}, - {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, empty: true}, - {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, dial: true, empty: true}, + {snet: "udp", saddr: "[::1]:0", cnet: "udp", caddr: "::1", dial: true}, + {snet: "udp", saddr: "[::1]:0", cnet: "udp", caddr: "::1", empty: true}, + {snet: "udp", saddr: "[::1]:0", cnet: "udp", caddr: "::1", dial: true, empty: true}, {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr()}, {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), dial: true}, {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), empty: true}, {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), dial: true, empty: true}, - {snet: "unixgram", saddr: "@gotest6/net", cnet: "unixgram", caddr: "@gotest6/net.local", linuxOnly: true}, + {snet: "unixgram", saddr: "@gotest6/net", cnet: "unixgram", caddr: "@gotest6/net.local"}, } func TestDatagramPacketConnServer(t *testing.T) { @@ -321,15 +272,14 @@ func TestDatagramPacketConnServer(t *testing.T) { } for _, tt := range datagramPacketConnServerTests { - if skipServerTest(tt.snet, "unixgram", tt.saddr, tt.ipv6, tt.ipv4map, tt.linuxOnly) { + if !testableListenArgs(tt.snet, tt.saddr, tt.caddr) { + t.Logf("skipping %s test", tt.snet+":"+tt.saddr+"->"+tt.caddr) continue } listening := make(chan string) done := make(chan int) switch tt.snet { - case "udp", "udp4", "udp6": - tt.saddr += ":0" case "unixgram": os.Remove(tt.saddr) os.Remove(tt.caddr) @@ -344,8 +294,8 @@ func TestDatagramPacketConnServer(t *testing.T) { if err != nil { t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err) } - taddr = tt.caddr + ":" + port - tt.caddr += ":0" + taddr = JoinHostPort(tt.caddr, port) + tt.caddr = JoinHostPort(tt.caddr, "0") } if tt.dial { runDatagramConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty) diff --git a/src/net/tcpsock.go b/src/net/tcpsock.go index f3dfbd23d3..fbadad65b0 100644 --- a/src/net/tcpsock.go +++ b/src/net/tcpsock.go @@ -25,6 +25,13 @@ func (a *TCPAddr) String() string { return JoinHostPort(ip, itoa(a.Port)) } +func (a *TCPAddr) isWildcard() bool { + if a == nil || a.IP == nil { + return true + } + return a.IP.IsUnspecified() +} + func (a *TCPAddr) toAddr() Addr { if a == nil { return nil diff --git a/src/net/tcpsock_posix.go b/src/net/tcpsock_posix.go index aaff0acaa6..024dcd4f83 100644 --- a/src/net/tcpsock_posix.go +++ b/src/net/tcpsock_posix.go @@ -38,13 +38,6 @@ func (a *TCPAddr) family() int { return syscall.AF_INET6 } -func (a *TCPAddr) isWildcard() bool { - if a == nil || a.IP == nil { - return true - } - return a.IP.IsUnspecified() -} - func (a *TCPAddr) sockaddr(family int) (syscall.Sockaddr, error) { if a == nil { return nil, nil diff --git a/src/net/udpsock.go b/src/net/udpsock.go index 4c99ae4af6..532f7d5080 100644 --- a/src/net/udpsock.go +++ b/src/net/udpsock.go @@ -25,6 +25,13 @@ func (a *UDPAddr) String() string { return JoinHostPort(ip, itoa(a.Port)) } +func (a *UDPAddr) isWildcard() bool { + if a == nil || a.IP == nil { + return true + } + return a.IP.IsUnspecified() +} + func (a *UDPAddr) toAddr() Addr { if a == nil { return nil diff --git a/src/net/udpsock_posix.go b/src/net/udpsock_posix.go index 0770b7c5ce..9733e7b833 100644 --- a/src/net/udpsock_posix.go +++ b/src/net/udpsock_posix.go @@ -31,13 +31,6 @@ func (a *UDPAddr) family() int { return syscall.AF_INET6 } -func (a *UDPAddr) isWildcard() bool { - if a == nil || a.IP == nil { - return true - } - return a.IP.IsUnspecified() -} - func (a *UDPAddr) sockaddr(family int) (syscall.Sockaddr, error) { if a == nil { return nil, nil diff --git a/src/net/unix_test.go b/src/net/unix_test.go index 55c5072bc9..85d1ff422f 100644 --- a/src/net/unix_test.go +++ b/src/net/unix_test.go @@ -17,9 +17,10 @@ import ( ) func TestReadUnixgramWithUnnamedSocket(t *testing.T) { - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { - t.Skipf("skipping unixgram test on %s/%s", runtime.GOOS, runtime.GOARCH) + if !testableNetwork("unixgram") { + t.Skip("unixgram test") } + addr := testUnixAddr() la, err := ResolveUnixAddr("unixgram", addr) if err != nil { @@ -67,8 +68,8 @@ func TestReadUnixgramWithUnnamedSocket(t *testing.T) { } func TestReadUnixgramWithZeroBytesBuffer(t *testing.T) { - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { - t.Skipf("skipping unixgram test on %s/%s", runtime.GOOS, runtime.GOARCH) + if !testableNetwork("unixgram") { + t.Skip("unixgram test") } // issue 4352: Recvfrom failed with "address family not // supported by protocol family" if zero-length buffer provided @@ -149,6 +150,7 @@ func TestUnixAutobindClose(t *testing.T) { if runtime.GOOS != "linux" { t.Skip("skipping: autobind is linux only") } + laddr := &UnixAddr{Name: "", Net: "unix"} ln, err := ListenUnix("unix", laddr) if err != nil { @@ -158,9 +160,10 @@ func TestUnixAutobindClose(t *testing.T) { } func TestUnixgramWrite(t *testing.T) { - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { - t.Skipf("skipping unixgram test on %s/%s", runtime.GOOS, runtime.GOARCH) + if !testableNetwork("unixgram") { + t.Skip("unixgram test") } + addr := testUnixAddr() laddr, err := ResolveUnixAddr("unixgram", addr) if err != nil { @@ -228,9 +231,10 @@ func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) { } func TestUnixConnLocalAndRemoteNames(t *testing.T) { - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { - t.Skipf("skipping unixgram test on %s/%s", runtime.GOOS, runtime.GOARCH) + if !testableNetwork("unix") { + t.Skip("unix test") } + for _, laddr := range []string{"", testUnixAddr()} { laddr := laddr taddr := testUnixAddr() @@ -290,9 +294,10 @@ func TestUnixConnLocalAndRemoteNames(t *testing.T) { } func TestUnixgramConnLocalAndRemoteNames(t *testing.T) { - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { - t.Skipf("skipping unixgram test on %s/%s", runtime.GOOS, runtime.GOARCH) + if !testableNetwork("unixgram") { + t.Skip("unixgram test") } + for _, laddr := range []string{"", testUnixAddr()} { laddr := laddr taddr := testUnixAddr()