Commit 1a76020c authored by Mikio Hara's avatar Mikio Hara

go.net/ipv6: add missing API tests

Now the package has a code coverage of 76.1% of statements.
Also fixes flaky concurrent test.

Fixes golang/go#5696.

R=golang-codereviews, dave
CC=golang-codereviews
https://golang.org/cl/45620043
parent f316b44c
// Copyright 2013 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 ipv6
import (
"sync"
"testing"
)
func TestControlFlags(t *testing.T) {
tf := FlagInterface | FlagPathMTU
opt := rawOpt{cflags: tf | FlagHopLimit}
// This loop runs methods of raw.Opt concurrently for testing
// concurrent access to the rawOpt. The first entry shold be
// opt.set and the last entry should be opt.clear.
tfns := []func(ControlFlags){opt.set, opt.clear, opt.clear}
ch := make(chan bool)
var wg sync.WaitGroup
for i, fn := range tfns {
wg.Add(1)
go func(i int, fn func(ControlFlags)) {
defer wg.Done()
switch i {
case 0:
close(ch)
case len(tfns) - 1:
<-ch
}
opt.Lock()
defer opt.Unlock()
fn(tf)
}(i, fn)
}
wg.Wait()
if opt.isset(tf) {
t.Fatalf("got %#x; expected %#x", opt.cflags, FlagHopLimit)
}
}
......@@ -14,6 +14,24 @@ import (
"testing"
)
var icmpStringTests = []struct {
in ipv6.ICMPType
out string
}{
{ipv6.ICMPTypeDestinationUnreachable, "destination unreachable"},
{256, "<nil>"},
}
func TestICMPString(t *testing.T) {
for _, tt := range icmpStringTests {
s := tt.in.String()
if s != tt.out {
t.Errorf("got %s; expected %s", s, tt.out)
}
}
}
func TestICMPFilter(t *testing.T) {
switch runtime.GOOS {
case "plan9", "windows":
......
......@@ -5,6 +5,7 @@
package ipv6_test
import (
"bytes"
"code.google.com/p/go.net/ipv6"
"net"
"os"
......@@ -64,9 +65,11 @@ func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
cm := ipv6.ControlMessage{
TrafficClass: DiffServAF11 | CongestionExperienced,
Src: net.IPv6loopback,
IfIndex: ifi.Index,
}
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
wb := []byte("HELLO-R-U-THERE")
for i, toggle := range []bool{true, false, true} {
if err := p.SetControlMessage(cf, toggle); err != nil {
......@@ -76,12 +79,16 @@ func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
t.Fatalf("ipv6.PacketConn.SetDeadline failed: %v", err)
}
cm.HopLimit = i + 1
if _, err := p.WriteTo([]byte("HELLO-R-U-THERE"), &cm, dst); err != nil {
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
} else if n != len(wb) {
t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
}
b := make([]byte, 128)
if _, cm, _, err := p.ReadFrom(b); err != nil {
rb := make([]byte, 128)
if n, cm, _, err := p.ReadFrom(rb); err != nil {
t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
} else if !bytes.Equal(rb[:n], wb) {
t.Fatalf("got %v; expected %v", rb[:n], wb)
} else {
t.Logf("rcvd cmsg: %v", cm)
}
......@@ -136,9 +143,10 @@ func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
cm := ipv6.ControlMessage{
TrafficClass: DiffServAF11 | CongestionExperienced,
Src: net.IPv6loopback,
IfIndex: ifi.Index,
}
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
var f ipv6.ICMPFilter
f.SetAll(true)
......@@ -177,15 +185,17 @@ func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
t.Fatalf("ipv6.PacketConn.SetDeadline failed: %v", err)
}
cm.HopLimit = i + 1
if _, err := p.WriteTo(wb, &cm, dst); err != nil {
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
} else if n != len(wb) {
t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
}
b := make([]byte, 128)
if n, cm, _, err := p.ReadFrom(b); err != nil {
rb := make([]byte, 128)
if n, cm, _, err := p.ReadFrom(rb); err != nil {
t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
} else {
t.Logf("rcvd cmsg: %v", cm)
if m, err := parseICMPMessage(b[:n]); err != nil {
if m, err := parseICMPMessage(rb[:n]); err != nil {
t.Fatalf("parseICMPMessage failed: %v", err)
} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
......
// Copyright 2013 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 ipv6_test
import (
"bytes"
"code.google.com/p/go.net/ipv6"
"net"
"runtime"
"sync"
"testing"
)
func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
c, err := net.ListenPacket("udp6", "[::1]:0")
if err != nil {
return nil, nil, err
}
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
if err != nil {
c.Close()
return nil, nil, err
}
return c, dst, nil
}
func BenchmarkReadWriteNetUDP(b *testing.B) {
c, dst, err := benchmarkUDPListener()
if err != nil {
b.Fatalf("benchmarkUDPListener failed: %v", err)
}
defer c.Close()
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
b.ResetTimer()
for i := 0; i < b.N; i++ {
benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
}
}
func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
if _, err := c.WriteTo(wb, dst); err != nil {
b.Fatalf("net.PacketConn.WriteTo failed: %v", err)
}
if _, _, err := c.ReadFrom(rb); err != nil {
b.Fatalf("net.PacketConn.ReadFrom failed: %v", err)
}
}
func BenchmarkReadWriteIPv6UDP(b *testing.B) {
c, dst, err := benchmarkUDPListener()
if err != nil {
b.Fatalf("benchmarkUDPListener failed: %v", err)
}
defer c.Close()
p := ipv6.NewPacketConn(c)
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
if err := p.SetControlMessage(cf, true); err != nil {
b.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
}
ifi := loopbackInterface()
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
b.ResetTimer()
for i := 0; i < b.N; i++ {
benchmarkReadWriteIPv6UDP(b, p, wb, rb, dst, ifi)
}
}
func benchmarkReadWriteIPv6UDP(b *testing.B, p *ipv6.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
cm := ipv6.ControlMessage{
TrafficClass: DiffServAF11 | CongestionExperienced,
HopLimit: 1,
}
if ifi != nil {
cm.IfIndex = ifi.Index
}
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
b.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
} else if n != len(wb) {
b.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
}
if _, _, _, err := p.ReadFrom(rb); err != nil {
b.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
}
}
func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
switch runtime.GOOS {
case "plan9", "windows":
t.Skipf("not supported on %q", runtime.GOOS)
}
if !supportsIPv6 {
t.Skip("ipv6 is not supported")
}
c, err := net.ListenPacket("udp6", "[::1]:0")
if err != nil {
t.Fatalf("net.ListenPacket failed: %v", err)
}
defer c.Close()
p := ipv6.NewPacketConn(c)
defer p.Close()
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
if err != nil {
t.Fatalf("net.ResolveUDPAddr failed: %v", err)
}
ifi := loopbackInterface()
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
wb := []byte("HELLO-R-U-THERE")
var wg sync.WaitGroup
reader := func() {
defer wg.Done()
rb := make([]byte, 128)
if n, cm, _, err := p.ReadFrom(rb); err != nil {
t.Errorf("ipv6.PacketConn.ReadFrom failed: %v", err)
return
} else if !bytes.Equal(rb[:n], wb) {
t.Errorf("got %v; expected %v", rb[:n], wb)
return
} else {
t.Logf("rcvd cmsg: %v", cm)
}
}
writer := func(toggle bool) {
defer wg.Done()
cm := ipv6.ControlMessage{
TrafficClass: DiffServAF11 | CongestionExperienced,
Src: net.IPv6loopback,
Dst: net.IPv6loopback,
}
if ifi != nil {
cm.IfIndex = ifi.Index
}
if err := p.SetControlMessage(cf, toggle); err != nil {
t.Errorf("ipv6.PacketConn.SetControlMessage failed: %v", err)
return
}
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
t.Errorf("ipv6.PacketConn.WriteTo failed: %v", err)
return
} else if n != len(wb) {
t.Errorf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
return
}
}
const N = 10
wg.Add(N)
for i := 0; i < N; i++ {
go reader()
}
wg.Add(2 * N)
for i := 0; i < 2*N; i++ {
go writer(i%2 != 0)
}
wg.Add(N)
for i := 0; i < N; i++ {
go reader()
}
wg.Wait()
}
......@@ -5,6 +5,7 @@
package ipv6_test
import (
"bytes"
"code.google.com/p/go.net/ipv6"
"net"
"os"
......@@ -13,79 +14,6 @@ import (
"time"
)
func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
c, err := net.ListenPacket("udp6", "[::1]:0")
if err != nil {
return nil, nil, err
}
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
if err != nil {
c.Close()
return nil, nil, err
}
return c, dst, nil
}
func BenchmarkReadWriteNetUDP(b *testing.B) {
c, dst, err := benchmarkUDPListener()
if err != nil {
b.Fatalf("benchmarkUDPListener failed: %v", err)
}
defer c.Close()
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
b.ResetTimer()
for i := 0; i < b.N; i++ {
benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
}
}
func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
if _, err := c.WriteTo(wb, dst); err != nil {
b.Fatalf("net.PacketConn.WriteTo failed: %v", err)
}
if _, _, err := c.ReadFrom(rb); err != nil {
b.Fatalf("net.PacketConn.ReadFrom failed: %v", err)
}
}
func BenchmarkReadWriteIPv6UDP(b *testing.B) {
c, dst, err := benchmarkUDPListener()
if err != nil {
b.Fatalf("benchmarkUDPListener failed: %v", err)
}
defer c.Close()
p := ipv6.NewPacketConn(c)
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
if err := p.SetControlMessage(cf, true); err != nil {
b.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
}
ifi := loopbackInterface()
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
b.ResetTimer()
for i := 0; i < b.N; i++ {
benchmarkReadWriteIPv6UDP(b, p, wb, rb, dst, ifi)
}
}
func benchmarkReadWriteIPv6UDP(b *testing.B, p *ipv6.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
cm := ipv6.ControlMessage{
TrafficClass: DiffServAF11 | CongestionExperienced,
HopLimit: 1,
}
if ifi != nil {
cm.IfIndex = ifi.Index
}
if _, err := p.WriteTo(wb, &cm, dst); err != nil {
b.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
}
if _, _, _, err := p.ReadFrom(rb); err != nil {
b.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
}
}
func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
switch runtime.GOOS {
case "plan9", "windows":
......@@ -100,22 +28,25 @@ func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
t.Fatalf("net.ListenPacket failed: %v", err)
}
defer c.Close()
p := ipv6.NewPacketConn(c)
defer p.Close()
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
if err != nil {
t.Fatalf("net.ResolveUDPAddr failed: %v", err)
}
p := ipv6.NewPacketConn(c)
defer p.Close()
cm := ipv6.ControlMessage{
TrafficClass: DiffServAF11 | CongestionExperienced,
Src: net.IPv6loopback,
Dst: net.IPv6loopback,
}
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
ifi := loopbackInterface()
if ifi != nil {
cm.IfIndex = ifi.Index
}
wb := []byte("HELLO-R-U-THERE")
for i, toggle := range []bool{true, false, true} {
if err := p.SetControlMessage(cf, toggle); err != nil {
......@@ -125,15 +56,19 @@ func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
if err := p.SetWriteDeadline(time.Now().Add(time.Millisecond * 100)); err != nil {
t.Fatalf("ipv6.PacketConn.SetWriteDeadline failed: %v", err)
}
if _, err := p.WriteTo([]byte("HELLO-R-U-THERE"), &cm, dst); err != nil {
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
} else if n != len(wb) {
t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
}
b := make([]byte, 128)
rb := make([]byte, 128)
if err := p.SetReadDeadline(time.Now().Add(time.Millisecond * 100)); err != nil {
t.Fatalf("ipv6.PacketConn.SetReadDeadline failed: %v", err)
}
if _, cm, _, err := p.ReadFrom(b); err != nil {
if n, cm, _, err := p.ReadFrom(rb); err != nil {
t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
} else if !bytes.Equal(rb[:n], wb) {
t.Fatalf("got %v; expected %v", rb[:n], wb)
} else {
t.Logf("rcvd cmsg: %v", cm)
}
......@@ -157,6 +92,8 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
t.Fatalf("net.ListenPacket failed: %v", err)
}
defer c.Close()
p := ipv6.NewPacketConn(c)
defer p.Close()
dst, err := net.ResolveIPAddr("ip6", "::1")
if err != nil {
......@@ -164,10 +101,12 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
}
pshicmp := ipv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, dst.IP, ianaProtocolIPv6ICMP)
p := ipv6.NewPacketConn(c)
defer p.Close()
cm := ipv6.ControlMessage{TrafficClass: DiffServAF11 | CongestionExperienced}
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
cm := ipv6.ControlMessage{
TrafficClass: DiffServAF11 | CongestionExperienced,
Src: net.IPv6loopback,
Dst: net.IPv6loopback,
}
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
ifi := loopbackInterface()
if ifi != nil {
cm.IfIndex = ifi.Index
......@@ -210,18 +149,20 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
if err := p.SetWriteDeadline(time.Now().Add(time.Millisecond * 100)); err != nil {
t.Fatalf("ipv6.PacketConn.SetWriteDeadline failed: %v", err)
}
if _, err := p.WriteTo(wb, &cm, dst); err != nil {
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
} else if n != len(wb) {
t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
}
b := make([]byte, 128)
rb := make([]byte, 128)
if err := p.SetReadDeadline(time.Now().Add(time.Millisecond * 100)); err != nil {
t.Fatalf("ipv6.PacketConn.SetReadDeadline failed: %v", err)
}
if n, cm, _, err := p.ReadFrom(b); err != nil {
if n, cm, _, err := p.ReadFrom(rb); err != nil {
t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
} else {
t.Logf("rcvd cmsg: %v", cm)
if m, err := parseICMPMessage(b[:n]); err != nil {
if m, err := parseICMPMessage(rb[:n]); err != nil {
t.Fatalf("parseICMPMessage failed: %v", err)
} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment