...

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