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>
diff --git a/src/net/unix_test.go b/src/net/unix_test.go
index ca7872e..9e0db57 100644
--- a/src/net/unix_test.go
+++ b/src/net/unix_test.go
@@ -67,50 +67,101 @@
 	}
 }
 
-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))
 		}
-	}()
-
-	<-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)
+		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)
+			}
+		}
 	}
 }