...
Run Format

Source file src/net/net_test.go

Documentation: net

     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.
     4  
     5  // +build !js
     6  
     7  package net
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"internal/testenv"
    13  	"io"
    14  	"net/internal/socktest"
    15  	"os"
    16  	"runtime"
    17  	"testing"
    18  	"time"
    19  )
    20  
    21  func TestCloseRead(t *testing.T) {
    22  	switch runtime.GOOS {
    23  	case "plan9":
    24  		t.Skipf("not supported on %s", runtime.GOOS)
    25  	}
    26  
    27  	for _, network := range []string{"tcp", "unix", "unixpacket"} {
    28  		if !testableNetwork(network) {
    29  			t.Logf("skipping %s test", network)
    30  			continue
    31  		}
    32  
    33  		ln, err := newLocalListener(network)
    34  		if err != nil {
    35  			t.Fatal(err)
    36  		}
    37  		switch network {
    38  		case "unix", "unixpacket":
    39  			defer os.Remove(ln.Addr().String())
    40  		}
    41  		defer ln.Close()
    42  
    43  		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
    44  		if err != nil {
    45  			t.Fatal(err)
    46  		}
    47  		switch network {
    48  		case "unix", "unixpacket":
    49  			defer os.Remove(c.LocalAddr().String())
    50  		}
    51  		defer c.Close()
    52  
    53  		switch c := c.(type) {
    54  		case *TCPConn:
    55  			err = c.CloseRead()
    56  		case *UnixConn:
    57  			err = c.CloseRead()
    58  		}
    59  		if err != nil {
    60  			if perr := parseCloseError(err, true); perr != nil {
    61  				t.Error(perr)
    62  			}
    63  			t.Fatal(err)
    64  		}
    65  		var b [1]byte
    66  		n, err := c.Read(b[:])
    67  		if n != 0 || err == nil {
    68  			t.Fatalf("got (%d, %v); want (0, error)", n, err)
    69  		}
    70  	}
    71  }
    72  
    73  func TestCloseWrite(t *testing.T) {
    74  	switch runtime.GOOS {
    75  	case "nacl", "plan9":
    76  		t.Skipf("not supported on %s", runtime.GOOS)
    77  	}
    78  
    79  	handler := func(ls *localServer, ln Listener) {
    80  		c, err := ln.Accept()
    81  		if err != nil {
    82  			t.Error(err)
    83  			return
    84  		}
    85  		defer c.Close()
    86  
    87  		var b [1]byte
    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)
    91  			return
    92  		}
    93  		switch c := c.(type) {
    94  		case *TCPConn:
    95  			err = c.CloseWrite()
    96  		case *UnixConn:
    97  			err = c.CloseWrite()
    98  		}
    99  		if err != nil {
   100  			if perr := parseCloseError(err, true); perr != nil {
   101  				t.Error(perr)
   102  			}
   103  			t.Error(err)
   104  			return
   105  		}
   106  		n, err = c.Write(b[:])
   107  		if err == nil {
   108  			t.Errorf("got (%d, %v); want (any, error)", n, err)
   109  			return
   110  		}
   111  	}
   112  
   113  	for _, network := range []string{"tcp", "unix", "unixpacket"} {
   114  		if !testableNetwork(network) {
   115  			t.Logf("skipping %s test", network)
   116  			continue
   117  		}
   118  
   119  		ls, err := newLocalServer(network)
   120  		if err != nil {
   121  			t.Fatal(err)
   122  		}
   123  		defer ls.teardown()
   124  		if err := ls.buildup(handler); err != nil {
   125  			t.Fatal(err)
   126  		}
   127  
   128  		c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
   129  		if err != nil {
   130  			t.Fatal(err)
   131  		}
   132  		switch network {
   133  		case "unix", "unixpacket":
   134  			defer os.Remove(c.LocalAddr().String())
   135  		}
   136  		defer c.Close()
   137  
   138  		switch c := c.(type) {
   139  		case *TCPConn:
   140  			err = c.CloseWrite()
   141  		case *UnixConn:
   142  			err = c.CloseWrite()
   143  		}
   144  		if err != nil {
   145  			if perr := parseCloseError(err, true); perr != nil {
   146  				t.Error(perr)
   147  			}
   148  			t.Fatal(err)
   149  		}
   150  		var b [1]byte
   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)
   154  		}
   155  		n, err = c.Write(b[:])
   156  		if err == nil {
   157  			t.Fatalf("got (%d, %v); want (any, error)", n, err)
   158  		}
   159  	}
   160  }
   161  
   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)
   166  			continue
   167  		}
   168  
   169  		ln, err := newLocalListener(network)
   170  		if err != nil {
   171  			t.Fatal(err)
   172  		}
   173  		switch network {
   174  		case "unix", "unixpacket":
   175  			defer os.Remove(ln.Addr().String())
   176  		}
   177  		defer ln.Close()
   178  
   179  		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   180  		if err != nil {
   181  			t.Fatal(err)
   182  		}
   183  		switch network {
   184  		case "unix", "unixpacket":
   185  			defer os.Remove(c.LocalAddr().String())
   186  		}
   187  		defer c.Close()
   188  
   189  		if err := c.Close(); err != nil {
   190  			if perr := parseCloseError(err, false); perr != nil {
   191  				t.Error(perr)
   192  			}
   193  			t.Fatal(err)
   194  		}
   195  		var b [1]byte
   196  		n, err := c.Read(b[:])
   197  		if n != 0 || err == nil {
   198  			t.Fatalf("got (%d, %v); want (0, error)", n, err)
   199  		}
   200  	}
   201  }
   202  
   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)
   207  			continue
   208  		}
   209  
   210  		ln, err := newLocalListener(network)
   211  		if err != nil {
   212  			t.Fatal(err)
   213  		}
   214  		switch network {
   215  		case "unix", "unixpacket":
   216  			defer os.Remove(ln.Addr().String())
   217  		}
   218  
   219  		dst := ln.Addr().String()
   220  		if err := ln.Close(); err != nil {
   221  			if perr := parseCloseError(err, false); perr != nil {
   222  				t.Error(perr)
   223  			}
   224  			t.Fatal(err)
   225  		}
   226  		c, err := ln.Accept()
   227  		if err == nil {
   228  			c.Close()
   229  			t.Fatal("should fail")
   230  		}
   231  
   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.
   243  			//
   244  			// Note that net.inet.tcp.reuseport_ext=1 by
   245  			// default on DragonFly BSD.
   246  			time.Sleep(time.Millisecond)
   247  
   248  			cc, err := Dial("tcp", dst)
   249  			if err == nil {
   250  				t.Error("Dial to closed TCP listener succeeded.")
   251  				cc.Close()
   252  			}
   253  		}
   254  	}
   255  }
   256  
   257  func TestPacketConnClose(t *testing.T) {
   258  	for _, network := range []string{"udp", "unixgram"} {
   259  		if !testableNetwork(network) {
   260  			t.Logf("skipping %s test", network)
   261  			continue
   262  		}
   263  
   264  		c, err := newLocalPacketListener(network)
   265  		if err != nil {
   266  			t.Fatal(err)
   267  		}
   268  		switch network {
   269  		case "unixgram":
   270  			defer os.Remove(c.LocalAddr().String())
   271  		}
   272  		defer c.Close()
   273  
   274  		if err := c.Close(); err != nil {
   275  			if perr := parseCloseError(err, false); perr != nil {
   276  				t.Error(perr)
   277  			}
   278  			t.Fatal(err)
   279  		}
   280  		var b [1]byte
   281  		n, _, err := c.ReadFrom(b[:])
   282  		if n != 0 || err == nil {
   283  			t.Fatalf("got (%d, %v); want (0, error)", n, err)
   284  		}
   285  	}
   286  }
   287  
   288  // nacl was previous failing to reuse an address.
   289  func TestListenCloseListen(t *testing.T) {
   290  	const maxTries = 10
   291  	for tries := 0; tries < maxTries; tries++ {
   292  		ln, err := newLocalListener("tcp")
   293  		if err != nil {
   294  			t.Fatal(err)
   295  		}
   296  		addr := ln.Addr().String()
   297  		if err := ln.Close(); err != nil {
   298  			if perr := parseCloseError(err, false); perr != nil {
   299  				t.Error(perr)
   300  			}
   301  			t.Fatal(err)
   302  		}
   303  		ln, err = Listen("tcp", addr)
   304  		if err == nil {
   305  			// Success. nacl couldn't do this before.
   306  			ln.Close()
   307  			return
   308  		}
   309  		t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err)
   310  	}
   311  	t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries)
   312  }
   313  
   314  // See golang.org/issue/6163, golang.org/issue/6987.
   315  func TestAcceptIgnoreAbortedConnRequest(t *testing.T) {
   316  	switch runtime.GOOS {
   317  	case "plan9":
   318  		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
   319  	}
   320  
   321  	syserr := make(chan error)
   322  	go func() {
   323  		defer close(syserr)
   324  		for _, err := range abortedConnRequestErrors {
   325  			syserr <- err
   326  		}
   327  	}()
   328  	sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) {
   329  		if err, ok := <-syserr; ok {
   330  			return nil, err
   331  		}
   332  		return nil, nil
   333  	})
   334  	defer sw.Set(socktest.FilterAccept, nil)
   335  
   336  	operr := make(chan error, 1)
   337  	handler := func(ls *localServer, ln Listener) {
   338  		defer close(operr)
   339  		c, err := ln.Accept()
   340  		if err != nil {
   341  			if perr := parseAcceptError(err); perr != nil {
   342  				operr <- perr
   343  			}
   344  			operr <- err
   345  			return
   346  		}
   347  		c.Close()
   348  	}
   349  	ls, err := newLocalServer("tcp")
   350  	if err != nil {
   351  		t.Fatal(err)
   352  	}
   353  	defer ls.teardown()
   354  	if err := ls.buildup(handler); err != nil {
   355  		t.Fatal(err)
   356  	}
   357  
   358  	c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
   359  	if err != nil {
   360  		t.Fatal(err)
   361  	}
   362  	c.Close()
   363  
   364  	for err := range operr {
   365  		t.Error(err)
   366  	}
   367  }
   368  
   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)
   373  			continue
   374  		}
   375  
   376  		ln, err := newLocalListener(network)
   377  		if err != nil {
   378  			t.Fatal(err)
   379  		}
   380  		connc := make(chan Conn, 1)
   381  		go func() {
   382  			defer ln.Close()
   383  			c, err := ln.Accept()
   384  			if err != nil {
   385  				t.Error(err)
   386  			}
   387  			connc <- c // might be nil
   388  		}()
   389  		c, err := Dial(network, ln.Addr().String())
   390  		if err != nil {
   391  			t.Fatal(err)
   392  		}
   393  		defer c.Close()
   394  		sc := <-connc
   395  		if sc == nil {
   396  			continue
   397  		}
   398  		defer sc.Close()
   399  
   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.
   403  			// See Issue 15735.
   404  			go io.WriteString(sc, "a")
   405  		}
   406  
   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)
   410  		}
   411  
   412  		if runtime.GOOS == "windows" {
   413  			// Same as comment above.
   414  			go io.WriteString(c, "a")
   415  		}
   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)
   419  		}
   420  	}
   421  }
   422  
   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")
   428  	if err != nil {
   429  		t.Fatal(err)
   430  	}
   431  	defer ln.Close()
   432  	errc := make(chan error, 2)
   433  	go func() {
   434  		c1, err := ln.Accept()
   435  		if err != nil {
   436  			errc <- err
   437  			return
   438  		}
   439  		defer c1.Close()
   440  		errc <- peer1(c1.(*TCPConn))
   441  	}()
   442  	go func() {
   443  		c2, err := Dial("tcp", ln.Addr().String())
   444  		if err != nil {
   445  			errc <- err
   446  			return
   447  		}
   448  		defer c2.Close()
   449  		errc <- peer2(c2.(*TCPConn))
   450  	}()
   451  	for i := 0; i < 2; i++ {
   452  		if err := <-errc; err != nil {
   453  			t.Fatal(err)
   454  		}
   455  	}
   456  }
   457  
   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
   461  // depends on this.
   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)
   467  		go func() {
   468  			defer close(errc)
   469  			go func() {
   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)
   474  
   475  				// Interrupt the upcoming Read, unblocking it:
   476  				cs.SetReadDeadline(time.Unix(123, 0)) // time in the past
   477  			}()
   478  			var buf [1]byte
   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)
   482  			}
   483  		}()
   484  		select {
   485  		case err := <-errc:
   486  			return 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")
   492  		}
   493  
   494  	}
   495  	// Do nothing in the client. Never write. Just wait for the
   496  	// server's half to be done.
   497  	client := func(*TCPConn) error {
   498  		<-serverDone
   499  		return nil
   500  	}
   501  	withTCPConnPair(t, client, server)
   502  }
   503  
   504  // Issue 17695: verify that a blocked Read is woken up by a Close.
   505  func TestCloseUnblocksRead(t *testing.T) {
   506  	t.Parallel()
   507  	server := func(cs *TCPConn) error {
   508  		// Give the client time to get stuck in a Read:
   509  		time.Sleep(20 * time.Millisecond)
   510  		cs.Close()
   511  		return nil
   512  	}
   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)
   517  		}
   518  		return nil
   519  	}
   520  	withTCPConnPair(t, client, server)
   521  }
   522  
   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)
   527  	}
   528  	t.Parallel()
   529  	server := func(cs *TCPConn) error {
   530  		cs.SetLinger(0)
   531  		// Give the client time to get stuck in a Read.
   532  		time.Sleep(20 * time.Millisecond)
   533  		cs.Close()
   534  		return nil
   535  	}
   536  	client := func(ss *TCPConn) error {
   537  		_, err := ss.Read([]byte{0})
   538  		if err == nil {
   539  			return errors.New("Read succeeded unexpectedly")
   540  		} else if err == io.EOF {
   541  			// This happens on NaCl and Plan 9.
   542  			return nil
   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)
   547  		}
   548  		return nil
   549  	}
   550  	withTCPConnPair(t, client, server)
   551  }
   552  

View as plain text