forked from fl00r/go-tarantool-1.6
-
Notifications
You must be signed in to change notification settings - Fork 64
Expand file tree
/
Copy patherrors_test.go
More file actions
124 lines (114 loc) · 3.21 KB
/
Copy patherrors_test.go
File metadata and controls
124 lines (114 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package tarantool
import (
"errors"
"net"
"testing"
"github.com/tarantool/go-iproto"
)
func TestClientError_IsSentinel(t *testing.T) {
cases := []struct {
code iproto.Error
sentinel error
}{
{CodeConnectionNotReady, ErrConnectionNotReady},
{CodeConnectionClosed, ErrConnectionClosed},
{CodeProtocolError, ErrProtocolError},
{CodeTimeouted, ErrTimeouted},
{CodeRateLimited, ErrRateLimited},
{CodeConnectionShutdown, ErrConnectionShutdown},
{CodeIoError, ErrIoError},
}
for _, tc := range cases {
err := newClientError(tc.code, "x", nil)
if !errors.Is(err, tc.sentinel) {
t.Errorf("code 0x%x: errors.Is did not match its sentinel", int(tc.code))
}
}
}
func TestClientError_IsRetryableError(t *testing.T) {
retryable := []iproto.Error{
CodeConnectionNotReady, CodeTimeouted, CodeRateLimited, CodeIoError,
}
notRetryable := []iproto.Error{
CodeConnectionClosed, CodeProtocolError, CodeConnectionShutdown,
}
for _, code := range retryable {
err := newClientError(code, "x", nil)
if !IsRetryableError(err) {
t.Errorf("code 0x%x should be retryable", int(code))
}
if !errors.Is(err, ErrRetryable) {
t.Errorf("code 0x%x: errors.Is(_, ErrRetryable) failed", int(code))
}
}
for _, code := range notRetryable {
err := newClientError(code, "x", nil)
if IsRetryableError(err) {
t.Errorf("code 0x%x should NOT be retryable", int(code))
}
}
}
func TestClientError_WrapsCause(t *testing.T) {
cause := &net.OpError{Op: "read", Err: errors.New("eof")}
err := newClientError(CodeIoError, "failed to read", cause)
var got *net.OpError
if !errors.As(err, &got) {
t.Fatal("errors.As did not unwrap to *net.OpError")
}
if got != cause {
t.Fatal("errors.As returned a different *net.OpError instance")
}
if !errors.Is(err, ErrIoError) {
t.Fatal("errors.Is did not match ErrIoError after wrap")
}
if !errors.Is(err, ErrRetryable) {
t.Fatal("I/O error should also imply ErrRetryable")
}
}
func TestClientError_ErrorString(t *testing.T) {
cases := []struct {
err ClientError
want string
}{
{
newClientError(CodeConnectionShutdown, "server shutdown in progress", nil),
"connection shutdown: server shutdown in progress",
},
{
newClientError(CodeIoError, "failed to read", errors.New("eof")),
"I/O error: failed to read: eof",
},
{
newClientError(CodeTimeouted, "", nil),
"request timed out",
},
{
ClientError{Code: iproto.Error(0x9999), Msg: "weird"},
"client error 0x9999: weird",
},
}
for _, tc := range cases {
if got := tc.err.Error(); got != tc.want {
t.Errorf("Error() = %q, want %q", got, tc.want)
}
}
}
func TestServerError_AsAndFormat(t *testing.T) {
se := ServerError{Code: iproto.ER_TUPLE_FOUND, Msg: "Duplicate key exists"}
var got ServerError
if !errors.As(se, &got) {
t.Fatal("errors.As did not match ServerError")
}
if got.Code != iproto.ER_TUPLE_FOUND {
t.Fatalf("Code = %v", got.Code)
}
if want := "Duplicate key exists (0x3)"; se.Error() != want {
t.Errorf("Error() = %q, want %q", se.Error(), want)
}
}
func TestSentinelError_DoesNotMatchOtherSentinel(t *testing.T) {
err := newClientError(CodeTimeouted, "x", nil)
if errors.Is(err, ErrConnectionClosed) {
t.Error("ErrTimeouted matched ErrConnectionClosed")
}
}