Skip to content

Commit

Permalink
go.net/ipv6: add missing API tests
Browse files Browse the repository at this point in the history
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
  • Loading branch information
cixtor committed Dec 31, 2013
1 parent f316b44 commit 1a76020
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 138 deletions.
42 changes: 0 additions & 42 deletions ipv6/control_test.go

This file was deleted.

18 changes: 18 additions & 0 deletions ipv6/icmp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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":
Expand Down
28 changes: 19 additions & 9 deletions ipv6/multicast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package ipv6_test

import (
"bytes"
"code.google.com/p/go.net/ipv6"
"net"
"os"
Expand Down Expand Up @@ -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 {
Expand All @@ -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)
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
168 changes: 168 additions & 0 deletions ipv6/readwrite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// 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()
}

0 comments on commit 1a76020

Please sign in to comment.