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.
13 "net/internal/socktest"
20 var dialTimeoutTests
= []struct {
22 delta time
.Duration
// for deadline
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
},
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
39 func 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)
45 for i
, tt
:= range dialTimeoutTests
{
47 case "plan9", "windows":
48 testHookDialChannel
= func() { time
.Sleep(tt
.guard
) }
49 if runtime
.GOOS
== "plan9" {
54 sw
.Set(socktest
.FilterConnect
, func(so
*socktest
.Status
) (socktest
.AfterFilter
, error
) {
56 return nil, errTimedout
60 ch
:= make(chan error
)
61 d
:= Dialer
{Timeout
: tt
.timeout
}
63 d
.Deadline
= time
.Now().Add(tt
.delta
)
65 max
:= time
.NewTimer(tt
.max
)
68 // This dial never starts to send any TCP SYN
69 // segment because of above socket filter and
71 c
, err
:= d
.Dial("tcp", "127.0.0.1:0")
73 err
= fmt
.Errorf("unexpectedly established: tcp:%s->%s", c
.LocalAddr(), c
.RemoteAddr())
81 t
.Fatalf("#%d: Dial didn't return in an expected time", i
)
83 if perr
:= parseDialError(err
); perr
!= nil {
84 t
.Errorf("#%d: %v", i
, perr
)
86 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
87 t
.Fatalf("#%d: %v", i
, err
)
93 var dialTimeoutMaxDurationTests
= []struct {
95 delta time
.Duration
// for deadline
97 // Large timeouts that will overflow an int64 unix nanos.
102 func TestDialTimeoutMaxDuration(t
*testing
.T
) {
103 if runtime
.GOOS
== "openbsd" {
104 testenv
.SkipFlaky(t
, 15157)
107 ln
, err
:= newLocalListener("tcp")
113 for i
, tt
:= range dialTimeoutMaxDurationTests
{
114 ch
:= make(chan error
)
115 max
:= time
.NewTimer(250 * time
.Millisecond
)
118 d
:= Dialer
{Timeout
: tt
.timeout
}
120 d
.Deadline
= time
.Now().Add(tt
.delta
)
122 c
, err
:= d
.Dial(ln
.Addr().Network(), ln
.Addr().String())
131 t
.Fatalf("#%d: Dial didn't return in an expected time", i
)
133 if perr
:= parseDialError(err
); perr
!= nil {
137 t
.Errorf("#%d: %v", i
, err
)
143 var acceptTimeoutTests
= []struct {
144 timeout time
.Duration
145 xerrs
[2]error
// expected errors in transition
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
}},
151 {50 * time
.Millisecond
, [2]error
{nil, poll
.ErrTimeout
}},
154 func TestAcceptTimeout(t
*testing
.T
) {
155 testenv
.SkipFlaky(t
, 17948)
158 switch runtime
.GOOS
{
160 t
.Skipf("not supported on %s", runtime
.GOOS
)
163 ln
, err
:= newLocalListener("tcp")
169 var wg sync
.WaitGroup
170 for i
, tt
:= range acceptTimeoutTests
{
175 d
:= Dialer
{Timeout
: 100 * time
.Millisecond
}
176 c
, err
:= d
.Dial(ln
.Addr().Network(), ln
.Addr().String())
185 if err
:= ln
.(*TCPListener
).SetDeadline(time
.Now().Add(tt
.timeout
)); err
!= nil {
186 t
.Fatalf("$%d: %v", i
, err
)
188 for j
, xerr
:= range tt
.xerrs
{
190 c
, err
:= ln
.Accept()
192 if perr
:= parseAcceptError(err
); perr
!= nil {
193 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
195 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
196 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
201 time
.Sleep(10 * time
.Millisecond
)
211 func TestAcceptTimeoutMustReturn(t
*testing
.T
) {
214 switch runtime
.GOOS
{
216 t
.Skipf("not supported on %s", runtime
.GOOS
)
219 ln
, err
:= newLocalListener("tcp")
225 max
:= time
.NewTimer(time
.Second
)
227 ch
:= make(chan error
)
229 if err
:= ln
.(*TCPListener
).SetDeadline(noDeadline
); err
!= nil {
232 if err
:= ln
.(*TCPListener
).SetDeadline(time
.Now().Add(10 * time
.Millisecond
)); err
!= nil {
235 c
, err
:= ln
.Accept()
245 <-ch
// wait for tester goroutine to stop
246 t
.Fatal("Accept didn't return in an expected time")
248 if perr
:= parseAcceptError(err
); perr
!= nil {
251 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
257 func TestAcceptTimeoutMustNotReturn(t
*testing
.T
) {
260 switch runtime
.GOOS
{
262 t
.Skipf("not supported on %s", runtime
.GOOS
)
265 ln
, err
:= newLocalListener("tcp")
271 max
:= time
.NewTimer(100 * time
.Millisecond
)
273 ch
:= make(chan error
)
275 if err
:= ln
.(*TCPListener
).SetDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
278 if err
:= ln
.(*TCPListener
).SetDeadline(noDeadline
); err
!= nil {
281 _
, err
:= ln
.Accept()
287 if perr
:= parseAcceptError(err
); perr
!= nil {
290 t
.Fatalf("expected Accept to not return, but it returned with %v", err
)
293 <-ch
// wait for tester goroutine to stop
297 var readTimeoutTests
= []struct {
298 timeout time
.Duration
299 xerrs
[2]error
// expected errors in transition
301 // Tests that read deadlines work, even if there's data ready
303 {-5 * time
.Second
, [2]error
{poll
.ErrTimeout
, poll
.ErrTimeout
}},
305 {50 * time
.Millisecond
, [2]error
{nil, poll
.ErrTimeout
}},
308 func TestReadTimeout(t
*testing
.T
) {
309 handler
:= func(ls
*localServer
, ln Listener
) {
310 c
, err
:= ln
.Accept()
315 c
.Write([]byte("READ TIMEOUT TEST"))
318 ls
, err
:= newLocalServer("tcp")
323 if err
:= ls
.buildup(handler
); err
!= nil {
327 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
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
)
338 for j
, xerr
:= range tt
.xerrs
{
340 n
, err
:= c
.Read(b
[:])
342 if perr
:= parseReadError(err
); perr
!= nil {
343 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
345 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
346 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
350 time
.Sleep(tt
.timeout
/ 3)
354 t
.Fatalf("#%d/%d: read %d; want 0", i
, j
, n
)
362 func TestReadTimeoutMustNotReturn(t
*testing
.T
) {
365 switch runtime
.GOOS
{
367 t
.Skipf("not supported on %s", runtime
.GOOS
)
370 ln
, err
:= newLocalListener("tcp")
376 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
382 max
:= time
.NewTimer(100 * time
.Millisecond
)
384 ch
:= make(chan error
)
386 if err
:= c
.SetDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
389 if err
:= c
.SetWriteDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
392 if err
:= c
.SetReadDeadline(noDeadline
); err
!= nil {
396 _
, err
:= c
.Read(b
[:])
402 if perr
:= parseReadError(err
); perr
!= nil {
405 t
.Fatalf("expected Read to not return, but it returned with %v", err
)
408 err
:= <-ch
// wait for tester goroutine to stop
409 if perr
:= parseReadError(err
); perr
!= nil {
412 if err
== io
.EOF
&& runtime
.GOOS
== "nacl" { // see golang.org/issue/8044
415 if nerr
, ok
:= err
.(Error
); !ok || nerr
.Timeout() || nerr
.Temporary() {
421 var readFromTimeoutTests
= []struct {
422 timeout time
.Duration
423 xerrs
[2]error
// expected errors in transition
425 // Tests that read deadlines work, even if there's data ready
427 {-5 * time
.Second
, [2]error
{poll
.ErrTimeout
, poll
.ErrTimeout
}},
429 {50 * time
.Millisecond
, [2]error
{nil, poll
.ErrTimeout
}},
432 func TestReadFromTimeout(t
*testing
.T
) {
433 switch runtime
.GOOS
{
435 t
.Skipf("not supported on %s", runtime
.GOOS
) // see golang.org/issue/8916
438 ch
:= make(chan Addr
)
440 handler
:= func(ls
*localPacketServer
, c PacketConn
) {
441 if dst
, ok
:= <-ch
; ok
{
442 c
.WriteTo([]byte("READFROM TIMEOUT TEST"), dst
)
445 ls
, err
:= newLocalPacketServer("udp")
450 if err
:= ls
.buildup(handler
); err
!= nil {
454 host
, _
, err
:= SplitHostPort(ls
.PacketConn
.LocalAddr().String())
458 c
, err
:= ListenPacket(ls
.PacketConn
.LocalAddr().Network(), JoinHostPort(host
, "0"))
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
)
470 for j
, xerr
:= range tt
.xerrs
{
472 n
, _
, err
:= c
.ReadFrom(b
[:])
474 if perr
:= parseReadError(err
); perr
!= nil {
475 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
477 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
478 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
482 time
.Sleep(tt
.timeout
/ 3)
486 t
.Fatalf("#%d/%d: read %d; want 0", i
, j
, n
)
494 var writeTimeoutTests
= []struct {
495 timeout time
.Duration
496 xerrs
[2]error
// expected errors in transition
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
}},
502 {10 * time
.Millisecond
, [2]error
{nil, poll
.ErrTimeout
}},
505 func TestWriteTimeout(t
*testing
.T
) {
508 ln
, err
:= newLocalListener("tcp")
514 for i
, tt
:= range writeTimeoutTests
{
515 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
521 if err
:= c
.SetWriteDeadline(time
.Now().Add(tt
.timeout
)); err
!= nil {
522 t
.Fatalf("#%d: %v", i
, err
)
524 for j
, xerr
:= range tt
.xerrs
{
526 n
, err
:= c
.Write([]byte("WRITE TIMEOUT TEST"))
528 if perr
:= parseWriteError(err
); perr
!= nil {
529 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
531 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
532 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
536 time
.Sleep(tt
.timeout
/ 3)
540 t
.Fatalf("#%d/%d: wrote %d; want 0", i
, j
, n
)
548 func TestWriteTimeoutMustNotReturn(t
*testing
.T
) {
551 switch runtime
.GOOS
{
553 t
.Skipf("not supported on %s", runtime
.GOOS
)
556 ln
, err
:= newLocalListener("tcp")
562 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
568 max
:= time
.NewTimer(100 * time
.Millisecond
)
570 ch
:= make(chan error
)
572 if err
:= c
.SetDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
575 if err
:= c
.SetReadDeadline(time
.Now().Add(-5 * time
.Second
)); err
!= nil {
578 if err
:= c
.SetWriteDeadline(noDeadline
); err
!= nil {
583 if _
, err
:= c
.Write(b
[:]); err
!= nil {
592 if perr
:= parseWriteError(err
); perr
!= nil {
595 t
.Fatalf("expected Write to not return, but it returned with %v", err
)
598 err
:= <-ch
// wait for tester goroutine to stop
599 if perr
:= parseWriteError(err
); perr
!= nil {
602 if nerr
, ok
:= err
.(Error
); !ok || nerr
.Timeout() || nerr
.Temporary() {
608 var writeToTimeoutTests
= []struct {
609 timeout time
.Duration
610 xerrs
[2]error
// expected errors in transition
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
}},
616 {10 * time
.Millisecond
, [2]error
{nil, poll
.ErrTimeout
}},
619 func TestWriteToTimeout(t
*testing
.T
) {
622 switch runtime
.GOOS
{
624 t
.Skipf("not supported on %s", runtime
.GOOS
)
627 c1
, err
:= newLocalPacketListener("udp")
633 host
, _
, err
:= SplitHostPort(c1
.LocalAddr().String())
638 for i
, tt
:= range writeToTimeoutTests
{
639 c2
, err
:= ListenPacket(c1
.LocalAddr().Network(), JoinHostPort(host
, "0"))
645 if err
:= c2
.SetWriteDeadline(time
.Now().Add(tt
.timeout
)); err
!= nil {
646 t
.Fatalf("#%d: %v", i
, err
)
648 for j
, xerr
:= range tt
.xerrs
{
650 n
, err
:= c2
.WriteTo([]byte("WRITETO TIMEOUT TEST"), c1
.LocalAddr())
652 if perr
:= parseWriteError(err
); perr
!= nil {
653 t
.Errorf("#%d/%d: %v", i
, j
, perr
)
655 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
656 t
.Fatalf("#%d/%d: %v", i
, j
, err
)
660 time
.Sleep(tt
.timeout
/ 3)
664 t
.Fatalf("#%d/%d: wrote %d; want 0", i
, j
, n
)
672 func TestReadTimeoutFluctuation(t
*testing
.T
) {
675 ln
, err
:= newLocalListener("tcp")
681 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
687 max
:= time
.NewTimer(time
.Second
)
689 ch
:= make(chan error
)
690 go timeoutReceiver(c
, 100*time
.Millisecond
, 50*time
.Millisecond
, 250*time
.Millisecond
, ch
)
694 t
.Fatal("Read took over 1s; expected 0.1s")
696 if perr
:= parseReadError(err
); perr
!= nil {
699 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
705 func TestReadFromTimeoutFluctuation(t
*testing
.T
) {
708 c1
, err
:= newLocalPacketListener("udp")
714 c2
, err
:= Dial(c1
.LocalAddr().Network(), c1
.LocalAddr().String())
720 max
:= time
.NewTimer(time
.Second
)
722 ch
:= make(chan error
)
723 go timeoutPacketReceiver(c2
.(PacketConn
), 100*time
.Millisecond
, 50*time
.Millisecond
, 250*time
.Millisecond
, ch
)
727 t
.Fatal("ReadFrom took over 1s; expected 0.1s")
729 if perr
:= parseReadError(err
); perr
!= nil {
732 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
738 func TestWriteTimeoutFluctuation(t
*testing
.T
) {
741 switch runtime
.GOOS
{
743 t
.Skipf("not supported on %s", runtime
.GOOS
)
746 ln
, err
:= newLocalListener("tcp")
752 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
759 if runtime
.GOOS
== "darwin" && (runtime
.GOARCH
== "arm" || runtime
.GOARCH
== "arm64") {
760 d
= 3 * time
.Second
// see golang.org/issue/10775
762 max
:= time
.NewTimer(d
)
764 ch
:= make(chan error
)
765 go timeoutTransmitter(c
, 100*time
.Millisecond
, 50*time
.Millisecond
, 250*time
.Millisecond
, ch
)
769 t
.Fatalf("Write took over %v; expected 0.1s", d
)
771 if perr
:= parseWriteError(err
); perr
!= nil {
774 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
780 func TestVariousDeadlines(t
*testing
.T
) {
782 testVariousDeadlines(t
)
785 func TestVariousDeadlines1Proc(t
*testing
.T
) {
786 // Cannot use t.Parallel - modifies global GOMAXPROCS.
788 t
.Skip("skipping in short mode")
790 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(1))
791 testVariousDeadlines(t
)
794 func TestVariousDeadlines4Proc(t
*testing
.T
) {
795 // Cannot use t.Parallel - modifies global GOMAXPROCS.
797 t
.Skip("skipping in short mode")
799 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(4))
800 testVariousDeadlines(t
)
803 type neverEnding
byte
805 func (b neverEnding
) Read(p
[]byte) (int, error
) {
812 func testVariousDeadlines(t
*testing
.T
) {
819 ch
:= make(chan error
, 1)
820 pasvch
:= make(chan result
)
821 handler
:= func(ls
*localServer
, ln Listener
) {
823 c
, err
:= ln
.Accept()
828 // The server, with no timeouts of its own,
829 // sending bytes to clients as fast as it can.
832 n
, err
:= io
.Copy(c
, neverEnding('a'))
835 pasvch
<- result
{n
, err
, dt
}
839 ls
, err
:= newLocalServer("tcp")
844 if err
:= ls
.buildup(handler
); err
!= nil {
848 for _
, timeout
:= range []time
.Duration
{
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
,
872 if timeout
> 500*time
.Microsecond
{
876 for run
:= 0; run
< numRuns
; run
++ {
877 name
:= fmt
.Sprintf("%v run %d/%d", timeout
, run
+1, numRuns
)
880 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
885 tooLong
:= 5 * time
.Second
886 max
:= time
.NewTimer(tooLong
)
888 actvch
:= make(chan result
)
891 if err
:= c
.SetDeadline(t0
.Add(timeout
)); err
!= nil {
894 n
, err
:= io
.Copy(ioutil
.Discard
, c
)
897 actvch
<- result
{n
, err
, dt
}
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
)
905 t
.Fatalf("for %v, client Copy = %d, %v; want timeout", name
, res
.n
, res
.err
)
908 t
.Fatalf("for %v, timeout (%v) waiting for client to timeout (%v) reading", name
, tooLong
, timeout
)
912 case res
:= <-pasvch
:
913 t
.Logf("for %v, server in %v wrote %d: %v", name
, res
.d
, res
.n
, res
.err
)
915 t
.Fatalf("for %v, Accept = %v", name
, err
)
917 t
.Fatalf("for %v, timeout waiting for server to finish writing", name
)
923 // TestReadWriteProlongedTimeout tests concurrent deadline
924 // modification. Known to cause data races in the past.
925 func TestReadWriteProlongedTimeout(t
*testing
.T
) {
928 switch runtime
.GOOS
{
930 t
.Skipf("not supported on %s", runtime
.GOOS
)
933 handler
:= func(ls
*localServer
, ln Listener
) {
934 c
, err
:= ln
.Accept()
941 var wg sync
.WaitGroup
947 if err
:= c
.SetReadDeadline(time
.Now().Add(time
.Hour
)); err
!= nil {
948 if perr
:= parseCommonError(err
); perr
!= nil {
954 if _
, err
:= c
.Read(b
[:]); err
!= nil {
955 if perr
:= parseReadError(err
); perr
!= nil {
966 if err
:= c
.SetWriteDeadline(time
.Now().Add(time
.Hour
)); err
!= nil {
967 if perr
:= parseCommonError(err
); perr
!= nil {
973 if _
, err
:= c
.Write(b
[:]); err
!= nil {
974 if perr
:= parseWriteError(err
); perr
!= nil {
983 ls
, err
:= newLocalServer("tcp")
988 if err
:= ls
.buildup(handler
); err
!= nil {
992 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
999 for i
:= 0; i
< 1000; i
++ {
1005 func TestReadWriteDeadlineRace(t
*testing
.T
) {
1008 switch runtime
.GOOS
{
1010 t
.Skipf("not supported on %s", runtime
.GOOS
)
1014 if testing
.Short() {
1018 ln
, err
:= newLocalListener("tcp")
1024 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
1030 var wg sync
.WaitGroup
1034 tic
:= time
.NewTicker(2 * time
.Microsecond
)
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 {
1043 if err
:= c
.SetWriteDeadline(time
.Now().Add(2 * time
.Microsecond
)); err
!= nil {
1044 if perr
:= parseCommonError(err
); perr
!= nil {
1055 for i
:= 0; i
< N
; i
++ {
1056 c
.Read(b
[:]) // ignore possible timeout errors
1062 for i
:= 0; i
< N
; i
++ {
1063 c
.Write(b
[:]) // ignore possible timeout errors
1066 wg
.Wait() // wait for tester goroutine to stop