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.
14 "net/internal/socktest"
21 func TestCloseRead(t
*testing
.T
) {
24 t
.Skipf("not supported on %s", runtime
.GOOS
)
27 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
28 if !testableNetwork(network
) {
29 t
.Logf("skipping %s test", network
)
33 ln
, err
:= newLocalListener(network
)
38 case "unix", "unixpacket":
39 defer os
.Remove(ln
.Addr().String())
43 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
48 case "unix", "unixpacket":
49 defer os
.Remove(c
.LocalAddr().String())
53 switch c
:= c
.(type) {
60 if perr
:= parseCloseError(err
, true); perr
!= nil {
66 n
, err
:= c
.Read(b
[:])
67 if n
!= 0 || err
== nil {
68 t
.Fatalf("got (%d, %v); want (0, error)", n
, err
)
73 func TestCloseWrite(t
*testing
.T
) {
76 t
.Skipf("not supported on %s", runtime
.GOOS
)
79 handler
:= func(ls
*localServer
, ln Listener
) {
88 n
, err
:= c
.Read(b
[:])
89 if n
!= 0 || err
!= io
.EOF
{
90 t
.Errorf("got (%d, %v); want (0, io.EOF)", n
, err
)
93 switch c
:= c
.(type) {
100 if perr
:= parseCloseError(err
, true); perr
!= nil {
106 n
, err
= c
.Write(b
[:])
108 t
.Errorf("got (%d, %v); want (any, error)", n
, err
)
113 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
114 if !testableNetwork(network
) {
115 t
.Logf("skipping %s test", network
)
119 ls
, err
:= newLocalServer(network
)
124 if err
:= ls
.buildup(handler
); err
!= nil {
128 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
133 case "unix", "unixpacket":
134 defer os
.Remove(c
.LocalAddr().String())
138 switch c
:= c
.(type) {
145 if perr
:= parseCloseError(err
, true); perr
!= nil {
151 n
, err
:= c
.Read(b
[:])
152 if n
!= 0 || err
!= io
.EOF
{
153 t
.Fatalf("got (%d, %v); want (0, io.EOF)", n
, err
)
155 n
, err
= c
.Write(b
[:])
157 t
.Fatalf("got (%d, %v); want (any, error)", n
, err
)
162 func TestConnClose(t
*testing
.T
) {
163 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
164 if !testableNetwork(network
) {
165 t
.Logf("skipping %s test", network
)
169 ln
, err
:= newLocalListener(network
)
174 case "unix", "unixpacket":
175 defer os
.Remove(ln
.Addr().String())
179 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
184 case "unix", "unixpacket":
185 defer os
.Remove(c
.LocalAddr().String())
189 if err
:= c
.Close(); err
!= nil {
190 if perr
:= parseCloseError(err
, false); perr
!= nil {
196 n
, err
:= c
.Read(b
[:])
197 if n
!= 0 || err
== nil {
198 t
.Fatalf("got (%d, %v); want (0, error)", n
, err
)
203 func TestListenerClose(t
*testing
.T
) {
204 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
205 if !testableNetwork(network
) {
206 t
.Logf("skipping %s test", network
)
210 ln
, err
:= newLocalListener(network
)
215 case "unix", "unixpacket":
216 defer os
.Remove(ln
.Addr().String())
219 dst
:= ln
.Addr().String()
220 if err
:= ln
.Close(); err
!= nil {
221 if perr
:= parseCloseError(err
, false); perr
!= nil {
226 c
, err
:= ln
.Accept()
229 t
.Fatal("should fail")
232 if network
== "tcp" {
233 // We will have two TCP FSMs inside the
234 // kernel here. There's no guarantee that a
235 // signal comes from the far end FSM will be
236 // delivered immediately to the near end FSM,
237 // especially on the platforms that allow
238 // multiple consumer threads to pull pending
239 // established connections at the same time by
240 // enabling SO_REUSEPORT option such as Linux,
241 // DragonFly BSD. So we need to give some time
242 // quantum to the kernel.
244 // Note that net.inet.tcp.reuseport_ext=1 by
245 // default on DragonFly BSD.
246 time
.Sleep(time
.Millisecond
)
248 cc
, err
:= Dial("tcp", dst
)
250 t
.Error("Dial to closed TCP listener succeeded.")
257 func TestPacketConnClose(t
*testing
.T
) {
258 for _
, network
:= range []string{"udp", "unixgram"} {
259 if !testableNetwork(network
) {
260 t
.Logf("skipping %s test", network
)
264 c
, err
:= newLocalPacketListener(network
)
270 defer os
.Remove(c
.LocalAddr().String())
274 if err
:= c
.Close(); err
!= nil {
275 if perr
:= parseCloseError(err
, false); perr
!= nil {
281 n
, _
, err
:= c
.ReadFrom(b
[:])
282 if n
!= 0 || err
== nil {
283 t
.Fatalf("got (%d, %v); want (0, error)", n
, err
)
288 // nacl was previous failing to reuse an address.
289 func TestListenCloseListen(t
*testing
.T
) {
291 for tries
:= 0; tries
< maxTries
; tries
++ {
292 ln
, err
:= newLocalListener("tcp")
296 addr
:= ln
.Addr().String()
297 if err
:= ln
.Close(); err
!= nil {
298 if perr
:= parseCloseError(err
, false); perr
!= nil {
303 ln
, err
= Listen("tcp", addr
)
305 // Success. nacl couldn't do this before.
309 t
.Errorf("failed on try %d/%d: %v", tries
+1, maxTries
, err
)
311 t
.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries
)
314 // See golang.org/issue/6163, golang.org/issue/6987.
315 func TestAcceptIgnoreAbortedConnRequest(t
*testing
.T
) {
316 switch runtime
.GOOS
{
318 t
.Skipf("%s does not have full support of socktest", runtime
.GOOS
)
321 syserr
:= make(chan error
)
324 for _
, err
:= range abortedConnRequestErrors
{
328 sw
.Set(socktest
.FilterAccept
, func(so
*socktest
.Status
) (socktest
.AfterFilter
, error
) {
329 if err
, ok
:= <-syserr
; ok
{
334 defer sw
.Set(socktest
.FilterAccept
, nil)
336 operr
:= make(chan error
, 1)
337 handler
:= func(ls
*localServer
, ln Listener
) {
339 c
, err
:= ln
.Accept()
341 if perr
:= parseAcceptError(err
); perr
!= nil {
349 ls
, err
:= newLocalServer("tcp")
354 if err
:= ls
.buildup(handler
); err
!= nil {
358 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
364 for err
:= range operr
{
369 func TestZeroByteRead(t
*testing
.T
) {
370 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
371 if !testableNetwork(network
) {
372 t
.Logf("skipping %s test", network
)
376 ln
, err
:= newLocalListener(network
)
380 connc
:= make(chan Conn
, 1)
383 c
, err
:= ln
.Accept()
387 connc
<- c
// might be nil
389 c
, err
:= Dial(network
, ln
.Addr().String())
400 if runtime
.GOOS
== "windows" {
401 // A zero byte read on Windows caused a wait for readability first.
402 // Rather than change that behavior, satisfy it in this test.
404 go io
.WriteString(sc
, "a")
407 n
, err
:= c
.Read(nil)
408 if n
!= 0 || err
!= nil {
409 t
.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network
, n
, err
)
412 if runtime
.GOOS
== "windows" {
413 // Same as comment above.
414 go io
.WriteString(c
, "a")
416 n
, err
= sc
.Read(nil)
417 if n
!= 0 || err
!= nil {
418 t
.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network
, n
, err
)
423 // withTCPConnPair sets up a TCP connection between two peers, then
424 // runs peer1 and peer2 concurrently. withTCPConnPair returns when
425 // both have completed.
426 func withTCPConnPair(t
*testing
.T
, peer1
, peer2
func(c
*TCPConn
) error
) {
427 ln
, err
:= newLocalListener("tcp")
432 errc
:= make(chan error
, 2)
434 c1
, err
:= ln
.Accept()
440 errc
<- peer1(c1
.(*TCPConn
))
443 c2
, err
:= Dial("tcp", ln
.Addr().String())
449 errc
<- peer2(c2
.(*TCPConn
))
451 for i
:= 0; i
< 2; i
++ {
452 if err
:= <-errc
; err
!= nil {
458 // Tests that a blocked Read is interrupted by a concurrent SetReadDeadline
459 // modifying that Conn's read deadline to the past.
460 // See golang.org/cl/30164 which documented this. The net/http package
462 func TestReadTimeoutUnblocksRead(t
*testing
.T
) {
463 serverDone
:= make(chan struct{})
464 server
:= func(cs
*TCPConn
) error
{
465 defer close(serverDone
)
466 errc
:= make(chan error
, 1)
470 // TODO: find a better way to wait
471 // until we're blocked in the cs.Read
472 // call below. Sleep is lame.
473 time
.Sleep(100 * time
.Millisecond
)
475 // Interrupt the upcoming Read, unblocking it:
476 cs
.SetReadDeadline(time
.Unix(123, 0)) // time in the past
479 n
, err
:= cs
.Read(buf
[:1])
480 if n
!= 0 || err
== nil {
481 errc
<- fmt
.Errorf("Read = %v, %v; want 0, non-nil", n
, err
)
487 case <-time
.After(5 * time
.Second
):
488 buf
:= make([]byte, 2<<20)
489 buf
= buf
[:runtime
.Stack(buf
, true)]
490 println("Stacks at timeout:\n", string(buf
))
491 return errors
.New("timeout waiting for Read to finish")
495 // Do nothing in the client. Never write. Just wait for the
496 // server's half to be done.
497 client
:= func(*TCPConn
) error
{
501 withTCPConnPair(t
, client
, server
)
504 // Issue 17695: verify that a blocked Read is woken up by a Close.
505 func TestCloseUnblocksRead(t
*testing
.T
) {
507 server
:= func(cs
*TCPConn
) error
{
508 // Give the client time to get stuck in a Read:
509 time
.Sleep(20 * time
.Millisecond
)
513 client
:= func(ss
*TCPConn
) error
{
514 n
, err
:= ss
.Read([]byte{0})
515 if n
!= 0 || err
!= io
.EOF
{
516 return fmt
.Errorf("Read = %v, %v; want 0, EOF", n
, err
)
520 withTCPConnPair(t
, client
, server
)
523 // Issue 24808: verify that ECONNRESET is not temporary for read.
524 func TestNotTemporaryRead(t
*testing
.T
) {
525 if runtime
.GOOS
== "freebsd" {
526 testenv
.SkipFlaky(t
, 25289)
529 server
:= func(cs
*TCPConn
) error
{
531 // Give the client time to get stuck in a Read.
532 time
.Sleep(20 * time
.Millisecond
)
536 client
:= func(ss
*TCPConn
) error
{
537 _
, err
:= ss
.Read([]byte{0})
539 return errors
.New("Read succeeded unexpectedly")
540 } else if err
== io
.EOF
{
541 // This happens on NaCl and Plan 9.
543 } else if ne
, ok
:= err
.(Error
); !ok
{
544 return fmt
.Errorf("unexpected error %v", err
)
545 } else if ne
.Temporary() {
546 return fmt
.Errorf("unexpected temporary error %v", err
)
550 withTCPConnPair(t
, client
, server
)