github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/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 "internal/testenv" 10 "io" 11 "io/ioutil" 12 "net/internal/socktest" 13 "runtime" 14 "sync" 15 "testing" 16 "time" 17 ) 18 19 var dialTimeoutTests = []struct { 20 timeout time.Duration 21 delta time.Duration // for deadline 22 23 guard time.Duration 24 max time.Duration 25 }{ 26 // Tests that dial timeouts, deadlines in the past work. 27 {-5 * time.Second, 0, -5 * time.Second, 100 * time.Millisecond}, 28 {0, -5 * time.Second, -5 * time.Second, 100 * time.Millisecond}, 29 {-5 * time.Second, 5 * time.Second, -5 * time.Second, 100 * time.Millisecond}, // timeout over deadline 30 {-1 << 63, 0, time.Second, 100 * time.Millisecond}, 31 {0, -1 << 63, time.Second, 100 * time.Millisecond}, 32 33 {50 * time.Millisecond, 0, 100 * time.Millisecond, time.Second}, 34 {0, 50 * time.Millisecond, 100 * time.Millisecond, time.Second}, 35 {50 * time.Millisecond, 5 * time.Second, 100 * time.Millisecond, time.Second}, // timeout over deadline 36 } 37 38 func TestDialTimeout(t *testing.T) { 39 // Cannot use t.Parallel - modifies global hooks. 40 origTestHookDialChannel := testHookDialChannel 41 defer func() { testHookDialChannel = origTestHookDialChannel }() 42 defer sw.Set(socktest.FilterConnect, nil) 43 44 for i, tt := range dialTimeoutTests { 45 switch runtime.GOOS { 46 case "plan9", "windows": 47 testHookDialChannel = func() { time.Sleep(tt.guard) } 48 if runtime.GOOS == "plan9" { 49 break 50 } 51 fallthrough 52 default: 53 sw.Set(socktest.FilterConnect, func(so *socktest.Status) (socktest.AfterFilter, error) { 54 time.Sleep(tt.guard) 55 return nil, errTimedout 56 }) 57 } 58 59 ch := make(chan error) 60 d := Dialer{Timeout: tt.timeout} 61 if tt.delta != 0 { 62 d.Deadline = time.Now().Add(tt.delta) 63 } 64 max := time.NewTimer(tt.max) 65 defer max.Stop() 66 go func() { 67 // This dial never starts to send any TCP SYN 68 // segment because of above socket filter and 69 // test hook. 70 c, err := d.Dial("tcp", "127.0.0.1:0") 71 if err == nil { 72 err = fmt.Errorf("unexpectedly established: tcp:%s->%s", c.LocalAddr(), c.RemoteAddr()) 73 c.Close() 74 } 75 ch <- err 76 }() 77 78 select { 79 case <-max.C: 80 t.Fatalf("#%d: Dial didn't return in an expected time", i) 81 case err := <-ch: 82 if perr := parseDialError(err); perr != nil { 83 t.Errorf("#%d: %v", i, perr) 84 } 85 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 86 t.Fatalf("#%d: %v", i, err) 87 } 88 } 89 } 90 } 91 92 var dialTimeoutMaxDurationTests = []struct { 93 timeout time.Duration 94 delta time.Duration // for deadline 95 }{ 96 // Large timeouts that will overflow an int64 unix nanos. 97 {1<<63 - 1, 0}, 98 {0, 1<<63 - 1}, 99 } 100 101 func TestDialTimeoutMaxDuration(t *testing.T) { 102 if runtime.GOOS == "openbsd" { 103 testenv.SkipFlaky(t, 15157) 104 } 105 106 ln, err := newLocalListener("tcp") 107 if err != nil { 108 t.Fatal(err) 109 } 110 defer ln.Close() 111 112 for i, tt := range dialTimeoutMaxDurationTests { 113 ch := make(chan error) 114 max := time.NewTimer(250 * time.Millisecond) 115 defer max.Stop() 116 go func() { 117 d := Dialer{Timeout: tt.timeout} 118 if tt.delta != 0 { 119 d.Deadline = time.Now().Add(tt.delta) 120 } 121 c, err := d.Dial(ln.Addr().Network(), ln.Addr().String()) 122 if err == nil { 123 c.Close() 124 } 125 ch <- err 126 }() 127 128 select { 129 case <-max.C: 130 t.Fatalf("#%d: Dial didn't return in an expected time", i) 131 case err := <-ch: 132 if perr := parseDialError(err); perr != nil { 133 t.Error(perr) 134 } 135 if err != nil { 136 t.Errorf("#%d: %v", i, err) 137 } 138 } 139 } 140 } 141 142 var acceptTimeoutTests = []struct { 143 timeout time.Duration 144 xerrs [2]error // expected errors in transition 145 }{ 146 // Tests that accept deadlines in the past work, even if 147 // there's incoming connections available. 148 {-5 * time.Second, [2]error{errTimeout, errTimeout}}, 149 150 {50 * time.Millisecond, [2]error{nil, errTimeout}}, 151 } 152 153 func TestAcceptTimeout(t *testing.T) { 154 t.Parallel() 155 156 switch runtime.GOOS { 157 case "plan9": 158 t.Skipf("not supported on %s", runtime.GOOS) 159 } 160 161 ln, err := newLocalListener("tcp") 162 if err != nil { 163 t.Fatal(err) 164 } 165 defer ln.Close() 166 167 for i, tt := range acceptTimeoutTests { 168 if tt.timeout < 0 { 169 go func() { 170 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 171 if err != nil { 172 t.Error(err) 173 return 174 } 175 var b [1]byte 176 c.Read(b[:]) 177 c.Close() 178 }() 179 } 180 181 if err := ln.(*TCPListener).SetDeadline(time.Now().Add(tt.timeout)); err != nil { 182 t.Fatalf("$%d: %v", i, err) 183 } 184 for j, xerr := range tt.xerrs { 185 for { 186 c, err := ln.Accept() 187 if xerr != nil { 188 if perr := parseAcceptError(err); perr != nil { 189 t.Errorf("#%d/%d: %v", i, j, perr) 190 } 191 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 192 t.Fatalf("#%d/%d: %v", i, j, err) 193 } 194 } 195 if err == nil { 196 c.Close() 197 time.Sleep(tt.timeout / 3) 198 continue 199 } 200 break 201 } 202 } 203 } 204 } 205 206 func TestAcceptTimeoutMustReturn(t *testing.T) { 207 t.Parallel() 208 209 switch runtime.GOOS { 210 case "plan9": 211 t.Skipf("not supported on %s", runtime.GOOS) 212 } 213 214 ln, err := newLocalListener("tcp") 215 if err != nil { 216 t.Fatal(err) 217 } 218 defer ln.Close() 219 220 max := time.NewTimer(time.Second) 221 defer max.Stop() 222 ch := make(chan error) 223 go func() { 224 if err := ln.(*TCPListener).SetDeadline(noDeadline); err != nil { 225 t.Error(err) 226 } 227 if err := ln.(*TCPListener).SetDeadline(time.Now().Add(10 * time.Millisecond)); err != nil { 228 t.Error(err) 229 } 230 c, err := ln.Accept() 231 if err == nil { 232 c.Close() 233 } 234 ch <- err 235 }() 236 237 select { 238 case <-max.C: 239 ln.Close() 240 <-ch // wait for tester goroutine to stop 241 t.Fatal("Accept didn't return in an expected time") 242 case err := <-ch: 243 if perr := parseAcceptError(err); perr != nil { 244 t.Error(perr) 245 } 246 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 247 t.Fatal(err) 248 } 249 } 250 } 251 252 func TestAcceptTimeoutMustNotReturn(t *testing.T) { 253 t.Parallel() 254 255 switch runtime.GOOS { 256 case "plan9": 257 t.Skipf("not supported on %s", runtime.GOOS) 258 } 259 260 ln, err := newLocalListener("tcp") 261 if err != nil { 262 t.Fatal(err) 263 } 264 defer ln.Close() 265 266 max := time.NewTimer(100 * time.Millisecond) 267 defer max.Stop() 268 ch := make(chan error) 269 go func() { 270 if err := ln.(*TCPListener).SetDeadline(time.Now().Add(-5 * time.Second)); err != nil { 271 t.Error(err) 272 } 273 if err := ln.(*TCPListener).SetDeadline(noDeadline); err != nil { 274 t.Error(err) 275 } 276 _, err := ln.Accept() 277 ch <- err 278 }() 279 280 select { 281 case err := <-ch: 282 if perr := parseAcceptError(err); perr != nil { 283 t.Error(perr) 284 } 285 t.Fatalf("expected Accept to not return, but it returned with %v", err) 286 case <-max.C: 287 ln.Close() 288 <-ch // wait for tester goroutine to stop 289 } 290 } 291 292 var readTimeoutTests = []struct { 293 timeout time.Duration 294 xerrs [2]error // expected errors in transition 295 }{ 296 // Tests that read deadlines work, even if there's data ready 297 // to be read. 298 {-5 * time.Second, [2]error{errTimeout, errTimeout}}, 299 300 {50 * time.Millisecond, [2]error{nil, errTimeout}}, 301 } 302 303 func TestReadTimeout(t *testing.T) { 304 switch runtime.GOOS { 305 case "plan9": 306 t.Skipf("not supported on %s", runtime.GOOS) 307 } 308 309 handler := func(ls *localServer, ln Listener) { 310 c, err := ln.Accept() 311 if err != nil { 312 t.Error(err) 313 return 314 } 315 c.Write([]byte("READ TIMEOUT TEST")) 316 defer c.Close() 317 } 318 ls, err := newLocalServer("tcp") 319 if err != nil { 320 t.Fatal(err) 321 } 322 defer ls.teardown() 323 if err := ls.buildup(handler); err != nil { 324 t.Fatal(err) 325 } 326 327 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 328 if err != nil { 329 t.Fatal(err) 330 } 331 defer c.Close() 332 333 for i, tt := range readTimeoutTests { 334 if err := c.SetReadDeadline(time.Now().Add(tt.timeout)); err != nil { 335 t.Fatalf("#%d: %v", i, err) 336 } 337 var b [1]byte 338 for j, xerr := range tt.xerrs { 339 for { 340 n, err := c.Read(b[:]) 341 if xerr != nil { 342 if perr := parseReadError(err); perr != nil { 343 t.Errorf("#%d/%d: %v", i, j, perr) 344 } 345 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 346 t.Fatalf("#%d/%d: %v", i, j, err) 347 } 348 } 349 if err == nil { 350 time.Sleep(tt.timeout / 3) 351 continue 352 } 353 if n != 0 { 354 t.Fatalf("#%d/%d: read %d; want 0", i, j, n) 355 } 356 break 357 } 358 } 359 } 360 } 361 362 func TestReadTimeoutMustNotReturn(t *testing.T) { 363 t.Parallel() 364 365 switch runtime.GOOS { 366 case "plan9": 367 t.Skipf("not supported on %s", runtime.GOOS) 368 } 369 370 ln, err := newLocalListener("tcp") 371 if err != nil { 372 t.Fatal(err) 373 } 374 defer ln.Close() 375 376 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 377 if err != nil { 378 t.Fatal(err) 379 } 380 defer c.Close() 381 382 max := time.NewTimer(100 * time.Millisecond) 383 defer max.Stop() 384 ch := make(chan error) 385 go func() { 386 if err := c.SetDeadline(time.Now().Add(-5 * time.Second)); err != nil { 387 t.Error(err) 388 } 389 if err := c.SetWriteDeadline(time.Now().Add(-5 * time.Second)); err != nil { 390 t.Error(err) 391 } 392 if err := c.SetReadDeadline(noDeadline); err != nil { 393 t.Error(err) 394 } 395 var b [1]byte 396 _, err := c.Read(b[:]) 397 ch <- err 398 }() 399 400 select { 401 case err := <-ch: 402 if perr := parseReadError(err); perr != nil { 403 t.Error(perr) 404 } 405 t.Fatalf("expected Read to not return, but it returned with %v", err) 406 case <-max.C: 407 c.Close() 408 err := <-ch // wait for tester goroutine to stop 409 if perr := parseReadError(err); perr != nil { 410 t.Error(perr) 411 } 412 if err == io.EOF && runtime.GOOS == "nacl" { // see golang.org/issue/8044 413 return 414 } 415 if nerr, ok := err.(Error); !ok || nerr.Timeout() || nerr.Temporary() { 416 t.Fatal(err) 417 } 418 } 419 } 420 421 var readFromTimeoutTests = []struct { 422 timeout time.Duration 423 xerrs [2]error // expected errors in transition 424 }{ 425 // Tests that read deadlines work, even if there's data ready 426 // to be read. 427 {-5 * time.Second, [2]error{errTimeout, errTimeout}}, 428 429 {50 * time.Millisecond, [2]error{nil, errTimeout}}, 430 } 431 432 func TestReadFromTimeout(t *testing.T) { 433 switch runtime.GOOS { 434 case "nacl", "plan9": 435 t.Skipf("not supported on %s", runtime.GOOS) // see golang.org/issue/8916 436 } 437 438 ch := make(chan Addr) 439 defer close(ch) 440 handler := func(ls *localPacketServer, c PacketConn) { 441 if dst, ok := <-ch; ok { 442 c.WriteTo([]byte("READFROM TIMEOUT TEST"), dst) 443 } 444 } 445 ls, err := newLocalPacketServer("udp") 446 if err != nil { 447 t.Fatal(err) 448 } 449 defer ls.teardown() 450 if err := ls.buildup(handler); err != nil { 451 t.Fatal(err) 452 } 453 454 host, _, err := SplitHostPort(ls.PacketConn.LocalAddr().String()) 455 if err != nil { 456 t.Fatal(err) 457 } 458 c, err := ListenPacket(ls.PacketConn.LocalAddr().Network(), JoinHostPort(host, "0")) 459 if err != nil { 460 t.Fatal(err) 461 } 462 defer c.Close() 463 ch <- c.LocalAddr() 464 465 for i, tt := range readFromTimeoutTests { 466 if err := c.SetReadDeadline(time.Now().Add(tt.timeout)); err != nil { 467 t.Fatalf("#%d: %v", i, err) 468 } 469 var b [1]byte 470 for j, xerr := range tt.xerrs { 471 for { 472 n, _, err := c.ReadFrom(b[:]) 473 if xerr != nil { 474 if perr := parseReadError(err); perr != nil { 475 t.Errorf("#%d/%d: %v", i, j, perr) 476 } 477 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 478 t.Fatalf("#%d/%d: %v", i, j, err) 479 } 480 } 481 if err == nil { 482 time.Sleep(tt.timeout / 3) 483 continue 484 } 485 if n != 0 { 486 t.Fatalf("#%d/%d: read %d; want 0", i, j, n) 487 } 488 break 489 } 490 } 491 } 492 } 493 494 var writeTimeoutTests = []struct { 495 timeout time.Duration 496 xerrs [2]error // expected errors in transition 497 }{ 498 // Tests that write deadlines work, even if there's buffer 499 // space available to write. 500 {-5 * time.Second, [2]error{errTimeout, errTimeout}}, 501 502 {10 * time.Millisecond, [2]error{nil, errTimeout}}, 503 } 504 505 func TestWriteTimeout(t *testing.T) { 506 t.Parallel() 507 508 switch runtime.GOOS { 509 case "plan9": 510 t.Skipf("not supported on %s", runtime.GOOS) 511 } 512 513 ln, err := newLocalListener("tcp") 514 if err != nil { 515 t.Fatal(err) 516 } 517 defer ln.Close() 518 519 for i, tt := range writeTimeoutTests { 520 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 521 if err != nil { 522 t.Fatal(err) 523 } 524 defer c.Close() 525 526 if err := c.SetWriteDeadline(time.Now().Add(tt.timeout)); err != nil { 527 t.Fatalf("#%d: %v", i, err) 528 } 529 for j, xerr := range tt.xerrs { 530 for { 531 n, err := c.Write([]byte("WRITE TIMEOUT TEST")) 532 if xerr != nil { 533 if perr := parseWriteError(err); perr != nil { 534 t.Errorf("#%d/%d: %v", i, j, perr) 535 } 536 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 537 t.Fatalf("#%d/%d: %v", i, j, err) 538 } 539 } 540 if err == nil { 541 time.Sleep(tt.timeout / 3) 542 continue 543 } 544 if n != 0 { 545 t.Fatalf("#%d/%d: wrote %d; want 0", i, j, n) 546 } 547 break 548 } 549 } 550 } 551 } 552 553 func TestWriteTimeoutMustNotReturn(t *testing.T) { 554 t.Parallel() 555 556 switch runtime.GOOS { 557 case "plan9": 558 t.Skipf("not supported on %s", runtime.GOOS) 559 } 560 561 ln, err := newLocalListener("tcp") 562 if err != nil { 563 t.Fatal(err) 564 } 565 defer ln.Close() 566 567 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 568 if err != nil { 569 t.Fatal(err) 570 } 571 defer c.Close() 572 573 max := time.NewTimer(100 * time.Millisecond) 574 defer max.Stop() 575 ch := make(chan error) 576 go func() { 577 if err := c.SetDeadline(time.Now().Add(-5 * time.Second)); err != nil { 578 t.Error(err) 579 } 580 if err := c.SetReadDeadline(time.Now().Add(-5 * time.Second)); err != nil { 581 t.Error(err) 582 } 583 if err := c.SetWriteDeadline(noDeadline); err != nil { 584 t.Error(err) 585 } 586 var b [1]byte 587 for { 588 if _, err := c.Write(b[:]); err != nil { 589 ch <- err 590 break 591 } 592 } 593 }() 594 595 select { 596 case err := <-ch: 597 if perr := parseWriteError(err); perr != nil { 598 t.Error(perr) 599 } 600 t.Fatalf("expected Write to not return, but it returned with %v", err) 601 case <-max.C: 602 c.Close() 603 err := <-ch // wait for tester goroutine to stop 604 if perr := parseWriteError(err); perr != nil { 605 t.Error(perr) 606 } 607 if nerr, ok := err.(Error); !ok || nerr.Timeout() || nerr.Temporary() { 608 t.Fatal(err) 609 } 610 } 611 } 612 613 var writeToTimeoutTests = []struct { 614 timeout time.Duration 615 xerrs [2]error // expected errors in transition 616 }{ 617 // Tests that write deadlines work, even if there's buffer 618 // space available to write. 619 {-5 * time.Second, [2]error{errTimeout, errTimeout}}, 620 621 {10 * time.Millisecond, [2]error{nil, errTimeout}}, 622 } 623 624 func TestWriteToTimeout(t *testing.T) { 625 t.Parallel() 626 627 switch runtime.GOOS { 628 case "nacl", "plan9": 629 t.Skipf("not supported on %s", runtime.GOOS) 630 } 631 632 c1, err := newLocalPacketListener("udp") 633 if err != nil { 634 t.Fatal(err) 635 } 636 defer c1.Close() 637 638 host, _, err := SplitHostPort(c1.LocalAddr().String()) 639 if err != nil { 640 t.Fatal(err) 641 } 642 643 for i, tt := range writeToTimeoutTests { 644 c2, err := ListenPacket(c1.LocalAddr().Network(), JoinHostPort(host, "0")) 645 if err != nil { 646 t.Fatal(err) 647 } 648 defer c2.Close() 649 650 if err := c2.SetWriteDeadline(time.Now().Add(tt.timeout)); err != nil { 651 t.Fatalf("#%d: %v", i, err) 652 } 653 for j, xerr := range tt.xerrs { 654 for { 655 n, err := c2.WriteTo([]byte("WRITETO TIMEOUT TEST"), c1.LocalAddr()) 656 if xerr != nil { 657 if perr := parseWriteError(err); perr != nil { 658 t.Errorf("#%d/%d: %v", i, j, perr) 659 } 660 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 661 t.Fatalf("#%d/%d: %v", i, j, err) 662 } 663 } 664 if err == nil { 665 time.Sleep(tt.timeout / 3) 666 continue 667 } 668 if n != 0 { 669 t.Fatalf("#%d/%d: wrote %d; want 0", i, j, n) 670 } 671 break 672 } 673 } 674 } 675 } 676 677 func TestReadTimeoutFluctuation(t *testing.T) { 678 t.Parallel() 679 680 switch runtime.GOOS { 681 case "plan9": 682 t.Skipf("not supported on %s", runtime.GOOS) 683 } 684 685 ln, err := newLocalListener("tcp") 686 if err != nil { 687 t.Fatal(err) 688 } 689 defer ln.Close() 690 691 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 692 if err != nil { 693 t.Fatal(err) 694 } 695 defer c.Close() 696 697 max := time.NewTimer(time.Second) 698 defer max.Stop() 699 ch := make(chan error) 700 go timeoutReceiver(c, 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch) 701 702 select { 703 case <-max.C: 704 t.Fatal("Read took over 1s; expected 0.1s") 705 case err := <-ch: 706 if perr := parseReadError(err); perr != nil { 707 t.Error(perr) 708 } 709 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 710 t.Fatal(err) 711 } 712 } 713 } 714 715 func TestReadFromTimeoutFluctuation(t *testing.T) { 716 t.Parallel() 717 718 switch runtime.GOOS { 719 case "plan9": 720 t.Skipf("not supported on %s", runtime.GOOS) 721 } 722 723 c1, err := newLocalPacketListener("udp") 724 if err != nil { 725 t.Fatal(err) 726 } 727 defer c1.Close() 728 729 c2, err := Dial(c1.LocalAddr().Network(), c1.LocalAddr().String()) 730 if err != nil { 731 t.Fatal(err) 732 } 733 defer c2.Close() 734 735 max := time.NewTimer(time.Second) 736 defer max.Stop() 737 ch := make(chan error) 738 go timeoutPacketReceiver(c2.(PacketConn), 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch) 739 740 select { 741 case <-max.C: 742 t.Fatal("ReadFrom took over 1s; expected 0.1s") 743 case err := <-ch: 744 if perr := parseReadError(err); perr != nil { 745 t.Error(perr) 746 } 747 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 748 t.Fatal(err) 749 } 750 } 751 } 752 753 func TestWriteTimeoutFluctuation(t *testing.T) { 754 t.Parallel() 755 756 switch runtime.GOOS { 757 case "plan9": 758 t.Skipf("not supported on %s", runtime.GOOS) 759 } 760 761 ln, err := newLocalListener("tcp") 762 if err != nil { 763 t.Fatal(err) 764 } 765 defer ln.Close() 766 767 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 768 if err != nil { 769 t.Fatal(err) 770 } 771 defer c.Close() 772 773 d := time.Second 774 if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { 775 d = 3 * time.Second // see golang.org/issue/10775 776 } 777 max := time.NewTimer(d) 778 defer max.Stop() 779 ch := make(chan error) 780 go timeoutTransmitter(c, 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch) 781 782 select { 783 case <-max.C: 784 t.Fatalf("Write took over %v; expected 0.1s", d) 785 case err := <-ch: 786 if perr := parseWriteError(err); perr != nil { 787 t.Error(perr) 788 } 789 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 790 t.Fatal(err) 791 } 792 } 793 } 794 795 func TestVariousDeadlines(t *testing.T) { 796 t.Parallel() 797 testVariousDeadlines(t) 798 } 799 800 func TestVariousDeadlines1Proc(t *testing.T) { 801 // Cannot use t.Parallel - modifies global GOMAXPROCS. 802 if testing.Short() { 803 t.Skip("skipping in short mode") 804 } 805 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1)) 806 testVariousDeadlines(t) 807 } 808 809 func TestVariousDeadlines4Proc(t *testing.T) { 810 // Cannot use t.Parallel - modifies global GOMAXPROCS. 811 if testing.Short() { 812 t.Skip("skipping in short mode") 813 } 814 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) 815 testVariousDeadlines(t) 816 } 817 818 type neverEnding byte 819 820 func (b neverEnding) Read(p []byte) (int, error) { 821 for i := range p { 822 p[i] = byte(b) 823 } 824 return len(p), nil 825 } 826 827 func testVariousDeadlines(t *testing.T) { 828 switch runtime.GOOS { 829 case "plan9": 830 t.Skipf("not supported on %s", runtime.GOOS) 831 } 832 833 type result struct { 834 n int64 835 err error 836 d time.Duration 837 } 838 839 ch := make(chan error, 1) 840 pasvch := make(chan result) 841 handler := func(ls *localServer, ln Listener) { 842 for { 843 c, err := ln.Accept() 844 if err != nil { 845 ch <- err 846 return 847 } 848 // The server, with no timeouts of its own, 849 // sending bytes to clients as fast as it can. 850 go func() { 851 t0 := time.Now() 852 n, err := io.Copy(c, neverEnding('a')) 853 dt := time.Since(t0) 854 c.Close() 855 pasvch <- result{n, err, dt} 856 }() 857 } 858 } 859 ls, err := newLocalServer("tcp") 860 if err != nil { 861 t.Fatal(err) 862 } 863 defer ls.teardown() 864 if err := ls.buildup(handler); err != nil { 865 t.Fatal(err) 866 } 867 868 for _, timeout := range []time.Duration{ 869 1 * time.Nanosecond, 870 2 * time.Nanosecond, 871 5 * time.Nanosecond, 872 50 * time.Nanosecond, 873 100 * time.Nanosecond, 874 200 * time.Nanosecond, 875 500 * time.Nanosecond, 876 750 * time.Nanosecond, 877 1 * time.Microsecond, 878 5 * time.Microsecond, 879 25 * time.Microsecond, 880 250 * time.Microsecond, 881 500 * time.Microsecond, 882 1 * time.Millisecond, 883 5 * time.Millisecond, 884 100 * time.Millisecond, 885 250 * time.Millisecond, 886 500 * time.Millisecond, 887 1 * time.Second, 888 } { 889 numRuns := 3 890 if testing.Short() { 891 numRuns = 1 892 if timeout > 500*time.Microsecond { 893 continue 894 } 895 } 896 for run := 0; run < numRuns; run++ { 897 name := fmt.Sprintf("%v run %d/%d", timeout, run+1, numRuns) 898 t.Log(name) 899 900 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 901 if err != nil { 902 t.Fatal(err) 903 } 904 905 tooLong := 5 * time.Second 906 max := time.NewTimer(tooLong) 907 defer max.Stop() 908 actvch := make(chan result) 909 go func() { 910 t0 := time.Now() 911 if err := c.SetDeadline(t0.Add(timeout)); err != nil { 912 t.Error(err) 913 } 914 n, err := io.Copy(ioutil.Discard, c) 915 dt := time.Since(t0) 916 c.Close() 917 actvch <- result{n, err, dt} 918 }() 919 920 select { 921 case res := <-actvch: 922 if nerr, ok := res.err.(Error); ok && nerr.Timeout() { 923 t.Logf("for %v, good client timeout after %v, reading %d bytes", name, res.d, res.n) 924 } else { 925 t.Fatalf("for %v, client Copy = %d, %v; want timeout", name, res.n, res.err) 926 } 927 case <-max.C: 928 t.Fatalf("for %v, timeout (%v) waiting for client to timeout (%v) reading", name, tooLong, timeout) 929 } 930 931 select { 932 case res := <-pasvch: 933 t.Logf("for %v, server in %v wrote %d: %v", name, res.d, res.n, res.err) 934 case err := <-ch: 935 t.Fatalf("for %v, Accept = %v", name, err) 936 case <-max.C: 937 t.Fatalf("for %v, timeout waiting for server to finish writing", name) 938 } 939 } 940 } 941 } 942 943 // TestReadWriteProlongedTimeout tests concurrent deadline 944 // modification. Known to cause data races in the past. 945 func TestReadWriteProlongedTimeout(t *testing.T) { 946 t.Parallel() 947 948 switch runtime.GOOS { 949 case "plan9": 950 t.Skipf("not supported on %s", runtime.GOOS) 951 } 952 953 handler := func(ls *localServer, ln Listener) { 954 c, err := ln.Accept() 955 if err != nil { 956 t.Error(err) 957 return 958 } 959 defer c.Close() 960 961 var wg sync.WaitGroup 962 wg.Add(2) 963 go func() { 964 defer wg.Done() 965 var b [1]byte 966 for { 967 if err := c.SetReadDeadline(time.Now().Add(time.Hour)); err != nil { 968 if perr := parseCommonError(err); perr != nil { 969 t.Error(perr) 970 } 971 t.Error(err) 972 return 973 } 974 if _, err := c.Read(b[:]); err != nil { 975 if perr := parseReadError(err); perr != nil { 976 t.Error(perr) 977 } 978 return 979 } 980 } 981 }() 982 go func() { 983 defer wg.Done() 984 var b [1]byte 985 for { 986 if err := c.SetWriteDeadline(time.Now().Add(time.Hour)); err != nil { 987 if perr := parseCommonError(err); perr != nil { 988 t.Error(perr) 989 } 990 t.Error(err) 991 return 992 } 993 if _, err := c.Write(b[:]); err != nil { 994 if perr := parseWriteError(err); perr != nil { 995 t.Error(perr) 996 } 997 return 998 } 999 } 1000 }() 1001 wg.Wait() 1002 } 1003 ls, err := newLocalServer("tcp") 1004 if err != nil { 1005 t.Fatal(err) 1006 } 1007 defer ls.teardown() 1008 if err := ls.buildup(handler); err != nil { 1009 t.Fatal(err) 1010 } 1011 1012 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 1013 if err != nil { 1014 t.Fatal(err) 1015 } 1016 defer c.Close() 1017 1018 var b [1]byte 1019 for i := 0; i < 1000; i++ { 1020 c.Write(b[:]) 1021 c.Read(b[:]) 1022 } 1023 } 1024 1025 func TestReadWriteDeadlineRace(t *testing.T) { 1026 t.Parallel() 1027 1028 switch runtime.GOOS { 1029 case "nacl", "plan9": 1030 t.Skipf("not supported on %s", runtime.GOOS) 1031 } 1032 1033 N := 1000 1034 if testing.Short() { 1035 N = 50 1036 } 1037 1038 ln, err := newLocalListener("tcp") 1039 if err != nil { 1040 t.Fatal(err) 1041 } 1042 defer ln.Close() 1043 1044 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 1045 if err != nil { 1046 t.Fatal(err) 1047 } 1048 defer c.Close() 1049 1050 var wg sync.WaitGroup 1051 wg.Add(3) 1052 go func() { 1053 defer wg.Done() 1054 tic := time.NewTicker(2 * time.Microsecond) 1055 defer tic.Stop() 1056 for i := 0; i < N; i++ { 1057 if err := c.SetReadDeadline(time.Now().Add(2 * time.Microsecond)); err != nil { 1058 if perr := parseCommonError(err); perr != nil { 1059 t.Error(perr) 1060 } 1061 break 1062 } 1063 if err := c.SetWriteDeadline(time.Now().Add(2 * time.Microsecond)); err != nil { 1064 if perr := parseCommonError(err); perr != nil { 1065 t.Error(perr) 1066 } 1067 break 1068 } 1069 <-tic.C 1070 } 1071 }() 1072 go func() { 1073 defer wg.Done() 1074 var b [1]byte 1075 for i := 0; i < N; i++ { 1076 c.Read(b[:]) // ignore possible timeout errors 1077 } 1078 }() 1079 go func() { 1080 defer wg.Done() 1081 var b [1]byte 1082 for i := 0; i < N; i++ { 1083 c.Write(b[:]) // ignore possible timeout errors 1084 } 1085 }() 1086 wg.Wait() // wait for tester goroutine to stop 1087 }