Commit f077505d authored by Mikio Hara's avatar Mikio Hara

net: fix tester goroutine leakage in tests

This change tries to stop various tester goroutines at the end of each
scope for avoiding interference between test cases including benchmarks.
Not yet finished completely but enough to land upcoming changes to Dial
functions. The rest will be fixed later.

Change-Id: Ic38b8681a3a2ddbcd69ba3696f24a61d418a0346
Reviewed-on: https://go-review.googlesource.com/8398Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 75883bae
...@@ -8,57 +8,42 @@ ...@@ -8,57 +8,42 @@
package net package net
import ( import (
"os"
"testing" "testing"
"time" "time"
) )
var connTests = []struct {
net string
addr string
}{
{"tcp", "127.0.0.1:0"},
{"unix", testUnixAddr()},
{"unixpacket", testUnixAddr()},
}
// someTimeout is used just to test that net.Conn implementations // someTimeout is used just to test that net.Conn implementations
// don't explode when their SetFooDeadline methods are called. // don't explode when their SetFooDeadline methods are called.
// It isn't actually used for testing timeouts. // It isn't actually used for testing timeouts.
const someTimeout = 10 * time.Second const someTimeout = 10 * time.Second
func TestConnAndListener(t *testing.T) { func TestConnAndListener(t *testing.T) {
for _, tt := range connTests { handler := func(ls *localServer, ln Listener) { transponder(t, ln) }
if !testableNetwork(tt.net) { for _, network := range []string{"tcp", "unix", "unixpacket"} {
t.Logf("skipping %s test", tt.net) if !testableNetwork(network) {
t.Logf("skipping %s test", network)
continue continue
} }
ln, err := Listen(tt.net, tt.addr) ls, err := newLocalServer(network)
if err != nil { if err != nil {
t.Fatalf("Listen failed: %v", err) t.Fatalf("Listen failed: %v", err)
} }
defer func(ln Listener, net, addr string) { defer ls.teardown()
ln.Close() if err := ls.buildup(handler); err != nil {
switch net { t.Fatal(err)
case "unix", "unixpacket":
os.Remove(addr)
} }
}(ln, tt.net, tt.addr) if ls.Listener.Addr().Network() != network {
if ln.Addr().Network() != tt.net { t.Fatalf("got %s; want %s", ls.Listener.Addr().Network(), network)
t.Fatalf("got %v; expected %v", ln.Addr().Network(), tt.net)
} }
done := make(chan int) c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
go transponder(t, ln, done)
c, err := Dial(tt.net, ln.Addr().String())
if err != nil { if err != nil {
t.Fatalf("Dial failed: %v", err) t.Fatalf("Dial failed: %v", err)
} }
defer c.Close() defer c.Close()
if c.LocalAddr().Network() != tt.net || c.LocalAddr().Network() != tt.net { if c.LocalAddr().Network() != network || c.LocalAddr().Network() != network {
t.Fatalf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), tt.net, tt.net) t.Fatalf("got %v->%v; want %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network)
} }
c.SetDeadline(time.Now().Add(someTimeout)) c.SetDeadline(time.Now().Add(someTimeout))
c.SetReadDeadline(time.Now().Add(someTimeout)) c.SetReadDeadline(time.Now().Add(someTimeout))
...@@ -71,14 +56,10 @@ func TestConnAndListener(t *testing.T) { ...@@ -71,14 +56,10 @@ func TestConnAndListener(t *testing.T) {
if _, err := c.Read(rb); err != nil { if _, err := c.Read(rb); err != nil {
t.Fatalf("Conn.Read failed: %v", err) t.Fatalf("Conn.Read failed: %v", err)
} }
<-done
} }
} }
func transponder(t *testing.T, ln Listener, done chan<- int) { func transponder(t *testing.T, ln Listener) {
defer func() { done <- 1 }()
switch ln := ln.(type) { switch ln := ln.(type) {
case *TCPListener: case *TCPListener:
ln.SetDeadline(time.Now().Add(someTimeout)) ln.SetDeadline(time.Now().Add(someTimeout))
...@@ -91,6 +72,7 @@ func transponder(t *testing.T, ln Listener, done chan<- int) { ...@@ -91,6 +72,7 @@ func transponder(t *testing.T, ln Listener, done chan<- int) {
return return
} }
defer c.Close() defer c.Close()
network := ln.Addr().Network() network := ln.Addr().Network()
if c.LocalAddr().Network() != network || c.LocalAddr().Network() != network { if c.LocalAddr().Network() != network || c.LocalAddr().Network() != network {
t.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network) t.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network)
......
...@@ -19,17 +19,6 @@ import ( ...@@ -19,17 +19,6 @@ import (
"time" "time"
) )
func newLocalListener(t *testing.T) Listener {
ln, err := Listen("tcp", "127.0.0.1:0")
if err != nil {
ln, err = Listen("tcp6", "[::1]:0")
}
if err != nil {
t.Fatal(err)
}
return ln
}
func TestSelfConnect(t *testing.T) { func TestSelfConnect(t *testing.T) {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
// TODO(brainman): do not know why it hangs. // TODO(brainman): do not know why it hangs.
...@@ -249,7 +238,7 @@ func TestDialMultiFDLeak(t *testing.T) { ...@@ -249,7 +238,7 @@ func TestDialMultiFDLeak(t *testing.T) {
t.Skip("neither ipv4 nor ipv6 is supported") t.Skip("neither ipv4 nor ipv6 is supported")
} }
halfDeadServer := func(dss *dualStackServer, ln Listener) { handler := func(dss *dualStackServer, ln Listener) {
for { for {
if c, err := ln.Accept(); err != nil { if c, err := ln.Accept(); err != nil {
return return
...@@ -262,14 +251,14 @@ func TestDialMultiFDLeak(t *testing.T) { ...@@ -262,14 +251,14 @@ func TestDialMultiFDLeak(t *testing.T) {
} }
} }
dss, err := newDualStackServer([]streamListener{ dss, err := newDualStackServer([]streamListener{
{net: "tcp4", addr: "127.0.0.1"}, {network: "tcp4", address: "127.0.0.1"},
{net: "tcp6", addr: "[::1]"}, {network: "tcp6", address: "::1"},
}) })
if err != nil { if err != nil {
t.Fatalf("newDualStackServer failed: %v", err) t.Fatalf("newDualStackServer failed: %v", err)
} }
defer dss.teardown() defer dss.teardown()
if err := dss.buildup(halfDeadServer); err != nil { if err := dss.buildup(handler); err != nil {
t.Fatalf("dualStackServer.buildup failed: %v", err) t.Fatalf("dualStackServer.buildup failed: %v", err)
} }
...@@ -319,14 +308,9 @@ func TestDialMultiFDLeak(t *testing.T) { ...@@ -319,14 +308,9 @@ func TestDialMultiFDLeak(t *testing.T) {
} }
} }
func TestDialer(t *testing.T) { func TestDialerLocalAddr(t *testing.T) {
ln, err := Listen("tcp4", "127.0.0.1:0")
if err != nil {
t.Fatalf("Listen failed: %v", err)
}
defer ln.Close()
ch := make(chan error, 1) ch := make(chan error, 1)
go func() { handler := func(ls *localServer, ln Listener) {
c, err := ln.Accept() c, err := ln.Accept()
if err != nil { if err != nil {
ch <- fmt.Errorf("Accept failed: %v", err) ch <- fmt.Errorf("Accept failed: %v", err)
...@@ -334,14 +318,23 @@ func TestDialer(t *testing.T) { ...@@ -334,14 +318,23 @@ func TestDialer(t *testing.T) {
} }
defer c.Close() defer c.Close()
ch <- nil ch <- nil
}() }
ls, err := newLocalServer("tcp")
if err != nil {
t.Fatal(err)
}
defer ls.teardown()
if err := ls.buildup(handler); err != nil {
t.Fatal(err)
}
laddr, err := ResolveTCPAddr("tcp4", "127.0.0.1:0") laddr, err := ResolveTCPAddr(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
if err != nil { if err != nil {
t.Fatalf("ResolveTCPAddr failed: %v", err) t.Fatalf("ResolveTCPAddr failed: %v", err)
} }
laddr.Port = 0
d := &Dialer{LocalAddr: laddr} d := &Dialer{LocalAddr: laddr}
c, err := d.Dial("tcp4", ln.Addr().String()) c, err := d.Dial(ls.Listener.Addr().Network(), ls.Addr().String())
if err != nil { if err != nil {
t.Fatalf("Dial failed: %v", err) t.Fatalf("Dial failed: %v", err)
} }
...@@ -353,7 +346,7 @@ func TestDialer(t *testing.T) { ...@@ -353,7 +346,7 @@ func TestDialer(t *testing.T) {
} }
} }
func TestDialDualStackLocalhost(t *testing.T) { func TestDialerDualStack(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "nacl": case "nacl":
t.Skipf("skipping test on %q", runtime.GOOS) t.Skipf("skipping test on %q", runtime.GOOS)
...@@ -365,7 +358,7 @@ func TestDialDualStackLocalhost(t *testing.T) { ...@@ -365,7 +358,7 @@ func TestDialDualStackLocalhost(t *testing.T) {
t.Skip("localhost doesn't have a pair of different address family IP addresses") t.Skip("localhost doesn't have a pair of different address family IP addresses")
} }
touchAndByeServer := func(dss *dualStackServer, ln Listener) { handler := func(dss *dualStackServer, ln Listener) {
for { for {
if c, err := ln.Accept(); err != nil { if c, err := ln.Accept(); err != nil {
return return
...@@ -375,20 +368,20 @@ func TestDialDualStackLocalhost(t *testing.T) { ...@@ -375,20 +368,20 @@ func TestDialDualStackLocalhost(t *testing.T) {
} }
} }
dss, err := newDualStackServer([]streamListener{ dss, err := newDualStackServer([]streamListener{
{net: "tcp4", addr: "127.0.0.1"}, {network: "tcp4", address: "127.0.0.1"},
{net: "tcp6", addr: "[::1]"}, {network: "tcp6", address: "::1"},
}) })
if err != nil { if err != nil {
t.Fatalf("newDualStackServer failed: %v", err) t.Fatalf("newDualStackServer failed: %v", err)
} }
defer dss.teardown() defer dss.teardown()
if err := dss.buildup(touchAndByeServer); err != nil { if err := dss.buildup(handler); err != nil {
t.Fatalf("dualStackServer.buildup failed: %v", err) t.Fatalf("dualStackServer.buildup failed: %v", err)
} }
d := &Dialer{DualStack: true} d := &Dialer{DualStack: true}
for range dss.lns { for range dss.lns {
if c, err := d.Dial("tcp", "localhost:"+dss.port); err != nil { if c, err := d.Dial("tcp", JoinHostPort("localhost", dss.port)); err != nil {
t.Errorf("Dial failed: %v", err) t.Errorf("Dial failed: %v", err)
} else { } else {
if addr := c.LocalAddr().(*TCPAddr); addr.IP.To4() != nil { if addr := c.LocalAddr().(*TCPAddr); addr.IP.To4() != nil {
...@@ -402,12 +395,7 @@ func TestDialDualStackLocalhost(t *testing.T) { ...@@ -402,12 +395,7 @@ func TestDialDualStackLocalhost(t *testing.T) {
} }
func TestDialerKeepAlive(t *testing.T) { func TestDialerKeepAlive(t *testing.T) {
ln := newLocalListener(t) handler := func(ls *localServer, ln Listener) {
defer ln.Close()
defer func() {
testHookSetKeepAlive = func() {}
}()
go func() {
for { for {
c, err := ln.Accept() c, err := ln.Accept()
if err != nil { if err != nil {
...@@ -415,7 +403,19 @@ func TestDialerKeepAlive(t *testing.T) { ...@@ -415,7 +403,19 @@ func TestDialerKeepAlive(t *testing.T) {
} }
c.Close() c.Close()
} }
}
ls, err := newLocalServer("tcp")
if err != nil {
t.Fatal(err)
}
defer ls.teardown()
if err := ls.buildup(handler); err != nil {
t.Fatal(err)
}
defer func() {
testHookSetKeepAlive = func() {}
}() }()
for _, keepAlive := range []bool{false, true} { for _, keepAlive := range []bool{false, true} {
got := false got := false
testHookSetKeepAlive = func() { got = true } testHookSetKeepAlive = func() { got = true }
...@@ -423,7 +423,7 @@ func TestDialerKeepAlive(t *testing.T) { ...@@ -423,7 +423,7 @@ func TestDialerKeepAlive(t *testing.T) {
if keepAlive { if keepAlive {
d.KeepAlive = 30 * time.Second d.KeepAlive = 30 * time.Second
} }
c, err := d.Dial("tcp", ln.Addr().String()) c, err := d.Dial("tcp", ls.Listener.Addr().String())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
......
...@@ -4,11 +4,74 @@ ...@@ -4,11 +4,74 @@
package net package net
import "sync" import (
"fmt"
"os"
"sync"
)
func newLocalListener(network string) (Listener, error) {
switch network {
case "tcp", "tcp4", "tcp6":
if supportsIPv4 {
return Listen("tcp4", "127.0.0.1:0")
}
if supportsIPv6 {
return Listen("tcp6", "[::1]:0")
}
case "unix", "unixpacket":
return Listen(network, testUnixAddr())
}
return nil, fmt.Errorf("%s is not supported", network)
}
type localServer struct {
lnmu sync.RWMutex
Listener
done chan bool // signal that indicates server stopped
}
func (ls *localServer) buildup(handler func(*localServer, Listener)) error {
go func() {
handler(ls, ls.Listener)
close(ls.done)
}()
return nil
}
func (ls *localServer) teardown() error {
ls.lnmu.Lock()
if ls.Listener != nil {
network := ls.Listener.Addr().Network()
address := ls.Listener.Addr().String()
ls.Listener.Close()
<-ls.done
ls.Listener = nil
switch network {
case "unix", "unixpacket":
os.Remove(address)
}
}
ls.lnmu.Unlock()
return nil
}
func newLocalServer(network string) (*localServer, error) {
ln, err := newLocalListener(network)
if err != nil {
return nil, err
}
return &localServer{Listener: ln, done: make(chan bool)}, nil
}
type streamListener struct { type streamListener struct {
net, addr string network, address string
ln Listener Listener
done chan bool // signal that indicates server stopped
}
func (sl *streamListener) newLocalServer() (*localServer, error) {
return &localServer{Listener: sl.Listener, done: make(chan bool)}, nil
} }
type dualStackServer struct { type dualStackServer struct {
...@@ -20,9 +83,12 @@ type dualStackServer struct { ...@@ -20,9 +83,12 @@ type dualStackServer struct {
cs []Conn // established connections at the passive open side cs []Conn // established connections at the passive open side
} }
func (dss *dualStackServer) buildup(server func(*dualStackServer, Listener)) error { func (dss *dualStackServer) buildup(handler func(*dualStackServer, Listener)) error {
for i := range dss.lns { for i := range dss.lns {
go server(dss, dss.lns[i].ln) go func(i int) {
handler(dss, dss.lns[i].Listener)
close(dss.lns[i].done)
}(i)
} }
return nil return nil
} }
...@@ -34,12 +100,13 @@ func (dss *dualStackServer) putConn(c Conn) error { ...@@ -34,12 +100,13 @@ func (dss *dualStackServer) putConn(c Conn) error {
return nil return nil
} }
func (dss *dualStackServer) teardownNetwork(net string) error { func (dss *dualStackServer) teardownNetwork(network string) error {
dss.lnmu.Lock() dss.lnmu.Lock()
for i := range dss.lns { for i := range dss.lns {
if net == dss.lns[i].net && dss.lns[i].ln != nil { if network == dss.lns[i].network && dss.lns[i].Listener != nil {
dss.lns[i].ln.Close() dss.lns[i].Listener.Close()
dss.lns[i].ln = nil <-dss.lns[i].done
dss.lns[i].Listener = nil
} }
} }
dss.lnmu.Unlock() dss.lnmu.Unlock()
...@@ -49,15 +116,18 @@ func (dss *dualStackServer) teardownNetwork(net string) error { ...@@ -49,15 +116,18 @@ func (dss *dualStackServer) teardownNetwork(net string) error {
func (dss *dualStackServer) teardown() error { func (dss *dualStackServer) teardown() error {
dss.lnmu.Lock() dss.lnmu.Lock()
for i := range dss.lns { for i := range dss.lns {
if dss.lns[i].ln != nil { if dss.lns[i].Listener != nil {
dss.lns[i].ln.Close() dss.lns[i].Listener.Close()
<-dss.lns[i].done
} }
} }
dss.lns = dss.lns[:0]
dss.lnmu.Unlock() dss.lnmu.Unlock()
dss.cmu.Lock() dss.cmu.Lock()
for _, c := range dss.cs { for _, c := range dss.cs {
c.Close() c.Close()
} }
dss.cs = dss.cs[:0]
dss.cmu.Unlock() dss.cmu.Unlock()
return nil return nil
} }
...@@ -65,15 +135,20 @@ func (dss *dualStackServer) teardown() error { ...@@ -65,15 +135,20 @@ func (dss *dualStackServer) teardown() error {
func newDualStackServer(lns []streamListener) (*dualStackServer, error) { func newDualStackServer(lns []streamListener) (*dualStackServer, error) {
dss := &dualStackServer{lns: lns, port: "0"} dss := &dualStackServer{lns: lns, port: "0"}
for i := range dss.lns { for i := range dss.lns {
ln, err := Listen(dss.lns[i].net, dss.lns[i].addr+":"+dss.port) ln, err := Listen(dss.lns[i].network, JoinHostPort(dss.lns[i].address, dss.port))
if err != nil { if err != nil {
dss.teardown() for _, ln := range dss.lns {
ln.Listener.Close()
}
return nil, err return nil, err
} }
dss.lns[i].ln = ln dss.lns[i].Listener = ln
dss.lns[i].done = make(chan bool)
if dss.port == "0" { if dss.port == "0" {
if _, dss.port, err = SplitHostPort(ln.Addr().String()); err != nil { if _, dss.port, err = SplitHostPort(ln.Addr().String()); err != nil {
dss.teardown() for _, ln := range dss.lns {
ln.Listener.Close()
}
return nil, err return nil, err
} }
} }
......
...@@ -84,13 +84,17 @@ func TestTCPConnSpecificMethods(t *testing.T) { ...@@ -84,13 +84,17 @@ func TestTCPConnSpecificMethods(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("ListenTCP failed: %v", err) t.Fatalf("ListenTCP failed: %v", err)
} }
defer ln.Close() handler := func(ls *localServer, ln Listener) { transponder(t, ls.Listener) }
ln.Addr() ls, err := (&streamListener{Listener: ln}).newLocalServer()
if err != nil {
done := make(chan int) t.Fatal(err)
go transponder(t, ln, done) }
defer ls.teardown()
if err := ls.buildup(handler); err != nil {
t.Fatal(err)
}
ra, err := ResolveTCPAddr("tcp4", ln.Addr().String()) ra, err := ResolveTCPAddr("tcp4", ls.Listener.Addr().String())
if err != nil { if err != nil {
t.Fatalf("ResolveTCPAddr failed: %v", err) t.Fatalf("ResolveTCPAddr failed: %v", err)
} }
...@@ -116,8 +120,6 @@ func TestTCPConnSpecificMethods(t *testing.T) { ...@@ -116,8 +120,6 @@ func TestTCPConnSpecificMethods(t *testing.T) {
if _, err := c.Read(rb); err != nil { if _, err := c.Read(rb); err != nil {
t.Fatalf("TCPConn.Read failed: %v", err) t.Fatalf("TCPConn.Read failed: %v", err)
} }
<-done
} }
func TestUDPConnSpecificMethods(t *testing.T) { func TestUDPConnSpecificMethods(t *testing.T) {
......
...@@ -414,6 +414,7 @@ func TestIPv6LinkLocalUnicastTCP(t *testing.T) { ...@@ -414,6 +414,7 @@ func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
{"tcp6", "[ip6-localhost%" + ifi.Name + "]:0", true}, {"tcp6", "[ip6-localhost%" + ifi.Name + "]:0", true},
}...) }...)
} }
handler := func(ls *localServer, ln Listener) { transponder(t, ln) }
for _, tt := range tests { for _, tt := range tests {
ln, err := Listen(tt.net, tt.addr) ln, err := Listen(tt.net, tt.addr)
if err != nil { if err != nil {
...@@ -422,15 +423,19 @@ func TestIPv6LinkLocalUnicastTCP(t *testing.T) { ...@@ -422,15 +423,19 @@ func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
t.Logf("Listen failed: %v", err) t.Logf("Listen failed: %v", err)
continue continue
} }
defer ln.Close() ls, err := (&streamListener{Listener: ln}).newLocalServer()
if err != nil {
t.Fatal(err)
}
defer ls.teardown()
if err := ls.buildup(handler); err != nil {
t.Fatal(err)
}
if la, ok := ln.Addr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" { if la, ok := ln.Addr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" {
t.Fatalf("got %v; expected a proper address with zone identifier", la) t.Fatalf("got %v; expected a proper address with zone identifier", la)
} }
done := make(chan int) c, err := Dial(tt.net, ls.Listener.Addr().String())
go transponder(t, ln, done)
c, err := Dial(tt.net, ln.Addr().String())
if err != nil { if err != nil {
t.Fatalf("Dial failed: %v", err) t.Fatalf("Dial failed: %v", err)
} }
...@@ -449,8 +454,6 @@ func TestIPv6LinkLocalUnicastTCP(t *testing.T) { ...@@ -449,8 +454,6 @@ func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
if _, err := c.Read(b); err != nil { if _, err := c.Read(b); err != nil {
t.Fatalf("Conn.Read failed: %v", err) t.Fatalf("Conn.Read failed: %v", err)
} }
<-done
} }
} }
......
...@@ -78,23 +78,26 @@ func TestAcceptTimeout(t *testing.T) { ...@@ -78,23 +78,26 @@ func TestAcceptTimeout(t *testing.T) {
t.Skipf("skipping test on %q", runtime.GOOS) t.Skipf("skipping test on %q", runtime.GOOS)
} }
ln := newLocalListener(t).(*TCPListener) ln, err := newLocalListener("tcp")
if err != nil {
t.Fatal(err)
}
defer ln.Close() defer ln.Close()
ln.SetDeadline(time.Now().Add(-1 * time.Second)) ln.(*TCPListener).SetDeadline(time.Now().Add(-1 * time.Second))
if _, err := ln.Accept(); !isTimeout(err) { if _, err := ln.Accept(); !isTimeout(err) {
t.Fatalf("Accept: expected err %v, got %v", errTimeout, err) t.Fatalf("Accept: expected err %v, got %v", errTimeout, err)
} }
if _, err := ln.Accept(); !isTimeout(err) { if _, err := ln.Accept(); !isTimeout(err) {
t.Fatalf("Accept: expected err %v, got %v", errTimeout, err) t.Fatalf("Accept: expected err %v, got %v", errTimeout, err)
} }
ln.SetDeadline(time.Now().Add(100 * time.Millisecond)) ln.(*TCPListener).SetDeadline(time.Now().Add(100 * time.Millisecond))
if _, err := ln.Accept(); !isTimeout(err) { if _, err := ln.Accept(); !isTimeout(err) {
t.Fatalf("Accept: expected err %v, got %v", errTimeout, err) t.Fatalf("Accept: expected err %v, got %v", errTimeout, err)
} }
if _, err := ln.Accept(); !isTimeout(err) { if _, err := ln.Accept(); !isTimeout(err) {
t.Fatalf("Accept: expected err %v, got %v", errTimeout, err) t.Fatalf("Accept: expected err %v, got %v", errTimeout, err)
} }
ln.SetDeadline(noDeadline) ln.(*TCPListener).SetDeadline(noDeadline)
errc := make(chan error) errc := make(chan error)
go func() { go func() {
_, err := ln.Accept() _, err := ln.Accept()
...@@ -125,7 +128,10 @@ func TestReadTimeout(t *testing.T) { ...@@ -125,7 +128,10 @@ func TestReadTimeout(t *testing.T) {
t.Skipf("skipping test on %q", runtime.GOOS) t.Skipf("skipping test on %q", runtime.GOOS)
} }
ln := newLocalListener(t) ln, err := newLocalListener("tcp")
if err != nil {
t.Fatal(err)
}
defer ln.Close() defer ln.Close()
c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr)) c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr))
if err != nil { if err != nil {
...@@ -183,7 +189,10 @@ func TestWriteTimeout(t *testing.T) { ...@@ -183,7 +189,10 @@ func TestWriteTimeout(t *testing.T) {
t.Skipf("skipping test on %q", runtime.GOOS) t.Skipf("skipping test on %q", runtime.GOOS)
} }
ln := newLocalListener(t) ln, err := newLocalListener("tcp")
if err != nil {
t.Fatal(err)
}
defer ln.Close() defer ln.Close()
c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr)) c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr))
if err != nil { if err != nil {
...@@ -475,14 +484,12 @@ func testVariousDeadlines(t *testing.T, maxProcs int) { ...@@ -475,14 +484,12 @@ func testVariousDeadlines(t *testing.T, maxProcs int) {
} }
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
ln := newLocalListener(t)
defer ln.Close()
acceptc := make(chan error, 1)
acceptc := make(chan error, 1)
// The server, with no timeouts of its own, sending bytes to clients // The server, with no timeouts of its own, sending bytes to clients
// as fast as it can. // as fast as it can.
servec := make(chan copyRes) servec := make(chan copyRes)
go func() { handler := func(ls *localServer, ln Listener) {
for { for {
c, err := ln.Accept() c, err := ln.Accept()
if err != nil { if err != nil {
...@@ -497,7 +504,15 @@ func testVariousDeadlines(t *testing.T, maxProcs int) { ...@@ -497,7 +504,15 @@ func testVariousDeadlines(t *testing.T, maxProcs int) {
servec <- copyRes{n, err, d} servec <- copyRes{n, err, d}
}() }()
} }
}() }
ls, err := newLocalServer("tcp")
if err != nil {
t.Fatal(err)
}
defer ls.teardown()
if err := ls.buildup(handler); err != nil {
t.Fatal(err)
}
for _, timeout := range []time.Duration{ for _, timeout := range []time.Duration{
1 * time.Nanosecond, 1 * time.Nanosecond,
...@@ -531,7 +546,7 @@ func testVariousDeadlines(t *testing.T, maxProcs int) { ...@@ -531,7 +546,7 @@ func testVariousDeadlines(t *testing.T, maxProcs int) {
name := fmt.Sprintf("%v run %d/%d", timeout, run+1, numRuns) name := fmt.Sprintf("%v run %d/%d", timeout, run+1, numRuns)
t.Log(name) t.Log(name)
c, err := Dial("tcp", ln.Addr().String()) c, err := Dial("tcp", ls.Listener.Addr().String())
if err != nil { if err != nil {
t.Fatalf("Dial: %v", err) t.Fatalf("Dial: %v", err)
} }
...@@ -577,12 +592,9 @@ func TestReadDeadlineDataAvailable(t *testing.T) { ...@@ -577,12 +592,9 @@ func TestReadDeadlineDataAvailable(t *testing.T) {
t.Skipf("skipping test on %q", runtime.GOOS) t.Skipf("skipping test on %q", runtime.GOOS)
} }
ln := newLocalListener(t)
defer ln.Close()
servec := make(chan copyRes) servec := make(chan copyRes)
const msg = "data client shouldn't read, even though it'll be waiting" const msg = "data client shouldn't read, even though it'll be waiting"
go func() { handler := func(ls *localServer, ln Listener) {
c, err := ln.Accept() c, err := ln.Accept()
if err != nil { if err != nil {
t.Errorf("Accept: %v", err) t.Errorf("Accept: %v", err)
...@@ -591,9 +603,17 @@ func TestReadDeadlineDataAvailable(t *testing.T) { ...@@ -591,9 +603,17 @@ func TestReadDeadlineDataAvailable(t *testing.T) {
defer c.Close() defer c.Close()
n, err := c.Write([]byte(msg)) n, err := c.Write([]byte(msg))
servec <- copyRes{n: int64(n), err: err} servec <- copyRes{n: int64(n), err: err}
}() }
ls, err := newLocalServer("tcp")
if err != nil {
t.Fatal(err)
}
defer ls.teardown()
if err := ls.buildup(handler); err != nil {
t.Fatal(err)
}
c, err := Dial("tcp", ln.Addr().String()) c, err := Dial("tcp", ls.Listener.Addr().String())
if err != nil { if err != nil {
t.Fatalf("Dial: %v", err) t.Fatalf("Dial: %v", err)
} }
...@@ -617,11 +637,8 @@ func TestWriteDeadlineBufferAvailable(t *testing.T) { ...@@ -617,11 +637,8 @@ func TestWriteDeadlineBufferAvailable(t *testing.T) {
t.Skipf("skipping test on %q", runtime.GOOS) t.Skipf("skipping test on %q", runtime.GOOS)
} }
ln := newLocalListener(t)
defer ln.Close()
servec := make(chan copyRes) servec := make(chan copyRes)
go func() { handler := func(ls *localServer, ln Listener) {
c, err := ln.Accept() c, err := ln.Accept()
if err != nil { if err != nil {
t.Errorf("Accept: %v", err) t.Errorf("Accept: %v", err)
...@@ -631,9 +648,17 @@ func TestWriteDeadlineBufferAvailable(t *testing.T) { ...@@ -631,9 +648,17 @@ func TestWriteDeadlineBufferAvailable(t *testing.T) {
c.SetWriteDeadline(time.Now().Add(-5 * time.Second)) // in the past c.SetWriteDeadline(time.Now().Add(-5 * time.Second)) // in the past
n, err := c.Write([]byte{'x'}) n, err := c.Write([]byte{'x'})
servec <- copyRes{n: int64(n), err: err} servec <- copyRes{n: int64(n), err: err}
}() }
ls, err := newLocalServer("tcp")
if err != nil {
t.Fatal(err)
}
defer ls.teardown()
if err := ls.buildup(handler); err != nil {
t.Fatal(err)
}
c, err := Dial("tcp", ln.Addr().String()) c, err := Dial("tcp", ls.Listener.Addr().String())
if err != nil { if err != nil {
t.Fatalf("Dial: %v", err) t.Fatalf("Dial: %v", err)
} }
...@@ -655,7 +680,10 @@ func TestAcceptDeadlineConnectionAvailable(t *testing.T) { ...@@ -655,7 +680,10 @@ func TestAcceptDeadlineConnectionAvailable(t *testing.T) {
t.Skipf("skipping test on %q", runtime.GOOS) t.Skipf("skipping test on %q", runtime.GOOS)
} }
ln := newLocalListener(t).(*TCPListener) ln, err := newLocalListener("tcp")
if err != nil {
t.Fatal(err)
}
defer ln.Close() defer ln.Close()
go func() { go func() {
...@@ -669,7 +697,7 @@ func TestAcceptDeadlineConnectionAvailable(t *testing.T) { ...@@ -669,7 +697,7 @@ func TestAcceptDeadlineConnectionAvailable(t *testing.T) {
c.Read(buf[:]) // block until the connection or listener is closed c.Read(buf[:]) // block until the connection or listener is closed
}() }()
time.Sleep(10 * time.Millisecond) time.Sleep(10 * time.Millisecond)
ln.SetDeadline(time.Now().Add(-5 * time.Second)) // in the past ln.(*TCPListener).SetDeadline(time.Now().Add(-5 * time.Second)) // in the past
c, err := ln.Accept() c, err := ln.Accept()
if err == nil { if err == nil {
defer c.Close() defer c.Close()
...@@ -682,7 +710,10 @@ func TestAcceptDeadlineConnectionAvailable(t *testing.T) { ...@@ -682,7 +710,10 @@ func TestAcceptDeadlineConnectionAvailable(t *testing.T) {
// TestConnectDeadlineInThePast tests that connect deadlines work, even // TestConnectDeadlineInThePast tests that connect deadlines work, even
// if the connection can be established w/o blocking. // if the connection can be established w/o blocking.
func TestConnectDeadlineInThePast(t *testing.T) { func TestConnectDeadlineInThePast(t *testing.T) {
ln := newLocalListener(t).(*TCPListener) ln, err := newLocalListener("tcp")
if err != nil {
t.Fatal(err)
}
defer ln.Close() defer ln.Close()
go func() { go func() {
...@@ -709,10 +740,8 @@ func TestProlongTimeout(t *testing.T) { ...@@ -709,10 +740,8 @@ func TestProlongTimeout(t *testing.T) {
t.Skipf("skipping test on %q", runtime.GOOS) t.Skipf("skipping test on %q", runtime.GOOS)
} }
ln := newLocalListener(t)
defer ln.Close()
connected := make(chan bool) connected := make(chan bool)
go func() { handler := func(ls *localServer, ln Listener) {
s, err := ln.Accept() s, err := ln.Accept()
connected <- true connected <- true
if err != nil { if err != nil {
...@@ -739,8 +768,17 @@ func TestProlongTimeout(t *testing.T) { ...@@ -739,8 +768,17 @@ func TestProlongTimeout(t *testing.T) {
} }
s.SetDeadline(time.Now().Add(time.Hour)) s.SetDeadline(time.Now().Add(time.Hour))
} }
}() }
c, err := Dial("tcp", ln.Addr().String()) ls, err := newLocalServer("tcp")
if err != nil {
t.Fatal(err)
}
defer ls.teardown()
if err := ls.buildup(handler); err != nil {
t.Fatal(err)
}
c, err := Dial("tcp", ls.Listener.Addr().String())
if err != nil { if err != nil {
t.Fatalf("DialTCP: %v", err) t.Fatalf("DialTCP: %v", err)
} }
...@@ -763,7 +801,10 @@ func TestDeadlineRace(t *testing.T) { ...@@ -763,7 +801,10 @@ func TestDeadlineRace(t *testing.T) {
N = 50 N = 50
} }
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
ln := newLocalListener(t) ln, err := newLocalListener("tcp")
if err != nil {
t.Fatal(err)
}
defer ln.Close() defer ln.Close()
c, err := Dial("tcp", ln.Addr().String()) c, err := Dial("tcp", ln.Addr().String())
if err != nil { if err != nil {
......
...@@ -235,6 +235,7 @@ func TestUnixConnLocalAndRemoteNames(t *testing.T) { ...@@ -235,6 +235,7 @@ func TestUnixConnLocalAndRemoteNames(t *testing.T) {
t.Skip("unix test") t.Skip("unix test")
} }
handler := func(ls *localServer, ln Listener) {}
for _, laddr := range []string{"", testUnixAddr()} { for _, laddr := range []string{"", testUnixAddr()} {
laddr := laddr laddr := laddr
taddr := testUnixAddr() taddr := testUnixAddr()
...@@ -246,13 +247,14 @@ func TestUnixConnLocalAndRemoteNames(t *testing.T) { ...@@ -246,13 +247,14 @@ func TestUnixConnLocalAndRemoteNames(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("ListenUnix failed: %v", err) t.Fatalf("ListenUnix failed: %v", err)
} }
defer func() { ls, err := (&streamListener{Listener: ln}).newLocalServer()
ln.Close() if err != nil {
os.Remove(taddr) t.Fatal(err)
}() }
defer ls.teardown()
done := make(chan int) if err := ls.buildup(handler); err != nil {
go transponder(t, ln, done) t.Fatal(err)
}
la, err := ResolveUnixAddr("unix", laddr) la, err := ResolveUnixAddr("unix", laddr)
if err != nil { if err != nil {
...@@ -288,8 +290,6 @@ func TestUnixConnLocalAndRemoteNames(t *testing.T) { ...@@ -288,8 +290,6 @@ func TestUnixConnLocalAndRemoteNames(t *testing.T) {
t.Fatalf("got %#v, expected %#v", ca.got, ca.want) t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
} }
} }
<-done
} }
} }
......
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