Skip to content

Commit 03eb132

Browse files
committed
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 <[email protected]>
1 parent 2757554 commit 03eb132

File tree

4 files changed

+154
-82
lines changed

4 files changed

+154
-82
lines changed

src/net/main_test.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@ var (
2424
)
2525

2626
var (
27-
// Do not test datagrams with empty payload by default.
28-
// It depends on each platform implementation whether generic
29-
// read, socket recv system calls return the result of zero
30-
// byte read.
31-
testDatagram = flag.Bool("datagram", false, "whether to test UDP and unixgram")
32-
3327
testDNSFlood = flag.Bool("dnsflood", false, "whether to test DNS query flooding")
3428

3529
testExternal = flag.Bool("external", true, "allow use of external networks during long test")

src/net/server_test.go

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -259,53 +259,6 @@ var datagramPacketConnServerTests = []struct {
259259
{snet: "unixgram", saddr: "@gotest6/net", cnet: "unixgram", caddr: "@gotest6/net.local"},
260260
}
261261

262-
func TestDatagramPacketConnServer(t *testing.T) {
263-
if !*testDatagram {
264-
return
265-
}
266-
267-
for _, tt := range datagramPacketConnServerTests {
268-
if !testableListenArgs(tt.snet, tt.saddr, tt.caddr) {
269-
t.Logf("skipping %s test", tt.snet+":"+tt.saddr+"->"+tt.caddr)
270-
continue
271-
}
272-
273-
listening := make(chan string)
274-
done := make(chan int)
275-
switch tt.snet {
276-
case "unixgram":
277-
os.Remove(tt.saddr)
278-
os.Remove(tt.caddr)
279-
}
280-
281-
go runDatagramPacketConnServer(t, tt.snet, tt.saddr, listening, done)
282-
taddr := <-listening // wait for server to start
283-
284-
switch tt.cnet {
285-
case "udp", "udp4", "udp6":
286-
_, port, err := SplitHostPort(taddr)
287-
if err != nil {
288-
t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err)
289-
}
290-
taddr = JoinHostPort(tt.caddr, port)
291-
tt.caddr = JoinHostPort(tt.caddr, "0")
292-
}
293-
if tt.dial {
294-
runDatagramConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty)
295-
} else {
296-
runDatagramPacketConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty)
297-
}
298-
<-done // tell server to stop
299-
<-done // make sure server stopped
300-
301-
switch tt.snet {
302-
case "unixgram":
303-
os.Remove(tt.saddr)
304-
os.Remove(tt.caddr)
305-
}
306-
}
307-
}
308-
309262
func runDatagramPacketConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) {
310263
c, err := ListenPacket(net, laddr)
311264
if err != nil {

src/net/udp_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,77 @@ func TestIPv6LinkLocalUnicastUDP(t *testing.T) {
355355
}
356356
}
357357
}
358+
359+
func TestUDPZeroBytePayload(t *testing.T) {
360+
switch runtime.GOOS {
361+
case "nacl", "plan9":
362+
t.Skipf("not supported on %s", runtime.GOOS)
363+
}
364+
365+
c, err := newLocalPacketListener("udp")
366+
if err != nil {
367+
t.Fatal(err)
368+
}
369+
defer c.Close()
370+
371+
for _, genericRead := range []bool{false, true} {
372+
n, err := c.WriteTo(nil, c.LocalAddr())
373+
if err != nil {
374+
t.Fatal(err)
375+
}
376+
if n != 0 {
377+
t.Errorf("got %d; want 0", n)
378+
}
379+
c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
380+
var b [1]byte
381+
if genericRead {
382+
_, err = c.(Conn).Read(b[:])
383+
} else {
384+
_, _, err = c.ReadFrom(b[:])
385+
}
386+
switch err {
387+
case nil: // ReadFrom succeeds
388+
default: // Read may timeout, it depends on the platform
389+
if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
390+
t.Fatal(err)
391+
}
392+
}
393+
}
394+
}
395+
396+
func TestUDPZeroByteBuffer(t *testing.T) {
397+
switch runtime.GOOS {
398+
case "nacl", "plan9":
399+
t.Skipf("not supported on %s", runtime.GOOS)
400+
}
401+
402+
c, err := newLocalPacketListener("udp")
403+
if err != nil {
404+
t.Fatal(err)
405+
}
406+
defer c.Close()
407+
408+
b := []byte("UDP ZERO BYTE BUFFER")
409+
for _, genericRead := range []bool{false, true} {
410+
n, err := c.WriteTo(b, c.LocalAddr())
411+
if err != nil {
412+
t.Fatal(err)
413+
}
414+
if n != len(b) {
415+
t.Errorf("got %d; want %d", n, len(b))
416+
}
417+
c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
418+
if genericRead {
419+
_, err = c.(Conn).Read(nil)
420+
} else {
421+
_, _, err = c.ReadFrom(nil)
422+
}
423+
switch err {
424+
case nil: // ReadFrom succeeds
425+
default: // Read may timeout, it depends on the platform
426+
if nerr, ok := err.(Error); (!ok || !nerr.Timeout()) && runtime.GOOS != "windows" { // Windows retruns WSAEMSGSIZ
427+
t.Fatal(err)
428+
}
429+
}
430+
}
431+
}

