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