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