github.com/roboticscm/goman@v0.0.0-20210203095141-87c07b4a0a55/src/net/timeout_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 package net 6 7 import ( 8 "fmt" 9 "io" 10 "io/ioutil" 11 "runtime" 12 "testing" 13 "time" 14 ) 15 16 func isTimeout(err error) bool { 17 e, ok := err.(Error) 18 return ok && e.Timeout() 19 } 20 21 type copyRes struct { 22 n int64 23 err error 24 d time.Duration 25 } 26 27 func TestAcceptTimeout(t *testing.T) { 28 switch runtime.GOOS { 29 case "plan9": 30 t.Skipf("skipping test on %q", runtime.GOOS) 31 } 32 33 ln := newLocalListener(t).(*TCPListener) 34 defer ln.Close() 35 ln.SetDeadline(time.Now().Add(-1 * time.Second)) 36 if _, err := ln.Accept(); !isTimeout(err) { 37 t.Fatalf("Accept: expected err %v, got %v", errTimeout, err) 38 } 39 if _, err := ln.Accept(); !isTimeout(err) { 40 t.Fatalf("Accept: expected err %v, got %v", errTimeout, err) 41 } 42 ln.SetDeadline(time.Now().Add(100 * time.Millisecond)) 43 if _, err := ln.Accept(); !isTimeout(err) { 44 t.Fatalf("Accept: expected err %v, got %v", errTimeout, err) 45 } 46 if _, err := ln.Accept(); !isTimeout(err) { 47 t.Fatalf("Accept: expected err %v, got %v", errTimeout, err) 48 } 49 ln.SetDeadline(noDeadline) 50 errc := make(chan error) 51 go func() { 52 _, err := ln.Accept() 53 errc <- err 54 }() 55 time.Sleep(100 * time.Millisecond) 56 select { 57 case err := <-errc: 58 t.Fatalf("Expected Accept() to not return, but it returned with %v\n", err) 59 default: 60 } 61 ln.Close() 62 switch nerr := <-errc; err := nerr.(type) { 63 case *OpError: 64 if err.Err != errClosing { 65 t.Fatalf("Accept: expected err %v, got %v", errClosing, err) 66 } 67 default: 68 if err != errClosing { 69 t.Fatalf("Accept: expected err %v, got %v", errClosing, err) 70 } 71 } 72 } 73 74 func TestReadTimeout(t *testing.T) { 75 switch runtime.GOOS { 76 case "plan9": 77 t.Skipf("skipping test on %q", runtime.GOOS) 78 } 79 80 ln := newLocalListener(t) 81 defer ln.Close() 82 c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr)) 83 if err != nil { 84 t.Fatalf("Connect: %v", err) 85 } 86 defer c.Close() 87 c.SetDeadline(time.Now().Add(time.Hour)) 88 c.SetReadDeadline(time.Now().Add(-1 * time.Second)) 89 buf := make([]byte, 1) 90 if _, err = c.Read(buf); !isTimeout(err) { 91 t.Fatalf("Read: expected err %v, got %v", errTimeout, err) 92 } 93 if _, err = c.Read(buf); !isTimeout(err) { 94 t.Fatalf("Read: expected err %v, got %v", errTimeout, err) 95 } 96 c.SetDeadline(time.Now().Add(100 * time.Millisecond)) 97 if _, err = c.Read(buf); !isTimeout(err) { 98 t.Fatalf("Read: expected err %v, got %v", errTimeout, err) 99 } 100 if _, err = c.Read(buf); !isTimeout(err) { 101 t.Fatalf("Read: expected err %v, got %v", errTimeout, err) 102 } 103 c.SetReadDeadline(noDeadline) 104 c.SetWriteDeadline(time.Now().Add(-1 * time.Second)) 105 errc := make(chan error) 106 go func() { 107 _, err := c.Read(buf) 108 errc <- err 109 }() 110 time.Sleep(100 * time.Millisecond) 111 select { 112 case err := <-errc: 113 t.Fatalf("Expected Read() to not return, but it returned with %v\n", err) 114 default: 115 } 116 c.Close() 117 switch nerr := <-errc; err := nerr.(type) { 118 case *OpError: 119 if err.Err != errClosing { 120 t.Fatalf("Read: expected err %v, got %v", errClosing, err) 121 } 122 default: 123 if err == io.EOF && runtime.GOOS == "nacl" { // close enough; golang.org/issue/8044 124 break 125 } 126 if err != errClosing { 127 t.Fatalf("Read: expected err %v, got %v", errClosing, err) 128 } 129 } 130 } 131 132 func TestWriteTimeout(t *testing.T) { 133 switch runtime.GOOS { 134 case "plan9": 135 t.Skipf("skipping test on %q", runtime.GOOS) 136 } 137 138 ln := newLocalListener(t) 139 defer ln.Close() 140 c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr)) 141 if err != nil { 142 t.Fatalf("Connect: %v", err) 143 } 144 defer c.Close() 145 c.SetDeadline(time.Now().Add(time.Hour)) 146 c.SetWriteDeadline(time.Now().Add(-1 * time.Second)) 147 buf := make([]byte, 4096) 148 writeUntilTimeout := func() { 149 for { 150 _, err := c.Write(buf) 151 if err != nil { 152 if isTimeout(err) { 153 return 154 } 155 t.Fatalf("Write: expected err %v, got %v", errTimeout, err) 156 } 157 } 158 } 159 writeUntilTimeout() 160 c.SetDeadline(time.Now().Add(10 * time.Millisecond)) 161 writeUntilTimeout() 162 writeUntilTimeout() 163 c.SetWriteDeadline(noDeadline) 164 c.SetReadDeadline(time.Now().Add(-1 * time.Second)) 165 errc := make(chan error) 166 go func() { 167 for { 168 _, err := c.Write(buf) 169 if err != nil { 170 errc <- err 171 } 172 } 173 }() 174 time.Sleep(100 * time.Millisecond) 175 select { 176 case err := <-errc: 177 t.Fatalf("Expected Write() to not return, but it returned with %v\n", err) 178 default: 179 } 180 c.Close() 181 switch nerr := <-errc; err := nerr.(type) { 182 case *OpError: 183 if err.Err != errClosing { 184 t.Fatalf("Write: expected err %v, got %v", errClosing, err) 185 } 186 default: 187 if err != errClosing { 188 t.Fatalf("Write: expected err %v, got %v", errClosing, err) 189 } 190 } 191 } 192 193 func testTimeout(t *testing.T, net, addr string, readFrom bool) { 194 c, err := Dial(net, addr) 195 if err != nil { 196 t.Errorf("Dial(%q, %q) failed: %v", net, addr, err) 197 return 198 } 199 defer c.Close() 200 what := "Read" 201 if readFrom { 202 what = "ReadFrom" 203 } 204 205 errc := make(chan error, 1) 206 go func() { 207 t0 := time.Now() 208 c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 209 var b [100]byte 210 var n int 211 var err error 212 if readFrom { 213 n, _, err = c.(PacketConn).ReadFrom(b[0:]) 214 } else { 215 n, err = c.Read(b[0:]) 216 } 217 t1 := time.Now() 218 if n != 0 || err == nil || !err.(Error).Timeout() { 219 errc <- fmt.Errorf("%s(%q, %q) did not return 0, timeout: %v, %v", what, net, addr, n, err) 220 return 221 } 222 if dt := t1.Sub(t0); dt < 50*time.Millisecond || !testing.Short() && dt > 250*time.Millisecond { 223 errc <- fmt.Errorf("%s(%q, %q) took %s, expected 0.1s", what, net, addr, dt) 224 return 225 } 226 errc <- nil 227 }() 228 select { 229 case err := <-errc: 230 if err != nil { 231 t.Error(err) 232 } 233 case <-time.After(1 * time.Second): 234 t.Errorf("%s(%q, %q) took over 1 second, expected 0.1s", what, net, addr) 235 } 236 } 237 238 func TestTimeoutUDP(t *testing.T) { 239 switch runtime.GOOS { 240 case "plan9": 241 t.Skipf("skipping test on %q", runtime.GOOS) 242 } 243 244 // set up a listener that won't talk back 245 listening := make(chan string) 246 done := make(chan int) 247 go runDatagramPacketConnServer(t, "udp", "127.0.0.1:0", listening, done) 248 addr := <-listening 249 250 testTimeout(t, "udp", addr, false) 251 testTimeout(t, "udp", addr, true) 252 <-done 253 } 254 255 func TestTimeoutTCP(t *testing.T) { 256 switch runtime.GOOS { 257 case "plan9": 258 t.Skipf("skipping test on %q", runtime.GOOS) 259 } 260 261 // set up a listener that won't talk back 262 listening := make(chan string) 263 done := make(chan int) 264 go runStreamConnServer(t, "tcp", "127.0.0.1:0", listening, done) 265 addr := <-listening 266 267 testTimeout(t, "tcp", addr, false) 268 <-done 269 } 270 271 func TestDeadlineReset(t *testing.T) { 272 switch runtime.GOOS { 273 case "plan9": 274 t.Skipf("skipping test on %q", runtime.GOOS) 275 } 276 ln, err := Listen("tcp", "127.0.0.1:0") 277 if err != nil { 278 t.Fatal(err) 279 } 280 defer ln.Close() 281 tl := ln.(*TCPListener) 282 tl.SetDeadline(time.Now().Add(1 * time.Minute)) 283 tl.SetDeadline(noDeadline) // reset it 284 errc := make(chan error, 1) 285 go func() { 286 _, err := ln.Accept() 287 errc <- err 288 }() 289 select { 290 case <-time.After(50 * time.Millisecond): 291 // Pass. 292 case err := <-errc: 293 // Accept should never return; we never 294 // connected to it. 295 t.Errorf("unexpected return from Accept; err=%v", err) 296 } 297 } 298 299 func TestTimeoutAccept(t *testing.T) { 300 switch runtime.GOOS { 301 case "plan9": 302 t.Skipf("skipping test on %q", runtime.GOOS) 303 } 304 ln, err := Listen("tcp", "127.0.0.1:0") 305 if err != nil { 306 t.Fatal(err) 307 } 308 defer ln.Close() 309 tl := ln.(*TCPListener) 310 tl.SetDeadline(time.Now().Add(100 * time.Millisecond)) 311 errc := make(chan error, 1) 312 go func() { 313 _, err := ln.Accept() 314 errc <- err 315 }() 316 select { 317 case <-time.After(1 * time.Second): 318 // Accept shouldn't block indefinitely 319 t.Errorf("Accept didn't return in an expected time") 320 case <-errc: 321 // Pass. 322 } 323 } 324 325 func TestReadWriteDeadline(t *testing.T) { 326 switch runtime.GOOS { 327 case "plan9": 328 t.Skipf("skipping test on %q", runtime.GOOS) 329 } 330 331 const ( 332 readTimeout = 50 * time.Millisecond 333 writeTimeout = 250 * time.Millisecond 334 ) 335 checkTimeout := func(command string, start time.Time, should time.Duration) { 336 is := time.Now().Sub(start) 337 d := is - should 338 if d < -30*time.Millisecond || !testing.Short() && 150*time.Millisecond < d { 339 t.Errorf("%s timeout test failed: is=%v should=%v\n", command, is, should) 340 } 341 } 342 343 ln, err := Listen("tcp", "127.0.0.1:0") 344 if err != nil { 345 t.Fatalf("ListenTCP on :0: %v", err) 346 } 347 defer ln.Close() 348 349 lnquit := make(chan bool) 350 351 go func() { 352 c, err := ln.Accept() 353 if err != nil { 354 t.Errorf("Accept: %v", err) 355 return 356 } 357 defer c.Close() 358 lnquit <- true 359 }() 360 361 c, err := Dial("tcp", ln.Addr().String()) 362 if err != nil { 363 t.Fatalf("Dial: %v", err) 364 } 365 defer c.Close() 366 367 start := time.Now() 368 err = c.SetReadDeadline(start.Add(readTimeout)) 369 if err != nil { 370 t.Fatalf("SetReadDeadline: %v", err) 371 } 372 err = c.SetWriteDeadline(start.Add(writeTimeout)) 373 if err != nil { 374 t.Fatalf("SetWriteDeadline: %v", err) 375 } 376 377 quit := make(chan bool) 378 379 go func() { 380 var buf [10]byte 381 _, err := c.Read(buf[:]) 382 if err == nil { 383 t.Errorf("Read should not succeed") 384 } 385 checkTimeout("Read", start, readTimeout) 386 quit <- true 387 }() 388 389 go func() { 390 var buf [10000]byte 391 for { 392 _, err := c.Write(buf[:]) 393 if err != nil { 394 break 395 } 396 } 397 checkTimeout("Write", start, writeTimeout) 398 quit <- true 399 }() 400 401 <-quit 402 <-quit 403 <-lnquit 404 } 405 406 type neverEnding byte 407 408 func (b neverEnding) Read(p []byte) (n int, err error) { 409 for i := range p { 410 p[i] = byte(b) 411 } 412 return len(p), nil 413 } 414 415 func TestVariousDeadlines1Proc(t *testing.T) { 416 testVariousDeadlines(t, 1) 417 } 418 419 func TestVariousDeadlines4Proc(t *testing.T) { 420 testVariousDeadlines(t, 4) 421 } 422 423 func testVariousDeadlines(t *testing.T, maxProcs int) { 424 switch runtime.GOOS { 425 case "plan9": 426 t.Skipf("skipping test on %q", runtime.GOOS) 427 } 428 429 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) 430 ln := newLocalListener(t) 431 defer ln.Close() 432 acceptc := make(chan error, 1) 433 434 // The server, with no timeouts of its own, sending bytes to clients 435 // as fast as it can. 436 servec := make(chan copyRes) 437 go func() { 438 for { 439 c, err := ln.Accept() 440 if err != nil { 441 acceptc <- err 442 return 443 } 444 go func() { 445 t0 := time.Now() 446 n, err := io.Copy(c, neverEnding('a')) 447 d := time.Since(t0) 448 c.Close() 449 servec <- copyRes{n, err, d} 450 }() 451 } 452 }() 453 454 for _, timeout := range []time.Duration{ 455 1 * time.Nanosecond, 456 2 * time.Nanosecond, 457 5 * time.Nanosecond, 458 50 * time.Nanosecond, 459 100 * time.Nanosecond, 460 200 * time.Nanosecond, 461 500 * time.Nanosecond, 462 750 * time.Nanosecond, 463 1 * time.Microsecond, 464 5 * time.Microsecond, 465 25 * time.Microsecond, 466 250 * time.Microsecond, 467 500 * time.Microsecond, 468 1 * time.Millisecond, 469 5 * time.Millisecond, 470 100 * time.Millisecond, 471 250 * time.Millisecond, 472 500 * time.Millisecond, 473 1 * time.Second, 474 } { 475 numRuns := 3 476 if testing.Short() { 477 numRuns = 1 478 if timeout > 500*time.Microsecond { 479 continue 480 } 481 } 482 for run := 0; run < numRuns; run++ { 483 name := fmt.Sprintf("%v run %d/%d", timeout, run+1, numRuns) 484 t.Log(name) 485 486 c, err := Dial("tcp", ln.Addr().String()) 487 if err != nil { 488 t.Fatalf("Dial: %v", err) 489 } 490 clientc := make(chan copyRes) 491 go func() { 492 t0 := time.Now() 493 c.SetDeadline(t0.Add(timeout)) 494 n, err := io.Copy(ioutil.Discard, c) 495 d := time.Since(t0) 496 c.Close() 497 clientc <- copyRes{n, err, d} 498 }() 499 500 tooLong := 5 * time.Second 501 select { 502 case res := <-clientc: 503 if isTimeout(res.err) { 504 t.Logf("for %v, good client timeout after %v, reading %d bytes", name, res.d, res.n) 505 } else { 506 t.Fatalf("for %v: client Copy = %d, %v (want timeout)", name, res.n, res.err) 507 } 508 case <-time.After(tooLong): 509 t.Fatalf("for %v: timeout (%v) waiting for client to timeout (%v) reading", name, tooLong, timeout) 510 } 511 512 select { 513 case res := <-servec: 514 t.Logf("for %v: server in %v wrote %d, %v", name, res.d, res.n, res.err) 515 case err := <-acceptc: 516 t.Fatalf("for %v: server Accept = %v", name, err) 517 case <-time.After(tooLong): 518 t.Fatalf("for %v, timeout waiting for server to finish writing", name) 519 } 520 } 521 } 522 } 523 524 // TestReadDeadlineDataAvailable tests that read deadlines work, even 525 // if there's data ready to be read. 526 func TestReadDeadlineDataAvailable(t *testing.T) { 527 switch runtime.GOOS { 528 case "plan9": 529 t.Skipf("skipping test on %q", runtime.GOOS) 530 } 531 532 ln := newLocalListener(t) 533 defer ln.Close() 534 535 servec := make(chan copyRes) 536 const msg = "data client shouldn't read, even though it'll be waiting" 537 go func() { 538 c, err := ln.Accept() 539 if err != nil { 540 t.Errorf("Accept: %v", err) 541 return 542 } 543 defer c.Close() 544 n, err := c.Write([]byte(msg)) 545 servec <- copyRes{n: int64(n), err: err} 546 }() 547 548 c, err := Dial("tcp", ln.Addr().String()) 549 if err != nil { 550 t.Fatalf("Dial: %v", err) 551 } 552 defer c.Close() 553 if res := <-servec; res.err != nil || res.n != int64(len(msg)) { 554 t.Fatalf("unexpected server Write: n=%d, err=%v; want n=%d, err=nil", res.n, res.err, len(msg)) 555 } 556 c.SetReadDeadline(time.Now().Add(-5 * time.Second)) // in the psat. 557 buf := make([]byte, len(msg)/2) 558 n, err := c.Read(buf) 559 if n > 0 || !isTimeout(err) { 560 t.Fatalf("client read = %d (%q) err=%v; want 0, timeout", n, buf[:n], err) 561 } 562 } 563 564 // TestWriteDeadlineBufferAvailable tests that write deadlines work, even 565 // if there's buffer space available to write. 566 func TestWriteDeadlineBufferAvailable(t *testing.T) { 567 switch runtime.GOOS { 568 case "plan9": 569 t.Skipf("skipping test on %q", runtime.GOOS) 570 } 571 572 ln := newLocalListener(t) 573 defer ln.Close() 574 575 servec := make(chan copyRes) 576 go func() { 577 c, err := ln.Accept() 578 if err != nil { 579 t.Errorf("Accept: %v", err) 580 return 581 } 582 defer c.Close() 583 c.SetWriteDeadline(time.Now().Add(-5 * time.Second)) // in the past 584 n, err := c.Write([]byte{'x'}) 585 servec <- copyRes{n: int64(n), err: err} 586 }() 587 588 c, err := Dial("tcp", ln.Addr().String()) 589 if err != nil { 590 t.Fatalf("Dial: %v", err) 591 } 592 defer c.Close() 593 res := <-servec 594 if res.n != 0 { 595 t.Errorf("Write = %d; want 0", res.n) 596 } 597 if !isTimeout(res.err) { 598 t.Errorf("Write error = %v; want timeout", res.err) 599 } 600 } 601 602 // TestAcceptDeadlineConnectionAvailable tests that accept deadlines work, even 603 // if there's incoming connections available. 604 func TestAcceptDeadlineConnectionAvailable(t *testing.T) { 605 switch runtime.GOOS { 606 case "plan9": 607 t.Skipf("skipping test on %q", runtime.GOOS) 608 } 609 610 ln := newLocalListener(t).(*TCPListener) 611 defer ln.Close() 612 613 go func() { 614 c, err := Dial("tcp", ln.Addr().String()) 615 if err != nil { 616 t.Errorf("Dial: %v", err) 617 return 618 } 619 defer c.Close() 620 var buf [1]byte 621 c.Read(buf[:]) // block until the connection or listener is closed 622 }() 623 time.Sleep(10 * time.Millisecond) 624 ln.SetDeadline(time.Now().Add(-5 * time.Second)) // in the past 625 c, err := ln.Accept() 626 if err == nil { 627 defer c.Close() 628 } 629 if !isTimeout(err) { 630 t.Fatalf("Accept: got %v; want timeout", err) 631 } 632 } 633 634 // TestConnectDeadlineInThePast tests that connect deadlines work, even 635 // if the connection can be established w/o blocking. 636 func TestConnectDeadlineInThePast(t *testing.T) { 637 switch runtime.GOOS { 638 case "plan9": 639 t.Skipf("skipping test on %q", runtime.GOOS) 640 } 641 642 ln := newLocalListener(t).(*TCPListener) 643 defer ln.Close() 644 645 go func() { 646 c, err := ln.Accept() 647 if err == nil { 648 defer c.Close() 649 } 650 }() 651 time.Sleep(10 * time.Millisecond) 652 c, err := DialTimeout("tcp", ln.Addr().String(), -5*time.Second) // in the past 653 if err == nil { 654 defer c.Close() 655 } 656 if !isTimeout(err) { 657 t.Fatalf("DialTimeout: got %v; want timeout", err) 658 } 659 } 660 661 // TestProlongTimeout tests concurrent deadline modification. 662 // Known to cause data races in the past. 663 func TestProlongTimeout(t *testing.T) { 664 switch runtime.GOOS { 665 case "plan9": 666 t.Skipf("skipping test on %q", runtime.GOOS) 667 } 668 669 ln := newLocalListener(t) 670 defer ln.Close() 671 connected := make(chan bool) 672 go func() { 673 s, err := ln.Accept() 674 connected <- true 675 if err != nil { 676 t.Errorf("ln.Accept: %v", err) 677 return 678 } 679 defer s.Close() 680 s.SetDeadline(time.Now().Add(time.Hour)) 681 go func() { 682 var buf [4096]byte 683 for { 684 _, err := s.Write(buf[:]) 685 if err != nil { 686 break 687 } 688 s.SetDeadline(time.Now().Add(time.Hour)) 689 } 690 }() 691 buf := make([]byte, 1) 692 for { 693 _, err := s.Read(buf) 694 if err != nil { 695 break 696 } 697 s.SetDeadline(time.Now().Add(time.Hour)) 698 } 699 }() 700 c, err := Dial("tcp", ln.Addr().String()) 701 if err != nil { 702 t.Fatalf("DialTCP: %v", err) 703 } 704 defer c.Close() 705 <-connected 706 for i := 0; i < 1024; i++ { 707 var buf [1]byte 708 c.Write(buf[:]) 709 } 710 } 711 712 func TestDeadlineRace(t *testing.T) { 713 switch runtime.GOOS { 714 case "nacl", "plan9": 715 t.Skipf("skipping test on %q", runtime.GOOS) 716 } 717 718 N := 1000 719 if testing.Short() { 720 N = 50 721 } 722 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) 723 ln := newLocalListener(t) 724 defer ln.Close() 725 c, err := Dial("tcp", ln.Addr().String()) 726 if err != nil { 727 t.Fatalf("Dial: %v", err) 728 } 729 defer c.Close() 730 done := make(chan bool) 731 go func() { 732 t := time.NewTicker(2 * time.Microsecond).C 733 for i := 0; i < N; i++ { 734 if err := c.SetDeadline(time.Now().Add(2 * time.Microsecond)); err != nil { 735 break 736 } 737 <-t 738 } 739 done <- true 740 }() 741 var buf [1]byte 742 for i := 0; i < N; i++ { 743 c.Read(buf[:]) // ignore possible timeout errors 744 } 745 c.Close() 746 <-done 747 }