diff options
| author | Mikio Hara <mikioh.mikioh@gmail.com> | 2015-04-17 12:24:42 +0900 |
|---|---|---|
| committer | Mikio Hara <mikioh.mikioh@gmail.com> | 2015-04-18 03:12:04 +0000 |
| commit | 310db63c5bc121e7bfccb494c01a6b91a257e7fc (patch) | |
| tree | cb37e11966a9ca7f85a5e373a4cbe081d09a9c31 /src/net/error_test.go | |
| parent | 11b5f98bf0d5eb8854f735cc332c912725070214 (diff) | |
| download | go-310db63c5bc121e7bfccb494c01a6b91a257e7fc.tar.xz | |
net: fix inconsistent error values on Close
This change fixes inconsistent error values on Close, CloseRead and
CloseWrite.
Updates #4856.
Change-Id: I3c4d46ccd7d6e1a2f52d8e75b512f62c533a368d
Reviewed-on: https://go-review.googlesource.com/8994
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/net/error_test.go')
| -rw-r--r-- | src/net/error_test.go | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/net/error_test.go b/src/net/error_test.go index 5668027d98..9f4a90d8e1 100644 --- a/src/net/error_test.go +++ b/src/net/error_test.go @@ -332,3 +332,95 @@ third: } return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr) } + +// parseCloseError parses nestedErr and reports whether it is a valid +// error value from Close functions. +// It returns nil when nestedErr is valid. +func parseCloseError(nestedErr error) error { + if nestedErr == nil { + return nil + } + + switch err := nestedErr.(type) { + case *OpError: + if err := err.isValid(); err != nil { + return err + } + nestedErr = err.Err + goto second + } + return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr) + +second: + if isPlatformError(nestedErr) { + return nil + } + switch err := nestedErr.(type) { + case *os.SyscallError: + nestedErr = err.Err + goto third + case *os.PathError: // for Plan 9 + nestedErr = err.Err + goto third + } + switch nestedErr { + case errClosing: + return nil + } + return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) + +third: + if isPlatformError(nestedErr) { + return nil + } + return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr) +} + +func TestCloseError(t *testing.T) { + ln, err := newLocalListener("tcp") + if err != nil { + t.Fatal(err) + } + defer ln.Close() + c, err := Dial(ln.Addr().Network(), ln.Addr().String()) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + for i := 0; i < 3; i++ { + err = c.(*TCPConn).CloseRead() + if perr := parseCloseError(err); perr != nil { + t.Errorf("#%d: %v", i, perr) + } + } + for i := 0; i < 3; i++ { + err = c.(*TCPConn).CloseWrite() + if perr := parseCloseError(err); perr != nil { + t.Errorf("#%d: %v", i, perr) + } + } + for i := 0; i < 3; i++ { + err = c.Close() + if perr := parseCloseError(err); perr != nil { + t.Errorf("#%d: %v", i, perr) + } + err = ln.Close() + if perr := parseCloseError(err); perr != nil { + t.Errorf("#%d: %v", i, perr) + } + } + + pc, err := ListenPacket("udp", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + defer pc.Close() + + for i := 0; i < 3; i++ { + err = pc.Close() + if perr := parseCloseError(err); perr != nil { + t.Errorf("#%d: %v", i, perr) + } + } +} |
