github.com/rafaeltorres324/go/src@v0.0.0-20210519164414-9fdf653a9838/net/net_test.go (about) 1 // Copyright 2009 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 // +build !js 6 7 package net 8 9 import ( 10 "errors" 11 "fmt" 12 "internal/testenv" 13 "io" 14 "net/internal/socktest" 15 "os" 16 "runtime" 17 "testing" 18 "time" 19 ) 20 21 func TestCloseRead(t *testing.T) { 22 switch runtime.GOOS { 23 case "plan9": 24 t.Skipf("not supported on %s", runtime.GOOS) 25 } 26 t.Parallel() 27 28 for _, network := range []string{"tcp", "unix", "unixpacket"} { 29 network := network 30 t.Run(network, func(t *testing.T) { 31 if !testableNetwork(network) { 32 t.Skipf("network %s is not testable on the current platform", network) 33 } 34 t.Parallel() 35 36 ln, err := newLocalListener(network) 37 if err != nil { 38 t.Fatal(err) 39 } 40 switch network { 41 case "unix", "unixpacket": 42 defer os.Remove(ln.Addr().String()) 43 } 44 defer ln.Close() 45 46 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 47 if err != nil { 48 t.Fatal(err) 49 } 50 switch network { 51 case "unix", "unixpacket": 52 defer os.Remove(c.LocalAddr().String()) 53 } 54 defer c.Close() 55 56 switch c := c.(type) { 57 case *TCPConn: 58 err = c.CloseRead() 59 case *UnixConn: 60 err = c.CloseRead() 61 } 62 if err != nil { 63 if perr := parseCloseError(err, true); perr != nil { 64 t.Error(perr) 65 } 66 t.Fatal(err) 67 } 68 var b [1]byte 69 n, err := c.Read(b[:]) 70 if n != 0 || err == nil { 71 t.Fatalf("got (%d, %v); want (0, error)", n, err) 72 } 73 }) 74 } 75 } 76 77 func TestCloseWrite(t *testing.T) { 78 switch runtime.GOOS { 79 case "plan9": 80 t.Skipf("not supported on %s", runtime.GOOS) 81 } 82 83 t.Parallel() 84 deadline, _ := t.Deadline() 85 if !deadline.IsZero() { 86 // Leave 10% headroom on the deadline to report errors and clean up. 87 deadline = deadline.Add(-time.Until(deadline) / 10) 88 } 89 90 for _, network := range []string{"tcp", "unix", "unixpacket"} { 91 network := network 92 t.Run(network, func(t *testing.T) { 93 if !testableNetwork(network) { 94 t.Skipf("network %s is not testable on the current platform", network) 95 } 96 t.Parallel() 97 98 handler := func(ls *localServer, ln Listener) { 99 c, err := ln.Accept() 100 if err != nil { 101 t.Error(err) 102 return 103 } 104 if !deadline.IsZero() { 105 c.SetDeadline(deadline) 106 } 107 defer c.Close() 108 109 var b [1]byte 110 n, err := c.Read(b[:]) 111 if n != 0 || err != io.EOF { 112 t.Errorf("got (%d, %v); want (0, io.EOF)", n, err) 113 return 114 } 115 switch c := c.(type) { 116 case *TCPConn: 117 err = c.CloseWrite() 118 case *UnixConn: 119 err = c.CloseWrite() 120 } 121 if err != nil { 122 if perr := parseCloseError(err, true); perr != nil { 123 t.Error(perr) 124 } 125 t.Error(err) 126 return 127 } 128 n, err = c.Write(b[:]) 129 if err == nil { 130 t.Errorf("got (%d, %v); want (any, error)", n, err) 131 return 132 } 133 } 134 135 ls, err := newLocalServer(network) 136 if err != nil { 137 t.Fatal(err) 138 } 139 defer ls.teardown() 140 if err := ls.buildup(handler); err != nil { 141 t.Fatal(err) 142 } 143 144 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 145 if err != nil { 146 t.Fatal(err) 147 } 148 if !deadline.IsZero() { 149 c.SetDeadline(deadline) 150 } 151 switch network { 152 case "unix", "unixpacket": 153 defer os.Remove(c.LocalAddr().String()) 154 } 155 defer c.Close() 156 157 switch c := c.(type) { 158 case *TCPConn: 159 err = c.CloseWrite() 160 case *UnixConn: 161 err = c.CloseWrite() 162 } 163 if err != nil { 164 if perr := parseCloseError(err, true); perr != nil { 165 t.Error(perr) 166 } 167 t.Fatal(err) 168 } 169 var b [1]byte 170 n, err := c.Read(b[:]) 171 if n != 0 || err != io.EOF { 172 t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err) 173 } 174 n, err = c.Write(b[:]) 175 if err == nil { 176 t.Fatalf("got (%d, %v); want (any, error)", n, err) 177 } 178 }) 179 } 180 } 181 182 func TestConnClose(t *testing.T) { 183 t.Parallel() 184 for _, network := range []string{"tcp", "unix", "unixpacket"} { 185 network := network 186 t.Run(network, func(t *testing.T) { 187 if !testableNetwork(network) { 188 t.Skipf("network %s is not testable on the current platform", network) 189 } 190 t.Parallel() 191 192 ln, err := newLocalListener(network) 193 if err != nil { 194 t.Fatal(err) 195 } 196 switch network { 197 case "unix", "unixpacket": 198 defer os.Remove(ln.Addr().String()) 199 } 200 defer ln.Close() 201 202 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 203 if err != nil { 204 t.Fatal(err) 205 } 206 switch network { 207 case "unix", "unixpacket": 208 defer os.Remove(c.LocalAddr().String()) 209 } 210 defer c.Close() 211 212 if err := c.Close(); err != nil { 213 if perr := parseCloseError(err, false); perr != nil { 214 t.Error(perr) 215 } 216 t.Fatal(err) 217 } 218 var b [1]byte 219 n, err := c.Read(b[:]) 220 if n != 0 || err == nil { 221 t.Fatalf("got (%d, %v); want (0, error)", n, err) 222 } 223 }) 224 } 225 } 226 227 func TestListenerClose(t *testing.T) { 228 t.Parallel() 229 for _, network := range []string{"tcp", "unix", "unixpacket"} { 230 network := network 231 t.Run(network, func(t *testing.T) { 232 if !testableNetwork(network) { 233 t.Skipf("network %s is not testable on the current platform", network) 234 } 235 t.Parallel() 236 237 ln, err := newLocalListener(network) 238 if err != nil { 239 t.Fatal(err) 240 } 241 switch network { 242 case "unix", "unixpacket": 243 defer os.Remove(ln.Addr().String()) 244 } 245 246 dst := ln.Addr().String() 247 if err := ln.Close(); err != nil { 248 if perr := parseCloseError(err, false); perr != nil { 249 t.Error(perr) 250 } 251 t.Fatal(err) 252 } 253 c, err := ln.Accept() 254 if err == nil { 255 c.Close() 256 t.Fatal("should fail") 257 } 258 259 if network == "tcp" { 260 // We will have two TCP FSMs inside the 261 // kernel here. There's no guarantee that a 262 // signal comes from the far end FSM will be 263 // delivered immediately to the near end FSM, 264 // especially on the platforms that allow 265 // multiple consumer threads to pull pending 266 // established connections at the same time by 267 // enabling SO_REUSEPORT option such as Linux, 268 // DragonFly BSD. So we need to give some time 269 // quantum to the kernel. 270 // 271 // Note that net.inet.tcp.reuseport_ext=1 by 272 // default on DragonFly BSD. 273 time.Sleep(time.Millisecond) 274 275 cc, err := Dial("tcp", dst) 276 if err == nil { 277 t.Error("Dial to closed TCP listener succeeded.") 278 cc.Close() 279 } 280 } 281 }) 282 } 283 } 284 285 func TestPacketConnClose(t *testing.T) { 286 t.Parallel() 287 for _, network := range []string{"udp", "unixgram"} { 288 network := network 289 t.Run(network, func(t *testing.T) { 290 if !testableNetwork(network) { 291 t.Skipf("network %s is not testable on the current platform", network) 292 } 293 t.Parallel() 294 295 c, err := newLocalPacketListener(network) 296 if err != nil { 297 t.Fatal(err) 298 } 299 switch network { 300 case "unixgram": 301 defer os.Remove(c.LocalAddr().String()) 302 } 303 defer c.Close() 304 305 if err := c.Close(); err != nil { 306 if perr := parseCloseError(err, false); perr != nil { 307 t.Error(perr) 308 } 309 t.Fatal(err) 310 } 311 var b [1]byte 312 n, _, err := c.ReadFrom(b[:]) 313 if n != 0 || err == nil { 314 t.Fatalf("got (%d, %v); want (0, error)", n, err) 315 } 316 }) 317 } 318 } 319 320 func TestListenCloseListen(t *testing.T) { 321 const maxTries = 10 322 for tries := 0; tries < maxTries; tries++ { 323 ln, err := newLocalListener("tcp") 324 if err != nil { 325 t.Fatal(err) 326 } 327 addr := ln.Addr().String() 328 if err := ln.Close(); err != nil { 329 if perr := parseCloseError(err, false); perr != nil { 330 t.Error(perr) 331 } 332 t.Fatal(err) 333 } 334 ln, err = Listen("tcp", addr) 335 if err == nil { 336 // Success. (This test didn't always make it here earlier.) 337 ln.Close() 338 return 339 } 340 t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err) 341 } 342 t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries) 343 } 344 345 // See golang.org/issue/6163, golang.org/issue/6987. 346 func TestAcceptIgnoreAbortedConnRequest(t *testing.T) { 347 switch runtime.GOOS { 348 case "plan9": 349 t.Skipf("%s does not have full support of socktest", runtime.GOOS) 350 } 351 352 syserr := make(chan error) 353 go func() { 354 defer close(syserr) 355 for _, err := range abortedConnRequestErrors { 356 syserr <- err 357 } 358 }() 359 sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) { 360 if err, ok := <-syserr; ok { 361 return nil, err 362 } 363 return nil, nil 364 }) 365 defer sw.Set(socktest.FilterAccept, nil) 366 367 operr := make(chan error, 1) 368 handler := func(ls *localServer, ln Listener) { 369 defer close(operr) 370 c, err := ln.Accept() 371 if err != nil { 372 if perr := parseAcceptError(err); perr != nil { 373 operr <- perr 374 } 375 operr <- err 376 return 377 } 378 c.Close() 379 } 380 ls, err := newLocalServer("tcp") 381 if err != nil { 382 t.Fatal(err) 383 } 384 defer ls.teardown() 385 if err := ls.buildup(handler); err != nil { 386 t.Fatal(err) 387 } 388 389 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 390 if err != nil { 391 t.Fatal(err) 392 } 393 c.Close() 394 395 for err := range operr { 396 t.Error(err) 397 } 398 } 399 400 func TestZeroByteRead(t *testing.T) { 401 t.Parallel() 402 for _, network := range []string{"tcp", "unix", "unixpacket"} { 403 network := network 404 t.Run(network, func(t *testing.T) { 405 if !testableNetwork(network) { 406 t.Skipf("network %s is not testable on the current platform", network) 407 } 408 t.Parallel() 409 410 ln, err := newLocalListener(network) 411 if err != nil { 412 t.Fatal(err) 413 } 414 connc := make(chan Conn, 1) 415 go func() { 416 defer ln.Close() 417 c, err := ln.Accept() 418 if err != nil { 419 t.Error(err) 420 } 421 connc <- c // might be nil 422 }() 423 c, err := Dial(network, ln.Addr().String()) 424 if err != nil { 425 t.Fatal(err) 426 } 427 defer c.Close() 428 sc := <-connc 429 if sc == nil { 430 return 431 } 432 defer sc.Close() 433 434 if runtime.GOOS == "windows" { 435 // A zero byte read on Windows caused a wait for readability first. 436 // Rather than change that behavior, satisfy it in this test. 437 // See Issue 15735. 438 go io.WriteString(sc, "a") 439 } 440 441 n, err := c.Read(nil) 442 if n != 0 || err != nil { 443 t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err) 444 } 445 446 if runtime.GOOS == "windows" { 447 // Same as comment above. 448 go io.WriteString(c, "a") 449 } 450 n, err = sc.Read(nil) 451 if n != 0 || err != nil { 452 t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err) 453 } 454 }) 455 } 456 } 457 458 // withTCPConnPair sets up a TCP connection between two peers, then 459 // runs peer1 and peer2 concurrently. withTCPConnPair returns when 460 // both have completed. 461 func withTCPConnPair(t *testing.T, peer1, peer2 func(c *TCPConn) error) { 462 ln, err := newLocalListener("tcp") 463 if err != nil { 464 t.Fatal(err) 465 } 466 defer ln.Close() 467 errc := make(chan error, 2) 468 go func() { 469 c1, err := ln.Accept() 470 if err != nil { 471 errc <- err 472 return 473 } 474 defer c1.Close() 475 errc <- peer1(c1.(*TCPConn)) 476 }() 477 go func() { 478 c2, err := Dial("tcp", ln.Addr().String()) 479 if err != nil { 480 errc <- err 481 return 482 } 483 defer c2.Close() 484 errc <- peer2(c2.(*TCPConn)) 485 }() 486 for i := 0; i < 2; i++ { 487 if err := <-errc; err != nil { 488 t.Fatal(err) 489 } 490 } 491 } 492 493 // Tests that a blocked Read is interrupted by a concurrent SetReadDeadline 494 // modifying that Conn's read deadline to the past. 495 // See golang.org/cl/30164 which documented this. The net/http package 496 // depends on this. 497 func TestReadTimeoutUnblocksRead(t *testing.T) { 498 serverDone := make(chan struct{}) 499 server := func(cs *TCPConn) error { 500 defer close(serverDone) 501 errc := make(chan error, 1) 502 go func() { 503 defer close(errc) 504 go func() { 505 // TODO: find a better way to wait 506 // until we're blocked in the cs.Read 507 // call below. Sleep is lame. 508 time.Sleep(100 * time.Millisecond) 509 510 // Interrupt the upcoming Read, unblocking it: 511 cs.SetReadDeadline(time.Unix(123, 0)) // time in the past 512 }() 513 var buf [1]byte 514 n, err := cs.Read(buf[:1]) 515 if n != 0 || err == nil { 516 errc <- fmt.Errorf("Read = %v, %v; want 0, non-nil", n, err) 517 } 518 }() 519 select { 520 case err := <-errc: 521 return err 522 case <-time.After(5 * time.Second): 523 buf := make([]byte, 2<<20) 524 buf = buf[:runtime.Stack(buf, true)] 525 println("Stacks at timeout:\n", string(buf)) 526 return errors.New("timeout waiting for Read to finish") 527 } 528 529 } 530 // Do nothing in the client. Never write. Just wait for the 531 // server's half to be done. 532 client := func(*TCPConn) error { 533 <-serverDone 534 return nil 535 } 536 withTCPConnPair(t, client, server) 537 } 538 539 // Issue 17695: verify that a blocked Read is woken up by a Close. 540 func TestCloseUnblocksRead(t *testing.T) { 541 t.Parallel() 542 server := func(cs *TCPConn) error { 543 // Give the client time to get stuck in a Read: 544 time.Sleep(20 * time.Millisecond) 545 cs.Close() 546 return nil 547 } 548 client := func(ss *TCPConn) error { 549 n, err := ss.Read([]byte{0}) 550 if n != 0 || err != io.EOF { 551 return fmt.Errorf("Read = %v, %v; want 0, EOF", n, err) 552 } 553 return nil 554 } 555 withTCPConnPair(t, client, server) 556 } 557 558 // Issue 24808: verify that ECONNRESET is not temporary for read. 559 func TestNotTemporaryRead(t *testing.T) { 560 if runtime.GOOS == "freebsd" { 561 testenv.SkipFlaky(t, 25289) 562 } 563 if runtime.GOOS == "aix" { 564 testenv.SkipFlaky(t, 29685) 565 } 566 t.Parallel() 567 server := func(cs *TCPConn) error { 568 cs.SetLinger(0) 569 // Give the client time to get stuck in a Read. 570 time.Sleep(50 * time.Millisecond) 571 cs.Close() 572 return nil 573 } 574 client := func(ss *TCPConn) error { 575 _, err := ss.Read([]byte{0}) 576 if err == nil { 577 return errors.New("Read succeeded unexpectedly") 578 } else if err == io.EOF { 579 // This happens on Plan 9. 580 return nil 581 } else if ne, ok := err.(Error); !ok { 582 return fmt.Errorf("unexpected error %v", err) 583 } else if ne.Temporary() { 584 return fmt.Errorf("unexpected temporary error %v", err) 585 } 586 return nil 587 } 588 withTCPConnPair(t, client, server) 589 }