github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/net/tcpsock_test.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go: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 := (&streamListener{Listener: ln}).newLocalServer() 391 defer ls.teardown() 392 ch := make(chan error, 1) 393 handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) } 394 if err := ls.buildup(handler); err != nil { 395 t.Fatal(err) 396 } 397 if la, ok := ln.Addr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" { 398 t.Fatalf("got %v; expected a proper address with zone identifier", la) 399 } 400 401 c, err := Dial(tt.network, ls.Listener.Addr().String()) 402 if err != nil { 403 t.Fatal(err) 404 } 405 defer c.Close() 406 if la, ok := c.LocalAddr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" { 407 t.Fatalf("got %v; expected a proper address with zone identifier", la) 408 } 409 if ra, ok := c.RemoteAddr().(*TCPAddr); !ok || !tt.nameLookup && ra.Zone == "" { 410 t.Fatalf("got %v; expected a proper address with zone identifier", ra) 411 } 412 413 if _, err := c.Write([]byte("TCP OVER IPV6 LINKLOCAL TEST")); err != nil { 414 t.Fatal(err) 415 } 416 b := make([]byte, 32) 417 if _, err := c.Read(b); err != nil { 418 t.Fatal(err) 419 } 420 421 for err := range ch { 422 t.Errorf("#%d: %v", i, err) 423 } 424 } 425 } 426 427 func TestTCPConcurrentAccept(t *testing.T) { 428 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) 429 ln, err := Listen("tcp", "127.0.0.1:0") 430 if err != nil { 431 t.Fatal(err) 432 } 433 const N = 10 434 var wg sync.WaitGroup 435 wg.Add(N) 436 for i := 0; i < N; i++ { 437 go func() { 438 for { 439 c, err := ln.Accept() 440 if err != nil { 441 break 442 } 443 c.Close() 444 } 445 wg.Done() 446 }() 447 } 448 attempts := 10 * N 449 fails := 0 450 d := &Dialer{Timeout: 200 * time.Millisecond} 451 for i := 0; i < attempts; i++ { 452 c, err := d.Dial("tcp", ln.Addr().String()) 453 if err != nil { 454 fails++ 455 } else { 456 c.Close() 457 } 458 } 459 ln.Close() 460 wg.Wait() 461 if fails > attempts/9 { // see issues 7400 and 7541 462 t.Fatalf("too many Dial failed: %v", fails) 463 } 464 if fails > 0 { 465 t.Logf("# of failed Dials: %v", fails) 466 } 467 } 468 469 func TestTCPReadWriteAllocs(t *testing.T) { 470 switch runtime.GOOS { 471 case "plan9": 472 // The implementation of asynchronous cancelable 473 // I/O on Plan 9 allocates memory. 474 // See net/fd_io_plan9.go. 475 t.Skipf("not supported on %s", runtime.GOOS) 476 } 477 478 ln, err := Listen("tcp", "127.0.0.1:0") 479 if err != nil { 480 t.Fatal(err) 481 } 482 defer ln.Close() 483 var server Conn 484 errc := make(chan error, 1) 485 go func() { 486 var err error 487 server, err = ln.Accept() 488 errc <- err 489 }() 490 client, err := Dial("tcp", ln.Addr().String()) 491 if err != nil { 492 t.Fatal(err) 493 } 494 defer client.Close() 495 if err := <-errc; err != nil { 496 t.Fatal(err) 497 } 498 defer server.Close() 499 500 var buf [128]byte 501 allocs := testing.AllocsPerRun(1000, func() { 502 _, err := server.Write(buf[:]) 503 if err != nil { 504 t.Fatal(err) 505 } 506 _, err = io.ReadFull(client, buf[:]) 507 if err != nil { 508 t.Fatal(err) 509 } 510 }) 511 if allocs > 0 { 512 t.Fatalf("got %v; want 0", allocs) 513 } 514 515 var bufwrt [128]byte 516 ch := make(chan bool) 517 defer close(ch) 518 go func() { 519 for <-ch { 520 _, err := server.Write(bufwrt[:]) 521 errc <- err 522 } 523 }() 524 allocs = testing.AllocsPerRun(1000, func() { 525 ch <- true 526 if _, err = io.ReadFull(client, buf[:]); err != nil { 527 t.Fatal(err) 528 } 529 if err := <-errc; err != nil { 530 t.Fatal(err) 531 } 532 }) 533 if allocs > 0 { 534 t.Fatalf("got %v; want 0", allocs) 535 } 536 } 537 538 func TestTCPStress(t *testing.T) { 539 const conns = 2 540 const msgLen = 512 541 msgs := int(1e4) 542 if testing.Short() { 543 msgs = 1e2 544 } 545 546 sendMsg := func(c Conn, buf []byte) bool { 547 n, err := c.Write(buf) 548 if n != len(buf) || err != nil { 549 t.Log(err) 550 return false 551 } 552 return true 553 } 554 recvMsg := func(c Conn, buf []byte) bool { 555 for read := 0; read != len(buf); { 556 n, err := c.Read(buf) 557 read += n 558 if err != nil { 559 t.Log(err) 560 return false 561 } 562 } 563 return true 564 } 565 566 ln, err := Listen("tcp", "127.0.0.1:0") 567 if err != nil { 568 t.Fatal(err) 569 } 570 done := make(chan bool) 571 // Acceptor. 572 go func() { 573 defer func() { 574 done <- true 575 }() 576 for { 577 c, err := ln.Accept() 578 if err != nil { 579 break 580 } 581 // Server connection. 582 go func(c Conn) { 583 defer c.Close() 584 var buf [msgLen]byte 585 for m := 0; m < msgs; m++ { 586 if !recvMsg(c, buf[:]) || !sendMsg(c, buf[:]) { 587 break 588 } 589 } 590 }(c) 591 } 592 }() 593 for i := 0; i < conns; i++ { 594 // Client connection. 595 go func() { 596 defer func() { 597 done <- true 598 }() 599 c, err := Dial("tcp", ln.Addr().String()) 600 if err != nil { 601 t.Log(err) 602 return 603 } 604 defer c.Close() 605 var buf [msgLen]byte 606 for m := 0; m < msgs; m++ { 607 if !sendMsg(c, buf[:]) || !recvMsg(c, buf[:]) { 608 break 609 } 610 } 611 }() 612 } 613 for i := 0; i < conns; i++ { 614 <-done 615 } 616 ln.Close() 617 <-done 618 } 619 620 func TestTCPSelfConnect(t *testing.T) { 621 if runtime.GOOS == "windows" { 622 // TODO(brainman): do not know why it hangs. 623 t.Skip("known-broken test on windows") 624 } 625 626 ln := newLocalListener(t, "tcp") 627 var d Dialer 628 c, err := d.Dial(ln.Addr().Network(), ln.Addr().String()) 629 if err != nil { 630 ln.Close() 631 t.Fatal(err) 632 } 633 network := c.LocalAddr().Network() 634 laddr := *c.LocalAddr().(*TCPAddr) 635 c.Close() 636 ln.Close() 637 638 // Try to connect to that address repeatedly. 639 n := 100000 640 if testing.Short() { 641 n = 1000 642 } 643 switch runtime.GOOS { 644 case "darwin", "ios", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "illumos", "solaris", "windows": 645 // Non-Linux systems take a long time to figure 646 // out that there is nothing listening on localhost. 647 n = 100 648 } 649 for i := 0; i < n; i++ { 650 d.Timeout = time.Millisecond 651 c, err := d.Dial(network, laddr.String()) 652 if err == nil { 653 addr := c.LocalAddr().(*TCPAddr) 654 if addr.Port == laddr.Port || addr.IP.Equal(laddr.IP) { 655 t.Errorf("Dial %v should fail", addr) 656 } else { 657 t.Logf("Dial %v succeeded - possibly racing with other listener", addr) 658 } 659 c.Close() 660 } 661 } 662 } 663 664 // Test that >32-bit reads work on 64-bit systems. 665 // On 32-bit systems this tests that maxint reads work. 666 func TestTCPBig(t *testing.T) { 667 if !*testTCPBig { 668 t.Skip("test disabled; use -tcpbig to enable") 669 } 670 671 for _, writev := range []bool{false, true} { 672 t.Run(fmt.Sprintf("writev=%v", writev), func(t *testing.T) { 673 ln := newLocalListener(t, "tcp") 674 defer ln.Close() 675 676 x := int(1 << 30) 677 x = x*5 + 1<<20 // just over 5 GB on 64-bit, just over 1GB on 32-bit 678 done := make(chan int) 679 go func() { 680 defer close(done) 681 c, err := ln.Accept() 682 if err != nil { 683 t.Error(err) 684 return 685 } 686 buf := make([]byte, x) 687 var n int 688 if writev { 689 var n64 int64 690 n64, err = (&Buffers{buf}).WriteTo(c) 691 n = int(n64) 692 } else { 693 n, err = c.Write(buf) 694 } 695 if n != len(buf) || err != nil { 696 t.Errorf("Write(buf) = %d, %v, want %d, nil", n, err, x) 697 } 698 c.Close() 699 }() 700 701 c, err := Dial("tcp", ln.Addr().String()) 702 if err != nil { 703 t.Fatal(err) 704 } 705 buf := make([]byte, x) 706 n, err := io.ReadFull(c, buf) 707 if n != len(buf) || err != nil { 708 t.Errorf("Read(buf) = %d, %v, want %d, nil", n, err, x) 709 } 710 c.Close() 711 <-done 712 }) 713 } 714 } 715 716 func TestCopyPipeIntoTCP(t *testing.T) { 717 ln := newLocalListener(t, "tcp") 718 defer ln.Close() 719 720 errc := make(chan error, 1) 721 defer func() { 722 if err := <-errc; err != nil { 723 t.Error(err) 724 } 725 }() 726 go func() { 727 c, err := ln.Accept() 728 if err != nil { 729 errc <- err 730 return 731 } 732 defer c.Close() 733 734 buf := make([]byte, 100) 735 n, err := io.ReadFull(c, buf) 736 if err != io.ErrUnexpectedEOF || n != 2 { 737 errc <- fmt.Errorf("got err=%q n=%v; want err=%q n=2", err, n, io.ErrUnexpectedEOF) 738 return 739 } 740 741 errc <- nil 742 }() 743 744 c, err := Dial("tcp", ln.Addr().String()) 745 if err != nil { 746 t.Fatal(err) 747 } 748 defer c.Close() 749 750 r, w, err := os.Pipe() 751 if err != nil { 752 t.Fatal(err) 753 } 754 defer r.Close() 755 756 errc2 := make(chan error, 1) 757 defer func() { 758 if err := <-errc2; err != nil { 759 t.Error(err) 760 } 761 }() 762 763 defer w.Close() 764 765 go func() { 766 _, err := io.Copy(c, r) 767 errc2 <- err 768 }() 769 770 // Split write into 2 packets. That makes Windows TransmitFile 771 // drop second packet. 772 packet := make([]byte, 1) 773 _, err = w.Write(packet) 774 if err != nil { 775 t.Fatal(err) 776 } 777 time.Sleep(100 * time.Millisecond) 778 _, err = w.Write(packet) 779 if err != nil { 780 t.Fatal(err) 781 } 782 } 783 784 func BenchmarkSetReadDeadline(b *testing.B) { 785 ln := newLocalListener(b, "tcp") 786 defer ln.Close() 787 var serv Conn 788 done := make(chan error) 789 go func() { 790 var err error 791 serv, err = ln.Accept() 792 done <- err 793 }() 794 c, err := Dial("tcp", ln.Addr().String()) 795 if err != nil { 796 b.Fatal(err) 797 } 798 defer c.Close() 799 if err := <-done; err != nil { 800 b.Fatal(err) 801 } 802 defer serv.Close() 803 c.SetWriteDeadline(time.Now().Add(2 * time.Hour)) 804 deadline := time.Now().Add(time.Hour) 805 b.ResetTimer() 806 for i := 0; i < b.N; i++ { 807 c.SetReadDeadline(deadline) 808 deadline = deadline.Add(1) 809 } 810 }