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.
11 "net/internal/socktest"
18 func TestCloseRead(t
*testing
.T
) {
21 t
.Skipf("not supported on %s", runtime
.GOOS
)
24 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
25 if !testableNetwork(network
) {
26 t
.Logf("skipping %s test", network
)
30 ln
, err
:= newLocalListener(network
)
35 case "unix", "unixpacket":
36 defer os
.Remove(ln
.Addr().String())
40 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
45 case "unix", "unixpacket":
46 defer os
.Remove(c
.LocalAddr().String())
50 switch c
:= c
.(type) {
57 if perr
:= parseCloseError(err
); perr
!= nil {
63 n
, err
:= c
.Read(b
[:])
64 if n
!= 0 || err
== nil {
65 t
.Fatalf("got (%d, %v); want (0, error)", n
, err
)
70 func TestCloseWrite(t
*testing
.T
) {
73 t
.Skipf("not supported on %s", runtime
.GOOS
)
76 handler
:= func(ls
*localServer
, ln Listener
) {
85 n
, err
:= c
.Read(b
[:])
86 if n
!= 0 || err
!= io
.EOF
{
87 t
.Errorf("got (%d, %v); want (0, io.EOF)", n
, err
)
90 switch c
:= c
.(type) {
97 if perr
:= parseCloseError(err
); perr
!= nil {
103 n
, err
= c
.Write(b
[:])
105 t
.Errorf("got (%d, %v); want (any, error)", n
, err
)
110 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
111 if !testableNetwork(network
) {
112 t
.Logf("skipping %s test", network
)
116 ls
, err
:= newLocalServer(network
)
121 if err
:= ls
.buildup(handler
); err
!= nil {
125 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
130 case "unix", "unixpacket":
131 defer os
.Remove(c
.LocalAddr().String())
135 switch c
:= c
.(type) {
142 if perr
:= parseCloseError(err
); perr
!= nil {
148 n
, err
:= c
.Read(b
[:])
149 if n
!= 0 || err
!= io
.EOF
{
150 t
.Fatalf("got (%d, %v); want (0, io.EOF)", n
, err
)
152 n
, err
= c
.Write(b
[:])
154 t
.Fatalf("got (%d, %v); want (any, error)", n
, err
)
159 func TestConnClose(t
*testing
.T
) {
160 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
161 if !testableNetwork(network
) {
162 t
.Logf("skipping %s test", network
)
166 ln
, err
:= newLocalListener(network
)
171 case "unix", "unixpacket":
172 defer os
.Remove(ln
.Addr().String())
176 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
181 case "unix", "unixpacket":
182 defer os
.Remove(c
.LocalAddr().String())
186 if err
:= c
.Close(); err
!= nil {
187 if perr
:= parseCloseError(err
); perr
!= nil {
193 n
, err
:= c
.Read(b
[:])
194 if n
!= 0 || err
== nil {
195 t
.Fatalf("got (%d, %v); want (0, error)", n
, err
)
200 func TestListenerClose(t
*testing
.T
) {
201 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
202 if !testableNetwork(network
) {
203 t
.Logf("skipping %s test", network
)
207 ln
, err
:= newLocalListener(network
)
212 case "unix", "unixpacket":
213 defer os
.Remove(ln
.Addr().String())
216 dst
:= ln
.Addr().String()
217 if err
:= ln
.Close(); err
!= nil {
218 if perr
:= parseCloseError(err
); perr
!= nil {
223 c
, err
:= ln
.Accept()
226 t
.Fatal("should fail")
229 if network
== "tcp" {
230 // We will have two TCP FSMs inside the
231 // kernel here. There's no guarantee that a
232 // signal comes from the far end FSM will be
233 // delivered immediately to the near end FSM,
234 // especially on the platforms that allow
235 // multiple consumer threads to pull pending
236 // established connections at the same time by
237 // enabling SO_REUSEPORT option such as Linux,
238 // DragonFly BSD. So we need to give some time
239 // quantum to the kernel.
241 // Note that net.inet.tcp.reuseport_ext=1 by
242 // default on DragonFly BSD.
243 time
.Sleep(time
.Millisecond
)
245 cc
, err
:= Dial("tcp", dst
)
247 t
.Error("Dial to closed TCP listener succeeded.")
254 func TestPacketConnClose(t
*testing
.T
) {
255 for _
, network
:= range []string{"udp", "unixgram"} {
256 if !testableNetwork(network
) {
257 t
.Logf("skipping %s test", network
)
261 c
, err
:= newLocalPacketListener(network
)
267 defer os
.Remove(c
.LocalAddr().String())
271 if err
:= c
.Close(); err
!= nil {
272 if perr
:= parseCloseError(err
); perr
!= nil {
278 n
, _
, err
:= c
.ReadFrom(b
[:])
279 if n
!= 0 || err
== nil {
280 t
.Fatalf("got (%d, %v); want (0, error)", n
, err
)
285 // nacl was previous failing to reuse an address.
286 func TestListenCloseListen(t
*testing
.T
) {
288 for tries
:= 0; tries
< maxTries
; tries
++ {
289 ln
, err
:= newLocalListener("tcp")
293 addr
:= ln
.Addr().String()
294 if err
:= ln
.Close(); err
!= nil {
295 if perr
:= parseCloseError(err
); perr
!= nil {
300 ln
, err
= Listen("tcp", addr
)
302 // Success. nacl couldn't do this before.
306 t
.Errorf("failed on try %d/%d: %v", tries
+1, maxTries
, err
)
308 t
.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries
)
311 // See golang.org/issue/6163, golang.org/issue/6987.
312 func TestAcceptIgnoreAbortedConnRequest(t
*testing
.T
) {
313 switch runtime
.GOOS
{
315 t
.Skipf("%s does not have full support of socktest", runtime
.GOOS
)
318 syserr
:= make(chan error
)
321 for _
, err
:= range abortedConnRequestErrors
{
325 sw
.Set(socktest
.FilterAccept
, func(so
*socktest
.Status
) (socktest
.AfterFilter
, error
) {
326 if err
, ok
:= <-syserr
; ok
{
331 defer sw
.Set(socktest
.FilterAccept
, nil)
333 operr
:= make(chan error
, 1)
334 handler
:= func(ls
*localServer
, ln Listener
) {
336 c
, err
:= ln
.Accept()
338 if perr
:= parseAcceptError(err
); perr
!= nil {
346 ls
, err
:= newLocalServer("tcp")
351 if err
:= ls
.buildup(handler
); err
!= nil {
355 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
361 for err
:= range operr
{
366 func TestZeroByteRead(t
*testing
.T
) {
367 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
368 if !testableNetwork(network
) {
369 t
.Logf("skipping %s test", network
)
373 ln
, err
:= newLocalListener(network
)
377 connc
:= make(chan Conn
, 1)
380 c
, err
:= ln
.Accept()
384 connc
<- c
// might be nil
386 c
, err
:= Dial(network
, ln
.Addr().String())
397 if runtime
.GOOS
== "windows" {
398 // A zero byte read on Windows caused a wait for readability first.
399 // Rather than change that behavior, satisfy it in this test.
401 go io
.WriteString(sc
, "a")
404 n
, err
:= c
.Read(nil)
405 if n
!= 0 || err
!= nil {
406 t
.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network
, n
, err
)
409 if runtime
.GOOS
== "windows" {
410 // Same as comment above.
411 go io
.WriteString(c
, "a")
413 n
, err
= sc
.Read(nil)
414 if n
!= 0 || err
!= nil {
415 t
.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network
, n
, err
)
420 // withTCPConnPair sets up a TCP connection between two peers, then
421 // runs peer1 and peer2 concurrently. withTCPConnPair returns when
422 // both have completed.
423 func withTCPConnPair(t
*testing
.T
, peer1
, peer2
func(c
*TCPConn
) error
) {
424 ln
, err
:= newLocalListener("tcp")
429 errc
:= make(chan error
, 2)
431 c1
, err
:= ln
.Accept()
437 errc
<- peer1(c1
.(*TCPConn
))
440 c2
, err
:= Dial("tcp", ln
.Addr().String())
446 errc
<- peer2(c2
.(*TCPConn
))
448 for i
:= 0; i
< 2; i
++ {
449 if err
:= <-errc
; err
!= nil {
455 // Tests that a blocked Read is interrupted by a concurrent SetReadDeadline
456 // modifying that Conn's read deadline to the past.
457 // See golang.org/cl/30164 which documented this. The net/http package
459 func TestReadTimeoutUnblocksRead(t
*testing
.T
) {
460 serverDone
:= make(chan struct{})
461 server
:= func(cs
*TCPConn
) error
{
462 defer close(serverDone
)
463 errc
:= make(chan error
, 1)
467 // TODO: find a better way to wait
468 // until we're blocked in the cs.Read
469 // call below. Sleep is lame.
470 time
.Sleep(100 * time
.Millisecond
)
472 // Interrupt the upcoming Read, unblocking it:
473 cs
.SetReadDeadline(time
.Unix(123, 0)) // time in the past
476 n
, err
:= cs
.Read(buf
[:1])
477 if n
!= 0 || err
== nil {
478 errc
<- fmt
.Errorf("Read = %v, %v; want 0, non-nil", n
, err
)
484 case <-time
.After(5 * time
.Second
):
485 buf
:= make([]byte, 2<<20)
486 buf
= buf
[:runtime
.Stack(buf
, true)]
487 println("Stacks at timeout:\n", string(buf
))
488 return errors
.New("timeout waiting for Read to finish")
492 // Do nothing in the client. Never write. Just wait for the
493 // server's half to be done.
494 client
:= func(*TCPConn
) error
{
498 withTCPConnPair(t
, client
, server
)
501 // Issue 17695: verify that a blocked Read is woken up by a Close.
502 func TestCloseUnblocksRead(t
*testing
.T
) {
504 server
:= func(cs
*TCPConn
) error
{
505 // Give the client time to get stuck in a Read:
506 time
.Sleep(20 * time
.Millisecond
)
510 client
:= func(ss
*TCPConn
) error
{
511 n
, err
:= ss
.Read([]byte{0})
512 if n
!= 0 || err
!= io
.EOF
{
513 return fmt
.Errorf("Read = %v, %v; want 0, EOF", n
, err
)
517 withTCPConnPair(t
, client
, server
)