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