libgo: update to Go 1.11
[official-gcc.git] / libgo / go / net / mockserver_test.go
blob530293578a08e67b8649a4cff691127b0216a2fc
1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // +build !js
7 package net
9 import (
10 "errors"
11 "fmt"
12 "io/ioutil"
13 "os"
14 "sync"
15 "testing"
16 "time"
19 // testUnixAddr uses ioutil.TempFile to get a name that is unique.
20 // It also uses /tmp directory in case it is prohibited to create UNIX
21 // sockets in TMPDIR.
22 func testUnixAddr() string {
23 f, err := ioutil.TempFile("", "go-nettest")
24 if err != nil {
25 panic(err)
27 addr := f.Name()
28 f.Close()
29 os.Remove(addr)
30 return addr
33 func newLocalListener(network string) (Listener, error) {
34 switch network {
35 case "tcp":
36 if supportsIPv4() {
37 if ln, err := Listen("tcp4", "127.0.0.1:0"); err == nil {
38 return ln, nil
41 if supportsIPv6() {
42 return Listen("tcp6", "[::1]:0")
44 case "tcp4":
45 if supportsIPv4() {
46 return Listen("tcp4", "127.0.0.1:0")
48 case "tcp6":
49 if supportsIPv6() {
50 return Listen("tcp6", "[::1]:0")
52 case "unix", "unixpacket":
53 return Listen(network, testUnixAddr())
55 return nil, fmt.Errorf("%s is not supported", network)
58 func newDualStackListener() (lns []*TCPListener, err error) {
59 var args = []struct {
60 network string
61 TCPAddr
63 {"tcp4", TCPAddr{IP: IPv4(127, 0, 0, 1)}},
64 {"tcp6", TCPAddr{IP: IPv6loopback}},
66 for i := 0; i < 64; i++ {
67 var port int
68 var lns []*TCPListener
69 for _, arg := range args {
70 arg.TCPAddr.Port = port
71 ln, err := ListenTCP(arg.network, &arg.TCPAddr)
72 if err != nil {
73 continue
75 port = ln.Addr().(*TCPAddr).Port
76 lns = append(lns, ln)
78 if len(lns) != len(args) {
79 for _, ln := range lns {
80 ln.Close()
82 continue
84 return lns, nil
86 return nil, errors.New("no dualstack port available")
89 type localServer struct {
90 lnmu sync.RWMutex
91 Listener
92 done chan bool // signal that indicates server stopped
95 func (ls *localServer) buildup(handler func(*localServer, Listener)) error {
96 go func() {
97 handler(ls, ls.Listener)
98 close(ls.done)
99 }()
100 return nil
103 func (ls *localServer) teardown() error {
104 ls.lnmu.Lock()
105 if ls.Listener != nil {
106 network := ls.Listener.Addr().Network()
107 address := ls.Listener.Addr().String()
108 ls.Listener.Close()
109 <-ls.done
110 ls.Listener = nil
111 switch network {
112 case "unix", "unixpacket":
113 os.Remove(address)
116 ls.lnmu.Unlock()
117 return nil
120 func newLocalServer(network string) (*localServer, error) {
121 ln, err := newLocalListener(network)
122 if err != nil {
123 return nil, err
125 return &localServer{Listener: ln, done: make(chan bool)}, nil
128 type streamListener struct {
129 network, address string
130 Listener
131 done chan bool // signal that indicates server stopped
134 func (sl *streamListener) newLocalServer() (*localServer, error) {
135 return &localServer{Listener: sl.Listener, done: make(chan bool)}, nil
138 type dualStackServer struct {
139 lnmu sync.RWMutex
140 lns []streamListener
141 port string
143 cmu sync.RWMutex
144 cs []Conn // established connections at the passive open side
147 func (dss *dualStackServer) buildup(handler func(*dualStackServer, Listener)) error {
148 for i := range dss.lns {
149 go func(i int) {
150 handler(dss, dss.lns[i].Listener)
151 close(dss.lns[i].done)
152 }(i)
154 return nil
157 func (dss *dualStackServer) teardownNetwork(network string) error {
158 dss.lnmu.Lock()
159 for i := range dss.lns {
160 if network == dss.lns[i].network && dss.lns[i].Listener != nil {
161 dss.lns[i].Listener.Close()
162 <-dss.lns[i].done
163 dss.lns[i].Listener = nil
166 dss.lnmu.Unlock()
167 return nil
170 func (dss *dualStackServer) teardown() error {
171 dss.lnmu.Lock()
172 for i := range dss.lns {
173 if dss.lns[i].Listener != nil {
174 dss.lns[i].Listener.Close()
175 <-dss.lns[i].done
178 dss.lns = dss.lns[:0]
179 dss.lnmu.Unlock()
180 dss.cmu.Lock()
181 for _, c := range dss.cs {
182 c.Close()
184 dss.cs = dss.cs[:0]
185 dss.cmu.Unlock()
186 return nil
189 func newDualStackServer() (*dualStackServer, error) {
190 lns, err := newDualStackListener()
191 if err != nil {
192 return nil, err
194 _, port, err := SplitHostPort(lns[0].Addr().String())
195 if err != nil {
196 lns[0].Close()
197 lns[1].Close()
198 return nil, err
200 return &dualStackServer{
201 lns: []streamListener{
202 {network: "tcp4", address: lns[0].Addr().String(), Listener: lns[0], done: make(chan bool)},
203 {network: "tcp6", address: lns[1].Addr().String(), Listener: lns[1], done: make(chan bool)},
205 port: port,
206 }, nil
209 func transponder(ln Listener, ch chan<- error) {
210 defer close(ch)
212 switch ln := ln.(type) {
213 case *TCPListener:
214 ln.SetDeadline(time.Now().Add(someTimeout))
215 case *UnixListener:
216 ln.SetDeadline(time.Now().Add(someTimeout))
218 c, err := ln.Accept()
219 if err != nil {
220 if perr := parseAcceptError(err); perr != nil {
221 ch <- perr
223 ch <- err
224 return
226 defer c.Close()
228 network := ln.Addr().Network()
229 if c.LocalAddr().Network() != network || c.RemoteAddr().Network() != network {
230 ch <- fmt.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network)
231 return
233 c.SetDeadline(time.Now().Add(someTimeout))
234 c.SetReadDeadline(time.Now().Add(someTimeout))
235 c.SetWriteDeadline(time.Now().Add(someTimeout))
237 b := make([]byte, 256)
238 n, err := c.Read(b)
239 if err != nil {
240 if perr := parseReadError(err); perr != nil {
241 ch <- perr
243 ch <- err
244 return
246 if _, err := c.Write(b[:n]); err != nil {
247 if perr := parseWriteError(err); perr != nil {
248 ch <- perr
250 ch <- err
251 return
255 func transceiver(c Conn, wb []byte, ch chan<- error) {
256 defer close(ch)
258 c.SetDeadline(time.Now().Add(someTimeout))
259 c.SetReadDeadline(time.Now().Add(someTimeout))
260 c.SetWriteDeadline(time.Now().Add(someTimeout))
262 n, err := c.Write(wb)
263 if err != nil {
264 if perr := parseWriteError(err); perr != nil {
265 ch <- perr
267 ch <- err
268 return
270 if n != len(wb) {
271 ch <- fmt.Errorf("wrote %d; want %d", n, len(wb))
273 rb := make([]byte, len(wb))
274 n, err = c.Read(rb)
275 if err != nil {
276 if perr := parseReadError(err); perr != nil {
277 ch <- perr
279 ch <- err
280 return
282 if n != len(wb) {
283 ch <- fmt.Errorf("read %d; want %d", n, len(wb))
287 func timeoutReceiver(c Conn, d, min, max time.Duration, ch chan<- error) {
288 var err error
289 defer func() { ch <- err }()
291 t0 := time.Now()
292 if err = c.SetReadDeadline(time.Now().Add(d)); err != nil {
293 return
295 b := make([]byte, 256)
296 var n int
297 n, err = c.Read(b)
298 t1 := time.Now()
299 if n != 0 || err == nil || !err.(Error).Timeout() {
300 err = fmt.Errorf("Read did not return (0, timeout): (%d, %v)", n, err)
301 return
303 if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
304 err = fmt.Errorf("Read took %s; expected %s", dt, d)
305 return
309 func timeoutTransmitter(c Conn, d, min, max time.Duration, ch chan<- error) {
310 var err error
311 defer func() { ch <- err }()
313 t0 := time.Now()
314 if err = c.SetWriteDeadline(time.Now().Add(d)); err != nil {
315 return
317 var n int
318 for {
319 n, err = c.Write([]byte("TIMEOUT TRANSMITTER"))
320 if err != nil {
321 break
324 t1 := time.Now()
325 if err == nil || !err.(Error).Timeout() {
326 err = fmt.Errorf("Write did not return (any, timeout): (%d, %v)", n, err)
327 return
329 if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
330 err = fmt.Errorf("Write took %s; expected %s", dt, d)
331 return
335 func newLocalPacketListener(network string) (PacketConn, error) {
336 switch network {
337 case "udp":
338 if supportsIPv4() {
339 return ListenPacket("udp4", "127.0.0.1:0")
341 if supportsIPv6() {
342 return ListenPacket("udp6", "[::1]:0")
344 case "udp4":
345 if supportsIPv4() {
346 return ListenPacket("udp4", "127.0.0.1:0")
348 case "udp6":
349 if supportsIPv6() {
350 return ListenPacket("udp6", "[::1]:0")
352 case "unixgram":
353 return ListenPacket(network, testUnixAddr())
355 return nil, fmt.Errorf("%s is not supported", network)
358 func newDualStackPacketListener() (cs []*UDPConn, err error) {
359 var args = []struct {
360 network string
361 UDPAddr
363 {"udp4", UDPAddr{IP: IPv4(127, 0, 0, 1)}},
364 {"udp6", UDPAddr{IP: IPv6loopback}},
366 for i := 0; i < 64; i++ {
367 var port int
368 var cs []*UDPConn
369 for _, arg := range args {
370 arg.UDPAddr.Port = port
371 c, err := ListenUDP(arg.network, &arg.UDPAddr)
372 if err != nil {
373 continue
375 port = c.LocalAddr().(*UDPAddr).Port
376 cs = append(cs, c)
378 if len(cs) != len(args) {
379 for _, c := range cs {
380 c.Close()
382 continue
384 return cs, nil
386 return nil, errors.New("no dualstack port available")
389 type localPacketServer struct {
390 pcmu sync.RWMutex
391 PacketConn
392 done chan bool // signal that indicates server stopped
395 func (ls *localPacketServer) buildup(handler func(*localPacketServer, PacketConn)) error {
396 go func() {
397 handler(ls, ls.PacketConn)
398 close(ls.done)
400 return nil
403 func (ls *localPacketServer) teardown() error {
404 ls.pcmu.Lock()
405 if ls.PacketConn != nil {
406 network := ls.PacketConn.LocalAddr().Network()
407 address := ls.PacketConn.LocalAddr().String()
408 ls.PacketConn.Close()
409 <-ls.done
410 ls.PacketConn = nil
411 switch network {
412 case "unixgram":
413 os.Remove(address)
416 ls.pcmu.Unlock()
417 return nil
420 func newLocalPacketServer(network string) (*localPacketServer, error) {
421 c, err := newLocalPacketListener(network)
422 if err != nil {
423 return nil, err
425 return &localPacketServer{PacketConn: c, done: make(chan bool)}, nil
428 type packetListener struct {
429 PacketConn
432 func (pl *packetListener) newLocalServer() (*localPacketServer, error) {
433 return &localPacketServer{PacketConn: pl.PacketConn, done: make(chan bool)}, nil
436 func packetTransponder(c PacketConn, ch chan<- error) {
437 defer close(ch)
439 c.SetDeadline(time.Now().Add(someTimeout))
440 c.SetReadDeadline(time.Now().Add(someTimeout))
441 c.SetWriteDeadline(time.Now().Add(someTimeout))
443 b := make([]byte, 256)
444 n, peer, err := c.ReadFrom(b)
445 if err != nil {
446 if perr := parseReadError(err); perr != nil {
447 ch <- perr
449 ch <- err
450 return
452 if peer == nil { // for connected-mode sockets
453 switch c.LocalAddr().Network() {
454 case "udp":
455 peer, err = ResolveUDPAddr("udp", string(b[:n]))
456 case "unixgram":
457 peer, err = ResolveUnixAddr("unixgram", string(b[:n]))
459 if err != nil {
460 ch <- err
461 return
464 if _, err := c.WriteTo(b[:n], peer); err != nil {
465 if perr := parseWriteError(err); perr != nil {
466 ch <- perr
468 ch <- err
469 return
473 func packetTransceiver(c PacketConn, wb []byte, dst Addr, ch chan<- error) {
474 defer close(ch)
476 c.SetDeadline(time.Now().Add(someTimeout))
477 c.SetReadDeadline(time.Now().Add(someTimeout))
478 c.SetWriteDeadline(time.Now().Add(someTimeout))
480 n, err := c.WriteTo(wb, dst)
481 if err != nil {
482 if perr := parseWriteError(err); perr != nil {
483 ch <- perr
485 ch <- err
486 return
488 if n != len(wb) {
489 ch <- fmt.Errorf("wrote %d; want %d", n, len(wb))
491 rb := make([]byte, len(wb))
492 n, _, err = c.ReadFrom(rb)
493 if err != nil {
494 if perr := parseReadError(err); perr != nil {
495 ch <- perr
497 ch <- err
498 return
500 if n != len(wb) {
501 ch <- fmt.Errorf("read %d; want %d", n, len(wb))
505 func timeoutPacketReceiver(c PacketConn, d, min, max time.Duration, ch chan<- error) {
506 var err error
507 defer func() { ch <- err }()
509 t0 := time.Now()
510 if err = c.SetReadDeadline(time.Now().Add(d)); err != nil {
511 return
513 b := make([]byte, 256)
514 var n int
515 n, _, err = c.ReadFrom(b)
516 t1 := time.Now()
517 if n != 0 || err == nil || !err.(Error).Timeout() {
518 err = fmt.Errorf("ReadFrom did not return (0, timeout): (%d, %v)", n, err)
519 return
521 if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
522 err = fmt.Errorf("ReadFrom took %s; expected %s", dt, d)
523 return