diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2015-10-31 00:59:47 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2015-10-31 00:59:47 +0000 |
commit | af146490bb04205107cb23e301ec7a8ff927b5fc (patch) | |
tree | 13beeaed3698c61903fe93fb1ce70bd9b18d4e7f /libgo/go/net/mockserver_test.go | |
parent | 725e1be3406315d9bcc8195d7eef0a7082b3c7cc (diff) | |
download | gcc-af146490bb04205107cb23e301ec7a8ff927b5fc.zip gcc-af146490bb04205107cb23e301ec7a8ff927b5fc.tar.gz gcc-af146490bb04205107cb23e301ec7a8ff927b5fc.tar.bz2 |
runtime: Remove now unnecessary pad field from ParFor.
It is not needed due to the removal of the ctx field.
Reviewed-on: https://go-review.googlesource.com/16525
From-SVN: r229616
Diffstat (limited to 'libgo/go/net/mockserver_test.go')
-rw-r--r-- | libgo/go/net/mockserver_test.go | 464 |
1 files changed, 449 insertions, 15 deletions
diff --git a/libgo/go/net/mockserver_test.go b/libgo/go/net/mockserver_test.go index 68ded5d..dd6f4df 100644 --- a/libgo/go/net/mockserver_test.go +++ b/libgo/go/net/mockserver_test.go @@ -4,11 +4,123 @@ package net -import "sync" +import ( + "errors" + "fmt" + "io/ioutil" + "os" + "sync" + "testing" + "time" +) + +// testUnixAddr uses ioutil.TempFile to get a name that is unique. +// It also uses /tmp directory in case it is prohibited to create UNIX +// sockets in TMPDIR. +func testUnixAddr() string { + f, err := ioutil.TempFile("", "go-nettest") + if err != nil { + panic(err) + } + addr := f.Name() + f.Close() + os.Remove(addr) + return addr +} + +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) +} + +func newDualStackListener() (lns []*TCPListener, err error) { + var args = []struct { + network string + TCPAddr + }{ + {"tcp4", TCPAddr{IP: IPv4(127, 0, 0, 1)}}, + {"tcp6", TCPAddr{IP: IPv6loopback}}, + } + for i := 0; i < 64; i++ { + var port int + var lns []*TCPListener + for _, arg := range args { + arg.TCPAddr.Port = port + ln, err := ListenTCP(arg.network, &arg.TCPAddr) + if err != nil { + continue + } + port = ln.Addr().(*TCPAddr).Port + lns = append(lns, ln) + } + if len(lns) != len(args) { + for _, ln := range lns { + ln.Close() + } + continue + } + return lns, nil + } + return nil, errors.New("no dualstack port available") +} + +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 { - net, addr string - ln Listener + network, address string + 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 { @@ -20,9 +132,12 @@ type dualStackServer struct { 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 { - 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 } @@ -34,12 +149,13 @@ func (dss *dualStackServer) putConn(c Conn) error { return nil } -func (dss *dualStackServer) teardownNetwork(net string) error { +func (dss *dualStackServer) teardownNetwork(network string) error { dss.lnmu.Lock() for i := range dss.lns { - if net == dss.lns[i].net && dss.lns[i].ln != nil { - dss.lns[i].ln.Close() - dss.lns[i].ln = nil + if network == dss.lns[i].network && dss.lns[i].Listener != nil { + dss.lns[i].Listener.Close() + <-dss.lns[i].done + dss.lns[i].Listener = nil } } dss.lnmu.Unlock() @@ -49,15 +165,18 @@ func (dss *dualStackServer) teardownNetwork(net string) error { func (dss *dualStackServer) teardown() error { dss.lnmu.Lock() for i := range dss.lns { - if dss.lns[i].ln != nil { - dss.lns[i].ln.Close() + if dss.lns[i].Listener != nil { + dss.lns[i].Listener.Close() + <-dss.lns[i].done } } + dss.lns = dss.lns[:0] dss.lnmu.Unlock() dss.cmu.Lock() for _, c := range dss.cs { c.Close() } + dss.cs = dss.cs[:0] dss.cmu.Unlock() return nil } @@ -65,18 +184,333 @@ func (dss *dualStackServer) teardown() error { func newDualStackServer(lns []streamListener) (*dualStackServer, error) { dss := &dualStackServer{lns: lns, port: "0"} 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 { - dss.teardown() + for _, ln := range dss.lns[:i] { + ln.Listener.Close() + } 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, err = SplitHostPort(ln.Addr().String()); err != nil { - dss.teardown() + for _, ln := range dss.lns { + ln.Listener.Close() + } return nil, err } } } return dss, nil } + +func transponder(ln Listener, ch chan<- error) { + defer close(ch) + + switch ln := ln.(type) { + case *TCPListener: + ln.SetDeadline(time.Now().Add(someTimeout)) + case *UnixListener: + ln.SetDeadline(time.Now().Add(someTimeout)) + } + c, err := ln.Accept() + if err != nil { + if perr := parseAcceptError(err); perr != nil { + ch <- perr + } + ch <- err + return + } + defer c.Close() + + network := ln.Addr().Network() + if c.LocalAddr().Network() != network || c.LocalAddr().Network() != network { + ch <- fmt.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network) + return + } + c.SetDeadline(time.Now().Add(someTimeout)) + c.SetReadDeadline(time.Now().Add(someTimeout)) + c.SetWriteDeadline(time.Now().Add(someTimeout)) + + b := make([]byte, 256) + n, err := c.Read(b) + if err != nil { + if perr := parseReadError(err); perr != nil { + ch <- perr + } + ch <- err + return + } + if _, err := c.Write(b[:n]); err != nil { + if perr := parseWriteError(err); perr != nil { + ch <- perr + } + ch <- err + return + } +} + +func transceiver(c Conn, wb []byte, ch chan<- error) { + defer close(ch) + + c.SetDeadline(time.Now().Add(someTimeout)) + c.SetReadDeadline(time.Now().Add(someTimeout)) + c.SetWriteDeadline(time.Now().Add(someTimeout)) + + n, err := c.Write(wb) + if err != nil { + if perr := parseWriteError(err); perr != nil { + ch <- perr + } + ch <- err + return + } + if n != len(wb) { + ch <- fmt.Errorf("wrote %d; want %d", n, len(wb)) + } + rb := make([]byte, len(wb)) + n, err = c.Read(rb) + if err != nil { + if perr := parseReadError(err); perr != nil { + ch <- perr + } + ch <- err + return + } + if n != len(wb) { + ch <- fmt.Errorf("read %d; want %d", n, len(wb)) + } +} + +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) { + switch network { + case "udp", "udp4", "udp6": + if supportsIPv4 { + return ListenPacket("udp4", "127.0.0.1:0") + } + if supportsIPv6 { + return ListenPacket("udp6", "[::1]:0") + } + case "unixgram": + return ListenPacket(network, testUnixAddr()) + } + return nil, fmt.Errorf("%s is not supported", network) +} + +func newDualStackPacketListener() (cs []*UDPConn, err error) { + var args = []struct { + network string + UDPAddr + }{ + {"udp4", UDPAddr{IP: IPv4(127, 0, 0, 1)}}, + {"udp6", UDPAddr{IP: IPv6loopback}}, + } + for i := 0; i < 64; i++ { + var port int + var cs []*UDPConn + for _, arg := range args { + arg.UDPAddr.Port = port + c, err := ListenUDP(arg.network, &arg.UDPAddr) + if err != nil { + continue + } + port = c.LocalAddr().(*UDPAddr).Port + cs = append(cs, c) + } + if len(cs) != len(args) { + for _, c := range cs { + c.Close() + } + continue + } + return cs, nil + } + return nil, errors.New("no dualstack port available") +} + +type localPacketServer struct { + pcmu sync.RWMutex + PacketConn + done chan bool // signal that indicates server stopped +} + +func (ls *localPacketServer) buildup(handler func(*localPacketServer, PacketConn)) error { + go func() { + handler(ls, ls.PacketConn) + close(ls.done) + }() + return nil +} + +func (ls *localPacketServer) teardown() error { + ls.pcmu.Lock() + if ls.PacketConn != nil { + network := ls.PacketConn.LocalAddr().Network() + address := ls.PacketConn.LocalAddr().String() + ls.PacketConn.Close() + <-ls.done + ls.PacketConn = nil + switch network { + case "unixgram": + os.Remove(address) + } + } + ls.pcmu.Unlock() + return nil +} + +func newLocalPacketServer(network string) (*localPacketServer, error) { + c, err := newLocalPacketListener(network) + if err != nil { + return nil, err + } + return &localPacketServer{PacketConn: c, done: make(chan bool)}, nil +} + +type packetListener struct { + PacketConn +} + +func (pl *packetListener) newLocalServer() (*localPacketServer, error) { + return &localPacketServer{PacketConn: pl.PacketConn, done: make(chan bool)}, nil +} + +func packetTransponder(c PacketConn, ch chan<- error) { + defer close(ch) + + c.SetDeadline(time.Now().Add(someTimeout)) + c.SetReadDeadline(time.Now().Add(someTimeout)) + c.SetWriteDeadline(time.Now().Add(someTimeout)) + + b := make([]byte, 256) + n, peer, err := c.ReadFrom(b) + if err != nil { + if perr := parseReadError(err); perr != nil { + ch <- perr + } + ch <- err + return + } + if peer == nil { // for connected-mode sockets + switch c.LocalAddr().Network() { + case "udp": + peer, err = ResolveUDPAddr("udp", string(b[:n])) + case "unixgram": + peer, err = ResolveUnixAddr("unixgram", string(b[:n])) + } + if err != nil { + ch <- err + return + } + } + if _, err := c.WriteTo(b[:n], peer); err != nil { + if perr := parseWriteError(err); perr != nil { + ch <- perr + } + ch <- err + return + } +} + +func packetTransceiver(c PacketConn, wb []byte, dst Addr, ch chan<- error) { + defer close(ch) + + c.SetDeadline(time.Now().Add(someTimeout)) + c.SetReadDeadline(time.Now().Add(someTimeout)) + c.SetWriteDeadline(time.Now().Add(someTimeout)) + + n, err := c.WriteTo(wb, dst) + if err != nil { + if perr := parseWriteError(err); perr != nil { + ch <- perr + } + ch <- err + return + } + if n != len(wb) { + ch <- fmt.Errorf("wrote %d; want %d", n, len(wb)) + } + rb := make([]byte, len(wb)) + n, _, err = c.ReadFrom(rb) + if err != nil { + if perr := parseReadError(err); perr != nil { + ch <- perr + } + ch <- err + return + } + if 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 + } +} |