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