blob: ca94e24c81685cfc3e67655a544efea12a0a1e01 [file] [log] [blame]
Russ Cox1e37e8a2009-03-06 17:51:31 -08001// 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
5package net
6
7import (
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -08008 "fmt"
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -08009 "io"
10 "io/ioutil"
Mikio Hara8b0e38f2015-03-29 20:19:20 +090011 "net/internal/socktest"
Fazlul Shahriar58423362011-10-31 11:47:44 -040012 "runtime"
Mikio Hara98e05562015-04-28 21:17:46 +090013 "sync"
Robert Griesemera3d10452009-12-15 15:35:38 -080014 "testing"
15 "time"
Russ Cox1e37e8a2009-03-06 17:51:31 -080016)
17
Mikio Hara98e05562015-04-28 21:17:46 +090018var dialTimeoutTests = []struct {
19 timeout time.Duration
20 delta time.Duration // for deadline
21
22 guard time.Duration
23 max time.Duration
24}{
25 // Tests that dial timeouts, deadlines in the past work.
26 {-5 * time.Second, 0, -5 * time.Second, 100 * time.Millisecond},
27 {0, -5 * time.Second, -5 * time.Second, 100 * time.Millisecond},
28 {-5 * time.Second, 5 * time.Second, -5 * time.Second, 100 * time.Millisecond}, // timeout over deadline
29
30 {50 * time.Millisecond, 0, 100 * time.Millisecond, time.Second},
31 {0, 50 * time.Millisecond, 100 * time.Millisecond, time.Second},
32 {50 * time.Millisecond, 5 * time.Second, 100 * time.Millisecond, time.Second}, // timeout over deadline
33}
34
Mikio Hara8b0e38f2015-03-29 20:19:20 +090035func TestDialTimeout(t *testing.T) {
Mikio Hara98e05562015-04-28 21:17:46 +090036 origTestHookDialChannel := testHookDialChannel
37 defer func() { testHookDialChannel = origTestHookDialChannel }()
38 defer sw.Set(socktest.FilterConnect, nil)
Mikio Hara8b0e38f2015-03-29 20:19:20 +090039
Mikio Hara68557de2015-07-27 12:19:00 +090040 // Avoid tracking open-close jitterbugs between netFD and
41 // socket that leads to confusion of information inside
42 // socktest.Switch.
43 // It may happen when the Dial call bumps against TCP
44 // simultaneous open. See selfConnect in tcpsock_posix.go.
45 defer func() {
46 sw.Set(socktest.FilterClose, nil)
47 forceCloseSockets()
48 }()
49 sw.Set(socktest.FilterClose, func(so *socktest.Status) (socktest.AfterFilter, error) {
50 return nil, errTimedout
51 })
52
Mikio Hara98e05562015-04-28 21:17:46 +090053 for i, tt := range dialTimeoutTests {
54 switch runtime.GOOS {
55 case "plan9", "windows":
56 testHookDialChannel = func() { time.Sleep(tt.guard) }
57 if runtime.GOOS == "plan9" {
58 break
59 }
60 fallthrough
61 default:
62 sw.Set(socktest.FilterConnect, func(so *socktest.Status) (socktest.AfterFilter, error) {
63 time.Sleep(tt.guard)
64 return nil, errTimedout
65 })
Mikio Hara8b0e38f2015-03-29 20:19:20 +090066 }
Mikio Hara8b0e38f2015-03-29 20:19:20 +090067
Mikio Hara98e05562015-04-28 21:17:46 +090068 ch := make(chan error)
69 d := Dialer{Timeout: tt.timeout}
70 if tt.delta != 0 {
71 d.Deadline = time.Now().Add(tt.delta)
Mikio Hara8b0e38f2015-03-29 20:19:20 +090072 }
Mikio Hara98e05562015-04-28 21:17:46 +090073 max := time.NewTimer(tt.max)
74 defer max.Stop()
75 go func() {
76 // This dial never starts to send any TCP SYN
77 // segment because of above socket filter and
78 // test hook.
79 c, err := d.Dial("tcp", "127.0.0.1:0")
80 if err == nil {
81 err = fmt.Errorf("unexpectedly established: tcp:%s->%s", c.LocalAddr(), c.RemoteAddr())
82 c.Close()
83 }
84 ch <- err
85 }()
86
87 select {
88 case <-max.C:
89 t.Fatalf("#%d: Dial didn't return in an expected time", i)
90 case err := <-ch:
91 if perr := parseDialError(err); perr != nil {
92 t.Errorf("#%d: %v", i, perr)
93 }
94 if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
95 t.Fatalf("#%d: %v", i, err)
96 }
Mikio Hara8b0e38f2015-03-29 20:19:20 +090097 }
98 }
99}
100
Mikio Hara98e05562015-04-28 21:17:46 +0900101var acceptTimeoutTests = []struct {
102 timeout time.Duration
103 xerrs [2]error // expected errors in transition
104}{
105 // Tests that accept deadlines in the past work, even if
106 // there's incoming connections available.
107 {-5 * time.Second, [2]error{errTimeout, errTimeout}},
108
109 {50 * time.Millisecond, [2]error{nil, errTimeout}},
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800110}
111
Dmitriy Vyukov74fcf822012-11-25 13:27:32 +0400112func TestAcceptTimeout(t *testing.T) {
113 switch runtime.GOOS {
114 case "plan9":
Mikio Hara98e05562015-04-28 21:17:46 +0900115 t.Skipf("not supported on %s", runtime.GOOS)
Dmitriy Vyukov74fcf822012-11-25 13:27:32 +0400116 }
117
Mikio Haraf0775052015-04-02 23:11:39 +0900118 ln, err := newLocalListener("tcp")
119 if err != nil {
120 t.Fatal(err)
121 }
Dmitriy Vyukov74fcf822012-11-25 13:27:32 +0400122 defer ln.Close()
Mikio Hara98e05562015-04-28 21:17:46 +0900123
124 for i, tt := range acceptTimeoutTests {
125 if tt.timeout < 0 {
126 go func() {
127 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
128 if err != nil {
129 t.Error(err)
130 return
131 }
132 var b [1]byte
133 c.Read(b[:])
134 c.Close()
135 }()
136 }
137
138 if err := ln.(*TCPListener).SetDeadline(time.Now().Add(tt.timeout)); err != nil {
139 t.Fatalf("$%d: %v", i, err)
140 }
141 for j, xerr := range tt.xerrs {
142 for {
143 c, err := ln.Accept()
144 if xerr != nil {
145 if perr := parseAcceptError(err); perr != nil {
146 t.Errorf("#%d/%d: %v", i, j, perr)
147 }
148 if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
149 t.Fatalf("#%d/%d: %v", i, j, err)
150 }
151 }
152 if err == nil {
153 c.Close()
154 time.Sleep(tt.timeout / 3)
155 continue
156 }
157 break
158 }
159 }
Dmitriy Vyukov74fcf822012-11-25 13:27:32 +0400160 }
Mikio Hara98e05562015-04-28 21:17:46 +0900161}
162
163func TestAcceptTimeoutMustReturn(t *testing.T) {
164 switch runtime.GOOS {
165 case "plan9":
166 t.Skipf("not supported on %s", runtime.GOOS)
Mikio Hara4540e162015-04-17 14:35:54 +0900167 }
Mikio Hara98e05562015-04-28 21:17:46 +0900168
169 ln, err := newLocalListener("tcp")
170 if err != nil {
171 t.Fatal(err)
Dmitriy Vyukov74fcf822012-11-25 13:27:32 +0400172 }
Mikio Hara98e05562015-04-28 21:17:46 +0900173 defer ln.Close()
174
175 max := time.NewTimer(time.Second)
176 defer max.Stop()
177 ch := make(chan error)
Dmitriy Vyukov74fcf822012-11-25 13:27:32 +0400178 go func() {
Mikio Hara98e05562015-04-28 21:17:46 +0900179 if err := ln.(*TCPListener).SetDeadline(noDeadline); err != nil {
180 t.Error(err)
181 }
182 if err := ln.(*TCPListener).SetDeadline(time.Now().Add(10 * time.Millisecond)); err != nil {
183 t.Error(err)
184 }
185 c, err := ln.Accept()
186 if err == nil {
187 c.Close()
188 }
189 ch <- err
Dmitriy Vyukov74fcf822012-11-25 13:27:32 +0400190 }()
Mikio Hara98e05562015-04-28 21:17:46 +0900191
Dmitriy Vyukov74fcf822012-11-25 13:27:32 +0400192 select {
Mikio Hara98e05562015-04-28 21:17:46 +0900193 case <-max.C:
194 ln.Close()
195 <-ch // wait for tester goroutine to stop
196 t.Fatal("Accept didn't return in an expected time")
197 case err := <-ch:
198 if perr := parseAcceptError(err); perr != nil {
199 t.Error(perr)
200 }
201 if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
202 t.Fatal(err)
203 }
Dmitriy Vyukov74fcf822012-11-25 13:27:32 +0400204 }
Mikio Hara98e05562015-04-28 21:17:46 +0900205}
206
207func TestAcceptTimeoutMustNotReturn(t *testing.T) {
208 switch runtime.GOOS {
209 case "plan9":
210 t.Skipf("not supported on %s", runtime.GOOS)
Dmitriy Vyukov74fcf822012-11-25 13:27:32 +0400211 }
Mikio Hara98e05562015-04-28 21:17:46 +0900212
213 ln, err := newLocalListener("tcp")
214 if err != nil {
215 t.Fatal(err)
216 }
217 defer ln.Close()
218
219 max := time.NewTimer(100 * time.Millisecond)
220 defer max.Stop()
221 ch := make(chan error)
222 go func() {
223 if err := ln.(*TCPListener).SetDeadline(time.Now().Add(-5 * time.Second)); err != nil {
224 t.Error(err)
225 }
226 if err := ln.(*TCPListener).SetDeadline(noDeadline); err != nil {
227 t.Error(err)
228 }
229 _, err := ln.Accept()
230 ch <- err
231 }()
232
233 select {
234 case err := <-ch:
235 if perr := parseAcceptError(err); perr != nil {
236 t.Error(perr)
237 }
238 t.Fatalf("expected Accept to not return, but it returned with %v", err)
239 case <-max.C:
240 ln.Close()
241 <-ch // wait for tester goroutine to stop
242 }
243}
244
245var readTimeoutTests = []struct {
246 timeout time.Duration
247 xerrs [2]error // expected errors in transition
248}{
249 // Tests that read deadlines work, even if there's data ready
250 // to be read.
251 {-5 * time.Second, [2]error{errTimeout, errTimeout}},
252
253 {50 * time.Millisecond, [2]error{nil, errTimeout}},
Dmitriy Vyukov74fcf822012-11-25 13:27:32 +0400254}
255
256func TestReadTimeout(t *testing.T) {
257 switch runtime.GOOS {
258 case "plan9":
Mikio Hara98e05562015-04-28 21:17:46 +0900259 t.Skipf("not supported on %s", runtime.GOOS)
Dmitriy Vyukov74fcf822012-11-25 13:27:32 +0400260 }
261
Mikio Hara98e05562015-04-28 21:17:46 +0900262 handler := func(ls *localServer, ln Listener) {
263 c, err := ln.Accept()
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800264 if err != nil {
265 t.Error(err)
Mikio Hara98e05562015-04-28 21:17:46 +0900266 return
Brad Fitzpatrickb71883e2012-01-18 16:24:06 -0800267 }
Mikio Hara98e05562015-04-28 21:17:46 +0900268 c.Write([]byte("READ TIMEOUT TEST"))
269 defer c.Close()
Mikio Hara15648d22015-04-21 22:10:09 +0900270 }
271 ls, err := newLocalServer("tcp")
272 if err != nil {
273 t.Fatal(err)
274 }
275 defer ls.teardown()
276 if err := ls.buildup(handler); err != nil {
277 t.Fatal(err)
278 }
Russ Coxe46e1922011-01-26 12:38:06 -0500279
Mikio Hara98e05562015-04-28 21:17:46 +0900280 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
Brad Fitzpatrickfe30ed22012-01-24 14:06:12 -0800281 if err != nil {
282 t.Fatal(err)
283 }
Mikio Hara98e05562015-04-28 21:17:46 +0900284 defer c.Close()
285
286 for i, tt := range readTimeoutTests {
287 if err := c.SetReadDeadline(time.Now().Add(tt.timeout)); err != nil {
288 t.Fatalf("#%d: %v", i, err)
289 }
290 var b [1]byte
291 for j, xerr := range tt.xerrs {
292 for {
293 n, err := c.Read(b[:])
294 if xerr != nil {
295 if perr := parseReadError(err); perr != nil {
296 t.Errorf("#%d/%d: %v", i, j, perr)
297 }
298 if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
299 t.Fatalf("#%d/%d: %v", i, j, err)
300 }
301 }
302 if err == nil {
303 time.Sleep(tt.timeout / 3)
304 continue
305 }
306 if n != 0 {
307 t.Fatalf("#%d/%d: read %d; want 0", i, j, n)
308 }
309 break
310 }
311 }
Brad Fitzpatrickfe30ed22012-01-24 14:06:12 -0800312 }
313}
Alexey Borzenkovd12a7d32012-10-31 09:58:05 +1100314
Mikio Hara98e05562015-04-28 21:17:46 +0900315func TestReadTimeoutMustNotReturn(t *testing.T) {
Alexey Borzenkovd12a7d32012-10-31 09:58:05 +1100316 switch runtime.GOOS {
317 case "plan9":
Mikio Hara98e05562015-04-28 21:17:46 +0900318 t.Skipf("not supported on %s", runtime.GOOS)
Alexey Borzenkovd12a7d32012-10-31 09:58:05 +1100319 }
Mikio Hara4540e162015-04-17 14:35:54 +0900320
321 ln, err := newLocalListener("tcp")
Alexey Borzenkovd12a7d32012-10-31 09:58:05 +1100322 if err != nil {
323 t.Fatal(err)
324 }
325 defer ln.Close()
Alex Brainmanfa3e4fc2012-10-31 10:24:37 +1100326
Mikio Hara98e05562015-04-28 21:17:46 +0900327 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
Alex Brainmanfa3e4fc2012-10-31 10:24:37 +1100328 if err != nil {
Mikio Hara98e05562015-04-28 21:17:46 +0900329 t.Fatal(err)
Alex Brainmanfa3e4fc2012-10-31 10:24:37 +1100330 }
331 defer c.Close()
332
Mikio Hara98e05562015-04-28 21:17:46 +0900333 max := time.NewTimer(100 * time.Millisecond)
334 defer max.Stop()
335 ch := make(chan error)
Alex Brainmanfa3e4fc2012-10-31 10:24:37 +1100336 go func() {
Mikio Hara98e05562015-04-28 21:17:46 +0900337 if err := c.SetDeadline(time.Now().Add(-5 * time.Second)); err != nil {
338 t.Error(err)
Alex Brainmanfa3e4fc2012-10-31 10:24:37 +1100339 }
Mikio Hara98e05562015-04-28 21:17:46 +0900340 if err := c.SetWriteDeadline(time.Now().Add(-5 * time.Second)); err != nil {
341 t.Error(err)
342 }
343 if err := c.SetReadDeadline(noDeadline); err != nil {
344 t.Error(err)
345 }
346 var b [1]byte
347 _, err := c.Read(b[:])
348 ch <- err
Alex Brainmanfa3e4fc2012-10-31 10:24:37 +1100349 }()
350
Mikio Hara98e05562015-04-28 21:17:46 +0900351 select {
352 case err := <-ch:
353 if perr := parseReadError(err); perr != nil {
354 t.Error(perr)
355 }
356 t.Fatalf("expected Read to not return, but it returned with %v", err)
357 case <-max.C:
358 c.Close()
359 err := <-ch // wait for tester goroutine to stop
360 if perr := parseReadError(err); perr != nil {
361 t.Error(perr)
362 }
363 if err == io.EOF && runtime.GOOS == "nacl" { // see golang.org/issue/8044
364 return
365 }
366 if nerr, ok := err.(Error); !ok || nerr.Timeout() || nerr.Temporary() {
367 t.Fatal(err)
368 }
369 }
370}
371
Mikio Hara2708f192015-05-02 17:58:06 +0900372var readFromTimeoutTests = []struct {
373 timeout time.Duration
374 xerrs [2]error // expected errors in transition
375}{
376 // Tests that read deadlines work, even if there's data ready
377 // to be read.
378 {-5 * time.Second, [2]error{errTimeout, errTimeout}},
379
380 {50 * time.Millisecond, [2]error{nil, errTimeout}},
381}
382
383func TestReadFromTimeout(t *testing.T) {
384 switch runtime.GOOS {
385 case "nacl", "plan9":
386 t.Skipf("not supported on %s", runtime.GOOS) // see golang.org/issue/8916
387 }
388
389 ch := make(chan Addr)
390 defer close(ch)
391 handler := func(ls *localPacketServer, c PacketConn) {
392 if dst, ok := <-ch; ok {
393 c.WriteTo([]byte("READFROM TIMEOUT TEST"), dst)
394 }
395 }
396 ls, err := newLocalPacketServer("udp")
397 if err != nil {
398 t.Fatal(err)
399 }
400 defer ls.teardown()
401 if err := ls.buildup(handler); err != nil {
402 t.Fatal(err)
403 }
404
405 host, _, err := SplitHostPort(ls.PacketConn.LocalAddr().String())
406 if err != nil {
407 t.Fatal(err)
408 }
409 c, err := ListenPacket(ls.PacketConn.LocalAddr().Network(), JoinHostPort(host, "0"))
410 if err != nil {
411 t.Fatal(err)
412 }
413 defer c.Close()
414 ch <- c.LocalAddr()
415
416 for i, tt := range readFromTimeoutTests {
417 if err := c.SetReadDeadline(time.Now().Add(tt.timeout)); err != nil {
418 t.Fatalf("#%d: %v", i, err)
419 }
420 var b [1]byte
421 for j, xerr := range tt.xerrs {
422 for {
423 n, _, err := c.ReadFrom(b[:])
424 if xerr != nil {
425 if perr := parseReadError(err); perr != nil {
426 t.Errorf("#%d/%d: %v", i, j, perr)
427 }
428 if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
429 t.Fatalf("#%d/%d: %v", i, j, err)
430 }
431 }
432 if err == nil {
433 time.Sleep(tt.timeout / 3)
434 continue
435 }
436 if n != 0 {
437 t.Fatalf("#%d/%d: read %d; want 0", i, j, n)
438 }
439 break
440 }
441 }
442 }
443}
444
Mikio Hara98e05562015-04-28 21:17:46 +0900445var writeTimeoutTests = []struct {
446 timeout time.Duration
447 xerrs [2]error // expected errors in transition
448}{
449 // Tests that write deadlines work, even if there's buffer
450 // space available to write.
451 {-5 * time.Second, [2]error{errTimeout, errTimeout}},
452
453 {10 * time.Millisecond, [2]error{nil, errTimeout}},
454}
455
456func TestWriteTimeout(t *testing.T) {
457 switch runtime.GOOS {
458 case "plan9":
459 t.Skipf("not supported on %s", runtime.GOOS)
460 }
461
462 ln, err := newLocalListener("tcp")
463 if err != nil {
464 t.Fatal(err)
465 }
466 defer ln.Close()
467
468 for i, tt := range writeTimeoutTests {
469 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
470 if err != nil {
471 t.Fatal(err)
472 }
473 defer c.Close()
474
475 if err := c.SetWriteDeadline(time.Now().Add(tt.timeout)); err != nil {
476 t.Fatalf("#%d: %v", i, err)
477 }
478 for j, xerr := range tt.xerrs {
479 for {
480 n, err := c.Write([]byte("WRITE TIMEOUT TEST"))
481 if xerr != nil {
482 if perr := parseWriteError(err); perr != nil {
483 t.Errorf("#%d/%d: %v", i, j, perr)
484 }
485 if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
486 t.Fatalf("#%d/%d: %v", i, j, err)
487 }
488 }
489 if err == nil {
490 time.Sleep(tt.timeout / 3)
491 continue
492 }
493 if n != 0 {
494 t.Fatalf("#%d/%d: wrote %d; want 0", i, j, n)
495 }
Alex Brainmanfa3e4fc2012-10-31 10:24:37 +1100496 break
497 }
498 }
Mikio Hara98e05562015-04-28 21:17:46 +0900499 }
Alex Brainmanfa3e4fc2012-10-31 10:24:37 +1100500}
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800501
Mikio Hara98e05562015-04-28 21:17:46 +0900502func TestWriteTimeoutMustNotReturn(t *testing.T) {
503 switch runtime.GOOS {
504 case "plan9":
505 t.Skipf("not supported on %s", runtime.GOOS)
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800506 }
Mikio Hara98e05562015-04-28 21:17:46 +0900507
508 ln, err := newLocalListener("tcp")
509 if err != nil {
510 t.Fatal(err)
511 }
512 defer ln.Close()
513
514 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
515 if err != nil {
516 t.Fatal(err)
517 }
518 defer c.Close()
519
520 max := time.NewTimer(100 * time.Millisecond)
521 defer max.Stop()
522 ch := make(chan error)
523 go func() {
524 if err := c.SetDeadline(time.Now().Add(-5 * time.Second)); err != nil {
525 t.Error(err)
526 }
527 if err := c.SetReadDeadline(time.Now().Add(-5 * time.Second)); err != nil {
528 t.Error(err)
529 }
530 if err := c.SetWriteDeadline(noDeadline); err != nil {
531 t.Error(err)
532 }
533 var b [1]byte
534 for {
535 if _, err := c.Write(b[:]); err != nil {
536 ch <- err
537 break
538 }
539 }
540 }()
541
542 select {
543 case err := <-ch:
544 if perr := parseWriteError(err); perr != nil {
545 t.Error(perr)
546 }
547 t.Fatalf("expected Write to not return, but it returned with %v", err)
548 case <-max.C:
549 c.Close()
550 err := <-ch // wait for tester goroutine to stop
551 if perr := parseWriteError(err); perr != nil {
552 t.Error(perr)
553 }
554 if nerr, ok := err.(Error); !ok || nerr.Timeout() || nerr.Temporary() {
555 t.Fatal(err)
556 }
557 }
558}
559
Mikio Hara2708f192015-05-02 17:58:06 +0900560var writeToTimeoutTests = []struct {
561 timeout time.Duration
562 xerrs [2]error // expected errors in transition
563}{
564 // Tests that write deadlines work, even if there's buffer
565 // space available to write.
566 {-5 * time.Second, [2]error{errTimeout, errTimeout}},
567
568 {10 * time.Millisecond, [2]error{nil, errTimeout}},
569}
570
571func TestWriteToTimeout(t *testing.T) {
572 switch runtime.GOOS {
573 case "nacl", "plan9":
574 t.Skipf("not supported on %s", runtime.GOOS)
575 }
576
577 c1, err := newLocalPacketListener("udp")
578 if err != nil {
579 t.Fatal(err)
580 }
581 defer c1.Close()
582
583 host, _, err := SplitHostPort(c1.LocalAddr().String())
584 if err != nil {
585 t.Fatal(err)
586 }
587
588 for i, tt := range writeToTimeoutTests {
589 c2, err := ListenPacket(c1.LocalAddr().Network(), JoinHostPort(host, "0"))
590 if err != nil {
591 t.Fatal(err)
592 }
593 defer c2.Close()
594
595 if err := c2.SetWriteDeadline(time.Now().Add(tt.timeout)); err != nil {
596 t.Fatalf("#%d: %v", i, err)
597 }
598 for j, xerr := range tt.xerrs {
599 for {
600 n, err := c2.WriteTo([]byte("WRITETO TIMEOUT TEST"), c1.LocalAddr())
601 if xerr != nil {
602 if perr := parseWriteError(err); perr != nil {
603 t.Errorf("#%d/%d: %v", i, j, perr)
604 }
605 if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
606 t.Fatalf("#%d/%d: %v", i, j, err)
607 }
608 }
609 if err == nil {
610 time.Sleep(tt.timeout / 3)
611 continue
612 }
613 if n != 0 {
614 t.Fatalf("#%d/%d: wrote %d; want 0", i, j, n)
615 }
616 break
617 }
618 }
619 }
620}
621
Mikio Hara98e05562015-04-28 21:17:46 +0900622func TestReadTimeoutFluctuation(t *testing.T) {
623 switch runtime.GOOS {
624 case "plan9":
625 t.Skipf("not supported on %s", runtime.GOOS)
626 }
627
628 ln, err := newLocalListener("tcp")
629 if err != nil {
630 t.Fatal(err)
631 }
632 defer ln.Close()
633
634 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
635 if err != nil {
636 t.Fatal(err)
637 }
638 defer c.Close()
639
640 max := time.NewTimer(time.Second)
641 defer max.Stop()
642 ch := make(chan error)
643 go timeoutReceiver(c, 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
644
645 select {
646 case <-max.C:
647 t.Fatal("Read took over 1s; expected 0.1s")
648 case err := <-ch:
649 if perr := parseReadError(err); perr != nil {
650 t.Error(perr)
651 }
652 if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
653 t.Fatal(err)
654 }
655 }
656}
657
658func TestReadFromTimeoutFluctuation(t *testing.T) {
659 switch runtime.GOOS {
660 case "plan9":
661 t.Skipf("not supported on %s", runtime.GOOS)
662 }
663
664 c1, err := newLocalPacketListener("udp")
665 if err != nil {
666 t.Fatal(err)
667 }
668 defer c1.Close()
669
670 c2, err := Dial(c1.LocalAddr().Network(), c1.LocalAddr().String())
671 if err != nil {
672 t.Fatal(err)
673 }
674 defer c2.Close()
675
676 max := time.NewTimer(time.Second)
677 defer max.Stop()
678 ch := make(chan error)
679 go timeoutPacketReceiver(c2.(PacketConn), 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
680
681 select {
682 case <-max.C:
683 t.Fatal("ReadFrom took over 1s; expected 0.1s")
684 case err := <-ch:
685 if perr := parseReadError(err); perr != nil {
686 t.Error(perr)
687 }
688 if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
689 t.Fatal(err)
690 }
691 }
692}
693
694func TestWriteTimeoutFluctuation(t *testing.T) {
695 switch runtime.GOOS {
696 case "plan9":
697 t.Skipf("not supported on %s", runtime.GOOS)
698 }
699
700 ln, err := newLocalListener("tcp")
701 if err != nil {
702 t.Fatal(err)
703 }
704 defer ln.Close()
705
706 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
707 if err != nil {
708 t.Fatal(err)
709 }
710 defer c.Close()
711
Mikio Haracbcc7582015-05-10 23:11:04 +0900712 d := time.Second
713 if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
714 d = 3 * time.Second // see golang.org/issue/10775
715 }
716 max := time.NewTimer(d)
Mikio Hara98e05562015-04-28 21:17:46 +0900717 defer max.Stop()
718 ch := make(chan error)
719 go timeoutTransmitter(c, 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
720
721 select {
722 case <-max.C:
Mikio Haracbcc7582015-05-10 23:11:04 +0900723 t.Fatalf("Write took over %v; expected 0.1s", d)
Mikio Hara98e05562015-04-28 21:17:46 +0900724 case err := <-ch:
725 if perr := parseWriteError(err); perr != nil {
726 t.Error(perr)
727 }
728 if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
729 t.Fatal(err)
730 }
731 }
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800732}
733
734func TestVariousDeadlines1Proc(t *testing.T) {
735 testVariousDeadlines(t, 1)
736}
737
738func TestVariousDeadlines4Proc(t *testing.T) {
739 testVariousDeadlines(t, 4)
740}
741
Mikio Hara98e05562015-04-28 21:17:46 +0900742type neverEnding byte
743
744func (b neverEnding) Read(p []byte) (int, error) {
745 for i := range p {
746 p[i] = byte(b)
747 }
748 return len(p), nil
749}
750
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800751func testVariousDeadlines(t *testing.T, maxProcs int) {
Akshat Kumarb2249f22013-02-28 07:18:02 +0100752 switch runtime.GOOS {
753 case "plan9":
Mikio Hara98e05562015-04-28 21:17:46 +0900754 t.Skipf("not supported on %s", runtime.GOOS)
Akshat Kumarb2249f22013-02-28 07:18:02 +0100755 }
756
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800757 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800758
Mikio Hara98e05562015-04-28 21:17:46 +0900759 type result struct {
760 n int64
761 err error
762 d time.Duration
763 }
764
765 ch := make(chan error, 1)
766 pasvch := make(chan result)
Mikio Haraf0775052015-04-02 23:11:39 +0900767 handler := func(ls *localServer, ln Listener) {
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800768 for {
769 c, err := ln.Accept()
770 if err != nil {
Mikio Hara98e05562015-04-28 21:17:46 +0900771 ch <- err
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800772 return
773 }
Mikio Hara98e05562015-04-28 21:17:46 +0900774 // The server, with no timeouts of its own,
775 // sending bytes to clients as fast as it can.
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800776 go func() {
777 t0 := time.Now()
778 n, err := io.Copy(c, neverEnding('a'))
Mikio Hara98e05562015-04-28 21:17:46 +0900779 dt := time.Since(t0)
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800780 c.Close()
Mikio Hara98e05562015-04-28 21:17:46 +0900781 pasvch <- result{n, err, dt}
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800782 }()
783 }
Mikio Haraf0775052015-04-02 23:11:39 +0900784 }
785 ls, err := newLocalServer("tcp")
786 if err != nil {
787 t.Fatal(err)
788 }
789 defer ls.teardown()
790 if err := ls.buildup(handler); err != nil {
791 t.Fatal(err)
792 }
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800793
794 for _, timeout := range []time.Duration{
795 1 * time.Nanosecond,
796 2 * time.Nanosecond,
797 5 * time.Nanosecond,
798 50 * time.Nanosecond,
799 100 * time.Nanosecond,
800 200 * time.Nanosecond,
801 500 * time.Nanosecond,
802 750 * time.Nanosecond,
803 1 * time.Microsecond,
804 5 * time.Microsecond,
805 25 * time.Microsecond,
806 250 * time.Microsecond,
807 500 * time.Microsecond,
808 1 * time.Millisecond,
809 5 * time.Millisecond,
810 100 * time.Millisecond,
811 250 * time.Millisecond,
812 500 * time.Millisecond,
813 1 * time.Second,
814 } {
815 numRuns := 3
816 if testing.Short() {
817 numRuns = 1
818 if timeout > 500*time.Microsecond {
819 continue
820 }
821 }
822 for run := 0; run < numRuns; run++ {
823 name := fmt.Sprintf("%v run %d/%d", timeout, run+1, numRuns)
824 t.Log(name)
825
Mikio Hara98e05562015-04-28 21:17:46 +0900826 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800827 if err != nil {
Mikio Hara98e05562015-04-28 21:17:46 +0900828 t.Fatal(err)
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800829 }
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800830
Josh Bleecher Snyder9cddb602014-04-21 13:07:51 -0700831 tooLong := 5 * time.Second
Mikio Hara98e05562015-04-28 21:17:46 +0900832 max := time.NewTimer(tooLong)
833 defer max.Stop()
834 actvch := make(chan result)
835 go func() {
836 t0 := time.Now()
837 if err := c.SetDeadline(t0.Add(timeout)); err != nil {
838 t.Error(err)
839 }
840 n, err := io.Copy(ioutil.Discard, c)
841 dt := time.Since(t0)
842 c.Close()
843 actvch <- result{n, err, dt}
844 }()
845
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800846 select {
Mikio Hara98e05562015-04-28 21:17:46 +0900847 case res := <-actvch:
848 if nerr, ok := res.err.(Error); ok && nerr.Timeout() {
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800849 t.Logf("for %v, good client timeout after %v, reading %d bytes", name, res.d, res.n)
850 } else {
Mikio Hara98e05562015-04-28 21:17:46 +0900851 t.Fatalf("for %v, client Copy = %d, %v; want timeout", name, res.n, res.err)
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800852 }
Mikio Hara98e05562015-04-28 21:17:46 +0900853 case <-max.C:
854 t.Fatalf("for %v, timeout (%v) waiting for client to timeout (%v) reading", name, tooLong, timeout)
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800855 }
856
857 select {
Mikio Hara98e05562015-04-28 21:17:46 +0900858 case res := <-pasvch:
859 t.Logf("for %v, server in %v wrote %d: %v", name, res.d, res.n, res.err)
860 case err := <-ch:
861 t.Fatalf("for %v, Accept = %v", name, err)
862 case <-max.C:
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800863 t.Fatalf("for %v, timeout waiting for server to finish writing", name)
864 }
865 }
866 }
867}
868
Mikio Hara98e05562015-04-28 21:17:46 +0900869// TestReadWriteProlongedTimeout tests concurrent deadline
870// modification. Known to cause data races in the past.
871func TestReadWriteProlongedTimeout(t *testing.T) {
Akshat Kumarb2249f22013-02-28 07:18:02 +0100872 switch runtime.GOOS {
873 case "plan9":
Mikio Hara98e05562015-04-28 21:17:46 +0900874 t.Skipf("not supported on %s", runtime.GOOS)
Akshat Kumarb2249f22013-02-28 07:18:02 +0100875 }
876
Mikio Haraf0775052015-04-02 23:11:39 +0900877 handler := func(ls *localServer, ln Listener) {
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800878 c, err := ln.Accept()
879 if err != nil {
Mikio Hara98e05562015-04-28 21:17:46 +0900880 t.Error(err)
Mikio Haraf0433e42014-03-15 13:43:02 +0900881 return
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800882 }
883 defer c.Close()
Brad Fitzpatrick5fa3aeb2012-11-23 22:15:26 -0800884
Mikio Hara98e05562015-04-28 21:17:46 +0900885 var wg sync.WaitGroup
886 wg.Add(2)
Dmitriy Vyukovf4ed50c2012-11-26 22:28:39 +0400887 go func() {
Mikio Hara98e05562015-04-28 21:17:46 +0900888 defer wg.Done()
889 var b [1]byte
Dmitriy Vyukovf4ed50c2012-11-26 22:28:39 +0400890 for {
Mikio Hara98e05562015-04-28 21:17:46 +0900891 if err := c.SetReadDeadline(time.Now().Add(time.Hour)); err != nil {
892 if perr := parseCommonError(err); perr != nil {
893 t.Error(perr)
894 }
895 t.Error(err)
896 return
Dmitriy Vyukovf4ed50c2012-11-26 22:28:39 +0400897 }
Mikio Hara98e05562015-04-28 21:17:46 +0900898 if _, err := c.Read(b[:]); err != nil {
899 if perr := parseReadError(err); perr != nil {
900 t.Error(perr)
901 }
902 return
903 }
Dmitriy Vyukovf4ed50c2012-11-26 22:28:39 +0400904 }
905 }()
Mikio Hara98e05562015-04-28 21:17:46 +0900906 go func() {
907 defer wg.Done()
908 var b [1]byte
909 for {
910 if err := c.SetWriteDeadline(time.Now().Add(time.Hour)); err != nil {
911 if perr := parseCommonError(err); perr != nil {
912 t.Error(perr)
913 }
914 t.Error(err)
915 return
916 }
917 if _, err := c.Write(b[:]); err != nil {
918 if perr := parseWriteError(err); perr != nil {
919 t.Error(perr)
920 }
921 return
922 }
Dmitriy Vyukovf4ed50c2012-11-26 22:28:39 +0400923 }
Mikio Hara98e05562015-04-28 21:17:46 +0900924 }()
925 wg.Wait()
Mikio Haraf0775052015-04-02 23:11:39 +0900926 }
927 ls, err := newLocalServer("tcp")
928 if err != nil {
929 t.Fatal(err)
930 }
931 defer ls.teardown()
932 if err := ls.buildup(handler); err != nil {
933 t.Fatal(err)
934 }
935
Mikio Hara98e05562015-04-28 21:17:46 +0900936 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
Dmitriy Vyukovf4ed50c2012-11-26 22:28:39 +0400937 if err != nil {
Mikio Hara98e05562015-04-28 21:17:46 +0900938 t.Fatal(err)
Dmitriy Vyukovf4ed50c2012-11-26 22:28:39 +0400939 }
940 defer c.Close()
Mikio Hara98e05562015-04-28 21:17:46 +0900941
942 var b [1]byte
943 for i := 0; i < 1000; i++ {
944 c.Write(b[:])
945 c.Read(b[:])
Dmitriy Vyukovf4ed50c2012-11-26 22:28:39 +0400946 }
947}
Dmitriy Vyukov9707f262013-08-13 12:55:57 +0400948
Mikio Hara98e05562015-04-28 21:17:46 +0900949func TestReadWriteDeadlineRace(t *testing.T) {
Dmitriy Vyukov9707f262013-08-13 12:55:57 +0400950 switch runtime.GOOS {
Russ Cox0c2a7272014-05-20 12:10:19 -0400951 case "nacl", "plan9":
Mikio Hara98e05562015-04-28 21:17:46 +0900952 t.Skipf("not supported on %s", runtime.GOOS)
Dmitriy Vyukov9707f262013-08-13 12:55:57 +0400953 }
954
Dmitriy Vyukov9bbf1e12013-08-14 21:20:11 +0400955 N := 1000
956 if testing.Short() {
957 N = 50
958 }
Dmitriy Vyukov9707f262013-08-13 12:55:57 +0400959 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
Mikio Hara98e05562015-04-28 21:17:46 +0900960
Mikio Haraf0775052015-04-02 23:11:39 +0900961 ln, err := newLocalListener("tcp")
962 if err != nil {
963 t.Fatal(err)
964 }
Dmitriy Vyukov9707f262013-08-13 12:55:57 +0400965 defer ln.Close()
Mikio Hara98e05562015-04-28 21:17:46 +0900966
967 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
Dmitriy Vyukov9707f262013-08-13 12:55:57 +0400968 if err != nil {
Mikio Hara98e05562015-04-28 21:17:46 +0900969 t.Fatal(err)
Dmitriy Vyukov9707f262013-08-13 12:55:57 +0400970 }
971 defer c.Close()
Mikio Hara98e05562015-04-28 21:17:46 +0900972
973 var wg sync.WaitGroup
974 wg.Add(3)
Dmitriy Vyukov9707f262013-08-13 12:55:57 +0400975 go func() {
Mikio Hara98e05562015-04-28 21:17:46 +0900976 defer wg.Done()
977 tic := time.NewTicker(2 * time.Microsecond)
978 defer tic.Stop()
Dmitriy Vyukov9bbf1e12013-08-14 21:20:11 +0400979 for i := 0; i < N; i++ {
Mikio Hara98e05562015-04-28 21:17:46 +0900980 if err := c.SetReadDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
981 if perr := parseCommonError(err); perr != nil {
982 t.Error(perr)
983 }
Dmitriy Vyukov9707f262013-08-13 12:55:57 +0400984 break
985 }
Mikio Hara98e05562015-04-28 21:17:46 +0900986 if err := c.SetWriteDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
987 if perr := parseCommonError(err); perr != nil {
988 t.Error(perr)
989 }
990 break
991 }
992 <-tic.C
Dmitriy Vyukov9707f262013-08-13 12:55:57 +0400993 }
Dmitriy Vyukov9707f262013-08-13 12:55:57 +0400994 }()
Mikio Hara98e05562015-04-28 21:17:46 +0900995 go func() {
996 defer wg.Done()
997 var b [1]byte
998 for i := 0; i < N; i++ {
999 c.Read(b[:]) // ignore possible timeout errors
1000 }
1001 }()
1002 go func() {
1003 defer wg.Done()
1004 var b [1]byte
1005 for i := 0; i < N; i++ {
1006 c.Write(b[:]) // ignore possible timeout errors
1007 }
1008 }()
1009 wg.Wait() // wait for tester goroutine to stop
Dmitriy Vyukov9707f262013-08-13 12:55:57 +04001010}