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