github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/net/error_test.go (about) 1 // Copyright 2015 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 "context" 12 "errors" 13 "fmt" 14 "internal/poll" 15 "io" 16 "io/fs" 17 "net/internal/socktest" 18 "os" 19 "runtime" 20 "strings" 21 "testing" 22 "time" 23 ) 24 25 func (e *OpError) isValid() error { 26 if e.Op == "" { 27 return fmt.Errorf("OpError.Op is empty: %v", e) 28 } 29 if e.Net == "" { 30 return fmt.Errorf("OpError.Net is empty: %v", e) 31 } 32 for _, addr := range []Addr{e.Source, e.Addr} { 33 switch addr := addr.(type) { 34 case nil: 35 case *TCPAddr: 36 if addr == nil { 37 return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e) 38 } 39 case *UDPAddr: 40 if addr == nil { 41 return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e) 42 } 43 case *IPAddr: 44 if addr == nil { 45 return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e) 46 } 47 case *IPNet: 48 if addr == nil { 49 return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e) 50 } 51 case *UnixAddr: 52 if addr == nil { 53 return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e) 54 } 55 case *pipeAddr: 56 if addr == nil { 57 return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e) 58 } 59 case fileAddr: 60 if addr == "" { 61 return fmt.Errorf("OpError.Source or Addr is empty: %#v, %v", addr, e) 62 } 63 default: 64 return fmt.Errorf("OpError.Source or Addr is unknown type: %T, %v", addr, e) 65 } 66 } 67 if e.Err == nil { 68 return fmt.Errorf("OpError.Err is empty: %v", e) 69 } 70 return nil 71 } 72 73 // parseDialError parses nestedErr and reports whether it is a valid 74 // error value from Dial, Listen functions. 75 // It returns nil when nestedErr is valid. 76 func parseDialError(nestedErr error) error { 77 if nestedErr == nil { 78 return nil 79 } 80 81 switch err := nestedErr.(type) { 82 case *OpError: 83 if err := err.isValid(); err != nil { 84 return err 85 } 86 nestedErr = err.Err 87 goto second 88 } 89 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr) 90 91 second: 92 if isPlatformError(nestedErr) { 93 return nil 94 } 95 switch err := nestedErr.(type) { 96 case *AddrError, addrinfoErrno, *timeoutError, *DNSError, InvalidAddrError, *ParseError, *poll.DeadlineExceededError, UnknownNetworkError: 97 return nil 98 case *os.SyscallError: 99 nestedErr = err.Err 100 goto third 101 case *fs.PathError: // for Plan 9 102 nestedErr = err.Err 103 goto third 104 } 105 switch nestedErr { 106 case errCanceled, ErrClosed, errMissingAddress, errNoSuitableAddress, 107 context.DeadlineExceeded, context.Canceled: 108 return nil 109 } 110 return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) 111 112 third: 113 if isPlatformError(nestedErr) { 114 return nil 115 } 116 return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr) 117 } 118 119 var dialErrorTests = []struct { 120 network, address string 121 }{ 122 {"foo", ""}, 123 {"bar", "baz"}, 124 {"datakit", "mh/astro/r70"}, 125 {"tcp", ""}, 126 {"tcp", "127.0.0.1:☺"}, 127 {"tcp", "no-such-name:80"}, 128 {"tcp", "mh/astro/r70:http"}, 129 130 {"tcp", JoinHostPort("127.0.0.1", "-1")}, 131 {"tcp", JoinHostPort("127.0.0.1", "123456789")}, 132 {"udp", JoinHostPort("127.0.0.1", "-1")}, 133 {"udp", JoinHostPort("127.0.0.1", "123456789")}, 134 {"ip:icmp", "127.0.0.1"}, 135 136 {"unix", "/path/to/somewhere"}, 137 {"unixgram", "/path/to/somewhere"}, 138 {"unixpacket", "/path/to/somewhere"}, 139 } 140 141 func TestDialError(t *testing.T) { 142 switch runtime.GOOS { 143 case "plan9": 144 t.Skipf("%s does not have full support of socktest", runtime.GOOS) 145 } 146 147 origTestHookLookupIP := testHookLookupIP 148 defer func() { testHookLookupIP = origTestHookLookupIP }() 149 testHookLookupIP = func(ctx context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) { 150 return nil, &DNSError{Err: "dial error test", Name: "name", Server: "server", IsTimeout: true} 151 } 152 sw.Set(socktest.FilterConnect, func(so *socktest.Status) (socktest.AfterFilter, error) { 153 return nil, errOpNotSupported 154 }) 155 defer sw.Set(socktest.FilterConnect, nil) 156 157 d := Dialer{Timeout: someTimeout} 158 for i, tt := range dialErrorTests { 159 c, err := d.Dial(tt.network, tt.address) 160 if err == nil { 161 t.Errorf("#%d: should fail; %s:%s->%s", i, c.LocalAddr().Network(), c.LocalAddr(), c.RemoteAddr()) 162 c.Close() 163 continue 164 } 165 if tt.network == "tcp" || tt.network == "udp" { 166 nerr := err 167 if op, ok := nerr.(*OpError); ok { 168 nerr = op.Err 169 } 170 if sys, ok := nerr.(*os.SyscallError); ok { 171 nerr = sys.Err 172 } 173 if nerr == errOpNotSupported { 174 t.Errorf("#%d: should fail without %v; %s:%s->", i, nerr, tt.network, tt.address) 175 continue 176 } 177 } 178 if c != nil { 179 t.Errorf("Dial returned non-nil interface %T(%v) with err != nil", c, c) 180 } 181 if err = parseDialError(err); err != nil { 182 t.Errorf("#%d: %v", i, err) 183 continue 184 } 185 } 186 } 187 188 func TestProtocolDialError(t *testing.T) { 189 switch runtime.GOOS { 190 case "solaris", "illumos": 191 t.Skipf("not supported on %s", runtime.GOOS) 192 } 193 194 for _, network := range []string{"tcp", "udp", "ip:4294967296", "unix", "unixpacket", "unixgram"} { 195 var err error 196 switch network { 197 case "tcp": 198 _, err = DialTCP(network, nil, &TCPAddr{Port: 1 << 16}) 199 case "udp": 200 _, err = DialUDP(network, nil, &UDPAddr{Port: 1 << 16}) 201 case "ip:4294967296": 202 _, err = DialIP(network, nil, nil) 203 case "unix", "unixpacket", "unixgram": 204 _, err = DialUnix(network, nil, &UnixAddr{Name: "//"}) 205 } 206 if err == nil { 207 t.Errorf("%s: should fail", network) 208 continue 209 } 210 if err = parseDialError(err); err != nil { 211 t.Errorf("%s: %v", network, err) 212 continue 213 } 214 } 215 } 216 217 func TestDialAddrError(t *testing.T) { 218 switch runtime.GOOS { 219 case "plan9": 220 t.Skipf("not supported on %s", runtime.GOOS) 221 } 222 if !supportsIPv4() || !supportsIPv6() { 223 t.Skip("both IPv4 and IPv6 are required") 224 } 225 226 for _, tt := range []struct { 227 network string 228 lit string 229 addr *TCPAddr 230 }{ 231 {"tcp4", "::1", nil}, 232 {"tcp4", "", &TCPAddr{IP: IPv6loopback}}, 233 // We don't test the {"tcp6", "byte sequence", nil} 234 // case for now because there is no easy way to 235 // control name resolution. 236 {"tcp6", "", &TCPAddr{IP: IP{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}}}, 237 } { 238 var err error 239 var c Conn 240 var op string 241 if tt.lit != "" { 242 c, err = Dial(tt.network, JoinHostPort(tt.lit, "0")) 243 op = fmt.Sprintf("Dial(%q, %q)", tt.network, JoinHostPort(tt.lit, "0")) 244 } else { 245 c, err = DialTCP(tt.network, nil, tt.addr) 246 op = fmt.Sprintf("DialTCP(%q, %q)", tt.network, tt.addr) 247 } 248 if err == nil { 249 c.Close() 250 t.Errorf("%s succeeded, want error", op) 251 continue 252 } 253 if perr := parseDialError(err); perr != nil { 254 t.Errorf("%s: %v", op, perr) 255 continue 256 } 257 operr := err.(*OpError).Err 258 aerr, ok := operr.(*AddrError) 259 if !ok { 260 t.Errorf("%s: %v is %T, want *AddrError", op, err, operr) 261 continue 262 } 263 want := tt.lit 264 if tt.lit == "" { 265 want = tt.addr.IP.String() 266 } 267 if aerr.Addr != want { 268 t.Errorf("%s: %v, error Addr=%q, want %q", op, err, aerr.Addr, want) 269 } 270 } 271 } 272 273 var listenErrorTests = []struct { 274 network, address string 275 }{ 276 {"foo", ""}, 277 {"bar", "baz"}, 278 {"datakit", "mh/astro/r70"}, 279 {"tcp", "127.0.0.1:☺"}, 280 {"tcp", "no-such-name:80"}, 281 {"tcp", "mh/astro/r70:http"}, 282 283 {"tcp", JoinHostPort("127.0.0.1", "-1")}, 284 {"tcp", JoinHostPort("127.0.0.1", "123456789")}, 285 286 {"unix", "/path/to/somewhere"}, 287 {"unixpacket", "/path/to/somewhere"}, 288 } 289 290 func TestListenError(t *testing.T) { 291 switch runtime.GOOS { 292 case "plan9": 293 t.Skipf("%s does not have full support of socktest", runtime.GOOS) 294 } 295 296 origTestHookLookupIP := testHookLookupIP 297 defer func() { testHookLookupIP = origTestHookLookupIP }() 298 testHookLookupIP = func(_ context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) { 299 return nil, &DNSError{Err: "listen error test", Name: "name", Server: "server", IsTimeout: true} 300 } 301 sw.Set(socktest.FilterListen, func(so *socktest.Status) (socktest.AfterFilter, error) { 302 return nil, errOpNotSupported 303 }) 304 defer sw.Set(socktest.FilterListen, nil) 305 306 for i, tt := range listenErrorTests { 307 ln, err := Listen(tt.network, tt.address) 308 if err == nil { 309 t.Errorf("#%d: should fail; %s:%s->", i, ln.Addr().Network(), ln.Addr()) 310 ln.Close() 311 continue 312 } 313 if tt.network == "tcp" { 314 nerr := err 315 if op, ok := nerr.(*OpError); ok { 316 nerr = op.Err 317 } 318 if sys, ok := nerr.(*os.SyscallError); ok { 319 nerr = sys.Err 320 } 321 if nerr == errOpNotSupported { 322 t.Errorf("#%d: should fail without %v; %s:%s->", i, nerr, tt.network, tt.address) 323 continue 324 } 325 } 326 if ln != nil { 327 t.Errorf("Listen returned non-nil interface %T(%v) with err != nil", ln, ln) 328 } 329 if err = parseDialError(err); err != nil { 330 t.Errorf("#%d: %v", i, err) 331 continue 332 } 333 } 334 } 335 336 var listenPacketErrorTests = []struct { 337 network, address string 338 }{ 339 {"foo", ""}, 340 {"bar", "baz"}, 341 {"datakit", "mh/astro/r70"}, 342 {"udp", "127.0.0.1:☺"}, 343 {"udp", "no-such-name:80"}, 344 {"udp", "mh/astro/r70:http"}, 345 346 {"udp", JoinHostPort("127.0.0.1", "-1")}, 347 {"udp", JoinHostPort("127.0.0.1", "123456789")}, 348 } 349 350 func TestListenPacketError(t *testing.T) { 351 switch runtime.GOOS { 352 case "plan9": 353 t.Skipf("%s does not have full support of socktest", runtime.GOOS) 354 } 355 356 origTestHookLookupIP := testHookLookupIP 357 defer func() { testHookLookupIP = origTestHookLookupIP }() 358 testHookLookupIP = func(_ context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) { 359 return nil, &DNSError{Err: "listen error test", Name: "name", Server: "server", IsTimeout: true} 360 } 361 362 for i, tt := range listenPacketErrorTests { 363 c, err := ListenPacket(tt.network, tt.address) 364 if err == nil { 365 t.Errorf("#%d: should fail; %s:%s->", i, c.LocalAddr().Network(), c.LocalAddr()) 366 c.Close() 367 continue 368 } 369 if c != nil { 370 t.Errorf("ListenPacket returned non-nil interface %T(%v) with err != nil", c, c) 371 } 372 if err = parseDialError(err); err != nil { 373 t.Errorf("#%d: %v", i, err) 374 continue 375 } 376 } 377 } 378 379 func TestProtocolListenError(t *testing.T) { 380 switch runtime.GOOS { 381 case "plan9": 382 t.Skipf("not supported on %s", runtime.GOOS) 383 } 384 385 for _, network := range []string{"tcp", "udp", "ip:4294967296", "unix", "unixpacket", "unixgram"} { 386 var err error 387 switch network { 388 case "tcp": 389 _, err = ListenTCP(network, &TCPAddr{Port: 1 << 16}) 390 case "udp": 391 _, err = ListenUDP(network, &UDPAddr{Port: 1 << 16}) 392 case "ip:4294967296": 393 _, err = ListenIP(network, nil) 394 case "unix", "unixpacket": 395 _, err = ListenUnix(network, &UnixAddr{Name: "//"}) 396 case "unixgram": 397 _, err = ListenUnixgram(network, &UnixAddr{Name: "//"}) 398 } 399 if err == nil { 400 t.Errorf("%s: should fail", network) 401 continue 402 } 403 if err = parseDialError(err); err != nil { 404 t.Errorf("%s: %v", network, err) 405 continue 406 } 407 } 408 } 409 410 // parseReadError parses nestedErr and reports whether it is a valid 411 // error value from Read functions. 412 // It returns nil when nestedErr is valid. 413 func parseReadError(nestedErr error) error { 414 if nestedErr == nil { 415 return nil 416 } 417 418 switch err := nestedErr.(type) { 419 case *OpError: 420 if err := err.isValid(); err != nil { 421 return err 422 } 423 nestedErr = err.Err 424 goto second 425 } 426 if nestedErr == io.EOF { 427 return nil 428 } 429 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr) 430 431 second: 432 if isPlatformError(nestedErr) { 433 return nil 434 } 435 switch err := nestedErr.(type) { 436 case *os.SyscallError: 437 nestedErr = err.Err 438 goto third 439 } 440 switch nestedErr { 441 case ErrClosed, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded: 442 return nil 443 } 444 return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) 445 446 third: 447 if isPlatformError(nestedErr) { 448 return nil 449 } 450 return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr) 451 } 452 453 // parseWriteError parses nestedErr and reports whether it is a valid 454 // error value from Write functions. 455 // It returns nil when nestedErr is valid. 456 func parseWriteError(nestedErr error) error { 457 if nestedErr == nil { 458 return nil 459 } 460 461 switch err := nestedErr.(type) { 462 case *OpError: 463 if err := err.isValid(); err != nil { 464 return err 465 } 466 nestedErr = err.Err 467 goto second 468 } 469 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr) 470 471 second: 472 if isPlatformError(nestedErr) { 473 return nil 474 } 475 switch err := nestedErr.(type) { 476 case *AddrError, addrinfoErrno, *timeoutError, *DNSError, InvalidAddrError, *ParseError, *poll.DeadlineExceededError, UnknownNetworkError: 477 return nil 478 case *os.SyscallError: 479 nestedErr = err.Err 480 goto third 481 } 482 switch nestedErr { 483 case errCanceled, ErrClosed, errMissingAddress, errTimeout, os.ErrDeadlineExceeded, ErrWriteToConnected, io.ErrUnexpectedEOF: 484 return nil 485 } 486 return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) 487 488 third: 489 if isPlatformError(nestedErr) { 490 return nil 491 } 492 return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr) 493 } 494 495 // parseCloseError parses nestedErr and reports whether it is a valid 496 // error value from Close functions. 497 // It returns nil when nestedErr is valid. 498 func parseCloseError(nestedErr error, isShutdown bool) error { 499 if nestedErr == nil { 500 return nil 501 } 502 503 // Because historically we have not exported the error that we 504 // return for an operation on a closed network connection, 505 // there are programs that test for the exact error string. 506 // Verify that string here so that we don't break those 507 // programs unexpectedly. See issues #4373 and #19252. 508 want := "use of closed network connection" 509 if !isShutdown && !strings.Contains(nestedErr.Error(), want) { 510 return fmt.Errorf("error string %q does not contain expected string %q", nestedErr, want) 511 } 512 513 if !isShutdown && !errors.Is(nestedErr, ErrClosed) { 514 return fmt.Errorf("errors.Is(%v, errClosed) returns false, want true", nestedErr) 515 } 516 517 switch err := nestedErr.(type) { 518 case *OpError: 519 if err := err.isValid(); err != nil { 520 return err 521 } 522 nestedErr = err.Err 523 goto second 524 } 525 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr) 526 527 second: 528 if isPlatformError(nestedErr) { 529 return nil 530 } 531 switch err := nestedErr.(type) { 532 case *os.SyscallError: 533 nestedErr = err.Err 534 goto third 535 case *fs.PathError: // for Plan 9 536 nestedErr = err.Err 537 goto third 538 } 539 switch nestedErr { 540 case ErrClosed: 541 return nil 542 } 543 return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) 544 545 third: 546 if isPlatformError(nestedErr) { 547 return nil 548 } 549 switch nestedErr { 550 case fs.ErrClosed: // for Plan 9 551 return nil 552 } 553 return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr) 554 } 555 556 func TestCloseError(t *testing.T) { 557 ln, err := newLocalListener("tcp") 558 if err != nil { 559 t.Fatal(err) 560 } 561 defer ln.Close() 562 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 563 if err != nil { 564 t.Fatal(err) 565 } 566 defer c.Close() 567 568 for i := 0; i < 3; i++ { 569 err = c.(*TCPConn).CloseRead() 570 if perr := parseCloseError(err, true); perr != nil { 571 t.Errorf("#%d: %v", i, perr) 572 } 573 } 574 for i := 0; i < 3; i++ { 575 err = c.(*TCPConn).CloseWrite() 576 if perr := parseCloseError(err, true); perr != nil { 577 t.Errorf("#%d: %v", i, perr) 578 } 579 } 580 for i := 0; i < 3; i++ { 581 err = c.Close() 582 if perr := parseCloseError(err, false); perr != nil { 583 t.Errorf("#%d: %v", i, perr) 584 } 585 err = ln.Close() 586 if perr := parseCloseError(err, false); perr != nil { 587 t.Errorf("#%d: %v", i, perr) 588 } 589 } 590 591 pc, err := ListenPacket("udp", "127.0.0.1:0") 592 if err != nil { 593 t.Fatal(err) 594 } 595 defer pc.Close() 596 597 for i := 0; i < 3; i++ { 598 err = pc.Close() 599 if perr := parseCloseError(err, false); perr != nil { 600 t.Errorf("#%d: %v", i, perr) 601 } 602 } 603 } 604 605 // parseAcceptError parses nestedErr and reports whether it is a valid 606 // error value from Accept functions. 607 // It returns nil when nestedErr is valid. 608 func parseAcceptError(nestedErr error) error { 609 if nestedErr == nil { 610 return nil 611 } 612 613 switch err := nestedErr.(type) { 614 case *OpError: 615 if err := err.isValid(); err != nil { 616 return err 617 } 618 nestedErr = err.Err 619 goto second 620 } 621 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr) 622 623 second: 624 if isPlatformError(nestedErr) { 625 return nil 626 } 627 switch err := nestedErr.(type) { 628 case *os.SyscallError: 629 nestedErr = err.Err 630 goto third 631 case *fs.PathError: // for Plan 9 632 nestedErr = err.Err 633 goto third 634 } 635 switch nestedErr { 636 case ErrClosed, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded: 637 return nil 638 } 639 return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) 640 641 third: 642 if isPlatformError(nestedErr) { 643 return nil 644 } 645 return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr) 646 } 647 648 func TestAcceptError(t *testing.T) { 649 handler := func(ls *localServer, ln Listener) { 650 for { 651 ln.(*TCPListener).SetDeadline(time.Now().Add(5 * time.Millisecond)) 652 c, err := ln.Accept() 653 if perr := parseAcceptError(err); perr != nil { 654 t.Error(perr) 655 } 656 if err != nil { 657 if c != nil { 658 t.Errorf("Accept returned non-nil interface %T(%v) with err != nil", c, c) 659 } 660 if nerr, ok := err.(Error); !ok || (!nerr.Timeout() && !nerr.Temporary()) { 661 return 662 } 663 continue 664 } 665 c.Close() 666 } 667 } 668 ls, err := newLocalServer("tcp") 669 if err != nil { 670 t.Fatal(err) 671 } 672 if err := ls.buildup(handler); err != nil { 673 ls.teardown() 674 t.Fatal(err) 675 } 676 677 time.Sleep(100 * time.Millisecond) 678 ls.teardown() 679 } 680 681 // parseCommonError parses nestedErr and reports whether it is a valid 682 // error value from miscellaneous functions. 683 // It returns nil when nestedErr is valid. 684 func parseCommonError(nestedErr error) error { 685 if nestedErr == nil { 686 return nil 687 } 688 689 switch err := nestedErr.(type) { 690 case *OpError: 691 if err := err.isValid(); err != nil { 692 return err 693 } 694 nestedErr = err.Err 695 goto second 696 } 697 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr) 698 699 second: 700 if isPlatformError(nestedErr) { 701 return nil 702 } 703 switch err := nestedErr.(type) { 704 case *os.SyscallError: 705 nestedErr = err.Err 706 goto third 707 case *os.LinkError: 708 nestedErr = err.Err 709 goto third 710 case *fs.PathError: 711 nestedErr = err.Err 712 goto third 713 } 714 switch nestedErr { 715 case ErrClosed: 716 return nil 717 } 718 return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) 719 720 third: 721 if isPlatformError(nestedErr) { 722 return nil 723 } 724 return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr) 725 } 726 727 func TestFileError(t *testing.T) { 728 switch runtime.GOOS { 729 case "windows": 730 t.Skipf("not supported on %s", runtime.GOOS) 731 } 732 733 f, err := os.CreateTemp("", "go-nettest") 734 if err != nil { 735 t.Fatal(err) 736 } 737 defer os.Remove(f.Name()) 738 defer f.Close() 739 740 c, err := FileConn(f) 741 if err != nil { 742 if c != nil { 743 t.Errorf("FileConn returned non-nil interface %T(%v) with err != nil", c, c) 744 } 745 if perr := parseCommonError(err); perr != nil { 746 t.Error(perr) 747 } 748 } else { 749 c.Close() 750 t.Error("should fail") 751 } 752 ln, err := FileListener(f) 753 if err != nil { 754 if ln != nil { 755 t.Errorf("FileListener returned non-nil interface %T(%v) with err != nil", ln, ln) 756 } 757 if perr := parseCommonError(err); perr != nil { 758 t.Error(perr) 759 } 760 } else { 761 ln.Close() 762 t.Error("should fail") 763 } 764 pc, err := FilePacketConn(f) 765 if err != nil { 766 if pc != nil { 767 t.Errorf("FilePacketConn returned non-nil interface %T(%v) with err != nil", pc, pc) 768 } 769 if perr := parseCommonError(err); perr != nil { 770 t.Error(perr) 771 } 772 } else { 773 pc.Close() 774 t.Error("should fail") 775 } 776 777 ln, err = newLocalListener("tcp") 778 if err != nil { 779 t.Fatal(err) 780 } 781 782 for i := 0; i < 3; i++ { 783 f, err := ln.(*TCPListener).File() 784 if err != nil { 785 if perr := parseCommonError(err); perr != nil { 786 t.Error(perr) 787 } 788 } else { 789 f.Close() 790 } 791 ln.Close() 792 } 793 } 794 795 func parseLookupPortError(nestedErr error) error { 796 if nestedErr == nil { 797 return nil 798 } 799 800 switch nestedErr.(type) { 801 case *AddrError, *DNSError: 802 return nil 803 case *fs.PathError: // for Plan 9 804 return nil 805 } 806 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr) 807 }