1
0
mirror of https://github.com/golang/go synced 2024-11-18 14:44:41 -07:00

net: deflake zero byte IO tests on datagram

This change deflakes zero byte read/write tests on datagram sockets, and
enables them by default.

Change-Id: I52f1a76f8ff379d90f40a07bb352fae9343ea41a
Reviewed-on: https://go-review.googlesource.com/9194
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Mikio Hara 2015-04-20 23:15:00 +09:00
parent 275755401d
commit 03eb132684
4 changed files with 157 additions and 85 deletions

View File

@ -24,12 +24,6 @@ var (
)
var (
// Do not test datagrams with empty payload by default.
// It depends on each platform implementation whether generic
// read, socket recv system calls return the result of zero
// byte read.
testDatagram = flag.Bool("datagram", false, "whether to test UDP and unixgram")
testDNSFlood = flag.Bool("dnsflood", false, "whether to test DNS query flooding")
testExternal = flag.Bool("external", true, "allow use of external networks during long test")

View File

@ -259,53 +259,6 @@ var datagramPacketConnServerTests = []struct {
{snet: "unixgram", saddr: "@gotest6/net", cnet: "unixgram", caddr: "@gotest6/net.local"},
}
func TestDatagramPacketConnServer(t *testing.T) {
if !*testDatagram {
return
}
for _, tt := range datagramPacketConnServerTests {
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 "unixgram":
os.Remove(tt.saddr)
os.Remove(tt.caddr)
}
go runDatagramPacketConnServer(t, tt.snet, tt.saddr, listening, done)
taddr := <-listening // wait for server to start
switch tt.cnet {
case "udp", "udp4", "udp6":
_, port, err := SplitHostPort(taddr)
if err != nil {
t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err)
}
taddr = JoinHostPort(tt.caddr, port)
tt.caddr = JoinHostPort(tt.caddr, "0")
}
if tt.dial {
runDatagramConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty)
} else {
runDatagramPacketConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty)
}
<-done // tell server to stop
<-done // make sure server stopped
switch tt.snet {
case "unixgram":
os.Remove(tt.saddr)
os.Remove(tt.caddr)
}
}
}
func runDatagramPacketConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) {
c, err := ListenPacket(net, laddr)
if err != nil {

View File

@ -355,3 +355,77 @@ func TestIPv6LinkLocalUnicastUDP(t *testing.T) {
}
}
}
func TestUDPZeroBytePayload(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
}
c, err := newLocalPacketListener("udp")
if err != nil {
t.Fatal(err)
}
defer c.Close()
for _, genericRead := range []bool{false, true} {
n, err := c.WriteTo(nil, c.LocalAddr())
if err != nil {
t.Fatal(err)
}
if n != 0 {
t.Errorf("got %d; want 0", n)
}
c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
var b [1]byte
if genericRead {
_, err = c.(Conn).Read(b[:])
} else {
_, _, err = c.ReadFrom(b[:])
}
switch err {
case nil: // ReadFrom succeeds
default: // Read may timeout, it depends on the platform
if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
t.Fatal(err)
}
}
}
}
func TestUDPZeroByteBuffer(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
}
c, err := newLocalPacketListener("udp")
if err != nil {
t.Fatal(err)
}
defer c.Close()
b := []byte("UDP ZERO BYTE BUFFER")
for _, genericRead := range []bool{false, true} {
n, err := c.WriteTo(b, c.LocalAddr())
if err != nil {
t.Fatal(err)
}
if n != len(b) {
t.Errorf("got %d; want %d", n, len(b))
}
c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
if genericRead {
_, err = c.(Conn).Read(nil)
} else {
_, _, err = c.ReadFrom(nil)
}
switch err {
case nil: // ReadFrom succeeds
default: // Read may timeout, it depends on the platform
if nerr, ok := err.(Error); (!ok || !nerr.Timeout()) && runtime.GOOS != "windows" { // Windows retruns WSAEMSGSIZ
t.Fatal(err)
}
}
}
}

View File

@ -67,50 +67,101 @@ func TestReadUnixgramWithUnnamedSocket(t *testing.T) {
}
}
func TestReadUnixgramWithZeroBytesBuffer(t *testing.T) {
func TestUnixgramZeroBytePayload(t *testing.T) {
if !testableNetwork("unixgram") {
t.Skip("unixgram test")
}
c1, err := newLocalPacketListener("unixgram")
if err != nil {
t.Fatal(err)
}
defer os.Remove(c1.LocalAddr().String())
defer c1.Close()
c2, err := Dial("unixgram", c1.LocalAddr().String())
if err != nil {
t.Fatal(err)
}
defer os.Remove(c2.LocalAddr().String())
defer c2.Close()
for _, genericRead := range []bool{false, true} {
n, err := c2.Write(nil)
if err != nil {
t.Fatal(err)
}
if n != 0 {
t.Errorf("got %d; want 0", n)
}
c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
var b [1]byte
var peer Addr
if genericRead {
_, err = c1.(Conn).Read(b[:])
} else {
_, peer, err = c1.ReadFrom(b[:])
}
switch err {
case nil: // ReadFrom succeeds
if peer != nil { // peer is connected-mode
t.Fatalf("unexpected peer address: %v", peer)
}
default: // Read may timeout, it depends on the platform
if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
t.Fatal(err)
}
}
}
}
func TestUnixgramZeroByteBuffer(t *testing.T) {
if !testableNetwork("unixgram") {
t.Skip("unixgram test")
}
// issue 4352: Recvfrom failed with "address family not
// supported by protocol family" if zero-length buffer provided
addr := testUnixAddr()
la, err := ResolveUnixAddr("unixgram", addr)
c1, err := newLocalPacketListener("unixgram")
if err != nil {
t.Fatalf("ResolveUnixAddr failed: %v", err)
t.Fatal(err)
}
c, err := ListenUnixgram("unixgram", la)
if err != nil {
t.Fatalf("ListenUnixgram failed: %v", err)
}
defer func() {
c.Close()
os.Remove(addr)
}()
defer os.Remove(c1.LocalAddr().String())
defer c1.Close()
off := make(chan bool)
go func() {
defer func() { off <- true }()
c, err := DialUnix("unixgram", nil, la)
c2, err := Dial("unixgram", c1.LocalAddr().String())
if err != nil {
t.Fatal(err)
}
defer os.Remove(c2.LocalAddr().String())
defer c2.Close()
b := []byte("UNIXGRAM ZERO BYTE BUFFER")
for _, genericRead := range []bool{false, true} {
n, err := c2.Write(b)
if err != nil {
t.Errorf("DialUnix failed: %v", err)
return
t.Fatal(err)
}
defer c.Close()
if _, err := c.Write([]byte{1, 2, 3, 4, 5}); err != nil {
t.Errorf("UnixConn.Write failed: %v", err)
return
if n != len(b) {
t.Errorf("got %d; want %d", n, len(b))
}
c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
var peer Addr
if genericRead {
_, err = c1.(Conn).Read(nil)
} else {
_, peer, err = c1.ReadFrom(nil)
}
switch err {
case nil: // ReadFrom succeeds
if peer != nil { // peer is connected-mode
t.Fatalf("unexpected peer address: %v", peer)
}
default: // Read may timeout, it depends on the platform
if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
t.Fatal(err)
}
}
}()
<-off
c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
_, from, err := c.ReadFrom(nil)
if err != nil {
t.Fatalf("UnixConn.ReadFrom failed: %v", err)
}
if from != nil {
t.Fatalf("neighbor address is %v", from)
}
}