github.com/hlts2/go@v0.0.0-20170904000733-812b34efaed8/src/net/mockserver_test.go (about) 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. 4 5 package net 6 7 import ( 8 "errors" 9 "fmt" 10 "io/ioutil" 11 "os" 12 "sync" 13 "testing" 14 "time" 15 ) 16 17 // testUnixAddr uses ioutil.TempFile to get a name that is unique. 18 // It also uses /tmp directory in case it is prohibited to create UNIX 19 // sockets in TMPDIR. 20 func testUnixAddr() string { 21 f, err := ioutil.TempFile("", "go-nettest") 22 if err != nil { 23 panic(err) 24 } 25 addr := f.Name() 26 f.Close() 27 os.Remove(addr) 28 return addr 29 } 30 31 func newLocalListener(network string) (Listener, error) { 32 switch network { 33 case "tcp": 34 if supportsIPv4() { 35 if ln, err := Listen("tcp4", "127.0.0.1:0"); err == nil { 36 return ln, nil 37 } 38 } 39 if supportsIPv6() { 40 return Listen("tcp6", "[::1]:0") 41 } 42 case "tcp4": 43 if supportsIPv4() { 44 return Listen("tcp4", "127.0.0.1:0") 45 } 46 case "tcp6": 47 if supportsIPv6() { 48 return Listen("tcp6", "[::1]:0") 49 } 50 case "unix", "unixpacket": 51 return Listen(network, testUnixAddr()) 52 } 53 return nil, fmt.Errorf("%s is not supported", network) 54 } 55 56 func newDualStackListener() (lns []*TCPListener, err error) { 57 var args = []struct { 58 network string 59 TCPAddr 60 }{ 61 {"tcp4", TCPAddr{IP: IPv4(127, 0, 0, 1)}}, 62 {"tcp6", TCPAddr{IP: IPv6loopback}}, 63 } 64 for i := 0; i < 64; i++ { 65 var port int 66 var lns []*TCPListener 67 for _, arg := range args { 68 arg.TCPAddr.Port = port 69 ln, err := ListenTCP(arg.network, &arg.TCPAddr) 70 if err != nil { 71 continue 72 } 73 port = ln.Addr().(*TCPAddr).Port 74 lns = append(lns, ln) 75 } 76 if len(lns) != len(args) { 77 for _, ln := range lns { 78 ln.Close() 79 } 80 continue 81 } 82 return lns, nil 83 } 84 return nil, errors.New("no dualstack port available") 85 } 86 87 type localServer struct { 88 lnmu sync.RWMutex 89 Listener 90 done chan bool // signal that indicates server stopped 91 } 92 93 func (ls *localServer) buildup(handler func(*localServer, Listener)) error { 94 go func() { 95 handler(ls, ls.Listener) 96 close(ls.done) 97 }() 98 return nil 99 } 100 101 func (ls *localServer) teardown() error { 102 ls.lnmu.Lock() 103 if ls.Listener != nil { 104 network := ls.Listener.Addr().Network() 105 address := ls.Listener.Addr().String() 106 ls.Listener.Close() 107 <-ls.done 108 ls.Listener = nil 109 switch network { 110 case "unix", "unixpacket": 111 os.Remove(address) 112 } 113 } 114 ls.lnmu.Unlock() 115 return nil 116 } 117 118 func newLocalServer(network string) (*localServer, error) { 119 ln, err := newLocalListener(network) 120 if err != nil { 121 return nil, err 122 } 123 return &localServer{Listener: ln, done: make(chan bool)}, nil 124 } 125 126 type streamListener struct { 127 network, address string 128 Listener 129 done chan bool // signal that indicates server stopped 130 } 131 132 func (sl *streamListener) newLocalServer() (*localServer, error) { 133 return &localServer{Listener: sl.Listener, done: make(chan bool)}, nil 134 } 135 136 type dualStackServer struct { 137 lnmu sync.RWMutex 138 lns []streamListener 139 port string 140 141 cmu sync.RWMutex 142 cs []Conn // established connections at the passive open side 143 } 144 145 func (dss *dualStackServer) buildup(handler func(*dualStackServer, Listener)) error { 146 for i := range dss.lns { 147 go func(i int) { 148 handler(dss, dss.lns[i].Listener) 149 close(dss.lns[i].done) 150 }(i) 151 } 152 return nil 153 } 154 155 func (dss *dualStackServer) teardownNetwork(network string) error { 156 dss.lnmu.Lock() 157 for i := range dss.lns { 158 if network == dss.lns[i].network && dss.lns[i].Listener != nil { 159 dss.lns[i].Listener.Close() 160 <-dss.lns[i].done 161 dss.lns[i].Listener = nil 162 } 163 } 164 dss.lnmu.Unlock() 165 return nil 166 } 167 168 func (dss *dualStackServer) teardown() error { 169 dss.lnmu.Lock() 170 for i := range dss.lns { 171 if dss.lns[i].Listener != nil { 172 dss.lns[i].Listener.Close() 173 <-dss.lns[i].done 174 } 175 } 176 dss.lns = dss.lns[:0] 177 dss.lnmu.Unlock() 178 dss.cmu.Lock() 179 for _, c := range dss.cs { 180 c.Close() 181 } 182 dss.cs = dss.cs[:0] 183 dss.cmu.Unlock() 184 return nil 185 } 186 187 func newDualStackServer() (*dualStackServer, error) { 188 lns, err := newDualStackListener() 189 if err != nil { 190 return nil, err 191 } 192 _, port, err := SplitHostPort(lns[0].Addr().String()) 193 if err != nil { 194 lns[0].Close() 195 lns[1].Close() 196 return nil, err 197 } 198 return &dualStackServer{ 199 lns: []streamListener{ 200 {network: "tcp4", address: lns[0].Addr().String(), Listener: lns[0], done: make(chan bool)}, 201 {network: "tcp6", address: lns[1].Addr().String(), Listener: lns[1], done: make(chan bool)}, 202 }, 203 port: port, 204 }, nil 205 } 206 207 func transponder(ln Listener, ch chan<- error) { 208 defer close(ch) 209 210 switch ln := ln.(type) { 211 case *TCPListener: 212 ln.SetDeadline(time.Now().Add(someTimeout)) 213 case *UnixListener: 214 ln.SetDeadline(time.Now().Add(someTimeout)) 215 } 216 c, err := ln.Accept() 217 if err != nil { 218 if perr := parseAcceptError(err); perr != nil { 219 ch <- perr 220 } 221 ch <- err 222 return 223 } 224 defer c.Close() 225 226 network := ln.Addr().Network() 227 if c.LocalAddr().Network() != network || c.RemoteAddr().Network() != network { 228 ch <- fmt.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network) 229 return 230 } 231 c.SetDeadline(time.Now().Add(someTimeout)) 232 c.SetReadDeadline(time.Now().Add(someTimeout)) 233 c.SetWriteDeadline(time.Now().Add(someTimeout)) 234 235 b := make([]byte, 256) 236 n, err := c.Read(b) 237 if err != nil { 238 if perr := parseReadError(err); perr != nil { 239 ch <- perr 240 } 241 ch <- err 242 return 243 } 244 if _, err := c.Write(b[:n]); err != nil { 245 if perr := parseWriteError(err); perr != nil { 246 ch <- perr 247 } 248 ch <- err 249 return 250 } 251 } 252 253 func transceiver(c Conn, wb []byte, ch chan<- error) { 254 defer close(ch) 255 256 c.SetDeadline(time.Now().Add(someTimeout)) 257 c.SetReadDeadline(time.Now().Add(someTimeout)) 258 c.SetWriteDeadline(time.Now().Add(someTimeout)) 259 260 n, err := c.Write(wb) 261 if err != nil { 262 if perr := parseWriteError(err); perr != nil { 263 ch <- perr 264 } 265 ch <- err 266 return 267 } 268 if n != len(wb) { 269 ch <- fmt.Errorf("wrote %d; want %d", n, len(wb)) 270 } 271 rb := make([]byte, len(wb)) 272 n, err = c.Read(rb) 273 if err != nil { 274 if perr := parseReadError(err); perr != nil { 275 ch <- perr 276 } 277 ch <- err 278 return 279 } 280 if n != len(wb) { 281 ch <- fmt.Errorf("read %d; want %d", n, len(wb)) 282 } 283 } 284 285 func timeoutReceiver(c Conn, d, min, max time.Duration, ch chan<- error) { 286 var err error 287 defer func() { ch <- err }() 288 289 t0 := time.Now() 290 if err = c.SetReadDeadline(time.Now().Add(d)); err != nil { 291 return 292 } 293 b := make([]byte, 256) 294 var n int 295 n, err = c.Read(b) 296 t1 := time.Now() 297 if n != 0 || err == nil || !err.(Error).Timeout() { 298 err = fmt.Errorf("Read did not return (0, timeout): (%d, %v)", n, err) 299 return 300 } 301 if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() { 302 err = fmt.Errorf("Read took %s; expected %s", dt, d) 303 return 304 } 305 } 306 307 func timeoutTransmitter(c Conn, d, min, max time.Duration, ch chan<- error) { 308 var err error 309 defer func() { ch <- err }() 310 311 t0 := time.Now() 312 if err = c.SetWriteDeadline(time.Now().Add(d)); err != nil { 313 return 314 } 315 var n int 316 for { 317 n, err = c.Write([]byte("TIMEOUT TRANSMITTER")) 318 if err != nil { 319 break 320 } 321 } 322 t1 := time.Now() 323 if err == nil || !err.(Error).Timeout() { 324 err = fmt.Errorf("Write did not return (any, timeout): (%d, %v)", n, err) 325 return 326 } 327 if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() { 328 err = fmt.Errorf("Write took %s; expected %s", dt, d) 329 return 330 } 331 } 332 333 func newLocalPacketListener(network string) (PacketConn, error) { 334 switch network { 335 case "udp": 336 if supportsIPv4() { 337 return ListenPacket("udp4", "127.0.0.1:0") 338 } 339 if supportsIPv6() { 340 return ListenPacket("udp6", "[::1]:0") 341 } 342 case "udp4": 343 if supportsIPv4() { 344 return ListenPacket("udp4", "127.0.0.1:0") 345 } 346 case "udp6": 347 if supportsIPv6() { 348 return ListenPacket("udp6", "[::1]:0") 349 } 350 case "unixgram": 351 return ListenPacket(network, testUnixAddr()) 352 } 353 return nil, fmt.Errorf("%s is not supported", network) 354 } 355 356 func newDualStackPacketListener() (cs []*UDPConn, err error) { 357 var args = []struct { 358 network string 359 UDPAddr 360 }{ 361 {"udp4", UDPAddr{IP: IPv4(127, 0, 0, 1)}}, 362 {"udp6", UDPAddr{IP: IPv6loopback}}, 363 } 364 for i := 0; i < 64; i++ { 365 var port int 366 var cs []*UDPConn 367 for _, arg := range args { 368 arg.UDPAddr.Port = port 369 c, err := ListenUDP(arg.network, &arg.UDPAddr) 370 if err != nil { 371 continue 372 } 373 port = c.LocalAddr().(*UDPAddr).Port 374 cs = append(cs, c) 375 } 376 if len(cs) != len(args) { 377 for _, c := range cs { 378 c.Close() 379 } 380 continue 381 } 382 return cs, nil 383 } 384 return nil, errors.New("no dualstack port available") 385 } 386 387 type localPacketServer struct { 388 pcmu sync.RWMutex 389 PacketConn 390 done chan bool // signal that indicates server stopped 391 } 392 393 func (ls *localPacketServer) buildup(handler func(*localPacketServer, PacketConn)) error { 394 go func() { 395 handler(ls, ls.PacketConn) 396 close(ls.done) 397 }() 398 return nil 399 } 400 401 func (ls *localPacketServer) teardown() error { 402 ls.pcmu.Lock() 403 if ls.PacketConn != nil { 404 network := ls.PacketConn.LocalAddr().Network() 405 address := ls.PacketConn.LocalAddr().String() 406 ls.PacketConn.Close() 407 <-ls.done 408 ls.PacketConn = nil 409 switch network { 410 case "unixgram": 411 os.Remove(address) 412 } 413 } 414 ls.pcmu.Unlock() 415 return nil 416 } 417 418 func newLocalPacketServer(network string) (*localPacketServer, error) { 419 c, err := newLocalPacketListener(network) 420 if err != nil { 421 return nil, err 422 } 423 return &localPacketServer{PacketConn: c, done: make(chan bool)}, nil 424 } 425 426 type packetListener struct { 427 PacketConn 428 } 429 430 func (pl *packetListener) newLocalServer() (*localPacketServer, error) { 431 return &localPacketServer{PacketConn: pl.PacketConn, done: make(chan bool)}, nil 432 } 433 434 func packetTransponder(c PacketConn, ch chan<- error) { 435 defer close(ch) 436 437 c.SetDeadline(time.Now().Add(someTimeout)) 438 c.SetReadDeadline(time.Now().Add(someTimeout)) 439 c.SetWriteDeadline(time.Now().Add(someTimeout)) 440 441 b := make([]byte, 256) 442 n, peer, err := c.ReadFrom(b) 443 if err != nil { 444 if perr := parseReadError(err); perr != nil { 445 ch <- perr 446 } 447 ch <- err 448 return 449 } 450 if peer == nil { // for connected-mode sockets 451 switch c.LocalAddr().Network() { 452 case "udp": 453 peer, err = ResolveUDPAddr("udp", string(b[:n])) 454 case "unixgram": 455 peer, err = ResolveUnixAddr("unixgram", string(b[:n])) 456 } 457 if err != nil { 458 ch <- err 459 return 460 } 461 } 462 if _, err := c.WriteTo(b[:n], peer); err != nil { 463 if perr := parseWriteError(err); perr != nil { 464 ch <- perr 465 } 466 ch <- err 467 return 468 } 469 } 470 471 func packetTransceiver(c PacketConn, wb []byte, dst Addr, ch chan<- error) { 472 defer close(ch) 473 474 c.SetDeadline(time.Now().Add(someTimeout)) 475 c.SetReadDeadline(time.Now().Add(someTimeout)) 476 c.SetWriteDeadline(time.Now().Add(someTimeout)) 477 478 n, err := c.WriteTo(wb, dst) 479 if err != nil { 480 if perr := parseWriteError(err); perr != nil { 481 ch <- perr 482 } 483 ch <- err 484 return 485 } 486 if n != len(wb) { 487 ch <- fmt.Errorf("wrote %d; want %d", n, len(wb)) 488 } 489 rb := make([]byte, len(wb)) 490 n, _, err = c.ReadFrom(rb) 491 if err != nil { 492 if perr := parseReadError(err); perr != nil { 493 ch <- perr 494 } 495 ch <- err 496 return 497 } 498 if n != len(wb) { 499 ch <- fmt.Errorf("read %d; want %d", n, len(wb)) 500 } 501 } 502 503 func timeoutPacketReceiver(c PacketConn, d, min, max time.Duration, ch chan<- error) { 504 var err error 505 defer func() { ch <- err }() 506 507 t0 := time.Now() 508 if err = c.SetReadDeadline(time.Now().Add(d)); err != nil { 509 return 510 } 511 b := make([]byte, 256) 512 var n int 513 n, _, err = c.ReadFrom(b) 514 t1 := time.Now() 515 if n != 0 || err == nil || !err.(Error).Timeout() { 516 err = fmt.Errorf("ReadFrom did not return (0, timeout): (%d, %v)", n, err) 517 return 518 } 519 if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() { 520 err = fmt.Errorf("ReadFrom took %s; expected %s", dt, d) 521 return 522 } 523 }