github.com/gidoBOSSftw5731/go/src@v0.0.0-20210226122457-d24b0edbf019/net/net_test.go (about) 1 // Copyright 2009 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 "errors" 12 "fmt" 13 "internal/testenv" 14 "io" 15 "net/internal/socktest" 16 "os" 17 "runtime" 18 "testing" 19 "time" 20 ) 21 22 func TestCloseRead(t *testing.T) { 23 switch runtime.GOOS { 24 case "plan9": 25 t.Skipf("not supported on %s", runtime.GOOS) 26 } 27 t.Parallel() 28 29 for _, network := range []string{"tcp", "unix", "unixpacket"} { 30 network := network 31 t.Run(network, func(t *testing.T) { 32 if !testableNetwork(network) { 33 t.Skipf("network %s is not testable on the current platform", network) 34 } 35 t.Parallel() 36 37 ln, err := newLocalListener(network) 38 if err != nil { 39 t.Fatal(err) 40 } 41 switch network { 42 case "unix", "unixpacket": 43 defer os.Remove(ln.Addr().String()) 44 } 45 defer ln.Close() 46 47 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 48 if err != nil { 49 t.Fatal(err) 50 } 51 switch network { 52 case "unix", "unixpacket": 53 defer os.Remove(c.LocalAddr().String()) 54 } 55 defer c.Close() 56 57 switch c := c.(type) { 58 case *TCPConn: 59 err = c.CloseRead() 60 case *UnixConn: 61 err = c.CloseRead() 62 } 63 if err != nil { 64 if perr := parseCloseError(err, true); perr != nil { 65 t.Error(perr) 66 } 67 t.Fatal(err) 68 } 69 var b [1]byte 70 n, err := c.Read(b[:]) 71 if n != 0 || err == nil { 72 t.Fatalf("got (%d, %v); want (0, error)", n, err) 73 } 74 }) 75 } 76 } 77 78 func TestCloseWrite(t *testing.T) { 79 switch runtime.GOOS { 80 case "plan9": 81 t.Skipf("not supported on %s", runtime.GOOS) 82 } 83 84 t.Parallel() 85 deadline, _ := t.Deadline() 86 if !deadline.IsZero() { 87 // Leave 10% headroom on the deadline to report errors and clean up. 88 deadline = deadline.Add(-time.Until(deadline) / 10) 89 } 90 91 for _, network := range []string{"tcp", "unix", "unixpacket"} { 92 network := network 93 t.Run(network, func(t *testing.T) { 94 if !testableNetwork(network) { 95 t.Skipf("network %s is not testable on the current platform", network) 96 } 97 t.Parallel() 98 99 handler := func(ls *localServer, ln Listener) { 100 c, err := ln.Accept() 101 if err != nil { 102 t.Error(err) 103 return 104 } 105 if !deadline.IsZero() { 106 c.SetDeadline(deadline) 107 } 108 defer c.Close() 109 110 var b [1]byte 111 n, err := c.Read(b[:]) 112 if n != 0 || err != io.EOF { 113 t.Errorf("got (%d, %v); want (0, io.EOF)", n, err) 114 return 115 } 116 switch c := c.(type) { 117 case *TCPConn: 118 err = c.CloseWrite() 119 case *UnixConn: 120 err = c.CloseWrite() 121 } 122 if err != nil { 123 if perr := parseCloseError(err, true); perr != nil { 124 t.Error(perr) 125 } 126 t.Error(err) 127 return 128 } 129 n, err = c.Write(b[:]) 130 if err == nil { 131 t.Errorf("got (%d, %v); want (any, error)", n, err) 132 return 133 } 134 } 135 136 ls, err := newLocalServer(network) 137 if err != nil { 138 t.Fatal(err) 139 } 140 defer ls.teardown() 141 if err := ls.buildup(handler); err != nil { 142 t.Fatal(err) 143 } 144 145 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 146 if err != nil { 147 t.Fatal(err) 148 } 149 if !deadline.IsZero() { 150 c.SetDeadline(deadline) 151 } 152 switch network { 153 case "unix", "unixpacket": 154 defer os.Remove(c.LocalAddr().String()) 155 } 156 defer c.Close() 157 158 switch c := c.(type) { 159 case *TCPConn: 160 err = c.CloseWrite() 161 case *UnixConn: 162 err = c.CloseWrite() 163 } 164 if err != nil { 165 if perr := parseCloseError(err, true); perr != nil { 166 t.Error(perr) 167 } 168 t.Fatal(err) 169 } 170 var b [1]byte 171 n, err := c.Read(b[:]) 172 if n != 0 || err != io.EOF { 173 t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err) 174 } 175 n, err = c.Write(b[:]) 176 if err == nil { 177 t.Fatalf("got (%d, %v); want (any, error)", n, err) 178 } 179 }) 180 } 181 } 182 183 func TestConnClose(t *testing.T) { 184 t.Parallel() 185 for _, network := range []string{"tcp", "unix", "unixpacket"} { 186 network := network 187 t.Run(network, func(t *testing.T) { 188 if !testableNetwork(network) { 189 t.Skipf("network %s is not testable on the current platform", network) 190 } 191 t.Parallel() 192 193 ln, err := newLocalListener(network) 194 if err != nil { 195 t.Fatal(err) 196 } 197 switch network { 198 case "unix", "unixpacket": 199 defer os.Remove(ln.Addr().String()) 200 } 201 defer ln.Close() 202 203 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 204 if err != nil { 205 t.Fatal(err) 206 } 207 switch network { 208 case "unix", "unixpacket": 209 defer os.Remove(c.LocalAddr().String()) 210 } 211 defer c.Close() 212 213 if err := c.Close(); err != nil { 214 if perr := parseCloseError(err, false); perr != nil { 215 t.Error(perr) 216 } 217 t.Fatal(err) 218 } 219 var b [1]byte 220 n, err := c.Read(b[:]) 221 if n != 0 || err == nil { 222 t.Fatalf("got (%d, %v); want (0, error)", n, err) 223 } 224 }) 225 } 226 } 227 228 func TestListenerClose(t *testing.T) { 229 t.Parallel() 230 for _, network := range []string{"tcp", "unix", "unixpacket"} { 231 network := network 232 t.Run(network, func(t *testing.T) { 233 if !testableNetwork(network) { 234 t.Skipf("network %s is not testable on the current platform", network) 235 } 236 t.Parallel() 237 238 ln, err := newLocalListener(network) 239 if err != nil { 240 t.Fatal(err) 241 } 242 switch network { 243 case "unix", "unixpacket": 244 defer os.Remove(ln.Addr().String()) 245 } 246 247 dst := ln.Addr().String() 248 if err := ln.Close(); err != nil { 249 if perr := parseCloseError(err, false); perr != nil { 250 t.Error(perr) 251 } 252 t.Fatal(err) 253 } 254 c, err := ln.Accept() 255 if err == nil { 256 c.Close() 257 t.Fatal("should fail") 258 } 259 260 if network == "tcp" { 261 // We will have two TCP FSMs inside the 262 // kernel here. There's no guarantee that a 263 // signal comes from the far end FSM will be 264 // delivered immediately to the near end FSM, 265 // especially on the platforms that allow 266 // multiple consumer threads to pull pending 267 // established connections at the same time by 268 // enabling SO_REUSEPORT option such as Linux, 269 // DragonFly BSD. So we need to give some time 270 // quantum to the kernel. 271 // 272 // Note that net.inet.tcp.reuseport_ext=1 by 273 // default on DragonFly BSD. 274 time.Sleep(time.Millisecond) 275 276 cc, err := Dial("tcp", dst) 277 if err == nil { 278 t.Error("Dial to closed TCP listener succeeded.") 279 cc.Close() 280 } 281 } 282 }) 283 } 284 } 285 286 func TestPacketConnClose(t *testing.T) { 287 t.Parallel() 288 for _, network := range []string{"udp", "unixgram"} { 289 network := network 290 t.Run(network, func(t *testing.T) { 291 if !testableNetwork(network) { 292 t.Skipf("network %s is not testable on the current platform", network) 293 } 294 t.Parallel() 295 296 c, err := newLocalPacketListener(network) 297 if err != nil { 298 t.Fatal(err) 299 } 300 switch network { 301 case "unixgram": 302 defer os.Remove(c.LocalAddr().String()) 303 } 304 defer c.Close() 305 306 if err := c.Close(); err != nil { 307 if perr := parseCloseError(err, false); perr != nil { 308 t.Error(perr) 309 } 310 t.Fatal(err) 311 } 312 var b [1]byte 313 n, _, err := c.ReadFrom(b[:]) 314 if n != 0 || err == nil { 315 t.Fatalf("got (%d, %v); want (0, error)", n, err) 316 } 317 }) 318 } 319 } 320 321 func TestListenCloseListen(t *testing.T) { 322 const maxTries = 10 323 for tries := 0; tries < maxTries; tries++ { 324 ln, err := newLocalListener("tcp") 325 if err != nil { 326 t.Fatal(err) 327 } 328 addr := ln.Addr().String() 329 if err := ln.Close(); err != nil { 330 if perr := parseCloseError(err, false); perr != nil { 331 t.Error(perr) 332 } 333 t.Fatal(err) 334 } 335 ln, err = Listen("tcp", addr) 336 if err == nil { 337 // Success. (This test didn't always make it here earlier.) 338 ln.Close() 339 return 340 } 341 t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err) 342 } 343 t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries) 344 } 345 346 // See golang.org/issue/6163, golang.org/issue/6987. 347 func TestAcceptIgnoreAbortedConnRequest(t *testing.T) { 348 switch runtime.GOOS { 349 case "plan9": 350 t.Skipf("%s does not have full support of socktest", runtime.GOOS) 351 } 352 353 syserr := make(chan error) 354 go func() { 355 defer close(syserr) 356 for _, err := range abortedConnRequestErrors { 357 syserr <- err 358 } 359 }() 360 sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) { 361 if err, ok := <-syserr; ok { 362 return nil, err 363 } 364 return nil, nil 365 }) 366 defer sw.Set(socktest.FilterAccept, nil) 367 368 operr := make(chan error, 1) 369 handler := func(ls *localServer, ln Listener) { 370 defer close(operr) 371 c, err := ln.Accept() 372 if err != nil { 373 if perr := parseAcceptError(err); perr != nil { 374 operr <- perr 375 } 376 operr <- err 377 return 378 } 379 c.Close() 380 } 381 ls, err := newLocalServer("tcp") 382 if err != nil { 383 t.Fatal(err) 384 } 385 defer ls.teardown() 386 if err := ls.buildup(handler); err != nil { 387 t.Fatal(err) 388 } 389 390 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 391 if err != nil { 392 t.Fatal(err) 393 } 394 c.Close() 395 396 for err := range operr { 397 t.Error(err) 398 } 399 } 400 401 func TestZeroByteRead(t *testing.T) { 402 t.Parallel() 403 for _, network := range []string{"tcp", "unix", "unixpacket"} { 404 network := network 405 t.Run(network, func(t *testing.T) { 406 if !testableNetwork(network) { 407 t.Skipf("network %s is not testable on the current platform", network) 408 } 409 t.Parallel() 410 411 ln, err := newLocalListener(network) 412 if err != nil { 413 t.Fatal(err) 414 } 415 connc := make(chan Conn, 1) 416 go func() { 417 defer ln.Close() 418 c, err := ln.Accept() 419 if err != nil { 420 t.Error(err) 421 } 422 connc <- c // might be nil 423 }() 424 c, err := Dial(network, ln.Addr().String()) 425 if err != nil { 426 t.Fatal(err) 427 } 428 defer c.Close() 429 sc := <-connc 430 if sc == nil { 431 return 432 } 433 defer sc.Close() 434 435 if runtime.GOOS == "windows" { 436 // A zero byte read on Windows caused a wait for readability first. 437 // Rather than change that behavior, satisfy it in this test. 438 // See Issue 15735. 439 go io.WriteString(sc, "a") 440 } 441 442 n, err := c.Read(nil) 443 if n != 0 || err != nil { 444 t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err) 445 } 446 447 if runtime.GOOS == "windows" { 448 // Same as comment above. 449 go io.WriteString(c, "a") 450 } 451 n, err = sc.Read(nil) 452 if n != 0 || err != nil { 453 t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err) 454 } 455 }) 456 } 457 } 458 459 // withTCPConnPair sets up a TCP connection between two peers, then 460 // runs peer1 and peer2 concurrently. withTCPConnPair returns when 461 // both have completed. 462 func withTCPConnPair(t *testing.T, peer1, peer2 func(c *TCPConn) error) { 463 ln, err := newLocalListener("tcp") 464 if err != nil { 465 t.Fatal(err) 466 } 467 defer ln.Close() 468 errc := make(chan error, 2) 469 go func() { 470 c1, err := ln.Accept() 471 if err != nil { 472 errc <- err 473 return 474 } 475 defer c1.Close() 476 errc <- peer1(c1.(*TCPConn)) 477 }() 478 go func() { 479 c2, err := Dial("tcp", ln.Addr().String()) 480 if err != nil { 481 errc <- err 482 return 483 } 484 defer c2.Close() 485 errc <- peer2(c2.(*TCPConn)) 486 }() 487 for i := 0; i < 2; i++ { 488 if err := <-errc; err != nil { 489 t.Fatal(err) 490 } 491 } 492 } 493 494 // Tests that a blocked Read is interrupted by a concurrent SetReadDeadline 495 // modifying that Conn's read deadline to the past. 496 // See golang.org/cl/30164 which documented this. The net/http package 497 // depends on this. 498 func TestReadTimeoutUnblocksRead(t *testing.T) { 499 serverDone := make(chan struct{}) 500 server := func(cs *TCPConn) error { 501 defer close(serverDone) 502 errc := make(chan error, 1) 503 go func() { 504 defer close(errc) 505 go func() { 506 // TODO: find a better way to wait 507 // until we're blocked in the cs.Read 508 // call below. Sleep is lame. 509 time.Sleep(100 * time.Millisecond) 510 511 // Interrupt the upcoming Read, unblocking it: 512 cs.SetReadDeadline(time.Unix(123, 0)) // time in the past 513 }() 514 var buf [1]byte 515 n, err := cs.Read(buf[:1]) 516 if n != 0 || err == nil { 517 errc <- fmt.Errorf("Read = %v, %v; want 0, non-nil", n, err) 518 } 519 }() 520 select { 521 case err := <-errc: 522 return err 523 case <-time.After(5 * time.Second): 524 buf := make([]byte, 2<<20) 525 buf = buf[:runtime.Stack(buf, true)] 526 println("Stacks at timeout:\n", string(buf)) 527 return errors.New("timeout waiting for Read to finish") 528 } 529 530 } 531 // Do nothing in the client. Never write. Just wait for the 532 // server's half to be done. 533 client := func(*TCPConn) error { 534 <-serverDone 535 return nil 536 } 537 withTCPConnPair(t, client, server) 538 } 539 540 // Issue 17695: verify that a blocked Read is woken up by a Close. 541 func TestCloseUnblocksRead(t *testing.T) { 542 t.Parallel() 543 server := func(cs *TCPConn) error { 544 // Give the client time to get stuck in a Read: 545 time.Sleep(20 * time.Millisecond) 546 cs.Close() 547 return nil 548 } 549 client := func(ss *TCPConn) error { 550 n, err := ss.Read([]byte{0}) 551 if n != 0 || err != io.EOF { 552 return fmt.Errorf("Read = %v, %v; want 0, EOF", n, err) 553 } 554 return nil 555 } 556 withTCPConnPair(t, client, server) 557 } 558 559 // Issue 24808: verify that ECONNRESET is not temporary for read. 560 func TestNotTemporaryRead(t *testing.T) { 561 if runtime.GOOS == "freebsd" { 562 testenv.SkipFlaky(t, 25289) 563 } 564 if runtime.GOOS == "aix" { 565 testenv.SkipFlaky(t, 29685) 566 } 567 t.Parallel() 568 server := func(cs *TCPConn) error { 569 cs.SetLinger(0) 570 // Give the client time to get stuck in a Read. 571 time.Sleep(50 * time.Millisecond) 572 cs.Close() 573 return nil 574 } 575 client := func(ss *TCPConn) error { 576 _, err := ss.Read([]byte{0}) 577 if err == nil { 578 return errors.New("Read succeeded unexpectedly") 579 } else if err == io.EOF { 580 // This happens on Plan 9. 581 return nil 582 } else if ne, ok := err.(Error); !ok { 583 return fmt.Errorf("unexpected error %v", err) 584 } else if ne.Temporary() { 585 return fmt.Errorf("unexpected temporary error %v", err) 586 } 587 return nil 588 } 589 withTCPConnPair(t, client, server) 590 }