From 03eb132684016cee4728504425764433d7d1ff70 Mon Sep 17 00:00:00 2001 From: Mikio Hara Date: Mon, 20 Apr 2015 23:15:00 +0900 Subject: [PATCH] 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 --- src/net/main_test.go | 6 --- src/net/server_test.go | 47 ------------------ src/net/udp_test.go | 74 ++++++++++++++++++++++++++++ src/net/unix_test.go | 109 ++++++++++++++++++++++++++++++----------- 4 files changed, 154 insertions(+), 82 deletions(-) diff --git a/src/net/main_test.go b/src/net/main_test.go index 08cf62561d..a56b9cd5f9 100644 --- a/src/net/main_test.go +++ b/src/net/main_test.go @@ -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") diff --git a/src/net/server_test.go b/src/net/server_test.go index 215d59d29f..f064782783 100644 --- a/src/net/server_test.go +++ b/src/net/server_test.go @@ -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 { diff --git a/src/net/udp_test.go b/src/net/udp_test.go index 371d4e6884..383c6b5f17 100644 --- a/src/net/udp_test.go +++ b/src/net/udp_test.go @@ -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) + } + } + } +} diff --git a/src/net/unix_test.go b/src/net/unix_test.go index ca7872e4ee..9e0db57cff 100644 --- a/src/net/unix_test.go +++ b/src/net/unix_test.go @@ -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") } - // 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) + defer os.Remove(c1.LocalAddr().String()) + defer c1.Close() + + c2, err := Dial("unixgram", c1.LocalAddr().String()) if err != nil { - t.Fatalf("ListenUnixgram failed: %v", err) + t.Fatal(err) } - defer func() { - c.Close() - os.Remove(addr) - }() + defer os.Remove(c2.LocalAddr().String()) + defer c2.Close() - off := make(chan bool) - go func() { - defer func() { off <- true }() - c, err := DialUnix("unixgram", nil, la) + for _, genericRead := range []bool{false, true} { + n, err := c2.Write(nil) 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 != 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) + } + } + } +} - <-off - c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) - _, from, err := c.ReadFrom(nil) +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 + + c1, err := newLocalPacketListener("unixgram") if err != nil { - t.Fatalf("UnixConn.ReadFrom failed: %v", err) + t.Fatal(err) } - if from != nil { - t.Fatalf("neighbor address is %v", from) + 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() + + b := []byte("UNIXGRAM ZERO BYTE BUFFER") + for _, genericRead := range []bool{false, true} { + n, err := c2.Write(b) + if err != nil { + t.Fatal(err) + } + 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) + } + } } } -- 2.48.1