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