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