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.
15 "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 var dialTimeoutMaxDurationTests
= []struct {
97 delta time
.Duration
// for deadline
99 // Large timeouts that will overflow an int64 unix nanos.
104 func TestDialTimeoutMaxDuration(t
*testing
.T
) {
105 if runtime
.GOOS
== "openbsd" {
106 testenv
.SkipFlaky(t
, 15157)
109 ln
, err
:= newLocalListener("tcp")
115 for i
, tt
:= range dialTimeoutMaxDurationTests
{
116 ch
:= make(chan error
)
117 max
:= time
.NewTimer(250 * time
.Millisecond
)
120 d
:= Dialer
{Timeout
: tt
.timeout
}
122 d
.Deadline
= time
.Now().Add(tt
.delta
)
124 c
, err
:= d
.Dial(ln
.Addr().Network(), ln
.Addr().String())
133 t
.Fatalf("#%d: Dial didn't return in an expected time", i
)
135 if perr
:= parseDialError(err
); perr
!= nil {
139 t
.Errorf("#%d: %v", i
, err
)
145 var acceptTimeoutTests
= []struct {
146 timeout time
.Duration
147 xerrs
[2]error
// expected errors in transition
149 // Tests that accept deadlines in the past work, even if
150 // there's incoming connections available.
151 {-5 * time
.Second
, [2]error
{poll
.ErrTimeout
, poll
.ErrTimeout
}},
153 {50 * time
.Millisecond
, [2]error
{nil, poll
.ErrTimeout
}},
156 func TestAcceptTimeout(t
*testing
.T
) {
157 testenv
.SkipFlaky(t
, 17948)
160 switch runtime
.GOOS
{
162 t
.Skipf("not supported on %s", runtime
.GOOS
)
165 ln
, err
:= newLocalListener("tcp")
171 var wg sync
.WaitGroup
172 for i
, tt
:= range acceptTimeoutTests
{
177 d
:= Dialer
{Timeout
: 100 * time
.Millisecond
}
178 c
, err
:= d
.Dial(ln
.Addr().Network(), ln
.Addr().String())
187 if err
:= ln
.(*TCPListener
).SetDeadline(time
.Now().Add(tt
.timeout
)); err
!= nil {
188 t
.Fatalf("$%d: %v", i
, err
)
190 for j
, xerr
:= range tt
.xerrs
{
192 c
, err
:= ln
.Accept()
194 if perr
:= parseAcceptError(err
); perr
!= nil {
195 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
197 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
198 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
203 time
.Sleep(10 * time
.Millisecond
)
213 func TestAcceptTimeoutMustReturn(t
*testing
.T
) {
216 switch runtime
.GOOS
{
218 t
.Skipf("not supported on %s", runtime
.GOOS
)
221 ln
, err
:= newLocalListener("tcp")
227 max
:= time
.NewTimer(time
.Second
)
229 ch
:= make(chan error
)
231 if err
:= ln
.(*TCPListener
).SetDeadline(noDeadline
); err
!= nil {
234 if err
:= ln
.(*TCPListener
).SetDeadline(time
.Now().Add(10 * time
.Millisecond
)); err
!= nil {
237 c
, err
:= ln
.Accept()
247 <-ch
// wait for tester goroutine to stop
248 t
.Fatal("Accept didn't return in an expected time")
250 if perr
:= parseAcceptError(err
); perr
!= nil {
253 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
259 func TestAcceptTimeoutMustNotReturn(t
*testing
.T
) {
262 switch runtime
.GOOS
{
264 t
.Skipf("not supported on %s", runtime
.GOOS
)
267 ln
, err
:= newLocalListener("tcp")
273 max
:= time
.NewTimer(100 * time
.Millisecond
)
275 ch
:= make(chan error
)
277 if err
:= ln
.(*TCPListener
).SetDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
280 if err
:= ln
.(*TCPListener
).SetDeadline(noDeadline
); err
!= nil {
283 _
, err
:= ln
.Accept()
289 if perr
:= parseAcceptError(err
); perr
!= nil {
292 t
.Fatalf("expected Accept to not return, but it returned with %v", err
)
295 <-ch
// wait for tester goroutine to stop
299 var readTimeoutTests
= []struct {
300 timeout time
.Duration
301 xerrs
[2]error
// expected errors in transition
303 // Tests that read deadlines work, even if there's data ready
305 {-5 * time
.Second
, [2]error
{poll
.ErrTimeout
, poll
.ErrTimeout
}},
307 {50 * time
.Millisecond
, [2]error
{nil, poll
.ErrTimeout
}},
310 func TestReadTimeout(t
*testing
.T
) {
311 handler
:= func(ls
*localServer
, ln Listener
) {
312 c
, err
:= ln
.Accept()
317 c
.Write([]byte("READ TIMEOUT TEST"))
320 ls
, err
:= newLocalServer("tcp")
325 if err
:= ls
.buildup(handler
); err
!= nil {
329 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
335 for i
, tt
:= range readTimeoutTests
{
336 if err
:= c
.SetReadDeadline(time
.Now().Add(tt
.timeout
)); err
!= nil {
337 t
.Fatalf("#%d: %v", i
, err
)
340 for j
, xerr
:= range tt
.xerrs
{
342 n
, err
:= c
.Read(b
[:])
344 if perr
:= parseReadError(err
); perr
!= nil {
345 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
347 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
348 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
352 time
.Sleep(tt
.timeout
/ 3)
356 t
.Fatalf("#%d/%d: read %d; want 0", i
, j
, n
)
364 func TestReadTimeoutMustNotReturn(t
*testing
.T
) {
367 switch runtime
.GOOS
{
369 t
.Skipf("not supported on %s", runtime
.GOOS
)
372 ln
, err
:= newLocalListener("tcp")
378 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
384 max
:= time
.NewTimer(100 * time
.Millisecond
)
386 ch
:= make(chan error
)
388 if err
:= c
.SetDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
391 if err
:= c
.SetWriteDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
394 if err
:= c
.SetReadDeadline(noDeadline
); err
!= nil {
398 _
, err
:= c
.Read(b
[:])
404 if perr
:= parseReadError(err
); perr
!= nil {
407 t
.Fatalf("expected Read to not return, but it returned with %v", err
)
410 err
:= <-ch
// wait for tester goroutine to stop
411 if perr
:= parseReadError(err
); perr
!= nil {
414 if err
== io
.EOF
&& runtime
.GOOS
== "nacl" { // see golang.org/issue/8044
417 if nerr
, ok
:= err
.(Error
); !ok || nerr
.Timeout() || nerr
.Temporary() {
423 var readFromTimeoutTests
= []struct {
424 timeout time
.Duration
425 xerrs
[2]error
// expected errors in transition
427 // Tests that read deadlines work, even if there's data ready
429 {-5 * time
.Second
, [2]error
{poll
.ErrTimeout
, poll
.ErrTimeout
}},
431 {50 * time
.Millisecond
, [2]error
{nil, poll
.ErrTimeout
}},
434 func TestReadFromTimeout(t
*testing
.T
) {
435 switch runtime
.GOOS
{
437 t
.Skipf("not supported on %s", runtime
.GOOS
) // see golang.org/issue/8916
440 ch
:= make(chan Addr
)
442 handler
:= func(ls
*localPacketServer
, c PacketConn
) {
443 if dst
, ok
:= <-ch
; ok
{
444 c
.WriteTo([]byte("READFROM TIMEOUT TEST"), dst
)
447 ls
, err
:= newLocalPacketServer("udp")
452 if err
:= ls
.buildup(handler
); err
!= nil {
456 host
, _
, err
:= SplitHostPort(ls
.PacketConn
.LocalAddr().String())
460 c
, err
:= ListenPacket(ls
.PacketConn
.LocalAddr().Network(), JoinHostPort(host
, "0"))
467 for i
, tt
:= range readFromTimeoutTests
{
468 if err
:= c
.SetReadDeadline(time
.Now().Add(tt
.timeout
)); err
!= nil {
469 t
.Fatalf("#%d: %v", i
, err
)
472 for j
, xerr
:= range tt
.xerrs
{
474 n
, _
, err
:= c
.ReadFrom(b
[:])
476 if perr
:= parseReadError(err
); perr
!= nil {
477 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
479 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
480 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
484 time
.Sleep(tt
.timeout
/ 3)
487 if nerr
, ok
:= err
.(Error
); ok
&& nerr
.Timeout() && n
!= 0 {
488 t
.Fatalf("#%d/%d: read %d; want 0", i
, j
, n
)
496 var writeTimeoutTests
= []struct {
497 timeout time
.Duration
498 xerrs
[2]error
// expected errors in transition
500 // Tests that write deadlines work, even if there's buffer
501 // space available to write.
502 {-5 * time
.Second
, [2]error
{poll
.ErrTimeout
, poll
.ErrTimeout
}},
504 {10 * time
.Millisecond
, [2]error
{nil, poll
.ErrTimeout
}},
507 func TestWriteTimeout(t
*testing
.T
) {
510 ln
, err
:= newLocalListener("tcp")
516 for i
, tt
:= range writeTimeoutTests
{
517 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
523 if err
:= c
.SetWriteDeadline(time
.Now().Add(tt
.timeout
)); err
!= nil {
524 t
.Fatalf("#%d: %v", i
, err
)
526 for j
, xerr
:= range tt
.xerrs
{
528 n
, err
:= c
.Write([]byte("WRITE TIMEOUT TEST"))
530 if perr
:= parseWriteError(err
); perr
!= nil {
531 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
533 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
534 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
538 time
.Sleep(tt
.timeout
/ 3)
542 t
.Fatalf("#%d/%d: wrote %d; want 0", i
, j
, n
)
550 func TestWriteTimeoutMustNotReturn(t
*testing
.T
) {
553 switch runtime
.GOOS
{
555 t
.Skipf("not supported on %s", runtime
.GOOS
)
558 ln
, err
:= newLocalListener("tcp")
564 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
570 max
:= time
.NewTimer(100 * time
.Millisecond
)
572 ch
:= make(chan error
)
574 if err
:= c
.SetDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
577 if err
:= c
.SetReadDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
580 if err
:= c
.SetWriteDeadline(noDeadline
); err
!= nil {
585 if _
, err
:= c
.Write(b
[:]); err
!= nil {
594 if perr
:= parseWriteError(err
); perr
!= nil {
597 t
.Fatalf("expected Write to not return, but it returned with %v", err
)
600 err
:= <-ch
// wait for tester goroutine to stop
601 if perr
:= parseWriteError(err
); perr
!= nil {
604 if nerr
, ok
:= err
.(Error
); !ok || nerr
.Timeout() || nerr
.Temporary() {
610 var writeToTimeoutTests
= []struct {
611 timeout time
.Duration
612 xerrs
[2]error
// expected errors in transition
614 // Tests that write deadlines work, even if there's buffer
615 // space available to write.
616 {-5 * time
.Second
, [2]error
{poll
.ErrTimeout
, poll
.ErrTimeout
}},
618 {10 * time
.Millisecond
, [2]error
{nil, poll
.ErrTimeout
}},
621 func TestWriteToTimeout(t
*testing
.T
) {
624 switch runtime
.GOOS
{
626 t
.Skipf("not supported on %s", runtime
.GOOS
)
629 c1
, err
:= newLocalPacketListener("udp")
635 host
, _
, err
:= SplitHostPort(c1
.LocalAddr().String())
640 for i
, tt
:= range writeToTimeoutTests
{
641 c2
, err
:= ListenPacket(c1
.LocalAddr().Network(), JoinHostPort(host
, "0"))
647 if err
:= c2
.SetWriteDeadline(time
.Now().Add(tt
.timeout
)); err
!= nil {
648 t
.Fatalf("#%d: %v", i
, err
)
650 for j
, xerr
:= range tt
.xerrs
{
652 n
, err
:= c2
.WriteTo([]byte("WRITETO TIMEOUT TEST"), c1
.LocalAddr())
654 if perr
:= parseWriteError(err
); perr
!= nil {
655 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
657 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
658 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
662 time
.Sleep(tt
.timeout
/ 3)
666 t
.Fatalf("#%d/%d: wrote %d; want 0", i
, j
, n
)
674 func TestReadTimeoutFluctuation(t
*testing
.T
) {
677 ln
, err
:= newLocalListener("tcp")
683 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
689 max
:= time
.NewTimer(time
.Second
)
691 ch
:= make(chan error
)
692 go timeoutReceiver(c
, 100*time
.Millisecond
, 50*time
.Millisecond
, 250*time
.Millisecond
, ch
)
696 t
.Fatal("Read took over 1s; expected 0.1s")
698 if perr
:= parseReadError(err
); perr
!= nil {
701 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
707 func TestReadFromTimeoutFluctuation(t
*testing
.T
) {
710 c1
, err
:= newLocalPacketListener("udp")
716 c2
, err
:= Dial(c1
.LocalAddr().Network(), c1
.LocalAddr().String())
722 max
:= time
.NewTimer(time
.Second
)
724 ch
:= make(chan error
)
725 go timeoutPacketReceiver(c2
.(PacketConn
), 100*time
.Millisecond
, 50*time
.Millisecond
, 250*time
.Millisecond
, ch
)
729 t
.Fatal("ReadFrom took over 1s; expected 0.1s")
731 if perr
:= parseReadError(err
); perr
!= nil {
734 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
740 func TestWriteTimeoutFluctuation(t
*testing
.T
) {
743 switch runtime
.GOOS
{
745 t
.Skipf("not supported on %s", runtime
.GOOS
)
748 ln
, err
:= newLocalListener("tcp")
754 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
761 if runtime
.GOOS
== "darwin" && (runtime
.GOARCH
== "arm" || runtime
.GOARCH
== "arm64") {
762 d
= 3 * time
.Second
// see golang.org/issue/10775
764 max
:= time
.NewTimer(d
)
766 ch
:= make(chan error
)
767 go timeoutTransmitter(c
, 100*time
.Millisecond
, 50*time
.Millisecond
, 250*time
.Millisecond
, ch
)
771 t
.Fatalf("Write took over %v; expected 0.1s", d
)
773 if perr
:= parseWriteError(err
); perr
!= nil {
776 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
782 func TestVariousDeadlines(t
*testing
.T
) {
784 testVariousDeadlines(t
)
787 func TestVariousDeadlines1Proc(t
*testing
.T
) {
788 // Cannot use t.Parallel - modifies global GOMAXPROCS.
790 t
.Skip("skipping in short mode")
792 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(1))
793 testVariousDeadlines(t
)
796 func TestVariousDeadlines4Proc(t
*testing
.T
) {
797 // Cannot use t.Parallel - modifies global GOMAXPROCS.
799 t
.Skip("skipping in short mode")
801 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(4))
802 testVariousDeadlines(t
)
805 type neverEnding
byte
807 func (b neverEnding
) Read(p
[]byte) (int, error
) {
814 func testVariousDeadlines(t
*testing
.T
) {
821 ch
:= make(chan error
, 1)
822 pasvch
:= make(chan result
)
823 handler
:= func(ls
*localServer
, ln Listener
) {
825 c
, err
:= ln
.Accept()
830 // The server, with no timeouts of its own,
831 // sending bytes to clients as fast as it can.
834 n
, err
:= io
.Copy(c
, neverEnding('a'))
837 pasvch
<- result
{n
, err
, dt
}
841 ls
, err
:= newLocalServer("tcp")
846 if err
:= ls
.buildup(handler
); err
!= nil {
850 for _
, timeout
:= range []time
.Duration
{
854 50 * time
.Nanosecond
,
855 100 * time
.Nanosecond
,
856 200 * time
.Nanosecond
,
857 500 * time
.Nanosecond
,
858 750 * time
.Nanosecond
,
859 1 * time
.Microsecond
,
860 5 * time
.Microsecond
,
861 25 * time
.Microsecond
,
862 250 * time
.Microsecond
,
863 500 * time
.Microsecond
,
864 1 * time
.Millisecond
,
865 5 * time
.Millisecond
,
866 100 * time
.Millisecond
,
867 250 * time
.Millisecond
,
868 500 * time
.Millisecond
,
874 if timeout
> 500*time
.Microsecond
{
878 for run
:= 0; run
< numRuns
; run
++ {
879 name
:= fmt
.Sprintf("%v run %d/%d", timeout
, run
+1, numRuns
)
882 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
887 tooLong
:= 5 * time
.Second
888 max
:= time
.NewTimer(tooLong
)
890 actvch
:= make(chan result
)
893 if err
:= c
.SetDeadline(t0
.Add(timeout
)); err
!= nil {
896 n
, err
:= io
.Copy(ioutil
.Discard
, c
)
899 actvch
<- result
{n
, err
, dt
}
903 case res
:= <-actvch
:
904 if nerr
, ok
:= res
.err
.(Error
); ok
&& nerr
.Timeout() {
905 t
.Logf("for %v, good client timeout after %v, reading %d bytes", name
, res
.d
, res
.n
)
907 t
.Fatalf("for %v, client Copy = %d, %v; want timeout", name
, res
.n
, res
.err
)
910 t
.Fatalf("for %v, timeout (%v) waiting for client to timeout (%v) reading", name
, tooLong
, timeout
)
914 case res
:= <-pasvch
:
915 t
.Logf("for %v, server in %v wrote %d: %v", name
, res
.d
, res
.n
, res
.err
)
917 t
.Fatalf("for %v, Accept = %v", name
, err
)
919 t
.Fatalf("for %v, timeout waiting for server to finish writing", name
)
925 // TestReadWriteProlongedTimeout tests concurrent deadline
926 // modification. Known to cause data races in the past.
927 func TestReadWriteProlongedTimeout(t
*testing
.T
) {
930 switch runtime
.GOOS
{
932 t
.Skipf("not supported on %s", runtime
.GOOS
)
935 handler
:= func(ls
*localServer
, ln Listener
) {
936 c
, err
:= ln
.Accept()
943 var wg sync
.WaitGroup
949 if err
:= c
.SetReadDeadline(time
.Now().Add(time
.Hour
)); err
!= nil {
950 if perr
:= parseCommonError(err
); perr
!= nil {
956 if _
, err
:= c
.Read(b
[:]); err
!= nil {
957 if perr
:= parseReadError(err
); perr
!= nil {
968 if err
:= c
.SetWriteDeadline(time
.Now().Add(time
.Hour
)); err
!= nil {
969 if perr
:= parseCommonError(err
); perr
!= nil {
975 if _
, err
:= c
.Write(b
[:]); err
!= nil {
976 if perr
:= parseWriteError(err
); perr
!= nil {
985 ls
, err
:= newLocalServer("tcp")
990 if err
:= ls
.buildup(handler
); err
!= nil {
994 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
1001 for i
:= 0; i
< 1000; i
++ {
1007 func TestReadWriteDeadlineRace(t
*testing
.T
) {
1010 switch runtime
.GOOS
{
1012 t
.Skipf("not supported on %s", runtime
.GOOS
)
1016 if testing
.Short() {
1020 ln
, err
:= newLocalListener("tcp")
1026 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
1032 var wg sync
.WaitGroup
1036 tic
:= time
.NewTicker(2 * time
.Microsecond
)
1038 for i
:= 0; i
< N
; i
++ {
1039 if err
:= c
.SetReadDeadline(time
.Now().Add(2 * time
.Microsecond
)); err
!= nil {
1040 if perr
:= parseCommonError(err
); perr
!= nil {
1045 if err
:= c
.SetWriteDeadline(time
.Now().Add(2 * time
.Microsecond
)); err
!= nil {
1046 if perr
:= parseCommonError(err
); perr
!= nil {
1057 for i
:= 0; i
< N
; i
++ {
1058 c
.Read(b
[:]) // ignore possible timeout errors
1064 for i
:= 0; i
< N
; i
++ {
1065 c
.Write(b
[:]) // ignore possible timeout errors
1068 wg
.Wait() // wait for tester goroutine to stop