Merged revisions 196716,196830,198094,198116,198502,198877,199007,199262,199319,19946...
[official-gcc.git] / main / libgo / go / net / timeout_test.go
blob2e92147b8e33e923390f92c9701a815d241b37dc
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.
5 package net
7 import (
8 "fmt"
9 "io"
10 "io/ioutil"
11 "runtime"
12 "testing"
13 "time"
16 func isTimeout(err error) bool {
17 e, ok := err.(Error)
18 return ok && e.Timeout()
21 type copyRes struct {
22 n int64
23 err error
24 d time.Duration
27 func TestAcceptTimeout(t *testing.T) {
28 switch runtime.GOOS {
29 case "plan9":
30 t.Skipf("skipping test on %q", runtime.GOOS)
33 ln := newLocalListener(t).(*TCPListener)
34 defer ln.Close()
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)
51 go func() {
52 _, err := ln.Accept()
53 errc <- err
54 }()
55 time.Sleep(100 * time.Millisecond)
56 select {
57 case err := <-errc:
58 t.Fatalf("Expected Accept() to not return, but it returned with %v\n", err)
59 default:
61 ln.Close()
62 switch nerr := <-errc; err := nerr.(type) {
63 case *OpError:
64 if err.Err != errClosing {
65 t.Fatalf("Accept: expected err %v, got %v", errClosing, err)
67 default:
68 if err != errClosing {
69 t.Fatalf("Accept: expected err %v, got %v", errClosing, err)
74 func TestReadTimeout(t *testing.T) {
75 switch runtime.GOOS {
76 case "plan9":
77 t.Skipf("skipping test on %q", runtime.GOOS)
80 ln := newLocalListener(t)
81 defer ln.Close()
82 c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr))
83 if err != nil {
84 t.Fatalf("Connect: %v", err)
86 defer c.Close()
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)
106 go func() {
107 _, err := c.Read(buf)
108 errc <- err
110 time.Sleep(100 * time.Millisecond)
111 select {
112 case err := <-errc:
113 t.Fatalf("Expected Read() to not return, but it returned with %v\n", err)
114 default:
116 c.Close()
117 switch nerr := <-errc; err := nerr.(type) {
118 case *OpError:
119 if err.Err != errClosing {
120 t.Fatalf("Read: expected err %v, got %v", errClosing, err)
122 default:
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 {
131 case "plan9":
132 t.Skipf("skipping test on %q", runtime.GOOS)
135 ln := newLocalListener(t)
136 defer ln.Close()
137 c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr))
138 if err != nil {
139 t.Fatalf("Connect: %v", err)
141 defer c.Close()
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() {
146 for {
147 _, err := c.Write(buf)
148 if err != nil {
149 if isTimeout(err) {
150 return
152 t.Fatalf("Write: expected err %v, got %v", errTimeout, err)
156 writeUntilTimeout()
157 c.SetDeadline(time.Now().Add(10 * time.Millisecond))
158 writeUntilTimeout()
159 writeUntilTimeout()
160 c.SetWriteDeadline(noDeadline)
161 c.SetReadDeadline(time.Now().Add(-1 * time.Second))
162 errc := make(chan error)
163 go func() {
164 for {
165 _, err := c.Write(buf)
166 if err != nil {
167 errc <- err
171 time.Sleep(100 * time.Millisecond)
172 select {
173 case err := <-errc:
174 t.Fatalf("Expected Write() to not return, but it returned with %v\n", err)
175 default:
177 c.Close()
178 switch nerr := <-errc; err := nerr.(type) {
179 case *OpError:
180 if err.Err != errClosing {
181 t.Fatalf("Write: expected err %v, got %v", errClosing, err)
183 default:
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)
192 if err != nil {
193 t.Errorf("Dial(%q, %q) failed: %v", net, addr, err)
194 return
196 defer c.Close()
197 what := "Read"
198 if readFrom {
199 what = "ReadFrom"
202 errc := make(chan error, 1)
203 go func() {
204 t0 := time.Now()
205 c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
206 var b [100]byte
207 var n int
208 var err error
209 if readFrom {
210 n, _, err = c.(PacketConn).ReadFrom(b[0:])
211 } else {
212 n, err = c.Read(b[0:])
214 t1 := time.Now()
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)
217 return
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)
221 return
223 errc <- nil
225 select {
226 case err := <-errc:
227 if err != nil {
228 t.Error(err)
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 {
237 case "plan9":
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)
245 addr := <-listening
247 testTimeout(t, "udp", addr, false)
248 testTimeout(t, "udp", addr, true)
249 <-done
252 func TestTimeoutTCP(t *testing.T) {
253 switch runtime.GOOS {
254 case "plan9":
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)
262 addr := <-listening
264 testTimeout(t, "tcp", addr, false)
265 <-done
268 func TestDeadlineReset(t *testing.T) {
269 switch runtime.GOOS {
270 case "plan9":
271 t.Skipf("skipping test on %q", runtime.GOOS)
273 ln, err := Listen("tcp", "127.0.0.1:0")
274 if err != nil {
275 t.Fatal(err)
277 defer ln.Close()
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)
282 go func() {
283 _, err := ln.Accept()
284 errc <- err
286 select {
287 case <-time.After(50 * time.Millisecond):
288 // Pass.
289 case err := <-errc:
290 // Accept should never return; we never
291 // connected to it.
292 t.Errorf("unexpected return from Accept; err=%v", err)
296 func TestTimeoutAccept(t *testing.T) {
297 switch runtime.GOOS {
298 case "plan9":
299 t.Skipf("skipping test on %q", runtime.GOOS)
301 ln, err := Listen("tcp", "127.0.0.1:0")
302 if err != nil {
303 t.Fatal(err)
305 defer ln.Close()
306 tl := ln.(*TCPListener)
307 tl.SetDeadline(time.Now().Add(100 * time.Millisecond))
308 errc := make(chan error, 1)
309 go func() {
310 _, err := ln.Accept()
311 errc <- err
313 select {
314 case <-time.After(1 * time.Second):
315 // Accept shouldn't block indefinitely
316 t.Errorf("Accept didn't return in an expected time")
317 case <-errc:
318 // Pass.
322 func TestReadWriteDeadline(t *testing.T) {
323 switch runtime.GOOS {
324 case "plan9":
325 t.Skipf("skipping test on %q", runtime.GOOS)
328 if !canCancelIO {
329 t.Skip("skipping test on this system")
331 const (
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)
337 d := is - should
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")
344 if err != nil {
345 t.Fatalf("ListenTCP on :0: %v", err)
347 defer ln.Close()
349 lnquit := make(chan bool)
351 go func() {
352 c, err := ln.Accept()
353 if err != nil {
354 t.Fatalf("Accept: %v", err)
356 defer c.Close()
357 lnquit <- true
360 c, err := Dial("tcp", ln.Addr().String())
361 if err != nil {
362 t.Fatalf("Dial: %v", err)
364 defer c.Close()
366 start := time.Now()
367 err = c.SetReadDeadline(start.Add(readTimeout))
368 if err != nil {
369 t.Fatalf("SetReadDeadline: %v", err)
371 err = c.SetWriteDeadline(start.Add(writeTimeout))
372 if err != nil {
373 t.Fatalf("SetWriteDeadline: %v", err)
376 quit := make(chan bool)
378 go func() {
379 var buf [10]byte
380 _, err := c.Read(buf[:])
381 if err == nil {
382 t.Errorf("Read should not succeed")
384 checkTimeout("Read", start, readTimeout)
385 quit <- true
388 go func() {
389 var buf [10000]byte
390 for {
391 _, err := c.Write(buf[:])
392 if err != nil {
393 break
396 checkTimeout("Write", start, writeTimeout)
397 quit <- true
400 <-quit
401 <-quit
402 <-lnquit
405 type neverEnding byte
407 func (b neverEnding) Read(p []byte) (n int, err error) {
408 for i := range p {
409 p[i] = byte(b)
411 return len(p), nil
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 {
424 case "plan9":
425 t.Skipf("skipping test on %q", runtime.GOOS)
428 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
429 ln := newLocalListener(t)
430 defer ln.Close()
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)
436 go func() {
437 for {
438 c, err := ln.Accept()
439 if err != nil {
440 acceptc <- err
441 return
443 go func() {
444 t0 := time.Now()
445 n, err := io.Copy(c, neverEnding('a'))
446 d := time.Since(t0)
447 c.Close()
448 servec <- copyRes{n, err, d}
453 for _, timeout := range []time.Duration{
454 1 * time.Nanosecond,
455 2 * time.Nanosecond,
456 5 * time.Nanosecond,
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,
472 1 * time.Second,
474 numRuns := 3
475 if testing.Short() {
476 numRuns = 1
477 if timeout > 500*time.Microsecond {
478 continue
481 for run := 0; run < numRuns; run++ {
482 name := fmt.Sprintf("%v run %d/%d", timeout, run+1, numRuns)
483 t.Log(name)
485 c, err := Dial("tcp", ln.Addr().String())
486 if err != nil {
487 t.Fatalf("Dial: %v", err)
489 clientc := make(chan copyRes)
490 go func() {
491 t0 := time.Now()
492 c.SetDeadline(t0.Add(timeout))
493 n, err := io.Copy(ioutil.Discard, c)
494 d := time.Since(t0)
495 c.Close()
496 clientc <- copyRes{n, err, d}
499 const tooLong = 2000 * time.Millisecond
500 select {
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)
504 } else {
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)
511 select {
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 {
527 case "plan9":
528 t.Skipf("skipping test on %q", runtime.GOOS)
531 ln := newLocalListener(t)
532 defer ln.Close()
534 servec := make(chan copyRes)
535 const msg = "data client shouldn't read, even though it'll be waiting"
536 go func() {
537 c, err := ln.Accept()
538 if err != nil {
539 t.Fatalf("Accept: %v", err)
541 defer c.Close()
542 n, err := c.Write([]byte(msg))
543 servec <- copyRes{n: int64(n), err: err}
546 c, err := Dial("tcp", ln.Addr().String())
547 if err != nil {
548 t.Fatalf("Dial: %v", err)
550 defer c.Close()
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 {
566 case "plan9":
567 t.Skipf("skipping test on %q", runtime.GOOS)
570 ln := newLocalListener(t)
571 defer ln.Close()
573 servec := make(chan copyRes)
574 go func() {
575 c, err := ln.Accept()
576 if err != nil {
577 t.Fatalf("Accept: %v", err)
579 defer c.Close()
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())
586 if err != nil {
587 t.Fatalf("Dial: %v", err)
589 defer c.Close()
590 res := <-servec
591 if res.n != 0 {
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 {
603 case "plan9":
604 t.Skipf("skipping test on %q", runtime.GOOS)
607 ln := newLocalListener(t).(*TCPListener)
608 defer ln.Close()
610 go func() {
611 c, err := Dial("tcp", ln.Addr().String())
612 if err != nil {
613 t.Fatalf("Dial: %v", err)
615 defer c.Close()
616 var buf [1]byte
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()
622 if err == nil {
623 defer c.Close()
625 if !isTimeout(err) {
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 {
634 case "plan9":
635 t.Skipf("skipping test on %q", runtime.GOOS)
638 ln := newLocalListener(t).(*TCPListener)
639 defer ln.Close()
641 go func() {
642 c, err := ln.Accept()
643 if err == nil {
644 defer c.Close()
647 time.Sleep(10 * time.Millisecond)
648 c, err := DialTimeout("tcp", ln.Addr().String(), -5*time.Second) // in the past
649 if err == nil {
650 defer c.Close()
652 if !isTimeout(err) {
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 {
661 case "plan9":
662 t.Skipf("skipping test on %q", runtime.GOOS)
665 ln := newLocalListener(t)
666 defer ln.Close()
667 connected := make(chan bool)
668 go func() {
669 s, err := ln.Accept()
670 connected <- true
671 if err != nil {
672 t.Fatalf("ln.Accept: %v", err)
674 defer s.Close()
675 s.SetDeadline(time.Now().Add(time.Hour))
676 go func() {
677 var buf [4096]byte
678 for {
679 _, err := s.Write(buf[:])
680 if err != nil {
681 break
683 s.SetDeadline(time.Now().Add(time.Hour))
686 buf := make([]byte, 1)
687 for {
688 _, err := s.Read(buf)
689 if err != nil {
690 break
692 s.SetDeadline(time.Now().Add(time.Hour))
695 c, err := Dial("tcp", ln.Addr().String())
696 if err != nil {
697 t.Fatalf("DialTCP: %v", err)
699 defer c.Close()
700 <-connected
701 for i := 0; i < 1024; i++ {
702 var buf [1]byte
703 c.Write(buf[:])