github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/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 // +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 }