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