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.
14 "net/internal/socktest"
22 var dialTimeoutTests
= []struct {
24 delta time
.Duration
// for deadline
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
},
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
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)
47 for i
, tt
:= range dialTimeoutTests
{
49 case "plan9", "windows":
50 testHookDialChannel
= func() { time
.Sleep(tt
.guard
) }
51 if runtime
.GOOS
== "plan9" {
56 sw
.Set(socktest
.FilterConnect
, func(so
*socktest
.Status
) (socktest
.AfterFilter
, error
) {
58 return nil, errTimedout
62 ch
:= make(chan error
)
63 d
:= Dialer
{Timeout
: tt
.timeout
}
65 d
.Deadline
= time
.Now().Add(tt
.delta
)
67 max
:= time
.NewTimer(tt
.max
)
70 // This dial never starts to send any TCP SYN
71 // segment because of above socket filter and
73 c
, err
:= d
.Dial("tcp", "127.0.0.1:0")
75 err
= fmt
.Errorf("unexpectedly established: tcp:%s->%s", c
.LocalAddr(), c
.RemoteAddr())
83 t
.Fatalf("#%d: Dial didn't return in an expected time", i
)
85 if perr
:= parseDialError(err
); perr
!= nil {
86 t
.Errorf("#%d: %v", i
, perr
)
88 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
89 t
.Fatalf("#%d: %v", i
, err
)
95 func TestDialTimeoutMaxDuration(t
*testing
.T
) {
96 ln
:= newLocalListener(t
, "tcp")
98 if err
:= ln
.Close(); err
!= nil {
103 for _
, tt
:= range []struct {
104 timeout time
.Duration
105 delta time
.Duration
// for deadline
107 // Large timeouts that will overflow an int64 unix nanos.
111 t
.Run(fmt
.Sprintf("timeout=%s/delta=%s", tt
.timeout
, tt
.delta
), func(t
*testing
.T
) {
112 d
:= Dialer
{Timeout
: tt
.timeout
}
114 d
.Deadline
= time
.Now().Add(tt
.delta
)
116 c
, err
:= d
.Dial(ln
.Addr().Network(), ln
.Addr().String())
120 if err
:= c
.Close(); err
!= nil {
127 var acceptTimeoutTests
= []struct {
128 timeout time
.Duration
129 xerrs
[2]error
// expected errors in transition
131 // Tests that accept deadlines in the past work, even if
132 // there's incoming connections available.
133 {-5 * time
.Second
, [2]error
{os
.ErrDeadlineExceeded
, os
.ErrDeadlineExceeded
}},
135 {50 * time
.Millisecond
, [2]error
{nil, os
.ErrDeadlineExceeded
}},
138 func TestAcceptTimeout(t
*testing
.T
) {
139 testenv
.SkipFlaky(t
, 17948)
142 switch runtime
.GOOS
{
144 t
.Skipf("not supported on %s", runtime
.GOOS
)
147 ln
:= newLocalListener(t
, "tcp")
150 var wg sync
.WaitGroup
151 for i
, tt
:= range acceptTimeoutTests
{
156 d
:= Dialer
{Timeout
: 100 * time
.Millisecond
}
157 c
, err
:= d
.Dial(ln
.Addr().Network(), ln
.Addr().String())
166 if err
:= ln
.(*TCPListener
).SetDeadline(time
.Now().Add(tt
.timeout
)); err
!= nil {
167 t
.Fatalf("$%d: %v", i
, err
)
169 for j
, xerr
:= range tt
.xerrs
{
171 c
, err
:= ln
.Accept()
173 if perr
:= parseAcceptError(err
); perr
!= nil {
174 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
176 if !isDeadlineExceeded(err
) {
177 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
182 time
.Sleep(10 * time
.Millisecond
)
192 func TestAcceptTimeoutMustReturn(t
*testing
.T
) {
195 switch runtime
.GOOS
{
197 t
.Skipf("not supported on %s", runtime
.GOOS
)
200 ln
:= newLocalListener(t
, "tcp")
203 max
:= time
.NewTimer(time
.Second
)
205 ch
:= make(chan error
)
207 if err
:= ln
.(*TCPListener
).SetDeadline(noDeadline
); err
!= nil {
210 if err
:= ln
.(*TCPListener
).SetDeadline(time
.Now().Add(10 * time
.Millisecond
)); err
!= nil {
213 c
, err
:= ln
.Accept()
223 <-ch
// wait for tester goroutine to stop
224 t
.Fatal("Accept didn't return in an expected time")
226 if perr
:= parseAcceptError(err
); perr
!= nil {
229 if !isDeadlineExceeded(err
) {
235 func TestAcceptTimeoutMustNotReturn(t
*testing
.T
) {
238 switch runtime
.GOOS
{
240 t
.Skipf("not supported on %s", runtime
.GOOS
)
243 ln
:= newLocalListener(t
, "tcp")
246 max
:= time
.NewTimer(100 * time
.Millisecond
)
248 ch
:= make(chan error
)
250 if err
:= ln
.(*TCPListener
).SetDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
253 if err
:= ln
.(*TCPListener
).SetDeadline(noDeadline
); err
!= nil {
256 _
, err
:= ln
.Accept()
262 if perr
:= parseAcceptError(err
); perr
!= nil {
265 t
.Fatalf("expected Accept to not return, but it returned with %v", err
)
268 <-ch
// wait for tester goroutine to stop
272 var readTimeoutTests
= []struct {
273 timeout time
.Duration
274 xerrs
[2]error
// expected errors in transition
276 // Tests that read deadlines work, even if there's data ready
278 {-5 * time
.Second
, [2]error
{os
.ErrDeadlineExceeded
, os
.ErrDeadlineExceeded
}},
280 {50 * time
.Millisecond
, [2]error
{nil, os
.ErrDeadlineExceeded
}},
283 func TestReadTimeout(t
*testing
.T
) {
284 handler
:= func(ls
*localServer
, ln Listener
) {
285 c
, err
:= ln
.Accept()
290 c
.Write([]byte("READ TIMEOUT TEST"))
293 ls
:= newLocalServer(t
, "tcp")
295 if err
:= ls
.buildup(handler
); err
!= nil {
299 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
305 for i
, tt
:= range readTimeoutTests
{
306 if err
:= c
.SetReadDeadline(time
.Now().Add(tt
.timeout
)); err
!= nil {
307 t
.Fatalf("#%d: %v", i
, err
)
310 for j
, xerr
:= range tt
.xerrs
{
312 n
, err
:= c
.Read(b
[:])
314 if perr
:= parseReadError(err
); perr
!= nil {
315 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
317 if !isDeadlineExceeded(err
) {
318 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
322 time
.Sleep(tt
.timeout
/ 3)
326 t
.Fatalf("#%d/%d: read %d; want 0", i
, j
, n
)
334 func TestReadTimeoutMustNotReturn(t
*testing
.T
) {
337 switch runtime
.GOOS
{
339 t
.Skipf("not supported on %s", runtime
.GOOS
)
342 ln
:= newLocalListener(t
, "tcp")
345 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
351 max
:= time
.NewTimer(100 * time
.Millisecond
)
353 ch
:= make(chan error
)
355 if err
:= c
.SetDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
358 if err
:= c
.SetWriteDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
361 if err
:= c
.SetReadDeadline(noDeadline
); err
!= nil {
365 _
, err
:= c
.Read(b
[:])
371 if perr
:= parseReadError(err
); perr
!= nil {
374 t
.Fatalf("expected Read to not return, but it returned with %v", err
)
377 err
:= <-ch
// wait for tester goroutine to stop
378 if perr
:= parseReadError(err
); perr
!= nil {
381 if nerr
, ok
:= err
.(Error
); !ok || nerr
.Timeout() || nerr
.Temporary() {
387 var readFromTimeoutTests
= []struct {
388 timeout time
.Duration
389 xerrs
[2]error
// expected errors in transition
391 // Tests that read deadlines work, even if there's data ready
393 {-5 * time
.Second
, [2]error
{os
.ErrDeadlineExceeded
, os
.ErrDeadlineExceeded
}},
395 {50 * time
.Millisecond
, [2]error
{nil, os
.ErrDeadlineExceeded
}},
398 func TestReadFromTimeout(t
*testing
.T
) {
399 ch
:= make(chan Addr
)
401 handler
:= func(ls
*localPacketServer
, c PacketConn
) {
402 if dst
, ok
:= <-ch
; ok
{
403 c
.WriteTo([]byte("READFROM TIMEOUT TEST"), dst
)
406 ls
:= newLocalPacketServer(t
, "udp")
408 if err
:= ls
.buildup(handler
); err
!= nil {
412 host
, _
, err
:= SplitHostPort(ls
.PacketConn
.LocalAddr().String())
416 c
, err
:= ListenPacket(ls
.PacketConn
.LocalAddr().Network(), JoinHostPort(host
, "0"))
423 for i
, tt
:= range readFromTimeoutTests
{
424 if err
:= c
.SetReadDeadline(time
.Now().Add(tt
.timeout
)); err
!= nil {
425 t
.Fatalf("#%d: %v", i
, err
)
428 for j
, xerr
:= range tt
.xerrs
{
430 n
, _
, err
:= c
.ReadFrom(b
[:])
432 if perr
:= parseReadError(err
); perr
!= nil {
433 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
435 if !isDeadlineExceeded(err
) {
436 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
440 time
.Sleep(tt
.timeout
/ 3)
443 if nerr
, ok
:= err
.(Error
); ok
&& nerr
.Timeout() && n
!= 0 {
444 t
.Fatalf("#%d/%d: read %d; want 0", i
, j
, n
)
452 var writeTimeoutTests
= []struct {
453 timeout time
.Duration
454 xerrs
[2]error
// expected errors in transition
456 // Tests that write deadlines work, even if there's buffer
457 // space available to write.
458 {-5 * time
.Second
, [2]error
{os
.ErrDeadlineExceeded
, os
.ErrDeadlineExceeded
}},
460 {10 * time
.Millisecond
, [2]error
{nil, os
.ErrDeadlineExceeded
}},
463 func TestWriteTimeout(t
*testing
.T
) {
466 ln
:= newLocalListener(t
, "tcp")
469 for i
, tt
:= range writeTimeoutTests
{
470 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
476 if err
:= c
.SetWriteDeadline(time
.Now().Add(tt
.timeout
)); err
!= nil {
477 t
.Fatalf("#%d: %v", i
, err
)
479 for j
, xerr
:= range tt
.xerrs
{
481 n
, err
:= c
.Write([]byte("WRITE TIMEOUT TEST"))
483 if perr
:= parseWriteError(err
); perr
!= nil {
484 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
486 if !isDeadlineExceeded(err
) {
487 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
491 time
.Sleep(tt
.timeout
/ 3)
495 t
.Fatalf("#%d/%d: wrote %d; want 0", i
, j
, n
)
503 func TestWriteTimeoutMustNotReturn(t
*testing
.T
) {
506 switch runtime
.GOOS
{
508 t
.Skipf("not supported on %s", runtime
.GOOS
)
511 ln
:= newLocalListener(t
, "tcp")
514 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
520 max
:= time
.NewTimer(100 * time
.Millisecond
)
522 ch
:= make(chan error
)
524 if err
:= c
.SetDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
527 if err
:= c
.SetReadDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
530 if err
:= c
.SetWriteDeadline(noDeadline
); err
!= nil {
535 if _
, err
:= c
.Write(b
[:]); err
!= nil {
544 if perr
:= parseWriteError(err
); perr
!= nil {
547 t
.Fatalf("expected Write to not return, but it returned with %v", err
)
550 err
:= <-ch
// wait for tester goroutine to stop
551 if perr
:= parseWriteError(err
); perr
!= nil {
554 if nerr
, ok
:= err
.(Error
); !ok || nerr
.Timeout() || nerr
.Temporary() {
560 func TestWriteToTimeout(t
*testing
.T
) {
563 c1
:= newLocalPacketListener(t
, "udp")
566 host
, _
, err
:= SplitHostPort(c1
.LocalAddr().String())
571 timeouts
:= []time
.Duration
{
573 10 * time
.Millisecond
,
576 for _
, timeout
:= range timeouts
{
577 t
.Run(fmt
.Sprint(timeout
), func(t
*testing
.T
) {
578 c2
, err
:= ListenPacket(c1
.LocalAddr().Network(), JoinHostPort(host
, "0"))
584 if err
:= c2
.SetWriteDeadline(time
.Now().Add(timeout
)); err
!= nil {
585 t
.Fatalf("SetWriteDeadline: %v", err
)
587 backoff
:= 1 * time
.Millisecond
588 nDeadlineExceeded
:= 0
589 for j
:= 0; nDeadlineExceeded
< 2; j
++ {
590 n
, err
:= c2
.WriteTo([]byte("WRITETO TIMEOUT TEST"), c1
.LocalAddr())
591 t
.Logf("#%d: WriteTo: %d, %v", j
, n
, err
)
592 if err
== nil && timeout
>= 0 && nDeadlineExceeded
== 0 {
593 // If the timeout is nonnegative, some number of WriteTo calls may
594 // succeed before the timeout takes effect.
595 t
.Logf("WriteTo succeeded; sleeping %v", timeout
/3)
596 time
.Sleep(timeout
/ 3)
600 t
.Logf("WriteTo: %v", err
)
601 // We're looking for a deadline exceeded error, but if the kernel's
602 // network buffers are saturated we may see ENOBUFS instead (see
603 // https://go.dev/issue/49930). Give it some time to unsaturate.
608 if perr
:= parseWriteError(err
); perr
!= nil {
609 t
.Errorf("failed to parse error: %v", perr
)
611 if !isDeadlineExceeded(err
) {
612 t
.Errorf("error is not 'deadline exceeded'")
615 t
.Errorf("unexpectedly wrote %d bytes", n
)
618 t
.Logf("WriteTo timed out as expected")
627 // minDynamicTimeout is the minimum timeout to attempt for
628 // tests that automatically increase timeouts until success.
630 // Lower values may allow tests to succeed more quickly if the value is close
631 // to the true minimum, but may require more iterations (and waste more time
632 // and CPU power on failed attempts) if the timeout is too low.
633 minDynamicTimeout
= 1 * time
.Millisecond
635 // maxDynamicTimeout is the maximum timeout to attempt for
636 // tests that automatically increase timeouts until succeess.
638 // This should be a strict upper bound on the latency required to hit a
639 // timeout accurately, even on a slow or heavily-loaded machine. If a test
640 // would increase the timeout beyond this value, the test fails.
641 maxDynamicTimeout
= 4 * time
.Second
644 // timeoutUpperBound returns the maximum time that we expect a timeout of
645 // duration d to take to return the caller.
646 func timeoutUpperBound(d time
.Duration
) time
.Duration
{
647 switch runtime
.GOOS
{
648 case "openbsd", "netbsd":
649 // NetBSD and OpenBSD seem to be unable to reliably hit deadlines even when
650 // the absolute durations are long.
651 // In https://build.golang.org/log/c34f8685d020b98377dd4988cd38f0c5bd72267e,
652 // we observed that an openbsd-amd64-68 builder took 4.090948779s for a
653 // 2.983020682s timeout (37.1% overhead).
654 // (See https://go.dev/issue/50189 for further detail.)
655 // Give them lots of slop to compensate.
658 // Other platforms seem to hit their deadlines more reliably,
659 // at least when they are long enough to cover scheduling jitter.
663 // nextTimeout returns the next timeout to try after an operation took the given
664 // actual duration with a timeout shorter than that duration.
665 func nextTimeout(actual time
.Duration
) (next time
.Duration
, ok
bool) {
666 if actual
>= maxDynamicTimeout
{
667 return maxDynamicTimeout
, false
669 // Since the previous attempt took actual, we can't expect to beat that
670 // duration by any significant margin. Try the next attempt with an arbitrary
671 // factor above that, so that our growth curve is at least exponential.
672 next
= actual
* 5 / 4
673 if next
> maxDynamicTimeout
{
674 return maxDynamicTimeout
, true
679 func TestReadTimeoutFluctuation(t
*testing
.T
) {
680 ln
:= newLocalListener(t
, "tcp")
683 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
689 d
:= minDynamicTimeout
690 b
:= make([]byte, 256)
692 t
.Logf("SetReadDeadline(+%v)", d
)
694 deadline
:= t0
.Add(d
)
695 if err
= c
.SetReadDeadline(deadline
); err
!= nil {
696 t
.Fatalf("SetReadDeadline(%v): %v", deadline
, err
)
702 if n
!= 0 || err
== nil ||
!err
.(Error
).Timeout() {
703 t
.Errorf("Read did not return (0, timeout): (%d, %v)", n
, err
)
705 if perr
:= parseReadError(err
); perr
!= nil {
708 if !isDeadlineExceeded(err
) {
709 t
.Errorf("Read error is not DeadlineExceeded: %v", err
)
713 if t1
.Before(deadline
) {
714 t
.Errorf("Read took %s; expected at least %s", actual
, d
)
719 if want
:= timeoutUpperBound(d
); actual
> want
{
720 next
, ok
:= nextTimeout(actual
)
722 t
.Fatalf("Read took %s; expected at most %v", actual
, want
)
724 // Maybe this machine is too slow to reliably schedule goroutines within
725 // the requested duration. Increase the timeout and try again.
726 t
.Logf("Read took %s (expected %s); trying with longer timeout", actual
, d
)
735 func TestReadFromTimeoutFluctuation(t
*testing
.T
) {
736 c1
:= newLocalPacketListener(t
, "udp")
739 c2
, err
:= Dial(c1
.LocalAddr().Network(), c1
.LocalAddr().String())
745 d
:= minDynamicTimeout
746 b
:= make([]byte, 256)
748 t
.Logf("SetReadDeadline(+%v)", d
)
750 deadline
:= t0
.Add(d
)
751 if err
= c2
.SetReadDeadline(deadline
); err
!= nil {
752 t
.Fatalf("SetReadDeadline(%v): %v", deadline
, err
)
755 n
, _
, err
= c2
.(PacketConn
).ReadFrom(b
)
758 if n
!= 0 || err
== nil ||
!err
.(Error
).Timeout() {
759 t
.Errorf("ReadFrom did not return (0, timeout): (%d, %v)", n
, err
)
761 if perr
:= parseReadError(err
); perr
!= nil {
764 if !isDeadlineExceeded(err
) {
765 t
.Errorf("ReadFrom error is not DeadlineExceeded: %v", err
)
769 if t1
.Before(deadline
) {
770 t
.Errorf("ReadFrom took %s; expected at least %s", actual
, d
)
775 if want
:= timeoutUpperBound(d
); actual
> want
{
776 next
, ok
:= nextTimeout(actual
)
778 t
.Fatalf("ReadFrom took %s; expected at most %s", actual
, want
)
780 // Maybe this machine is too slow to reliably schedule goroutines within
781 // the requested duration. Increase the timeout and try again.
782 t
.Logf("ReadFrom took %s (expected %s); trying with longer timeout", actual
, d
)
791 func TestWriteTimeoutFluctuation(t
*testing
.T
) {
792 switch runtime
.GOOS
{
794 t
.Skipf("not supported on %s", runtime
.GOOS
)
797 ln
:= newLocalListener(t
, "tcp")
800 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
806 d
:= minDynamicTimeout
808 t
.Logf("SetWriteDeadline(+%v)", d
)
810 deadline
:= t0
.Add(d
)
811 if err
= c
.SetWriteDeadline(deadline
); err
!= nil {
812 t
.Fatalf("SetWriteDeadline(%v): %v", deadline
, err
)
817 dn
, err
= c
.Write([]byte("TIMEOUT TRANSMITTER"))
825 if err
== nil ||
!err
.(Error
).Timeout() {
826 t
.Fatalf("Write did not return (any, timeout): (%d, %v)", n
, err
)
828 if perr
:= parseWriteError(err
); perr
!= nil {
831 if !isDeadlineExceeded(err
) {
832 t
.Errorf("Write error is not DeadlineExceeded: %v", err
)
836 if t1
.Before(deadline
) {
837 t
.Errorf("Write took %s; expected at least %s", actual
, d
)
842 if want
:= timeoutUpperBound(d
); actual
> want
{
844 // SetWriteDeadline specifies a time “after which I/O operations fail
845 // instead of blocking”. However, the kernel's send buffer is not yet
846 // full, we may be able to write some arbitrary (but finite) number of
847 // bytes to it without blocking.
848 t
.Logf("Wrote %d bytes into send buffer; retrying until buffer is full", n
)
849 if d
<= maxDynamicTimeout
/2 {
850 // We don't know how long the actual write loop would have taken if
851 // the buffer were full, so just guess and double the duration so that
852 // the next attempt can make twice as much progress toward filling it.
855 } else if next
, ok
:= nextTimeout(actual
); !ok
{
856 t
.Fatalf("Write took %s; expected at most %s", actual
, want
)
858 // Maybe this machine is too slow to reliably schedule goroutines within
859 // the requested duration. Increase the timeout and try again.
860 t
.Logf("Write took %s (expected %s); trying with longer timeout", actual
, d
)
870 func TestVariousDeadlines(t
*testing
.T
) {
872 testVariousDeadlines(t
)
875 func TestVariousDeadlines1Proc(t
*testing
.T
) {
876 // Cannot use t.Parallel - modifies global GOMAXPROCS.
878 t
.Skip("skipping in short mode")
880 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(1))
881 testVariousDeadlines(t
)
884 func TestVariousDeadlines4Proc(t
*testing
.T
) {
885 // Cannot use t.Parallel - modifies global GOMAXPROCS.
887 t
.Skip("skipping in short mode")
889 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(4))
890 testVariousDeadlines(t
)
893 type neverEnding
byte
895 func (b neverEnding
) Read(p
[]byte) (int, error
) {
902 func testVariousDeadlines(t
*testing
.T
) {
903 if runtime
.GOOS
== "plan9" {
904 t
.Skip("skipping test on plan9; see golang.org/issue/26945")
912 handler
:= func(ls
*localServer
, ln Listener
) {
914 c
, err
:= ln
.Accept()
918 c
.Read(make([]byte, 1)) // wait for client to close connection
922 ls
:= newLocalServer(t
, "tcp")
924 if err
:= ls
.buildup(handler
); err
!= nil {
928 for _
, timeout
:= range []time
.Duration
{
932 50 * time
.Nanosecond
,
933 100 * time
.Nanosecond
,
934 200 * time
.Nanosecond
,
935 500 * time
.Nanosecond
,
936 750 * time
.Nanosecond
,
937 1 * time
.Microsecond
,
938 5 * time
.Microsecond
,
939 25 * time
.Microsecond
,
940 250 * time
.Microsecond
,
941 500 * time
.Microsecond
,
942 1 * time
.Millisecond
,
943 5 * time
.Millisecond
,
944 100 * time
.Millisecond
,
945 250 * time
.Millisecond
,
946 500 * time
.Millisecond
,
952 if timeout
> 500*time
.Microsecond
{
956 for run
:= 0; run
< numRuns
; run
++ {
957 name
:= fmt
.Sprintf("%v %d/%d", timeout
, run
, numRuns
)
960 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
966 if err
:= c
.SetDeadline(t0
.Add(timeout
)); err
!= nil {
969 n
, err
:= io
.Copy(io
.Discard
, c
)
973 if nerr
, ok
:= err
.(Error
); ok
&& nerr
.Timeout() {
974 t
.Logf("%v: good timeout after %v; %d bytes", name
, dt
, n
)
976 t
.Fatalf("%v: Copy = %d, %v; want timeout", name
, n
, err
)
982 // TestReadWriteProlongedTimeout tests concurrent deadline
983 // modification. Known to cause data races in the past.
984 func TestReadWriteProlongedTimeout(t
*testing
.T
) {
987 switch runtime
.GOOS
{
989 t
.Skipf("not supported on %s", runtime
.GOOS
)
992 handler
:= func(ls
*localServer
, ln Listener
) {
993 c
, err
:= ln
.Accept()
1000 var wg sync
.WaitGroup
1006 if err
:= c
.SetReadDeadline(time
.Now().Add(time
.Hour
)); err
!= nil {
1007 if perr
:= parseCommonError(err
); perr
!= nil {
1013 if _
, err
:= c
.Read(b
[:]); err
!= nil {
1014 if perr
:= parseReadError(err
); perr
!= nil {
1025 if err
:= c
.SetWriteDeadline(time
.Now().Add(time
.Hour
)); err
!= nil {
1026 if perr
:= parseCommonError(err
); perr
!= nil {
1032 if _
, err
:= c
.Write(b
[:]); err
!= nil {
1033 if perr
:= parseWriteError(err
); perr
!= nil {
1042 ls
:= newLocalServer(t
, "tcp")
1044 if err
:= ls
.buildup(handler
); err
!= nil {
1048 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
1055 for i
:= 0; i
< 1000; i
++ {
1061 func TestReadWriteDeadlineRace(t
*testing
.T
) {
1065 if testing
.Short() {
1069 ln
:= newLocalListener(t
, "tcp")
1072 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
1078 var wg sync
.WaitGroup
1082 tic
:= time
.NewTicker(2 * time
.Microsecond
)
1084 for i
:= 0; i
< N
; i
++ {
1085 if err
:= c
.SetReadDeadline(time
.Now().Add(2 * time
.Microsecond
)); err
!= nil {
1086 if perr
:= parseCommonError(err
); perr
!= nil {
1091 if err
:= c
.SetWriteDeadline(time
.Now().Add(2 * time
.Microsecond
)); err
!= nil {
1092 if perr
:= parseCommonError(err
); perr
!= nil {
1103 for i
:= 0; i
< N
; i
++ {
1104 c
.Read(b
[:]) // ignore possible timeout errors
1110 for i
:= 0; i
< N
; i
++ {
1111 c
.Write(b
[:]) // ignore possible timeout errors
1114 wg
.Wait() // wait for tester goroutine to stop
1118 func TestConcurrentSetDeadline(t
*testing
.T
) {
1119 ln
:= newLocalListener(t
, "tcp")
1122 const goroutines
= 8
1127 for i
:= 0; i
< conns
; i
++ {
1129 c
[i
], err
= Dial(ln
.Addr().Network(), ln
.Addr().String())
1136 var wg sync
.WaitGroup
1139 for i
:= 0; i
< goroutines
; i
++ {
1142 // Make the deadlines steadily earlier,
1143 // to trigger runtime adjusttimers calls.
1144 for j
:= tries
; j
> 0; j
-- {
1145 for k
:= 0; k
< conns
; k
++ {
1146 c
[k
].SetReadDeadline(now
.Add(2*time
.Hour
+ time
.Duration(i
*j
*k
)*time
.Second
))
1147 c
[k
].SetWriteDeadline(now
.Add(1*time
.Hour
+ time
.Duration(i
*j
*k
)*time
.Second
))
1155 // isDeadlineExceeded reports whether err is or wraps os.ErrDeadlineExceeded.
1156 // We also check that the error implements net.Error, and that the
1157 // Timeout method returns true.
1158 func isDeadlineExceeded(err error
) bool {
1159 nerr
, ok
:= err
.(Error
)
1163 if !nerr
.Timeout() {
1166 if !errors
.Is(err
, os
.ErrDeadlineExceeded
) {