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.
16 func isTimeout(err error
) bool {
18 return ok
&& e
.Timeout()
27 func TestAcceptTimeout(t
*testing
.T
) {
30 t
.Skipf("skipping test on %q", runtime
.GOOS
)
33 ln
:= newLocalListener(t
).(*TCPListener
)
35 ln
.SetDeadline(time
.Now().Add(-1 * time
.Second
))
36 if _
, err
:= ln
.Accept(); !isTimeout(err
) {
37 t
.Fatalf("Accept: expected err %v, got %v", errTimeout
, err
)
39 if _
, err
:= ln
.Accept(); !isTimeout(err
) {
40 t
.Fatalf("Accept: expected err %v, got %v", errTimeout
, err
)
42 ln
.SetDeadline(time
.Now().Add(100 * time
.Millisecond
))
43 if _
, err
:= ln
.Accept(); !isTimeout(err
) {
44 t
.Fatalf("Accept: expected err %v, got %v", errTimeout
, err
)
46 if _
, err
:= ln
.Accept(); !isTimeout(err
) {
47 t
.Fatalf("Accept: expected err %v, got %v", errTimeout
, err
)
49 ln
.SetDeadline(noDeadline
)
50 errc
:= make(chan error
)
55 time
.Sleep(100 * time
.Millisecond
)
58 t
.Fatalf("Expected Accept() to not return, but it returned with %v\n", err
)
62 switch nerr
:= <-errc
; err
:= nerr
.(type) {
64 if err
.Err
!= errClosing
{
65 t
.Fatalf("Accept: expected err %v, got %v", errClosing
, err
)
68 if err
!= errClosing
{
69 t
.Fatalf("Accept: expected err %v, got %v", errClosing
, err
)
74 func TestReadTimeout(t
*testing
.T
) {
77 t
.Skipf("skipping test on %q", runtime
.GOOS
)
80 ln
:= newLocalListener(t
)
82 c
, err
:= DialTCP("tcp", nil, ln
.Addr().(*TCPAddr
))
84 t
.Fatalf("Connect: %v", err
)
87 c
.SetDeadline(time
.Now().Add(time
.Hour
))
88 c
.SetReadDeadline(time
.Now().Add(-1 * time
.Second
))
89 buf
:= make([]byte, 1)
90 if _
, err
= c
.Read(buf
); !isTimeout(err
) {
91 t
.Fatalf("Read: expected err %v, got %v", errTimeout
, err
)
93 if _
, err
= c
.Read(buf
); !isTimeout(err
) {
94 t
.Fatalf("Read: expected err %v, got %v", errTimeout
, err
)
96 c
.SetDeadline(time
.Now().Add(100 * time
.Millisecond
))
97 if _
, err
= c
.Read(buf
); !isTimeout(err
) {
98 t
.Fatalf("Read: expected err %v, got %v", errTimeout
, err
)
100 if _
, err
= c
.Read(buf
); !isTimeout(err
) {
101 t
.Fatalf("Read: expected err %v, got %v", errTimeout
, err
)
103 c
.SetReadDeadline(noDeadline
)
104 c
.SetWriteDeadline(time
.Now().Add(-1 * time
.Second
))
105 errc
:= make(chan error
)
107 _
, err
:= c
.Read(buf
)
110 time
.Sleep(100 * time
.Millisecond
)
113 t
.Fatalf("Expected Read() to not return, but it returned with %v\n", err
)
117 switch nerr
:= <-errc
; err
:= nerr
.(type) {
119 if err
.Err
!= errClosing
{
120 t
.Fatalf("Read: expected err %v, got %v", errClosing
, err
)
123 if err
!= errClosing
{
124 t
.Fatalf("Read: expected err %v, got %v", errClosing
, err
)
129 func TestWriteTimeout(t
*testing
.T
) {
130 switch runtime
.GOOS
{
132 t
.Skipf("skipping test on %q", runtime
.GOOS
)
135 ln
:= newLocalListener(t
)
137 c
, err
:= DialTCP("tcp", nil, ln
.Addr().(*TCPAddr
))
139 t
.Fatalf("Connect: %v", err
)
142 c
.SetDeadline(time
.Now().Add(time
.Hour
))
143 c
.SetWriteDeadline(time
.Now().Add(-1 * time
.Second
))
144 buf
:= make([]byte, 4096)
145 writeUntilTimeout
:= func() {
147 _
, err
:= c
.Write(buf
)
152 t
.Fatalf("Write: expected err %v, got %v", errTimeout
, err
)
157 c
.SetDeadline(time
.Now().Add(10 * time
.Millisecond
))
160 c
.SetWriteDeadline(noDeadline
)
161 c
.SetReadDeadline(time
.Now().Add(-1 * time
.Second
))
162 errc
:= make(chan error
)
165 _
, err
:= c
.Write(buf
)
171 time
.Sleep(100 * time
.Millisecond
)
174 t
.Fatalf("Expected Write() to not return, but it returned with %v\n", err
)
178 switch nerr
:= <-errc
; err
:= nerr
.(type) {
180 if err
.Err
!= errClosing
{
181 t
.Fatalf("Write: expected err %v, got %v", errClosing
, err
)
184 if err
!= errClosing
{
185 t
.Fatalf("Write: expected err %v, got %v", errClosing
, err
)
190 func testTimeout(t
*testing
.T
, net
, addr
string, readFrom
bool) {
191 c
, err
:= Dial(net
, addr
)
193 t
.Errorf("Dial(%q, %q) failed: %v", net
, addr
, err
)
202 errc
:= make(chan error
, 1)
205 c
.SetReadDeadline(time
.Now().Add(100 * time
.Millisecond
))
210 n
, _
, err
= c
.(PacketConn
).ReadFrom(b
[0:])
212 n
, err
= c
.Read(b
[0:])
215 if n
!= 0 || err
== nil ||
!err
.(Error
).Timeout() {
216 errc
<- fmt
.Errorf("%s(%q, %q) did not return 0, timeout: %v, %v", what
, net
, addr
, n
, err
)
219 if dt
:= t1
.Sub(t0
); dt
< 50*time
.Millisecond ||
!testing
.Short() && dt
> 250*time
.Millisecond
{
220 errc
<- fmt
.Errorf("%s(%q, %q) took %s, expected 0.1s", what
, net
, addr
, dt
)
230 case <-time
.After(1 * time
.Second
):
231 t
.Errorf("%s(%q, %q) took over 1 second, expected 0.1s", what
, net
, addr
)
235 func TestTimeoutUDP(t
*testing
.T
) {
236 switch runtime
.GOOS
{
238 t
.Skipf("skipping test on %q", runtime
.GOOS
)
241 // set up a listener that won't talk back
242 listening
:= make(chan string)
243 done
:= make(chan int)
244 go runDatagramPacketConnServer(t
, "udp", "127.0.0.1:0", listening
, done
)
247 testTimeout(t
, "udp", addr
, false)
248 testTimeout(t
, "udp", addr
, true)
252 func TestTimeoutTCP(t
*testing
.T
) {
253 switch runtime
.GOOS
{
255 t
.Skipf("skipping test on %q", runtime
.GOOS
)
258 // set up a listener that won't talk back
259 listening
:= make(chan string)
260 done
:= make(chan int)
261 go runStreamConnServer(t
, "tcp", "127.0.0.1:0", listening
, done
)
264 testTimeout(t
, "tcp", addr
, false)
268 func TestDeadlineReset(t
*testing
.T
) {
269 switch runtime
.GOOS
{
271 t
.Skipf("skipping test on %q", runtime
.GOOS
)
273 ln
, err
:= Listen("tcp", "127.0.0.1:0")
278 tl
:= ln
.(*TCPListener
)
279 tl
.SetDeadline(time
.Now().Add(1 * time
.Minute
))
280 tl
.SetDeadline(noDeadline
) // reset it
281 errc
:= make(chan error
, 1)
283 _
, err
:= ln
.Accept()
287 case <-time
.After(50 * time
.Millisecond
):
290 // Accept should never return; we never
292 t
.Errorf("unexpected return from Accept; err=%v", err
)
296 func TestTimeoutAccept(t
*testing
.T
) {
297 switch runtime
.GOOS
{
299 t
.Skipf("skipping test on %q", runtime
.GOOS
)
301 ln
, err
:= Listen("tcp", "127.0.0.1:0")
306 tl
:= ln
.(*TCPListener
)
307 tl
.SetDeadline(time
.Now().Add(100 * time
.Millisecond
))
308 errc
:= make(chan error
, 1)
310 _
, err
:= ln
.Accept()
314 case <-time
.After(1 * time
.Second
):
315 // Accept shouldn't block indefinitely
316 t
.Errorf("Accept didn't return in an expected time")
322 func TestReadWriteDeadline(t
*testing
.T
) {
323 switch runtime
.GOOS
{
325 t
.Skipf("skipping test on %q", runtime
.GOOS
)
329 t
.Skip("skipping test on this system")
332 readTimeout
= 50 * time
.Millisecond
333 writeTimeout
= 250 * time
.Millisecond
335 checkTimeout
:= func(command
string, start time
.Time
, should time
.Duration
) {
336 is
:= time
.Now().Sub(start
)
338 if d
< -30*time
.Millisecond ||
!testing
.Short() && 150*time
.Millisecond
< d
{
339 t
.Errorf("%s timeout test failed: is=%v should=%v\n", command
, is
, should
)
343 ln
, err
:= Listen("tcp", "127.0.0.1:0")
345 t
.Fatalf("ListenTCP on :0: %v", err
)
349 lnquit
:= make(chan bool)
352 c
, err
:= ln
.Accept()
354 t
.Fatalf("Accept: %v", err
)
360 c
, err
:= Dial("tcp", ln
.Addr().String())
362 t
.Fatalf("Dial: %v", err
)
367 err
= c
.SetReadDeadline(start
.Add(readTimeout
))
369 t
.Fatalf("SetReadDeadline: %v", err
)
371 err
= c
.SetWriteDeadline(start
.Add(writeTimeout
))
373 t
.Fatalf("SetWriteDeadline: %v", err
)
376 quit
:= make(chan bool)
380 _
, err
:= c
.Read(buf
[:])
382 t
.Errorf("Read should not succeed")
384 checkTimeout("Read", start
, readTimeout
)
391 _
, err
:= c
.Write(buf
[:])
396 checkTimeout("Write", start
, writeTimeout
)
405 type neverEnding
byte
407 func (b neverEnding
) Read(p
[]byte) (n
int, err error
) {
414 func TestVariousDeadlines1Proc(t
*testing
.T
) {
415 testVariousDeadlines(t
, 1)
418 func TestVariousDeadlines4Proc(t
*testing
.T
) {
419 testVariousDeadlines(t
, 4)
422 func testVariousDeadlines(t
*testing
.T
, maxProcs
int) {
423 switch runtime
.GOOS
{
425 t
.Skipf("skipping test on %q", runtime
.GOOS
)
428 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(maxProcs
))
429 ln
:= newLocalListener(t
)
431 acceptc
:= make(chan error
, 1)
433 // The server, with no timeouts of its own, sending bytes to clients
434 // as fast as it can.
435 servec
:= make(chan copyRes
)
438 c
, err
:= ln
.Accept()
445 n
, err
:= io
.Copy(c
, neverEnding('a'))
448 servec
<- copyRes
{n
, err
, d
}
453 for _
, timeout
:= range []time
.Duration
{
457 50 * time
.Nanosecond
,
458 100 * time
.Nanosecond
,
459 200 * time
.Nanosecond
,
460 500 * time
.Nanosecond
,
461 750 * time
.Nanosecond
,
462 1 * time
.Microsecond
,
463 5 * time
.Microsecond
,
464 25 * time
.Microsecond
,
465 250 * time
.Microsecond
,
466 500 * time
.Microsecond
,
467 1 * time
.Millisecond
,
468 5 * time
.Millisecond
,
469 100 * time
.Millisecond
,
470 250 * time
.Millisecond
,
471 500 * time
.Millisecond
,
477 if timeout
> 500*time
.Microsecond
{
481 for run
:= 0; run
< numRuns
; run
++ {
482 name
:= fmt
.Sprintf("%v run %d/%d", timeout
, run
+1, numRuns
)
485 c
, err
:= Dial("tcp", ln
.Addr().String())
487 t
.Fatalf("Dial: %v", err
)
489 clientc
:= make(chan copyRes
)
492 c
.SetDeadline(t0
.Add(timeout
))
493 n
, err
:= io
.Copy(ioutil
.Discard
, c
)
496 clientc
<- copyRes
{n
, err
, d
}
499 const tooLong
= 2000 * time
.Millisecond
501 case res
:= <-clientc
:
502 if isTimeout(res
.err
) {
503 t
.Logf("for %v, good client timeout after %v, reading %d bytes", name
, res
.d
, res
.n
)
505 t
.Fatalf("for %v: client Copy = %d, %v (want timeout)", name
, res
.n
, res
.err
)
507 case <-time
.After(tooLong
):
508 t
.Fatalf("for %v: timeout (%v) waiting for client to timeout (%v) reading", name
, tooLong
, timeout
)
512 case res
:= <-servec
:
513 t
.Logf("for %v: server in %v wrote %d, %v", name
, res
.d
, res
.n
, res
.err
)
514 case err
:= <-acceptc
:
515 t
.Fatalf("for %v: server Accept = %v", name
, err
)
516 case <-time
.After(tooLong
):
517 t
.Fatalf("for %v, timeout waiting for server to finish writing", name
)
523 // TestReadDeadlineDataAvailable tests that read deadlines work, even
524 // if there's data ready to be read.
525 func TestReadDeadlineDataAvailable(t
*testing
.T
) {
526 switch runtime
.GOOS
{
528 t
.Skipf("skipping test on %q", runtime
.GOOS
)
531 ln
:= newLocalListener(t
)
534 servec
:= make(chan copyRes
)
535 const msg
= "data client shouldn't read, even though it'll be waiting"
537 c
, err
:= ln
.Accept()
539 t
.Fatalf("Accept: %v", err
)
542 n
, err
:= c
.Write([]byte(msg
))
543 servec
<- copyRes
{n
: int64(n
), err
: err
}
546 c
, err
:= Dial("tcp", ln
.Addr().String())
548 t
.Fatalf("Dial: %v", err
)
551 if res
:= <-servec
; res
.err
!= nil || res
.n
!= int64(len(msg
)) {
552 t
.Fatalf("unexpected server Write: n=%d, err=%d; want n=%d, err=nil", res
.n
, res
.err
, len(msg
))
554 c
.SetReadDeadline(time
.Now().Add(-5 * time
.Second
)) // in the psat.
555 buf
:= make([]byte, len(msg
)/2)
556 n
, err
:= c
.Read(buf
)
557 if n
> 0 ||
!isTimeout(err
) {
558 t
.Fatalf("client read = %d (%q) err=%v; want 0, timeout", n
, buf
[:n
], err
)
562 // TestWriteDeadlineBufferAvailable tests that write deadlines work, even
563 // if there's buffer space available to write.
564 func TestWriteDeadlineBufferAvailable(t
*testing
.T
) {
565 switch runtime
.GOOS
{
567 t
.Skipf("skipping test on %q", runtime
.GOOS
)
570 ln
:= newLocalListener(t
)
573 servec
:= make(chan copyRes
)
575 c
, err
:= ln
.Accept()
577 t
.Fatalf("Accept: %v", err
)
580 c
.SetWriteDeadline(time
.Now().Add(-5 * time
.Second
)) // in the past
581 n
, err
:= c
.Write([]byte{'x'})
582 servec
<- copyRes
{n
: int64(n
), err
: err
}
585 c
, err
:= Dial("tcp", ln
.Addr().String())
587 t
.Fatalf("Dial: %v", err
)
592 t
.Errorf("Write = %d; want 0", res
.n
)
594 if !isTimeout(res
.err
) {
595 t
.Errorf("Write error = %v; want timeout", res
.err
)
599 // TestAcceptDeadlineConnectionAvailable tests that accept deadlines work, even
600 // if there's incoming connections available.
601 func TestAcceptDeadlineConnectionAvailable(t
*testing
.T
) {
602 switch runtime
.GOOS
{
604 t
.Skipf("skipping test on %q", runtime
.GOOS
)
607 ln
:= newLocalListener(t
).(*TCPListener
)
611 c
, err
:= Dial("tcp", ln
.Addr().String())
613 t
.Fatalf("Dial: %v", err
)
617 c
.Read(buf
[:]) // block until the connection or listener is closed
619 time
.Sleep(10 * time
.Millisecond
)
620 ln
.SetDeadline(time
.Now().Add(-5 * time
.Second
)) // in the past
621 c
, err
:= ln
.Accept()
626 t
.Fatalf("Accept: got %v; want timeout", err
)
630 // TestConnectDeadlineInThePast tests that connect deadlines work, even
631 // if the connection can be established w/o blocking.
632 func TestConnectDeadlineInThePast(t
*testing
.T
) {
633 switch runtime
.GOOS
{
635 t
.Skipf("skipping test on %q", runtime
.GOOS
)
638 ln
:= newLocalListener(t
).(*TCPListener
)
642 c
, err
:= ln
.Accept()
647 time
.Sleep(10 * time
.Millisecond
)
648 c
, err
:= DialTimeout("tcp", ln
.Addr().String(), -5*time
.Second
) // in the past
653 t
.Fatalf("DialTimeout: got %v; want timeout", err
)
657 // TestProlongTimeout tests concurrent deadline modification.
658 // Known to cause data races in the past.
659 func TestProlongTimeout(t
*testing
.T
) {
660 switch runtime
.GOOS
{
662 t
.Skipf("skipping test on %q", runtime
.GOOS
)
665 ln
:= newLocalListener(t
)
667 connected
:= make(chan bool)
669 s
, err
:= ln
.Accept()
672 t
.Fatalf("ln.Accept: %v", err
)
675 s
.SetDeadline(time
.Now().Add(time
.Hour
))
679 _
, err
:= s
.Write(buf
[:])
683 s
.SetDeadline(time
.Now().Add(time
.Hour
))
686 buf
:= make([]byte, 1)
688 _
, err
:= s
.Read(buf
)
692 s
.SetDeadline(time
.Now().Add(time
.Hour
))
695 c
, err
:= Dial("tcp", ln
.Addr().String())
697 t
.Fatalf("DialTCP: %v", err
)
701 for i
:= 0; i
< 1024; i
++ {