github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/net/net_test.go (about)

     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  	"github.com/x04/go/src/errors"
    11  	"github.com/x04/go/src/fmt"
    12  	"github.com/x04/go/src/internal/testenv"
    13  	"github.com/x04/go/src/io"
    14  	"github.com/x04/go/src/net/internal/socktest"
    15  	"github.com/x04/go/src/os"
    16  	"github.com/x04/go/src/runtime"
    17  	"github.com/x04/go/src/testing"
    18  	"github.com/x04/go/src/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 "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  func TestListenCloseListen(t *testing.T) {
   289  	const maxTries = 10
   290  	for tries := 0; tries < maxTries; tries++ {
   291  		ln, err := newLocalListener("tcp")
   292  		if err != nil {
   293  			t.Fatal(err)
   294  		}
   295  		addr := ln.Addr().String()
   296  		if err := ln.Close(); err != nil {
   297  			if perr := parseCloseError(err, false); perr != nil {
   298  				t.Error(perr)
   299  			}
   300  			t.Fatal(err)
   301  		}
   302  		ln, err = Listen("tcp", addr)
   303  		if err == nil {
   304  			// Success. (This test didn't always make it here earlier.)
   305  			ln.Close()
   306  			return
   307  		}
   308  		t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err)
   309  	}
   310  	t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries)
   311  }
   312  
   313  // See golang.org/issue/6163, golang.org/issue/6987.
   314  func TestAcceptIgnoreAbortedConnRequest(t *testing.T) {
   315  	switch runtime.GOOS {
   316  	case "plan9":
   317  		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
   318  	}
   319  
   320  	syserr := make(chan error)
   321  	go func() {
   322  		defer close(syserr)
   323  		for _, err := range abortedConnRequestErrors {
   324  			syserr <- err
   325  		}
   326  	}()
   327  	sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) {
   328  		if err, ok := <-syserr; ok {
   329  			return nil, err
   330  		}
   331  		return nil, nil
   332  	})
   333  	defer sw.Set(socktest.FilterAccept, nil)
   334  
   335  	operr := make(chan error, 1)
   336  	handler := func(ls *localServer, ln Listener) {
   337  		defer close(operr)
   338  		c, err := ln.Accept()
   339  		if err != nil {
   340  			if perr := parseAcceptError(err); perr != nil {
   341  				operr <- perr
   342  			}
   343  			operr <- err
   344  			return
   345  		}
   346  		c.Close()
   347  	}
   348  	ls, err := newLocalServer("tcp")
   349  	if err != nil {
   350  		t.Fatal(err)
   351  	}
   352  	defer ls.teardown()
   353  	if err := ls.buildup(handler); err != nil {
   354  		t.Fatal(err)
   355  	}
   356  
   357  	c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
   358  	if err != nil {
   359  		t.Fatal(err)
   360  	}
   361  	c.Close()
   362  
   363  	for err := range operr {
   364  		t.Error(err)
   365  	}
   366  }
   367  
   368  func TestZeroByteRead(t *testing.T) {
   369  	for _, network := range []string{"tcp", "unix", "unixpacket"} {
   370  		if !testableNetwork(network) {
   371  			t.Logf("skipping %s test", network)
   372  			continue
   373  		}
   374  
   375  		ln, err := newLocalListener(network)
   376  		if err != nil {
   377  			t.Fatal(err)
   378  		}
   379  		connc := make(chan Conn, 1)
   380  		go func() {
   381  			defer ln.Close()
   382  			c, err := ln.Accept()
   383  			if err != nil {
   384  				t.Error(err)
   385  			}
   386  			connc <- c	// might be nil
   387  		}()
   388  		c, err := Dial(network, ln.Addr().String())
   389  		if err != nil {
   390  			t.Fatal(err)
   391  		}
   392  		defer c.Close()
   393  		sc := <-connc
   394  		if sc == nil {
   395  			continue
   396  		}
   397  		defer sc.Close()
   398  
   399  		if runtime.GOOS == "windows" {
   400  			// A zero byte read on Windows caused a wait for readability first.
   401  			// Rather than change that behavior, satisfy it in this test.
   402  			// See Issue 15735.
   403  			go io.WriteString(sc, "a")
   404  		}
   405  
   406  		n, err := c.Read(nil)
   407  		if n != 0 || err != nil {
   408  			t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err)
   409  		}
   410  
   411  		if runtime.GOOS == "windows" {
   412  			// Same as comment above.
   413  			go io.WriteString(c, "a")
   414  		}
   415  		n, err = sc.Read(nil)
   416  		if n != 0 || err != nil {
   417  			t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err)
   418  		}
   419  	}
   420  }
   421  
   422  // withTCPConnPair sets up a TCP connection between two peers, then
   423  // runs peer1 and peer2 concurrently. withTCPConnPair returns when
   424  // both have completed.
   425  func withTCPConnPair(t *testing.T, peer1, peer2 func(c *TCPConn) error) {
   426  	ln, err := newLocalListener("tcp")
   427  	if err != nil {
   428  		t.Fatal(err)
   429  	}
   430  	defer ln.Close()
   431  	errc := make(chan error, 2)
   432  	go func() {
   433  		c1, err := ln.Accept()
   434  		if err != nil {
   435  			errc <- err
   436  			return
   437  		}
   438  		defer c1.Close()
   439  		errc <- peer1(c1.(*TCPConn))
   440  	}()
   441  	go func() {
   442  		c2, err := Dial("tcp", ln.Addr().String())
   443  		if err != nil {
   444  			errc <- err
   445  			return
   446  		}
   447  		defer c2.Close()
   448  		errc <- peer2(c2.(*TCPConn))
   449  	}()
   450  	for i := 0; i < 2; i++ {
   451  		if err := <-errc; err != nil {
   452  			t.Fatal(err)
   453  		}
   454  	}
   455  }
   456  
   457  // Tests that a blocked Read is interrupted by a concurrent SetReadDeadline
   458  // modifying that Conn's read deadline to the past.
   459  // See golang.org/cl/30164 which documented this. The net/http package
   460  // depends on this.
   461  func TestReadTimeoutUnblocksRead(t *testing.T) {
   462  	serverDone := make(chan struct{})
   463  	server := func(cs *TCPConn) error {
   464  		defer close(serverDone)
   465  		errc := make(chan error, 1)
   466  		go func() {
   467  			defer close(errc)
   468  			go func() {
   469  				// TODO: find a better way to wait
   470  				// until we're blocked in the cs.Read
   471  				// call below. Sleep is lame.
   472  				time.Sleep(100 * time.Millisecond)
   473  
   474  				// Interrupt the upcoming Read, unblocking it:
   475  				cs.SetReadDeadline(time.Unix(123, 0))	// time in the past
   476  			}()
   477  			var buf [1]byte
   478  			n, err := cs.Read(buf[:1])
   479  			if n != 0 || err == nil {
   480  				errc <- fmt.Errorf("Read = %v, %v; want 0, non-nil", n, err)
   481  			}
   482  		}()
   483  		select {
   484  		case err := <-errc:
   485  			return err
   486  		case <-time.After(5 * time.Second):
   487  			buf := make([]byte, 2<<20)
   488  			buf = buf[:runtime.Stack(buf, true)]
   489  			println("Stacks at timeout:\n", string(buf))
   490  			return errors.New("timeout waiting for Read to finish")
   491  		}
   492  
   493  	}
   494  	// Do nothing in the client. Never write. Just wait for the
   495  	// server's half to be done.
   496  	client := func(*TCPConn) error {
   497  		<-serverDone
   498  		return nil
   499  	}
   500  	withTCPConnPair(t, client, server)
   501  }
   502  
   503  // Issue 17695: verify that a blocked Read is woken up by a Close.
   504  func TestCloseUnblocksRead(t *testing.T) {
   505  	t.Parallel()
   506  	server := func(cs *TCPConn) error {
   507  		// Give the client time to get stuck in a Read:
   508  		time.Sleep(20 * time.Millisecond)
   509  		cs.Close()
   510  		return nil
   511  	}
   512  	client := func(ss *TCPConn) error {
   513  		n, err := ss.Read([]byte{0})
   514  		if n != 0 || err != io.EOF {
   515  			return fmt.Errorf("Read = %v, %v; want 0, EOF", n, err)
   516  		}
   517  		return nil
   518  	}
   519  	withTCPConnPair(t, client, server)
   520  }
   521  
   522  // Issue 24808: verify that ECONNRESET is not temporary for read.
   523  func TestNotTemporaryRead(t *testing.T) {
   524  	if runtime.GOOS == "freebsd" {
   525  		testenv.SkipFlaky(t, 25289)
   526  	}
   527  	if runtime.GOOS == "aix" {
   528  		testenv.SkipFlaky(t, 29685)
   529  	}
   530  	t.Parallel()
   531  	server := func(cs *TCPConn) error {
   532  		cs.SetLinger(0)
   533  		// Give the client time to get stuck in a Read.
   534  		time.Sleep(50 * time.Millisecond)
   535  		cs.Close()
   536  		return nil
   537  	}
   538  	client := func(ss *TCPConn) error {
   539  		_, err := ss.Read([]byte{0})
   540  		if err == nil {
   541  			return errors.New("Read succeeded unexpectedly")
   542  		} else if err == io.EOF {
   543  			// This happens on Plan 9.
   544  			return nil
   545  		} else if ne, ok := err.(Error); !ok {
   546  			return fmt.Errorf("unexpected error %v", err)
   547  		} else if ne.Temporary() {
   548  			return fmt.Errorf("unexpected temporary error %v", err)
   549  		}
   550  		return nil
   551  	}
   552  	withTCPConnPair(t, client, server)
   553  }