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)
25 for _, network := range []string{"tcp", "unix", "unixpacket"} {
27 t.Run(network, func(t *testing.T) {
28 if !testableNetwork(network) {
29 t.Skipf("network %s is not testable on the current platform", network)
33 ln := newLocalListener(t, 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, true); 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)
71 func TestCloseWrite(t *testing.T) {
74 t.Skipf("not supported on %s", runtime.GOOS)
78 deadline, _ := t.Deadline()
79 if !deadline.IsZero() {
80 // Leave 10% headroom on the deadline to report errors and clean up.
81 deadline = deadline.Add(-time.Until(deadline) / 10)
84 for _, network := range []string{"tcp", "unix", "unixpacket"} {
86 t.Run(network, func(t *testing.T) {
87 if !testableNetwork(network) {
88 t.Skipf("network %s is not testable on the current platform", network)
92 handler := func(ls *localServer, ln Listener) {
99 // Workaround for https://go.dev/issue/49352.
100 // On arm64 macOS (current as of macOS 12.4),
101 // reading from a socket at the same time as the client
102 // is closing it occasionally hangs for 60 seconds before
103 // returning ECONNRESET. Sleep for a bit to give the
104 // socket time to close before trying to read from it.
105 if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
106 time.Sleep(10 * time.Millisecond)
109 if !deadline.IsZero() {
110 c.SetDeadline(deadline)
115 n, err := c.Read(b[:])
116 if n != 0 || err != io.EOF {
117 t.Errorf("got (%d, %v); want (0, io.EOF)", n, err)
120 switch c := c.(type) {
127 if perr := parseCloseError(err, true); perr != nil {
133 n, err = c.Write(b[:])
135 t.Errorf("got (%d, %v); want (any, error)", n, err)
140 ls := newLocalServer(t, network)
142 if err := ls.buildup(handler); err != nil {
146 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
150 if !deadline.IsZero() {
151 c.SetDeadline(deadline)
154 case "unix", "unixpacket":
155 defer os.Remove(c.LocalAddr().String())
159 switch c := c.(type) {
166 if perr := parseCloseError(err, true); perr != nil {
172 n, err := c.Read(b[:])
173 if n != 0 || err != io.EOF {
174 t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err)
176 n, err = c.Write(b[:])
178 t.Fatalf("got (%d, %v); want (any, error)", n, err)
184 func TestConnClose(t *testing.T) {
186 for _, network := range []string{"tcp", "unix", "unixpacket"} {
188 t.Run(network, func(t *testing.T) {
189 if !testableNetwork(network) {
190 t.Skipf("network %s is not testable on the current platform", network)
194 ln := newLocalListener(t, network)
196 case "unix", "unixpacket":
197 defer os.Remove(ln.Addr().String())
201 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
206 case "unix", "unixpacket":
207 defer os.Remove(c.LocalAddr().String())
211 if err := c.Close(); err != nil {
212 if perr := parseCloseError(err, false); perr != nil {
218 n, err := c.Read(b[:])
219 if n != 0 || err == nil {
220 t.Fatalf("got (%d, %v); want (0, error)", n, err)
226 func TestListenerClose(t *testing.T) {
228 for _, network := range []string{"tcp", "unix", "unixpacket"} {
230 t.Run(network, func(t *testing.T) {
231 if !testableNetwork(network) {
232 t.Skipf("network %s is not testable on the current platform", network)
236 ln := newLocalListener(t, network)
238 case "unix", "unixpacket":
239 defer os.Remove(ln.Addr().String())
242 if err := ln.Close(); err != nil {
243 if perr := parseCloseError(err, false); perr != nil {
248 c, err := ln.Accept()
251 t.Fatal("should fail")
254 // Note: we cannot ensure that a subsequent Dial does not succeed, because
255 // we do not in general have any guarantee that ln.Addr is not immediately
256 // reused. (TCP sockets enter a TIME_WAIT state when closed, but that only
257 // applies to existing connections for the port — it does not prevent the
258 // port itself from being used for entirely new connections in the
264 func TestPacketConnClose(t *testing.T) {
266 for _, network := range []string{"udp", "unixgram"} {
268 t.Run(network, func(t *testing.T) {
269 if !testableNetwork(network) {
270 t.Skipf("network %s is not testable on the current platform", network)
274 c := newLocalPacketListener(t, network)
277 defer os.Remove(c.LocalAddr().String())
281 if err := c.Close(); err != nil {
282 if perr := parseCloseError(err, false); perr != nil {
288 n, _, err := c.ReadFrom(b[:])
289 if n != 0 || err == nil {
290 t.Fatalf("got (%d, %v); want (0, error)", n, err)
296 func TestListenCloseListen(t *testing.T) {
298 for tries := 0; tries < maxTries; tries++ {
299 ln := newLocalListener(t, "tcp")
300 addr := ln.Addr().String()
301 // TODO: This is racy. The selected address could be reused in between this
302 // Close and the subsequent Listen.
303 if err := ln.Close(); err != nil {
304 if perr := parseCloseError(err, false); perr != nil {
309 ln, err := Listen("tcp", addr)
311 // Success. (This test didn't always make it here earlier.)
315 t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err)
317 t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries)
320 // See golang.org/issue/6163, golang.org/issue/6987.
321 func TestAcceptIgnoreAbortedConnRequest(t *testing.T) {
322 switch runtime.GOOS {
324 t.Skipf("%s does not have full support of socktest", runtime.GOOS)
327 syserr := make(chan error)
330 for _, err := range abortedConnRequestErrors {
334 sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) {
335 if err, ok := <-syserr; ok {
340 defer sw.Set(socktest.FilterAccept, nil)
342 operr := make(chan error, 1)
343 handler := func(ls *localServer, ln Listener) {
345 c, err := ln.Accept()
347 if perr := parseAcceptError(err); perr != nil {
355 ls := newLocalServer(t, "tcp")
357 if err := ls.buildup(handler); err != nil {
361 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
367 for err := range operr {
372 func TestZeroByteRead(t *testing.T) {
374 for _, network := range []string{"tcp", "unix", "unixpacket"} {
376 t.Run(network, func(t *testing.T) {
377 if !testableNetwork(network) {
378 t.Skipf("network %s is not testable on the current platform", network)
382 ln := newLocalListener(t, network)
383 connc := make(chan Conn, 1)
386 for c := range connc {
394 c, err := ln.Accept()
398 connc <- c // might be nil
400 c, err := Dial(network, ln.Addr().String())
411 if runtime.GOOS == "windows" {
412 // A zero byte read on Windows caused a wait for readability first.
413 // Rather than change that behavior, satisfy it in this test.
415 go io.WriteString(sc, "a")
418 n, err := c.Read(nil)
419 if n != 0 || err != nil {
420 t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err)
423 if runtime.GOOS == "windows" {
424 // Same as comment above.
425 go io.WriteString(c, "a")
427 n, err = sc.Read(nil)
428 if n != 0 || err != nil {
429 t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err)
435 // withTCPConnPair sets up a TCP connection between two peers, then
436 // runs peer1 and peer2 concurrently. withTCPConnPair returns when
437 // both have completed.
438 func withTCPConnPair(t *testing.T, peer1, peer2 func(c *TCPConn) error) {
440 ln := newLocalListener(t, "tcp")
442 errc := make(chan error, 2)
444 c1, err := ln.Accept()
449 err = peer1(c1.(*TCPConn))
454 c2, err := Dial("tcp", ln.Addr().String())
459 err = peer2(c2.(*TCPConn))
463 for i := 0; i < 2; i++ {
464 if err := <-errc; err != nil {
470 // Tests that a blocked Read is interrupted by a concurrent SetReadDeadline
471 // modifying that Conn's read deadline to the past.
472 // See golang.org/cl/30164 which documented this. The net/http package
474 func TestReadTimeoutUnblocksRead(t *testing.T) {
475 serverDone := make(chan struct{})
476 server := func(cs *TCPConn) error {
477 defer close(serverDone)
478 errc := make(chan error, 1)
482 // TODO: find a better way to wait
483 // until we're blocked in the cs.Read
484 // call below. Sleep is lame.
485 time.Sleep(100 * time.Millisecond)
487 // Interrupt the upcoming Read, unblocking it:
488 cs.SetReadDeadline(time.Unix(123, 0)) // time in the past
491 n, err := cs.Read(buf[:1])
492 if n != 0 || err == nil {
493 errc <- fmt.Errorf("Read = %v, %v; want 0, non-nil", n, err)
499 case <-time.After(5 * time.Second):
500 buf := make([]byte, 2<<20)
501 buf = buf[:runtime.Stack(buf, true)]
502 println("Stacks at timeout:\n", string(buf))
503 return errors.New("timeout waiting for Read to finish")
507 // Do nothing in the client. Never write. Just wait for the
508 // server's half to be done.
509 client := func(*TCPConn) error {
513 withTCPConnPair(t, client, server)
516 // Issue 17695: verify that a blocked Read is woken up by a Close.
517 func TestCloseUnblocksRead(t *testing.T) {
519 server := func(cs *TCPConn) error {
520 // Give the client time to get stuck in a Read:
521 time.Sleep(20 * time.Millisecond)
525 client := func(ss *TCPConn) error {
526 n, err := ss.Read([]byte{0})
527 if n != 0 || err != io.EOF {
528 return fmt.Errorf("Read = %v, %v; want 0, EOF", n, err)
532 withTCPConnPair(t, client, server)
535 // Issue 24808: verify that ECONNRESET is not temporary for read.
536 func TestNotTemporaryRead(t *testing.T) {
539 ln := newLocalListener(t, "tcp")
540 serverDone := make(chan struct{})
541 dialed := make(chan struct{})
543 defer close(serverDone)
545 cs, err := ln.Accept()
550 cs.(*TCPConn).SetLinger(0)
558 ss, err := Dial("tcp", ln.Addr().String())
565 _, err = ss.Read([]byte{0})
567 t.Fatal("Read succeeded unexpectedly")
568 } else if err == io.EOF {
569 // This happens on Plan 9, but for some reason (prior to CL 385314) it was
570 // accepted everywhere else too.
571 if runtime.GOOS == "plan9" {
574 t.Fatal("Read unexpectedly returned io.EOF after socket was abruptly closed")
576 if ne, ok := err.(Error); !ok {
577 t.Errorf("Read error does not implement net.Error: %v", err)
578 } else if ne.Temporary() {
579 t.Errorf("Read error is unexpectedly temporary: %v", err)
583 // The various errors should implement the Error interface.
584 func TestErrors(t *testing.T) {
587 _ Error = &ParseError{}
588 _ Error = &AddrError{}
589 _ Error = UnknownNetworkError("")
590 _ Error = InvalidAddrError("")
591 _ Error = &timeoutError{}
592 _ Error = &DNSConfigError{}
593 _ Error = &DNSError{}
596 // ErrClosed was introduced as type error, so we can't check
597 // it using a declaration.
598 if _, ok := ErrClosed.(Error); !ok {
599 t.Fatal("ErrClosed does not implement Error")