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 func TestCloseRead(t
*testing
.T
) {
23 t
.Skipf("not supported on %s", runtime
.GOOS
)
27 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
29 t
.Run(network
, func(t
*testing
.T
) {
30 if !testableNetwork(network
) {
31 t
.Skipf("network %s is not testable on the current platform", network
)
35 ln
:= newLocalListener(t
, network
)
37 case "unix", "unixpacket":
38 defer os
.Remove(ln
.Addr().String())
42 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
47 case "unix", "unixpacket":
48 defer os
.Remove(c
.LocalAddr().String())
52 switch c
:= c
.(type) {
59 if perr
:= parseCloseError(err
, true); perr
!= nil {
65 n
, err
:= c
.Read(b
[:])
66 if n
!= 0 || err
== nil {
67 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
)
80 deadline
, _
:= t
.Deadline()
81 if !deadline
.IsZero() {
82 // Leave 10% headroom on the deadline to report errors and clean up.
83 deadline
= deadline
.Add(-time
.Until(deadline
) / 10)
86 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
88 t
.Run(network
, func(t
*testing
.T
) {
89 if !testableNetwork(network
) {
90 t
.Skipf("network %s is not testable on the current platform", network
)
94 handler
:= func(ls
*localServer
, ln Listener
) {
100 if !deadline
.IsZero() {
101 c
.SetDeadline(deadline
)
106 n
, err
:= c
.Read(b
[:])
107 if n
!= 0 || err
!= io
.EOF
{
108 t
.Errorf("got (%d, %v); want (0, io.EOF)", n
, err
)
111 switch c
:= c
.(type) {
118 if perr
:= parseCloseError(err
, true); perr
!= nil {
124 n
, err
= c
.Write(b
[:])
126 t
.Errorf("got (%d, %v); want (any, error)", n
, err
)
131 ls
:= newLocalServer(t
, network
)
133 if err
:= ls
.buildup(handler
); err
!= nil {
137 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
141 if !deadline
.IsZero() {
142 c
.SetDeadline(deadline
)
145 case "unix", "unixpacket":
146 defer os
.Remove(c
.LocalAddr().String())
150 switch c
:= c
.(type) {
157 if perr
:= parseCloseError(err
, true); perr
!= nil {
163 n
, err
:= c
.Read(b
[:])
164 if n
!= 0 || err
!= io
.EOF
{
165 t
.Fatalf("got (%d, %v); want (0, io.EOF)", n
, err
)
167 n
, err
= c
.Write(b
[:])
169 t
.Fatalf("got (%d, %v); want (any, error)", n
, err
)
175 func TestConnClose(t
*testing
.T
) {
177 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
179 t
.Run(network
, func(t
*testing
.T
) {
180 if !testableNetwork(network
) {
181 t
.Skipf("network %s is not testable on the current platform", network
)
185 ln
:= newLocalListener(t
, network
)
187 case "unix", "unixpacket":
188 defer os
.Remove(ln
.Addr().String())
192 c
, err
:= Dial(ln
.Addr().Network(), ln
.Addr().String())
197 case "unix", "unixpacket":
198 defer os
.Remove(c
.LocalAddr().String())
202 if err
:= c
.Close(); err
!= nil {
203 if perr
:= parseCloseError(err
, false); perr
!= nil {
209 n
, err
:= c
.Read(b
[:])
210 if n
!= 0 || err
== nil {
211 t
.Fatalf("got (%d, %v); want (0, error)", n
, err
)
217 func TestListenerClose(t
*testing
.T
) {
219 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
221 t
.Run(network
, func(t
*testing
.T
) {
222 if !testableNetwork(network
) {
223 t
.Skipf("network %s is not testable on the current platform", network
)
227 ln
:= newLocalListener(t
, network
)
229 case "unix", "unixpacket":
230 defer os
.Remove(ln
.Addr().String())
233 if err
:= ln
.Close(); err
!= nil {
234 if perr
:= parseCloseError(err
, false); perr
!= nil {
239 c
, err
:= ln
.Accept()
242 t
.Fatal("should fail")
245 // Note: we cannot ensure that a subsequent Dial does not succeed, because
246 // we do not in general have any guarantee that ln.Addr is not immediately
247 // reused. (TCP sockets enter a TIME_WAIT state when closed, but that only
248 // applies to existing connections for the port — it does not prevent the
249 // port itself from being used for entirely new connections in the
255 func TestPacketConnClose(t
*testing
.T
) {
257 for _
, network
:= range []string{"udp", "unixgram"} {
259 t
.Run(network
, func(t
*testing
.T
) {
260 if !testableNetwork(network
) {
261 t
.Skipf("network %s is not testable on the current platform", network
)
265 c
:= newLocalPacketListener(t
, network
)
268 defer os
.Remove(c
.LocalAddr().String())
272 if err
:= c
.Close(); err
!= nil {
273 if perr
:= parseCloseError(err
, false); perr
!= nil {
279 n
, _
, err
:= c
.ReadFrom(b
[:])
280 if n
!= 0 || err
== nil {
281 t
.Fatalf("got (%d, %v); want (0, error)", n
, err
)
287 func TestListenCloseListen(t
*testing
.T
) {
289 for tries
:= 0; tries
< maxTries
; tries
++ {
290 ln
:= newLocalListener(t
, "tcp")
291 addr
:= ln
.Addr().String()
292 // TODO: This is racy. The selected address could be reused in between this
293 // Close and the subsequent Listen.
294 if err
:= ln
.Close(); err
!= nil {
295 if perr
:= parseCloseError(err
, false); perr
!= nil {
300 ln
, err
:= Listen("tcp", addr
)
302 // Success. (This test didn't always make it here earlier.)
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
:= newLocalServer(t
, "tcp")
348 if err
:= ls
.buildup(handler
); err
!= nil {
352 c
, err
:= Dial(ls
.Listener
.Addr().Network(), ls
.Listener
.Addr().String())
358 for err
:= range operr
{
363 func TestZeroByteRead(t
*testing
.T
) {
365 for _
, network
:= range []string{"tcp", "unix", "unixpacket"} {
367 t
.Run(network
, func(t
*testing
.T
) {
368 if !testableNetwork(network
) {
369 t
.Skipf("network %s is not testable on the current platform", network
)
373 ln
:= newLocalListener(t
, network
)
374 connc
:= make(chan Conn
, 1)
377 c
, err
:= ln
.Accept()
381 connc
<- c
// might be nil
383 c
, err
:= Dial(network
, ln
.Addr().String())
394 if runtime
.GOOS
== "windows" {
395 // A zero byte read on Windows caused a wait for readability first.
396 // Rather than change that behavior, satisfy it in this test.
398 go io
.WriteString(sc
, "a")
401 n
, err
:= c
.Read(nil)
402 if n
!= 0 || err
!= nil {
403 t
.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network
, n
, err
)
406 if runtime
.GOOS
== "windows" {
407 // Same as comment above.
408 go io
.WriteString(c
, "a")
410 n
, err
= sc
.Read(nil)
411 if n
!= 0 || err
!= nil {
412 t
.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network
, n
, err
)
418 // withTCPConnPair sets up a TCP connection between two peers, then
419 // runs peer1 and peer2 concurrently. withTCPConnPair returns when
420 // both have completed.
421 func withTCPConnPair(t
*testing
.T
, peer1
, peer2
func(c
*TCPConn
) error
) {
422 ln
:= newLocalListener(t
, "tcp")
424 errc
:= make(chan error
, 2)
426 c1
, err
:= ln
.Accept()
432 errc
<- peer1(c1
.(*TCPConn
))
435 c2
, err
:= Dial("tcp", ln
.Addr().String())
441 errc
<- peer2(c2
.(*TCPConn
))
443 for i
:= 0; i
< 2; i
++ {
444 if err
:= <-errc
; err
!= nil {
450 // Tests that a blocked Read is interrupted by a concurrent SetReadDeadline
451 // modifying that Conn's read deadline to the past.
452 // See golang.org/cl/30164 which documented this. The net/http package
454 func TestReadTimeoutUnblocksRead(t
*testing
.T
) {
455 serverDone
:= make(chan struct{})
456 server
:= func(cs
*TCPConn
) error
{
457 defer close(serverDone
)
458 errc
:= make(chan error
, 1)
462 // TODO: find a better way to wait
463 // until we're blocked in the cs.Read
464 // call below. Sleep is lame.
465 time
.Sleep(100 * time
.Millisecond
)
467 // Interrupt the upcoming Read, unblocking it:
468 cs
.SetReadDeadline(time
.Unix(123, 0)) // time in the past
471 n
, err
:= cs
.Read(buf
[:1])
472 if n
!= 0 || err
== nil {
473 errc
<- fmt
.Errorf("Read = %v, %v; want 0, non-nil", n
, err
)
479 case <-time
.After(5 * time
.Second
):
480 buf
:= make([]byte, 2<<20)
481 buf
= buf
[:runtime
.Stack(buf
, true)]
482 println("Stacks at timeout:\n", string(buf
))
483 return errors
.New("timeout waiting for Read to finish")
487 // Do nothing in the client. Never write. Just wait for the
488 // server's half to be done.
489 client
:= func(*TCPConn
) error
{
493 withTCPConnPair(t
, client
, server
)
496 // Issue 17695: verify that a blocked Read is woken up by a Close.
497 func TestCloseUnblocksRead(t
*testing
.T
) {
499 server
:= func(cs
*TCPConn
) error
{
500 // Give the client time to get stuck in a Read:
501 time
.Sleep(20 * time
.Millisecond
)
505 client
:= func(ss
*TCPConn
) error
{
506 n
, err
:= ss
.Read([]byte{0})
507 if n
!= 0 || err
!= io
.EOF
{
508 return fmt
.Errorf("Read = %v, %v; want 0, EOF", n
, err
)
512 withTCPConnPair(t
, client
, server
)
515 // Issue 24808: verify that ECONNRESET is not temporary for read.
516 func TestNotTemporaryRead(t
*testing
.T
) {
519 ln
:= newLocalListener(t
, "tcp")
520 serverDone
:= make(chan struct{})
521 dialed
:= make(chan struct{})
523 defer close(serverDone
)
525 cs
, err
:= ln
.Accept()
530 cs
.(*TCPConn
).SetLinger(0)
535 defer func() { <-serverDone
}()
537 ss
, err
:= Dial("tcp", ln
.Addr().String())
543 _
, err
= ss
.Read([]byte{0})
545 t
.Fatal("Read succeeded unexpectedly")
546 } else if err
== io
.EOF
{
547 // This happens on Plan 9, but for some reason (prior to CL 385314) it was
548 // accepted everywhere else too.
549 if runtime
.GOOS
== "plan9" {
552 // TODO: during an open development cycle, try making this a failure
553 // and see whether it causes the test to become flaky anywhere else.
556 if ne
, ok
:= err
.(Error
); !ok
{
557 t
.Errorf("Read error does not implement net.Error: %v", err
)
558 } else if ne
.Temporary() {
559 t
.Errorf("Read error is unexpectedly temporary: %v", err
)
563 // The various errors should implement the Error interface.
564 func TestErrors(t
*testing
.T
) {
567 _ Error
= &ParseError
{}
568 _ Error
= &AddrError
{}
569 _ Error
= UnknownNetworkError("")
570 _ Error
= InvalidAddrError("")
571 _ Error
= &timeoutError
{}
572 _ Error
= &DNSConfigError
{}
573 _ Error
= &DNSError
{}
576 // ErrClosed was introduced as type error, so we can't check
577 // it using a declaration.
578 if _
, ok
:= ErrClosed
.(Error
); !ok
{
579 t
.Fatal("ErrClosed does not implement Error")