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

View as plain text