Commit 98e05562 authored by Mikio Hara's avatar Mikio Hara

net: deflake timeout, deadline tests

This change deflakes timeout, deadline tests, especially fixes socket
and goroutine leaks. Also adds a few missing tests that use features
introduced after go1 release.

Change-Id: Ibf73a4859f8d4a0ee494ca2fd180cbce72a7a2c7
Reviewed-on: https://go-review.googlesource.com/9464Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent e64764c8
...@@ -6,7 +6,10 @@ package net ...@@ -6,7 +6,10 @@ package net
import "syscall" import "syscall"
var errOpNotSupported = syscall.EPLAN9 var (
errTimedout = syscall.ETIMEDOUT
errOpNotSupported = syscall.EPLAN9
)
func isPlatformError(err error) bool { func isPlatformError(err error) bool {
_, ok := err.(syscall.ErrorString) _, ok := err.(syscall.ErrorString)
......
...@@ -8,7 +8,10 @@ package net ...@@ -8,7 +8,10 @@ package net
import "syscall" import "syscall"
var errOpNotSupported = syscall.EOPNOTSUPP var (
errTimedout = syscall.ETIMEDOUT
errOpNotSupported = syscall.EOPNOTSUPP
)
func isPlatformError(err error) bool { func isPlatformError(err error) bool {
_, ok := err.(syscall.Errno) _, ok := err.(syscall.Errno)
......
...@@ -15,16 +15,6 @@ import ( ...@@ -15,16 +15,6 @@ import (
"time" "time"
) )
func isTimeoutError(err error) bool {
nerr, ok := err.(Error)
return ok && nerr.Timeout()
}
func isTemporaryError(err error) bool {
nerr, ok := err.(Error)
return ok && nerr.Temporary()
}
func (e *OpError) isValid() error { func (e *OpError) isValid() error {
if e.Op == "" { if e.Op == "" {
return fmt.Errorf("OpError.Op is empty: %v", e) return fmt.Errorf("OpError.Op is empty: %v", e)
...@@ -467,7 +457,7 @@ func TestAcceptError(t *testing.T) { ...@@ -467,7 +457,7 @@ func TestAcceptError(t *testing.T) {
if c != nil { if c != nil {
t.Errorf("Accept returned non-nil interface %T(%v) with err != nil", c, c) t.Errorf("Accept returned non-nil interface %T(%v) with err != nil", c, c)
} }
if !isTimeoutError(err) && !isTemporaryError(err) { if nerr, ok := err.(Error); !ok || (!nerr.Timeout() && !nerr.Temporary()) {
return return
} }
continue continue
...@@ -521,6 +511,10 @@ second: ...@@ -521,6 +511,10 @@ second:
nestedErr = err.Err nestedErr = err.Err
goto third goto third
} }
switch nestedErr {
case errClosing:
return nil
}
return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
third: third:
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"sync" "sync"
"testing"
"time" "time"
) )
...@@ -250,6 +251,54 @@ func transceiver(c Conn, wb []byte, ch chan<- error) { ...@@ -250,6 +251,54 @@ func transceiver(c Conn, wb []byte, ch chan<- error) {
} }
} }
func timeoutReceiver(c Conn, d, min, max time.Duration, ch chan<- error) {
var err error
defer func() { ch <- err }()
t0 := time.Now()
if err = c.SetReadDeadline(time.Now().Add(d)); err != nil {
return
}
b := make([]byte, 256)
var n int
n, err = c.Read(b)
t1 := time.Now()
if n != 0 || err == nil || !err.(Error).Timeout() {
err = fmt.Errorf("Read did not return (0, timeout): (%d, %v)", n, err)
return
}
if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
err = fmt.Errorf("Read took %s; expected %s", dt, d)
return
}
}
func timeoutTransmitter(c Conn, d, min, max time.Duration, ch chan<- error) {
var err error
defer func() { ch <- err }()
t0 := time.Now()
if err = c.SetWriteDeadline(time.Now().Add(d)); err != nil {
return
}
var n int
for {
n, err = c.Write([]byte("TIMEOUT TRANSMITTER"))
if err != nil {
break
}
}
t1 := time.Now()
if err == nil || !err.(Error).Timeout() {
err = fmt.Errorf("Write did not return (any, timeout): (%d, %v)", n, err)
return
}
if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
err = fmt.Errorf("Write took %s; expected %s", dt, d)
return
}
}
func newLocalPacketListener(network string) (PacketConn, error) { func newLocalPacketListener(network string) (PacketConn, error) {
switch network { switch network {
case "udp", "udp4", "udp6": case "udp", "udp4", "udp6":
...@@ -380,3 +429,25 @@ func packetTransceiver(c PacketConn, wb []byte, dst Addr, ch chan<- error) { ...@@ -380,3 +429,25 @@ func packetTransceiver(c PacketConn, wb []byte, dst Addr, ch chan<- error) {
ch <- fmt.Errorf("read %d; want %d", n, len(wb)) ch <- fmt.Errorf("read %d; want %d", n, len(wb))
} }
} }
func timeoutPacketReceiver(c PacketConn, d, min, max time.Duration, ch chan<- error) {
var err error
defer func() { ch <- err }()
t0 := time.Now()
if err = c.SetReadDeadline(time.Now().Add(d)); err != nil {
return
}
b := make([]byte, 256)
var n int
n, _, err = c.ReadFrom(b)
t1 := time.Now()
if n != 0 || err == nil || !err.(Error).Timeout() {
err = fmt.Errorf("ReadFrom did not return (0, timeout): (%d, %v)", n, err)
return
}
if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
err = fmt.Errorf("ReadFrom took %s; expected %s", dt, d)
return
}
}
This diff is collapsed.
...@@ -95,7 +95,8 @@ func TestReadFromUDP(t *testing.T) { ...@@ -95,7 +95,8 @@ func TestReadFromUDP(t *testing.T) {
_, _, err = c.ReadFromUDP(b) _, _, err = c.ReadFromUDP(b)
if err == nil { if err == nil {
t.Fatal("ReadFromUDP should fail") t.Fatal("ReadFromUDP should fail")
} else if !isTimeoutError(err) { }
if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
t.Fatal(err) t.Fatal(err)
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment