diff options
Diffstat (limited to 'libgo/go/net/tcp_test.go')
-rw-r--r-- | libgo/go/net/tcp_test.go | 150 |
1 files changed, 134 insertions, 16 deletions
diff --git a/libgo/go/net/tcp_test.go b/libgo/go/net/tcp_test.go index 1d54b3a..a71b02b 100644 --- a/libgo/go/net/tcp_test.go +++ b/libgo/go/net/tcp_test.go @@ -5,29 +5,58 @@ package net import ( + "fmt" "reflect" "runtime" "testing" "time" ) -func BenchmarkTCPOneShot(b *testing.B) { - benchmarkTCP(b, false, false) +func BenchmarkTCP4OneShot(b *testing.B) { + benchmarkTCP(b, false, false, "127.0.0.1:0") } -func BenchmarkTCPOneShotTimeout(b *testing.B) { - benchmarkTCP(b, false, true) +func BenchmarkTCP4OneShotTimeout(b *testing.B) { + benchmarkTCP(b, false, true, "127.0.0.1:0") } -func BenchmarkTCPPersistent(b *testing.B) { - benchmarkTCP(b, true, false) +func BenchmarkTCP4Persistent(b *testing.B) { + benchmarkTCP(b, true, false, "127.0.0.1:0") } -func BenchmarkTCPPersistentTimeout(b *testing.B) { - benchmarkTCP(b, true, true) +func BenchmarkTCP4PersistentTimeout(b *testing.B) { + benchmarkTCP(b, true, true, "127.0.0.1:0") } -func benchmarkTCP(b *testing.B, persistent, timeout bool) { +func BenchmarkTCP6OneShot(b *testing.B) { + if !supportsIPv6 { + b.Skip("ipv6 is not supported") + } + benchmarkTCP(b, false, false, "[::1]:0") +} + +func BenchmarkTCP6OneShotTimeout(b *testing.B) { + if !supportsIPv6 { + b.Skip("ipv6 is not supported") + } + benchmarkTCP(b, false, true, "[::1]:0") +} + +func BenchmarkTCP6Persistent(b *testing.B) { + if !supportsIPv6 { + b.Skip("ipv6 is not supported") + } + benchmarkTCP(b, true, false, "[::1]:0") +} + +func BenchmarkTCP6PersistentTimeout(b *testing.B) { + if !supportsIPv6 { + b.Skip("ipv6 is not supported") + } + benchmarkTCP(b, true, true, "[::1]:0") +} + +func benchmarkTCP(b *testing.B, persistent, timeout bool, laddr string) { const msgLen = 512 conns := b.N numConcurrent := runtime.GOMAXPROCS(-1) * 16 @@ -61,7 +90,7 @@ func benchmarkTCP(b *testing.B, persistent, timeout bool) { } return true } - ln, err := Listen("tcp", "127.0.0.1:0") + ln, err := Listen("tcp", laddr) if err != nil { b.Fatalf("Listen failed: %v", err) } @@ -118,24 +147,39 @@ func benchmarkTCP(b *testing.B, persistent, timeout bool) { } } -var resolveTCPAddrTests = []struct { +type resolveTCPAddrTest struct { net string litAddr string addr *TCPAddr err error -}{ +} + +var resolveTCPAddrTests = []resolveTCPAddrTest{ {"tcp", "127.0.0.1:0", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, {"tcp4", "127.0.0.1:65535", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535}, nil}, {"tcp", "[::1]:1", &TCPAddr{IP: ParseIP("::1"), Port: 1}, nil}, {"tcp6", "[::1]:65534", &TCPAddr{IP: ParseIP("::1"), Port: 65534}, nil}, + {"tcp", "[::1%en0]:1", &TCPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"}, nil}, + {"tcp6", "[::1%911]:2", &TCPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911"}, nil}, + {"", "127.0.0.1:0", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, // Go 1.0 behavior {"", "[::1]:0", &TCPAddr{IP: ParseIP("::1"), Port: 0}, nil}, // Go 1.0 behavior {"http", "127.0.0.1:0", nil, UnknownNetworkError("http")}, } +func init() { + if ifi := loopbackInterface(); ifi != nil { + index := fmt.Sprintf("%v", ifi.Index) + resolveTCPAddrTests = append(resolveTCPAddrTests, []resolveTCPAddrTest{ + {"tcp6", "[fe80::1%" + ifi.Name + "]:3", &TCPAddr{IP: ParseIP("fe80::1"), Port: 3, Zone: zoneToString(ifi.Index)}, nil}, + {"tcp6", "[fe80::1%" + index + "]:4", &TCPAddr{IP: ParseIP("fe80::1"), Port: 4, Zone: index}, nil}, + }...) + } +} + func TestResolveTCPAddr(t *testing.T) { for _, tt := range resolveTCPAddrTests { addr, err := ResolveTCPAddr(tt.net, tt.litAddr) @@ -165,14 +209,88 @@ func TestTCPListenerName(t *testing.T) { for _, tt := range tcpListenerNameTests { ln, err := ListenTCP(tt.net, tt.laddr) if err != nil { - t.Errorf("ListenTCP failed: %v", err) - return + t.Fatalf("ListenTCP failed: %v", err) } defer ln.Close() la := ln.Addr() if a, ok := la.(*TCPAddr); !ok || a.Port == 0 { - t.Errorf("got %v; expected a proper address with non-zero port number", la) - return + t.Fatalf("got %v; expected a proper address with non-zero port number", la) + } + } +} + +func TestIPv6LinkLocalUnicastTCP(t *testing.T) { + if testing.Short() || !*testExternal { + t.Skip("skipping test to avoid external network") + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + ifi := loopbackInterface() + if ifi == nil { + t.Skip("loopback interface not found") + } + laddr := ipv6LinkLocalUnicastAddr(ifi) + if laddr == "" { + t.Skip("ipv6 unicast address on loopback not found") + } + + type test struct { + net, addr string + nameLookup bool + } + var tests = []test{ + {"tcp", "[" + laddr + "%" + ifi.Name + "]:0", false}, + {"tcp6", "[" + laddr + "%" + ifi.Name + "]:0", false}, + } + switch runtime.GOOS { + case "darwin", "freebsd", "opensbd", "netbsd": + tests = append(tests, []test{ + {"tcp", "[localhost%" + ifi.Name + "]:0", true}, + {"tcp6", "[localhost%" + ifi.Name + "]:0", true}, + }...) + case "linux": + tests = append(tests, []test{ + {"tcp", "[ip6-localhost%" + ifi.Name + "]:0", true}, + {"tcp6", "[ip6-localhost%" + ifi.Name + "]:0", true}, + }...) + } + for _, tt := range tests { + ln, err := Listen(tt.net, tt.addr) + if err != nil { + // It might return "LookupHost returned no + // suitable address" error on some platforms. + t.Logf("Listen failed: %v", err) + continue } + defer ln.Close() + if la, ok := ln.Addr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" { + t.Fatalf("got %v; expected a proper address with zone identifier", la) + } + + done := make(chan int) + go transponder(t, ln, done) + + c, err := Dial(tt.net, ln.Addr().String()) + if err != nil { + t.Fatalf("Dial failed: %v", err) + } + defer c.Close() + if la, ok := c.LocalAddr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" { + t.Fatalf("got %v; expected a proper address with zone identifier", la) + } + if ra, ok := c.RemoteAddr().(*TCPAddr); !ok || !tt.nameLookup && ra.Zone == "" { + t.Fatalf("got %v; expected a proper address with zone identifier", ra) + } + + if _, err := c.Write([]byte("TCP OVER IPV6 LINKLOCAL TEST")); err != nil { + t.Fatalf("Conn.Write failed: %v", err) + } + b := make([]byte, 32) + if _, err := c.Read(b); err != nil { + t.Fatalf("Conn.Read failed: %v", err) + } + + <-done } } |