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