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 7package net 8 9import ( 10 "fmt" 11 "internal/testenv" 12 "io" 13 "os" 14 "reflect" 15 "runtime" 16 "sync" 17 "testing" 18 "time" 19) 20 21func BenchmarkTCP4OneShot(b *testing.B) { 22 benchmarkTCP(b, false, false, "127.0.0.1:0") 23} 24 25func BenchmarkTCP4OneShotTimeout(b *testing.B) { 26 benchmarkTCP(b, false, true, "127.0.0.1:0") 27} 28 29func BenchmarkTCP4Persistent(b *testing.B) { 30 benchmarkTCP(b, true, false, "127.0.0.1:0") 31} 32 33func BenchmarkTCP4PersistentTimeout(b *testing.B) { 34 benchmarkTCP(b, true, true, "127.0.0.1:0") 35} 36 37func BenchmarkTCP6OneShot(b *testing.B) { 38 if !supportsIPv6() { 39 b.Skip("ipv6 is not supported") 40 } 41 benchmarkTCP(b, false, false, "[::1]:0") 42} 43 44func BenchmarkTCP6OneShotTimeout(b *testing.B) { 45 if !supportsIPv6() { 46 b.Skip("ipv6 is not supported") 47 } 48 benchmarkTCP(b, false, true, "[::1]:0") 49} 50 51func BenchmarkTCP6Persistent(b *testing.B) { 52 if !supportsIPv6() { 53 b.Skip("ipv6 is not supported") 54 } 55 benchmarkTCP(b, true, false, "[::1]:0") 56} 57 58func BenchmarkTCP6PersistentTimeout(b *testing.B) { 59 if !supportsIPv6() { 60 b.Skip("ipv6 is not supported") 61 } 62 benchmarkTCP(b, true, true, "[::1]:0") 63} 64 65func 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 164func BenchmarkTCP4ConcurrentReadWrite(b *testing.B) { 165 benchmarkTCPConcurrentReadWrite(b, "127.0.0.1:0") 166} 167 168func BenchmarkTCP6ConcurrentReadWrite(b *testing.B) { 169 if !supportsIPv6() { 170 b.Skip("ipv6 is not supported") 171 } 172 benchmarkTCPConcurrentReadWrite(b, "[::1]:0") 173} 174 175func 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 294type resolveTCPAddrTest struct { 295 network string 296 litAddrOrName string 297 addr *TCPAddr 298 err error 299} 300 301var 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 330func 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 350var 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 359func 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 375func 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 430func 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 472func TestTCPReadWriteAllocs(t *testing.T) { 473 if runtime.Compiler == "gccgo" { 474 t.Skip("skipping for gccgo until escape analysis is enabled") 475 } 476 477 switch runtime.GOOS { 478 case "plan9": 479 // The implementation of asynchronous cancelable 480 // I/O on Plan 9 allocates memory. 481 // See net/fd_io_plan9.go. 482 t.Skipf("not supported on %s", runtime.GOOS) 483 } 484 485 ln, err := Listen("tcp", "127.0.0.1:0") 486 if err != nil { 487 t.Fatal(err) 488 } 489 defer ln.Close() 490 var server Conn 491 errc := make(chan error, 1) 492 go func() { 493 var err error 494 server, err = ln.Accept() 495 errc <- err 496 }() 497 client, err := Dial("tcp", ln.Addr().String()) 498 if err != nil { 499 t.Fatal(err) 500 } 501 defer client.Close() 502 if err := <-errc; err != nil { 503 t.Fatal(err) 504 } 505 defer server.Close() 506 507 var buf [128]byte 508 allocs := testing.AllocsPerRun(1000, func() { 509 _, err := server.Write(buf[:]) 510 if err != nil { 511 t.Fatal(err) 512 } 513 _, err = io.ReadFull(client, buf[:]) 514 if err != nil { 515 t.Fatal(err) 516 } 517 }) 518 // For gccgo changed "> 0" to "> 7". 519 if allocs > 7 { 520 t.Fatalf("got %v; want 0", allocs) 521 } 522 523 var bufwrt [128]byte 524 ch := make(chan bool) 525 defer close(ch) 526 go func() { 527 for <-ch { 528 _, err := server.Write(bufwrt[:]) 529 errc <- err 530 } 531 }() 532 allocs = testing.AllocsPerRun(1000, func() { 533 ch <- true 534 if _, err = io.ReadFull(client, buf[:]); err != nil { 535 t.Fatal(err) 536 } 537 if err := <-errc; err != nil { 538 t.Fatal(err) 539 } 540 }) 541 if allocs > 0 { 542 t.Fatalf("got %v; want 0", allocs) 543 } 544} 545 546func TestTCPStress(t *testing.T) { 547 const conns = 2 548 const msgLen = 512 549 msgs := int(1e4) 550 if testing.Short() { 551 msgs = 1e2 552 } 553 554 sendMsg := func(c Conn, buf []byte) bool { 555 n, err := c.Write(buf) 556 if n != len(buf) || err != nil { 557 t.Log(err) 558 return false 559 } 560 return true 561 } 562 recvMsg := func(c Conn, buf []byte) bool { 563 for read := 0; read != len(buf); { 564 n, err := c.Read(buf) 565 read += n 566 if err != nil { 567 t.Log(err) 568 return false 569 } 570 } 571 return true 572 } 573 574 ln, err := Listen("tcp", "127.0.0.1:0") 575 if err != nil { 576 t.Fatal(err) 577 } 578 done := make(chan bool) 579 // Acceptor. 580 go func() { 581 defer func() { 582 done <- true 583 }() 584 for { 585 c, err := ln.Accept() 586 if err != nil { 587 break 588 } 589 // Server connection. 590 go func(c Conn) { 591 defer c.Close() 592 var buf [msgLen]byte 593 for m := 0; m < msgs; m++ { 594 if !recvMsg(c, buf[:]) || !sendMsg(c, buf[:]) { 595 break 596 } 597 } 598 }(c) 599 } 600 }() 601 for i := 0; i < conns; i++ { 602 // Client connection. 603 go func() { 604 defer func() { 605 done <- true 606 }() 607 c, err := Dial("tcp", ln.Addr().String()) 608 if err != nil { 609 t.Log(err) 610 return 611 } 612 defer c.Close() 613 var buf [msgLen]byte 614 for m := 0; m < msgs; m++ { 615 if !sendMsg(c, buf[:]) || !recvMsg(c, buf[:]) { 616 break 617 } 618 } 619 }() 620 } 621 for i := 0; i < conns; i++ { 622 <-done 623 } 624 ln.Close() 625 <-done 626} 627 628func TestTCPSelfConnect(t *testing.T) { 629 if runtime.GOOS == "windows" { 630 // TODO(brainman): do not know why it hangs. 631 t.Skip("known-broken test on windows") 632 } 633 634 ln, err := newLocalListener("tcp") 635 if err != nil { 636 t.Fatal(err) 637 } 638 var d Dialer 639 c, err := d.Dial(ln.Addr().Network(), ln.Addr().String()) 640 if err != nil { 641 ln.Close() 642 t.Fatal(err) 643 } 644 network := c.LocalAddr().Network() 645 laddr := *c.LocalAddr().(*TCPAddr) 646 c.Close() 647 ln.Close() 648 649 // Try to connect to that address repeatedly. 650 n := 100000 651 if testing.Short() { 652 n = 1000 653 } 654 switch runtime.GOOS { 655 case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "illumos", "solaris", "windows": 656 // Non-Linux systems take a long time to figure 657 // out that there is nothing listening on localhost. 658 n = 100 659 } 660 for i := 0; i < n; i++ { 661 d.Timeout = time.Millisecond 662 c, err := d.Dial(network, laddr.String()) 663 if err == nil { 664 addr := c.LocalAddr().(*TCPAddr) 665 if addr.Port == laddr.Port || addr.IP.Equal(laddr.IP) { 666 t.Errorf("Dial %v should fail", addr) 667 } else { 668 t.Logf("Dial %v succeeded - possibly racing with other listener", addr) 669 } 670 c.Close() 671 } 672 } 673} 674 675// Test that >32-bit reads work on 64-bit systems. 676// On 32-bit systems this tests that maxint reads work. 677func TestTCPBig(t *testing.T) { 678 if !*testTCPBig { 679 t.Skip("test disabled; use -tcpbig to enable") 680 } 681 682 for _, writev := range []bool{false, true} { 683 t.Run(fmt.Sprintf("writev=%v", writev), func(t *testing.T) { 684 ln, err := newLocalListener("tcp") 685 if err != nil { 686 t.Fatal(err) 687 } 688 defer ln.Close() 689 690 x := int(1 << 30) 691 x = x*5 + 1<<20 // just over 5 GB on 64-bit, just over 1GB on 32-bit 692 done := make(chan int) 693 go func() { 694 defer close(done) 695 c, err := ln.Accept() 696 if err != nil { 697 t.Error(err) 698 return 699 } 700 buf := make([]byte, x) 701 var n int 702 if writev { 703 var n64 int64 704 n64, err = (&Buffers{buf}).WriteTo(c) 705 n = int(n64) 706 } else { 707 n, err = c.Write(buf) 708 } 709 if n != len(buf) || err != nil { 710 t.Errorf("Write(buf) = %d, %v, want %d, nil", n, err, x) 711 } 712 c.Close() 713 }() 714 715 c, err := Dial("tcp", ln.Addr().String()) 716 if err != nil { 717 t.Fatal(err) 718 } 719 buf := make([]byte, x) 720 n, err := io.ReadFull(c, buf) 721 if n != len(buf) || err != nil { 722 t.Errorf("Read(buf) = %d, %v, want %d, nil", n, err, x) 723 } 724 c.Close() 725 <-done 726 }) 727 } 728} 729 730func TestCopyPipeIntoTCP(t *testing.T) { 731 ln, err := newLocalListener("tcp") 732 if err != nil { 733 t.Fatal(err) 734 } 735 defer ln.Close() 736 737 errc := make(chan error, 1) 738 defer func() { 739 if err := <-errc; err != nil { 740 t.Error(err) 741 } 742 }() 743 go func() { 744 c, err := ln.Accept() 745 if err != nil { 746 errc <- err 747 return 748 } 749 defer c.Close() 750 751 buf := make([]byte, 100) 752 n, err := io.ReadFull(c, buf) 753 if err != io.ErrUnexpectedEOF || n != 2 { 754 errc <- fmt.Errorf("got err=%q n=%v; want err=%q n=2", err, n, io.ErrUnexpectedEOF) 755 return 756 } 757 758 errc <- nil 759 }() 760 761 c, err := Dial("tcp", ln.Addr().String()) 762 if err != nil { 763 t.Fatal(err) 764 } 765 defer c.Close() 766 767 r, w, err := os.Pipe() 768 if err != nil { 769 t.Fatal(err) 770 } 771 defer r.Close() 772 773 errc2 := make(chan error, 1) 774 defer func() { 775 if err := <-errc2; err != nil { 776 t.Error(err) 777 } 778 }() 779 780 defer w.Close() 781 782 go func() { 783 _, err := io.Copy(c, r) 784 errc2 <- err 785 }() 786 787 // Split write into 2 packets. That makes Windows TransmitFile 788 // drop second packet. 789 packet := make([]byte, 1) 790 _, err = w.Write(packet) 791 if err != nil { 792 t.Fatal(err) 793 } 794 time.Sleep(100 * time.Millisecond) 795 _, err = w.Write(packet) 796 if err != nil { 797 t.Fatal(err) 798 } 799} 800 801func BenchmarkSetReadDeadline(b *testing.B) { 802 ln, err := newLocalListener("tcp") 803 if err != nil { 804 b.Fatal(err) 805 } 806 defer ln.Close() 807 var serv Conn 808 done := make(chan error) 809 go func() { 810 var err error 811 serv, err = ln.Accept() 812 done <- err 813 }() 814 c, err := Dial("tcp", ln.Addr().String()) 815 if err != nil { 816 b.Fatal(err) 817 } 818 defer c.Close() 819 if err := <-done; err != nil { 820 b.Fatal(err) 821 } 822 defer serv.Close() 823 c.SetWriteDeadline(time.Now().Add(2 * time.Hour)) 824 deadline := time.Now().Add(time.Hour) 825 b.ResetTimer() 826 for i := 0; i < b.N; i++ { 827 c.SetReadDeadline(deadline) 828 deadline = deadline.Add(1) 829 } 830} 831