github.com/dara-project/godist@v0.0.0-20200823115410-e0c80c8f0c78/src/net/tcpsock_test.go (about)

     1  // Copyright 2012 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  package net
     6  
     7  import (
     8  	"fmt"
     9  	"internal/testenv"
    10  	"io"
    11  	"os"
    12  	"reflect"
    13  	"runtime"
    14  	"sync"
    15  	"testing"
    16  	"time"
    17  )
    18  
    19  func BenchmarkTCP4OneShot(b *testing.B) {
    20  	benchmarkTCP(b, false, false, "127.0.0.1:0")
    21  }
    22  
    23  func BenchmarkTCP4OneShotTimeout(b *testing.B) {
    24  	benchmarkTCP(b, false, true, "127.0.0.1:0")
    25  }
    26  
    27  func BenchmarkTCP4Persistent(b *testing.B) {
    28  	benchmarkTCP(b, true, false, "127.0.0.1:0")
    29  }
    30  
    31  func BenchmarkTCP4PersistentTimeout(b *testing.B) {
    32  	benchmarkTCP(b, true, true, "127.0.0.1:0")
    33  }
    34  
    35  func BenchmarkTCP6OneShot(b *testing.B) {
    36  	if !supportsIPv6() {
    37  		b.Skip("ipv6 is not supported")
    38  	}
    39  	benchmarkTCP(b, false, false, "[::1]:0")
    40  }
    41  
    42  func BenchmarkTCP6OneShotTimeout(b *testing.B) {
    43  	if !supportsIPv6() {
    44  		b.Skip("ipv6 is not supported")
    45  	}
    46  	benchmarkTCP(b, false, true, "[::1]:0")
    47  }
    48  
    49  func BenchmarkTCP6Persistent(b *testing.B) {
    50  	if !supportsIPv6() {
    51  		b.Skip("ipv6 is not supported")
    52  	}
    53  	benchmarkTCP(b, true, false, "[::1]:0")
    54  }
    55  
    56  func BenchmarkTCP6PersistentTimeout(b *testing.B) {
    57  	if !supportsIPv6() {
    58  		b.Skip("ipv6 is not supported")
    59  	}
    60  	benchmarkTCP(b, true, true, "[::1]:0")
    61  }
    62  
    63  func benchmarkTCP(b *testing.B, persistent, timeout bool, laddr string) {
    64  	testHookUninstaller.Do(uninstallTestHooks)
    65  
    66  	const msgLen = 512
    67  	conns := b.N
    68  	numConcurrent := runtime.GOMAXPROCS(-1) * 2
    69  	msgs := 1
    70  	if persistent {
    71  		conns = numConcurrent
    72  		msgs = b.N / conns
    73  		if msgs == 0 {
    74  			msgs = 1
    75  		}
    76  		if conns > b.N {
    77  			conns = b.N
    78  		}
    79  	}
    80  	sendMsg := func(c Conn, buf []byte) bool {
    81  		n, err := c.Write(buf)
    82  		if n != len(buf) || err != nil {
    83  			b.Log(err)
    84  			return false
    85  		}
    86  		return true
    87  	}
    88  	recvMsg := func(c Conn, buf []byte) bool {
    89  		for read := 0; read != len(buf); {
    90  			n, err := c.Read(buf)
    91  			read += n
    92  			if err != nil {
    93  				b.Log(err)
    94  				return false
    95  			}
    96  		}
    97  		return true
    98  	}
    99  	ln, err := Listen("tcp", laddr)
   100  	if err != nil {
   101  		b.Fatal(err)
   102  	}
   103  	defer ln.Close()
   104  	serverSem := make(chan bool, numConcurrent)
   105  	// Acceptor.
   106  	go func() {
   107  		for {
   108  			c, err := ln.Accept()
   109  			if err != nil {
   110  				break
   111  			}
   112  			serverSem <- true
   113  			// Server connection.
   114  			go func(c Conn) {
   115  				defer func() {
   116  					c.Close()
   117  					<-serverSem
   118  				}()
   119  				if timeout {
   120  					c.SetDeadline(time.Now().Add(time.Hour)) // Not intended to fire.
   121  				}
   122  				var buf [msgLen]byte
   123  				for m := 0; m < msgs; m++ {
   124  					if !recvMsg(c, buf[:]) || !sendMsg(c, buf[:]) {
   125  						break
   126  					}
   127  				}
   128  			}(c)
   129  		}
   130  	}()
   131  	clientSem := make(chan bool, numConcurrent)
   132  	for i := 0; i < conns; i++ {
   133  		clientSem <- true
   134  		// Client connection.
   135  		go func() {
   136  			defer func() {
   137  				<-clientSem
   138  			}()
   139  			c, err := Dial("tcp", ln.Addr().String())
   140  			if err != nil {
   141  				b.Log(err)
   142  				return
   143  			}
   144  			defer c.Close()
   145  			if timeout {
   146  				c.SetDeadline(time.Now().Add(time.Hour)) // Not intended to fire.
   147  			}
   148  			var buf [msgLen]byte
   149  			for m := 0; m < msgs; m++ {
   150  				if !sendMsg(c, buf[:]) || !recvMsg(c, buf[:]) {
   151  					break
   152  				}
   153  			}
   154  		}()
   155  	}
   156  	for i := 0; i < numConcurrent; i++ {
   157  		clientSem <- true
   158  		serverSem <- true
   159  	}
   160  }
   161  
   162  func BenchmarkTCP4ConcurrentReadWrite(b *testing.B) {
   163  	benchmarkTCPConcurrentReadWrite(b, "127.0.0.1:0")
   164  }
   165  
   166  func BenchmarkTCP6ConcurrentReadWrite(b *testing.B) {
   167  	if !supportsIPv6() {
   168  		b.Skip("ipv6 is not supported")
   169  	}
   170  	benchmarkTCPConcurrentReadWrite(b, "[::1]:0")
   171  }
   172  
   173  func benchmarkTCPConcurrentReadWrite(b *testing.B, laddr string) {
   174  	testHookUninstaller.Do(uninstallTestHooks)
   175  
   176  	// The benchmark creates GOMAXPROCS client/server pairs.
   177  	// Each pair creates 4 goroutines: client reader/writer and server reader/writer.
   178  	// The benchmark stresses concurrent reading and writing to the same connection.
   179  	// Such pattern is used in net/http and net/rpc.
   180  
   181  	b.StopTimer()
   182  
   183  	P := runtime.GOMAXPROCS(0)
   184  	N := b.N / P
   185  	W := 1000
   186  
   187  	// Setup P client/server connections.
   188  	clients := make([]Conn, P)
   189  	servers := make([]Conn, P)
   190  	ln, err := Listen("tcp", laddr)
   191  	if err != nil {
   192  		b.Fatal(err)
   193  	}
   194  	defer ln.Close()
   195  	done := make(chan bool)
   196  	go func() {
   197  		for p := 0; p < P; p++ {
   198  			s, err := ln.Accept()
   199  			if err != nil {
   200  				b.Error(err)
   201  				return
   202  			}
   203  			servers[p] = s
   204  		}
   205  		done <- true
   206  	}()
   207  	for p := 0; p < P; p++ {
   208  		c, err := Dial("tcp", ln.Addr().String())
   209  		if err != nil {
   210  			b.Fatal(err)
   211  		}
   212  		clients[p] = c
   213  	}
   214  	<-done
   215  
   216  	b.StartTimer()
   217  
   218  	var wg sync.WaitGroup
   219  	wg.Add(4 * P)
   220  	for p := 0; p < P; p++ {
   221  		// Client writer.
   222  		go func(c Conn) {
   223  			defer wg.Done()
   224  			var buf [1]byte
   225  			for i := 0; i < N; i++ {
   226  				v := byte(i)
   227  				for w := 0; w < W; w++ {
   228  					v *= v
   229  				}
   230  				buf[0] = v
   231  				_, err := c.Write(buf[:])
   232  				if err != nil {
   233  					b.Error(err)
   234  					return
   235  				}
   236  			}
   237  		}(clients[p])
   238  
   239  		// Pipe between server reader and server writer.
   240  		pipe := make(chan byte, 128)
   241  
   242  		// Server reader.
   243  		go func(s Conn) {
   244  			defer wg.Done()
   245  			var buf [1]byte
   246  			for i := 0; i < N; i++ {
   247  				_, err := s.Read(buf[:])
   248  				if err != nil {
   249  					b.Error(err)
   250  					return
   251  				}
   252  				pipe <- buf[0]
   253  			}
   254  		}(servers[p])
   255  
   256  		// Server writer.
   257  		go func(s Conn) {
   258  			defer wg.Done()
   259  			var buf [1]byte
   260  			for i := 0; i < N; i++ {
   261  				v := <-pipe
   262  				for w := 0; w < W; w++ {
   263  					v *= v
   264  				}
   265  				buf[0] = v
   266  				_, err := s.Write(buf[:])
   267  				if err != nil {
   268  					b.Error(err)
   269  					return
   270  				}
   271  			}
   272  			s.Close()
   273  		}(servers[p])
   274  
   275  		// Client reader.
   276  		go func(c Conn) {
   277  			defer wg.Done()
   278  			var buf [1]byte
   279  			for i := 0; i < N; i++ {
   280  				_, err := c.Read(buf[:])
   281  				if err != nil {
   282  					b.Error(err)
   283  					return
   284  				}
   285  			}
   286  			c.Close()
   287  		}(clients[p])
   288  	}
   289  	wg.Wait()
   290  }
   291  
   292  type resolveTCPAddrTest struct {
   293  	network       string
   294  	litAddrOrName string
   295  	addr          *TCPAddr
   296  	err           error
   297  }
   298  
   299  var resolveTCPAddrTests = []resolveTCPAddrTest{
   300  	{"tcp", "127.0.0.1:0", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil},
   301  	{"tcp4", "127.0.0.1:65535", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535}, nil},
   302  
   303  	{"tcp", "[::1]:0", &TCPAddr{IP: ParseIP("::1"), Port: 0}, nil},
   304  	{"tcp6", "[::1]:65535", &TCPAddr{IP: ParseIP("::1"), Port: 65535}, nil},
   305  
   306  	{"tcp", "[::1%en0]:1", &TCPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"}, nil},
   307  	{"tcp6", "[::1%911]:2", &TCPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911"}, nil},
   308  
   309  	{"", "127.0.0.1:0", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, // Go 1.0 behavior
   310  	{"", "[::1]:0", &TCPAddr{IP: ParseIP("::1"), Port: 0}, nil},         // Go 1.0 behavior
   311  
   312  	{"tcp", ":12345", &TCPAddr{Port: 12345}, nil},
   313  
   314  	{"http", "127.0.0.1:0", nil, UnknownNetworkError("http")},
   315  
   316  	{"tcp", "127.0.0.1:http", &TCPAddr{IP: ParseIP("127.0.0.1"), Port: 80}, nil},
   317  	{"tcp", "[::ffff:127.0.0.1]:http", &TCPAddr{IP: ParseIP("::ffff:127.0.0.1"), Port: 80}, nil},
   318  	{"tcp", "[2001:db8::1]:http", &TCPAddr{IP: ParseIP("2001:db8::1"), Port: 80}, nil},
   319  	{"tcp4", "127.0.0.1:http", &TCPAddr{IP: ParseIP("127.0.0.1"), Port: 80}, nil},
   320  	{"tcp4", "[::ffff:127.0.0.1]:http", &TCPAddr{IP: ParseIP("127.0.0.1"), Port: 80}, nil},
   321  	{"tcp6", "[2001:db8::1]:http", &TCPAddr{IP: ParseIP("2001:db8::1"), Port: 80}, nil},
   322  
   323  	{"tcp4", "[2001:db8::1]:http", nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: "2001:db8::1"}},
   324  	{"tcp6", "127.0.0.1:http", nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: "127.0.0.1"}},
   325  	{"tcp6", "[::ffff:127.0.0.1]:http", nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: "::ffff:127.0.0.1"}},
   326  }
   327  
   328  func TestResolveTCPAddr(t *testing.T) {
   329  	origTestHookLookupIP := testHookLookupIP
   330  	defer func() { testHookLookupIP = origTestHookLookupIP }()
   331  	testHookLookupIP = lookupLocalhost
   332  
   333  	for _, tt := range resolveTCPAddrTests {
   334  		addr, err := ResolveTCPAddr(tt.network, tt.litAddrOrName)
   335  		if !reflect.DeepEqual(addr, tt.addr) || !reflect.DeepEqual(err, tt.err) {
   336  			t.Errorf("ResolveTCPAddr(%q, %q) = %#v, %v, want %#v, %v", tt.network, tt.litAddrOrName, addr, err, tt.addr, tt.err)
   337  			continue
   338  		}
   339  		if err == nil {
   340  			addr2, err := ResolveTCPAddr(addr.Network(), addr.String())
   341  			if !reflect.DeepEqual(addr2, tt.addr) || err != tt.err {
   342  				t.Errorf("(%q, %q): ResolveTCPAddr(%q, %q) = %#v, %v, want %#v, %v", tt.network, tt.litAddrOrName, addr.Network(), addr.String(), addr2, err, tt.addr, tt.err)
   343  			}
   344  		}
   345  	}
   346  }
   347  
   348  var tcpListenerNameTests = []struct {
   349  	net   string
   350  	laddr *TCPAddr
   351  }{
   352  	{"tcp4", &TCPAddr{IP: IPv4(127, 0, 0, 1)}},
   353  	{"tcp4", &TCPAddr{}},
   354  	{"tcp4", nil},
   355  }
   356  
   357  func TestTCPListenerName(t *testing.T) {
   358  	testenv.MustHaveExternalNetwork(t)
   359  
   360  	for _, tt := range tcpListenerNameTests {
   361  		ln, err := ListenTCP(tt.net, tt.laddr)
   362  		if err != nil {
   363  			t.Fatal(err)
   364  		}
   365  		defer ln.Close()
   366  		la := ln.Addr()
   367  		if a, ok := la.(*TCPAddr); !ok || a.Port == 0 {
   368  			t.Fatalf("got %v; expected a proper address with non-zero port number", la)
   369  		}
   370  	}
   371  }
   372  
   373  func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
   374  	testenv.MustHaveExternalNetwork(t)
   375  
   376  	if !supportsIPv6() {
   377  		t.Skip("IPv6 is not supported")
   378  	}
   379  
   380  	for i, tt := range ipv6LinkLocalUnicastTCPTests {
   381  		ln, err := Listen(tt.network, tt.address)
   382  		if err != nil {
   383  			// It might return "LookupHost returned no
   384  			// suitable address" error on some platforms.
   385  			t.Log(err)
   386  			continue
   387  		}
   388  		ls, err := (&streamListener{Listener: ln}).newLocalServer()
   389  		if err != nil {
   390  			t.Fatal(err)
   391  		}
   392  		defer ls.teardown()
   393  		ch := make(chan error, 1)
   394  		handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
   395  		if err := ls.buildup(handler); err != nil {
   396  			t.Fatal(err)
   397  		}
   398  		if la, ok := ln.Addr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" {
   399  			t.Fatalf("got %v; expected a proper address with zone identifier", la)
   400  		}
   401  
   402  		c, err := Dial(tt.network, ls.Listener.Addr().String())
   403  		if err != nil {
   404  			t.Fatal(err)
   405  		}
   406  		defer c.Close()
   407  		if la, ok := c.LocalAddr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" {
   408  			t.Fatalf("got %v; expected a proper address with zone identifier", la)
   409  		}
   410  		if ra, ok := c.RemoteAddr().(*TCPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
   411  			t.Fatalf("got %v; expected a proper address with zone identifier", ra)
   412  		}
   413  
   414  		if _, err := c.Write([]byte("TCP OVER IPV6 LINKLOCAL TEST")); err != nil {
   415  			t.Fatal(err)
   416  		}
   417  		b := make([]byte, 32)
   418  		if _, err := c.Read(b); err != nil {
   419  			t.Fatal(err)
   420  		}
   421  
   422  		for err := range ch {
   423  			t.Errorf("#%d: %v", i, err)
   424  		}
   425  	}
   426  }
   427  
   428  func TestTCPConcurrentAccept(t *testing.T) {
   429  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
   430  	ln, err := Listen("tcp", "127.0.0.1:0")
   431  	if err != nil {
   432  		t.Fatal(err)
   433  	}
   434  	const N = 10
   435  	var wg sync.WaitGroup
   436  	wg.Add(N)
   437  	for i := 0; i < N; i++ {
   438  		go func() {
   439  			for {
   440  				c, err := ln.Accept()
   441  				if err != nil {
   442  					break
   443  				}
   444  				c.Close()
   445  			}
   446  			wg.Done()
   447  		}()
   448  	}
   449  	attempts := 10 * N
   450  	fails := 0
   451  	d := &Dialer{Timeout: 200 * time.Millisecond}
   452  	for i := 0; i < attempts; i++ {
   453  		c, err := d.Dial("tcp", ln.Addr().String())
   454  		if err != nil {
   455  			fails++
   456  		} else {
   457  			c.Close()
   458  		}
   459  	}
   460  	ln.Close()
   461  	wg.Wait()
   462  	if fails > attempts/9 { // see issues 7400 and 7541
   463  		t.Fatalf("too many Dial failed: %v", fails)
   464  	}
   465  	if fails > 0 {
   466  		t.Logf("# of failed Dials: %v", fails)
   467  	}
   468  }
   469  
   470  func TestTCPReadWriteAllocs(t *testing.T) {
   471  	switch runtime.GOOS {
   472  	case "plan9":
   473  		// The implementation of asynchronous cancelable
   474  		// I/O on Plan 9 allocates memory.
   475  		// See net/fd_io_plan9.go.
   476  		t.Skipf("not supported on %s", runtime.GOOS)
   477  	case "nacl":
   478  		// NaCl needs to allocate pseudo file descriptor
   479  		// stuff. See syscall/fd_nacl.go.
   480  		t.Skipf("not supported on %s", runtime.GOOS)
   481  	}
   482  
   483  	ln, err := Listen("tcp", "127.0.0.1:0")
   484  	if err != nil {
   485  		t.Fatal(err)
   486  	}
   487  	defer ln.Close()
   488  	var server Conn
   489  	errc := make(chan error, 1)
   490  	go func() {
   491  		var err error
   492  		server, err = ln.Accept()
   493  		errc <- err
   494  	}()
   495  	client, err := Dial("tcp", ln.Addr().String())
   496  	if err != nil {
   497  		t.Fatal(err)
   498  	}
   499  	defer client.Close()
   500  	if err := <-errc; err != nil {
   501  		t.Fatal(err)
   502  	}
   503  	defer server.Close()
   504  
   505  	var buf [128]byte
   506  	allocs := testing.AllocsPerRun(1000, func() {
   507  		_, err := server.Write(buf[:])
   508  		if err != nil {
   509  			t.Fatal(err)
   510  		}
   511  		_, err = io.ReadFull(client, buf[:])
   512  		if err != nil {
   513  			t.Fatal(err)
   514  		}
   515  	})
   516  	if allocs > 0 {
   517  		t.Fatalf("got %v; want 0", allocs)
   518  	}
   519  
   520  	var bufwrt [128]byte
   521  	ch := make(chan bool)
   522  	defer close(ch)
   523  	go func() {
   524  		for <-ch {
   525  			_, err := server.Write(bufwrt[:])
   526  			errc <- err
   527  		}
   528  	}()
   529  	allocs = testing.AllocsPerRun(1000, func() {
   530  		ch <- true
   531  		if _, err = io.ReadFull(client, buf[:]); err != nil {
   532  			t.Fatal(err)
   533  		}
   534  		if err := <-errc; err != nil {
   535  			t.Fatal(err)
   536  		}
   537  	})
   538  	if allocs > 0 {
   539  		t.Fatalf("got %v; want 0", allocs)
   540  	}
   541  }
   542  
   543  func TestTCPStress(t *testing.T) {
   544  	const conns = 2
   545  	const msgLen = 512
   546  	msgs := int(1e4)
   547  	if testing.Short() {
   548  		msgs = 1e2
   549  	}
   550  
   551  	sendMsg := func(c Conn, buf []byte) bool {
   552  		n, err := c.Write(buf)
   553  		if n != len(buf) || err != nil {
   554  			t.Log(err)
   555  			return false
   556  		}
   557  		return true
   558  	}
   559  	recvMsg := func(c Conn, buf []byte) bool {
   560  		for read := 0; read != len(buf); {
   561  			n, err := c.Read(buf)
   562  			read += n
   563  			if err != nil {
   564  				t.Log(err)
   565  				return false
   566  			}
   567  		}
   568  		return true
   569  	}
   570  
   571  	ln, err := Listen("tcp", "127.0.0.1:0")
   572  	if err != nil {
   573  		t.Fatal(err)
   574  	}
   575  	done := make(chan bool)
   576  	// Acceptor.
   577  	go func() {
   578  		defer func() {
   579  			done <- true
   580  		}()
   581  		for {
   582  			c, err := ln.Accept()
   583  			if err != nil {
   584  				break
   585  			}
   586  			// Server connection.
   587  			go func(c Conn) {
   588  				defer c.Close()
   589  				var buf [msgLen]byte
   590  				for m := 0; m < msgs; m++ {
   591  					if !recvMsg(c, buf[:]) || !sendMsg(c, buf[:]) {
   592  						break
   593  					}
   594  				}
   595  			}(c)
   596  		}
   597  	}()
   598  	for i := 0; i < conns; i++ {
   599  		// Client connection.
   600  		go func() {
   601  			defer func() {
   602  				done <- true
   603  			}()
   604  			c, err := Dial("tcp", ln.Addr().String())
   605  			if err != nil {
   606  				t.Log(err)
   607  				return
   608  			}
   609  			defer c.Close()
   610  			var buf [msgLen]byte
   611  			for m := 0; m < msgs; m++ {
   612  				if !sendMsg(c, buf[:]) || !recvMsg(c, buf[:]) {
   613  					break
   614  				}
   615  			}
   616  		}()
   617  	}
   618  	for i := 0; i < conns; i++ {
   619  		<-done
   620  	}
   621  	ln.Close()
   622  	<-done
   623  }
   624  
   625  func TestTCPSelfConnect(t *testing.T) {
   626  	if runtime.GOOS == "windows" {
   627  		// TODO(brainman): do not know why it hangs.
   628  		t.Skip("known-broken test on windows")
   629  	}
   630  
   631  	ln, err := newLocalListener("tcp")
   632  	if err != nil {
   633  		t.Fatal(err)
   634  	}
   635  	var d Dialer
   636  	c, err := d.Dial(ln.Addr().Network(), ln.Addr().String())
   637  	if err != nil {
   638  		ln.Close()
   639  		t.Fatal(err)
   640  	}
   641  	network := c.LocalAddr().Network()
   642  	laddr := *c.LocalAddr().(*TCPAddr)
   643  	c.Close()
   644  	ln.Close()
   645  
   646  	// Try to connect to that address repeatedly.
   647  	n := 100000
   648  	if testing.Short() {
   649  		n = 1000
   650  	}
   651  	switch runtime.GOOS {
   652  	case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "solaris", "windows":
   653  		// Non-Linux systems take a long time to figure
   654  		// out that there is nothing listening on localhost.
   655  		n = 100
   656  	}
   657  	for i := 0; i < n; i++ {
   658  		d.Timeout = time.Millisecond
   659  		c, err := d.Dial(network, laddr.String())
   660  		if err == nil {
   661  			addr := c.LocalAddr().(*TCPAddr)
   662  			if addr.Port == laddr.Port || addr.IP.Equal(laddr.IP) {
   663  				t.Errorf("Dial %v should fail", addr)
   664  			} else {
   665  				t.Logf("Dial %v succeeded - possibly racing with other listener", addr)
   666  			}
   667  			c.Close()
   668  		}
   669  	}
   670  }
   671  
   672  // Test that >32-bit reads work on 64-bit systems.
   673  // On 32-bit systems this tests that maxint reads work.
   674  func TestTCPBig(t *testing.T) {
   675  	if !*testTCPBig {
   676  		t.Skip("test disabled; use -tcpbig to enable")
   677  	}
   678  
   679  	for _, writev := range []bool{false, true} {
   680  		t.Run(fmt.Sprintf("writev=%v", writev), func(t *testing.T) {
   681  			ln, err := newLocalListener("tcp")
   682  			if err != nil {
   683  				t.Fatal(err)
   684  			}
   685  			defer ln.Close()
   686  
   687  			x := int(1 << 30)
   688  			x = x*5 + 1<<20 // just over 5 GB on 64-bit, just over 1GB on 32-bit
   689  			done := make(chan int)
   690  			go func() {
   691  				defer close(done)
   692  				c, err := ln.Accept()
   693  				if err != nil {
   694  					t.Error(err)
   695  					return
   696  				}
   697  				buf := make([]byte, x)
   698  				var n int
   699  				if writev {
   700  					var n64 int64
   701  					n64, err = (&Buffers{buf}).WriteTo(c)
   702  					n = int(n64)
   703  				} else {
   704  					n, err = c.Write(buf)
   705  				}
   706  				if n != len(buf) || err != nil {
   707  					t.Errorf("Write(buf) = %d, %v, want %d, nil", n, err, x)
   708  				}
   709  				c.Close()
   710  			}()
   711  
   712  			c, err := Dial("tcp", ln.Addr().String())
   713  			if err != nil {
   714  				t.Fatal(err)
   715  			}
   716  			buf := make([]byte, x)
   717  			n, err := io.ReadFull(c, buf)
   718  			if n != len(buf) || err != nil {
   719  				t.Errorf("Read(buf) = %d, %v, want %d, nil", n, err, x)
   720  			}
   721  			c.Close()
   722  			<-done
   723  		})
   724  	}
   725  }
   726  
   727  func TestCopyPipeIntoTCP(t *testing.T) {
   728  	ln, err := newLocalListener("tcp")
   729  	if err != nil {
   730  		t.Fatal(err)
   731  	}
   732  	defer ln.Close()
   733  
   734  	errc := make(chan error, 1)
   735  	defer func() {
   736  		if err := <-errc; err != nil {
   737  			t.Error(err)
   738  		}
   739  	}()
   740  	go func() {
   741  		c, err := ln.Accept()
   742  		if err != nil {
   743  			errc <- err
   744  			return
   745  		}
   746  		defer c.Close()
   747  
   748  		buf := make([]byte, 100)
   749  		n, err := io.ReadFull(c, buf)
   750  		if err != io.ErrUnexpectedEOF || n != 2 {
   751  			errc <- fmt.Errorf("got err=%q n=%v; want err=%q n=2", err, n, io.ErrUnexpectedEOF)
   752  			return
   753  		}
   754  
   755  		errc <- nil
   756  	}()
   757  
   758  	c, err := Dial("tcp", ln.Addr().String())
   759  	if err != nil {
   760  		t.Fatal(err)
   761  	}
   762  	defer c.Close()
   763  
   764  	r, w, err := os.Pipe()
   765  	if err != nil {
   766  		t.Fatal(err)
   767  	}
   768  	defer r.Close()
   769  
   770  	errc2 := make(chan error, 1)
   771  	defer func() {
   772  		if err := <-errc2; err != nil {
   773  			t.Error(err)
   774  		}
   775  	}()
   776  
   777  	defer w.Close()
   778  
   779  	go func() {
   780  		_, err := io.Copy(c, r)
   781  		errc2 <- err
   782  	}()
   783  
   784  	// Split write into 2 packets. That makes Windows TransmitFile
   785  	// drop second packet.
   786  	packet := make([]byte, 1)
   787  	_, err = w.Write(packet)
   788  	if err != nil {
   789  		t.Fatal(err)
   790  	}
   791  	time.Sleep(100 * time.Millisecond)
   792  	_, err = w.Write(packet)
   793  	if err != nil {
   794  		t.Fatal(err)
   795  	}
   796  }