Skip to content

Commit 16d4f6a

Browse files
committed
errorutil: add benchmark for errors.Is
This is to help debug an expensive error handling call path that was seen in a profile. Release note: None
1 parent 2b2511f commit 16d4f6a

1 file changed

Lines changed: 147 additions & 0 deletions

File tree

pkg/util/errorutil/error_test.go

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@
66
package errorutil
77

88
import (
9+
"context"
910
"fmt"
11+
"net"
1012
"strings"
1113
"testing"
14+
15+
"github.com/cockroachdb/errors"
1216
)
1317

1418
// Renumber lines so they're stable no matter what changes above. (We
@@ -39,3 +43,146 @@ func TestUnexpectedWithIssueErrorf(t *testing.T) {
3943
t.Errorf("expected substring in error\n%s\ngot:\n%s", exp, safeMsg)
4044
}
4145
}
46+
47+
func BenchmarkErrorsIs(b *testing.B) {
48+
b.Run("SimpleError", func(b *testing.B) {
49+
err := errors.New("test")
50+
for range b.N {
51+
errors.Is(err, context.Canceled)
52+
}
53+
})
54+
55+
b.Run("WrappedError", func(b *testing.B) {
56+
baseErr := errors.New("test")
57+
err := errors.Wrap(baseErr, "wrapped error")
58+
for range b.N {
59+
errors.Is(err, context.Canceled)
60+
}
61+
})
62+
63+
b.Run("WrappedWithStack", func(b *testing.B) {
64+
baseErr := errors.New("test")
65+
err := errors.WithStack(baseErr)
66+
for range b.N {
67+
errors.Is(err, context.Canceled)
68+
}
69+
})
70+
71+
b.Run("NetworkError", func(b *testing.B) {
72+
netErr := &net.OpError{
73+
Op: "dial",
74+
Net: "tcp",
75+
Addr: &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 26257},
76+
Err: fmt.Errorf("connection refused"),
77+
}
78+
err := errors.Wrap(netErr, "network connection failed")
79+
for range b.N {
80+
errors.Is(err, context.Canceled)
81+
}
82+
})
83+
84+
b.Run("DeeplyWrappedNetworkError", func(b *testing.B) {
85+
netErr := &net.OpError{
86+
Op: "dial",
87+
Net: "tcp",
88+
Addr: &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 26257},
89+
Err: fmt.Errorf("connection refused"),
90+
}
91+
err := errors.WithStack(netErr)
92+
err = errors.Wrap(err, "failed to connect to database")
93+
err = errors.Wrap(err, "unable to establish connection")
94+
err = errors.WithStack(err)
95+
for range b.N {
96+
errors.Is(err, context.Canceled)
97+
}
98+
})
99+
100+
b.Run("MultipleWrappedErrors", func(b *testing.B) {
101+
baseErr := errors.New("internal error")
102+
err := errors.WithStack(baseErr)
103+
err = errors.Wrap(err, "operation failed")
104+
err = errors.WithStack(err)
105+
err = errors.Wrap(err, "transaction failed")
106+
err = errors.WithStack(err)
107+
for range b.N {
108+
errors.Is(err, context.Canceled)
109+
}
110+
})
111+
112+
b.Run("NetworkErrorWithLongAddress", func(b *testing.B) {
113+
netErr := &net.OpError{
114+
Op: "read",
115+
Net: "tcp",
116+
Addr: &net.TCPAddr{
117+
IP: net.ParseIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334"),
118+
Port: 26257,
119+
},
120+
Err: fmt.Errorf("i/o timeout"),
121+
}
122+
err := errors.WithStack(netErr)
123+
err = errors.Wrap(err, "failed to read from connection")
124+
for range b.N {
125+
errors.Is(err, context.Canceled)
126+
}
127+
})
128+
129+
b.Run("WithMessage", func(b *testing.B) {
130+
baseErr := errors.New("test")
131+
err := errors.WithMessage(baseErr, "additional context")
132+
for range b.N {
133+
errors.Is(err, context.Canceled)
134+
}
135+
})
136+
137+
b.Run("MultipleWithMessage", func(b *testing.B) {
138+
baseErr := errors.New("internal error")
139+
err := errors.WithMessage(baseErr, "first message")
140+
err = errors.WithMessage(err, "second message")
141+
err = errors.WithMessage(err, "third message")
142+
for range b.N {
143+
errors.Is(err, context.Canceled)
144+
}
145+
})
146+
147+
b.Run("WithMessageAndStack", func(b *testing.B) {
148+
baseErr := errors.New("test")
149+
err := errors.WithStack(baseErr)
150+
err = errors.WithMessage(err, "operation context")
151+
err = errors.WithStack(err)
152+
for range b.N {
153+
errors.Is(err, context.Canceled)
154+
}
155+
})
156+
157+
b.Run("NetworkErrorWithMessage", func(b *testing.B) {
158+
netErr := &net.OpError{
159+
Op: "dial",
160+
Net: "tcp",
161+
Addr: &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 26257},
162+
Err: fmt.Errorf("connection refused"),
163+
}
164+
err := errors.WithMessage(netErr, "database connection failed")
165+
err = errors.WithMessage(err, "unable to reach server")
166+
for range b.N {
167+
errors.Is(err, context.Canceled)
168+
}
169+
})
170+
171+
b.Run("NetworkErrorWithEverything", func(b *testing.B) {
172+
netErr := &net.OpError{
173+
Op: "dial",
174+
Net: "tcp",
175+
Addr: &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 26257},
176+
Err: fmt.Errorf("connection refused"),
177+
}
178+
err := errors.WithStack(netErr)
179+
err = errors.WithMessage(err, "database connection failed")
180+
err = errors.Wrap(err, "failed to establish TCP connection")
181+
err = errors.WithStack(err)
182+
err = errors.WithMessage(err, "unable to reach CockroachDB server")
183+
err = errors.Wrap(err, "connection attempt failed")
184+
for range b.N {
185+
errors.Is(err, context.Canceled)
186+
}
187+
})
188+
}

0 commit comments

Comments
 (0)