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