Black Lives Matter. Support the Equal Justice Initiative.

Source file src/net/tcpsock_test.go

Documentation: net

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

View as plain text