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