src/net/unix_test.go

Lines changed: 80 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -67,50 +67,101 @@ func TestReadUnixgramWithUnnamedSocket(t *testing.T) {
6767
}
6868
}
6969

70-
func TestReadUnixgramWithZeroBytesBuffer(t *testing.T) {
70+
func TestUnixgramZeroBytePayload(t *testing.T) {
7171
if !testableNetwork("unixgram") {
7272
t.Skip("unixgram test")
7373
}
74-
// issue 4352: Recvfrom failed with "address family not
75-
// supported by protocol family" if zero-length buffer provided
7674

77-
addr := testUnixAddr()
78-
la, err := ResolveUnixAddr("unixgram", addr)
75+
c1, err := newLocalPacketListener("unixgram")
7976
if err != nil {
80-
t.Fatalf("ResolveUnixAddr failed: %v", err)
77+
t.Fatal(err)
8178
}
82-
c, err := ListenUnixgram("unixgram", la)
79+
defer os.Remove(c1.LocalAddr().String())
80+
defer c1.Close()
81+
82+
c2, err := Dial("unixgram", c1.LocalAddr().String())
8383
if err != nil {
84-
t.Fatalf("ListenUnixgram failed: %v", err)
84+
t.Fatal(err)
8585
}
86-
defer func() {
87-
c.Close()
88-
os.Remove(addr)
89-
}()
86+
defer os.Remove(c2.LocalAddr().String())
87+
defer c2.Close()
9088

91-
off := make(chan bool)
92-
go func() {
93-
defer func() { off <- true }()
94-
c, err := DialUnix("unixgram", nil, la)
89+
for _, genericRead := range []bool{false, true} {
90+
n, err := c2.Write(nil)
9591
if err != nil {
96-
t.Errorf("DialUnix failed: %v", err)
97-
return
92+
t.Fatal(err)
9893
}
99-
defer c.Close()
100-
if _, err := c.Write([]byte{1, 2, 3, 4, 5}); err != nil {
101-
t.Errorf("UnixConn.Write failed: %v", err)
102-
return
94+
if n != 0 {
95+
t.Errorf("got %d; want 0", n)
10396
}
104-
}()
97+
c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
98+
var b [1]byte
99+
var peer Addr
100+
if genericRead {
101+
_, err = c1.(Conn).Read(b[:])
102+
} else {
103+
_, peer, err = c1.ReadFrom(b[:])
104+
}
105+
switch err {
106+
case nil: // ReadFrom succeeds
107+
if peer != nil { // peer is connected-mode
108+
t.Fatalf("unexpected peer address: %v", peer)
109+
}
110+
default: // Read may timeout, it depends on the platform
111+
if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
112+
t.Fatal(err)
113+
}
114+
}
115+
}
116+
}
105117

106-
<-off
107-
c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
108-
_, from, err := c.ReadFrom(nil)
118+
func TestUnixgramZeroByteBuffer(t *testing.T) {
119+
if !testableNetwork("unixgram") {
120+
t.Skip("unixgram test")
121+
}
122+
// issue 4352: Recvfrom failed with "address family not
123+
// supported by protocol family" if zero-length buffer provided
124+
125+
c1, err := newLocalPacketListener("unixgram")
109126
if err != nil {
110-
t.Fatalf("UnixConn.ReadFrom failed: %v", err)
127+
t.Fatal(err)
111128
}
112-
if from != nil {
113-
t.Fatalf("neighbor address is %v", from)
129+
defer os.Remove(c1.LocalAddr().String())
130+
defer c1.Close()
131+
132+
c2, err := Dial("unixgram", c1.LocalAddr().String())
133+
if err != nil {
134+
t.Fatal(err)
135+
}
136+
defer os.Remove(c2.LocalAddr().String())
137+
defer c2.Close()
138+
139+
b := []byte("UNIXGRAM ZERO BYTE BUFFER")
140+
for _, genericRead := range []bool{false, true} {
141+
n, err := c2.Write(b)
142+
if err != nil {
143+
t.Fatal(err)
144+
}
145+
if n != len(b) {
146+
t.Errorf("got %d; want %d", n, len(b))
147+
}
148+
c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
149+
var peer Addr
150+
if genericRead {
151+
_, err = c1.(Conn).Read(nil)
152+
} else {
153+
_, peer, err = c1.ReadFrom(nil)
154+
}
155+
switch err {
156+
case nil: // ReadFrom succeeds
157+
if peer != nil { // peer is connected-mode
158+
t.Fatalf("unexpected peer address: %v", peer)
159+
}
160+
default: // Read may timeout, it depends on the platform
161+
if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
162+
t.Fatal(err)
163+
}
164+
}
114165
}
115166
}
116167

0 commit comments

Comments
 (0)