1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package managedwriter
16
17 import (
18 "context"
19 "fmt"
20 "io"
21 "testing"
22
23 "github.com/googleapis/gax-go/v2/apierror"
24 "google.golang.org/grpc/codes"
25 "google.golang.org/grpc/status"
26 )
27
28 func TestManagedStream_AppendErrorRetries(t *testing.T) {
29
30 testCases := []struct {
31 err error
32 attemptCount int
33 want bool
34 }{
35 {
36 err: nil,
37 want: false,
38 },
39 {
40 err: fmt.Errorf("random error"),
41 want: false,
42 },
43 {
44 err: io.EOF,
45 want: true,
46 },
47 {
48 err: io.EOF,
49 attemptCount: 4,
50 want: false,
51 },
52 {
53 err: status.Error(codes.Unavailable, "nope"),
54 want: true,
55 },
56 {
57 err: status.Error(codes.ResourceExhausted, "out of gas"),
58 want: false,
59 },
60 {
61 err: status.Error(codes.ResourceExhausted, "Exceeds 'AppendRows throughput' quota for some reason"),
62 want: true,
63 },
64 {
65 err: context.Canceled,
66 want: false,
67 },
68 }
69
70 retry := newStatelessRetryer()
71
72 for _, tc := range testCases {
73 if _, got := retry.Retry(tc.err, tc.attemptCount); got != tc.want {
74 t.Errorf("got %t, want %t for error: %+v", got, tc.want, tc.err)
75 }
76 }
77 }
78
79 func TestManagedStream_ShouldReconnect(t *testing.T) {
80
81 testCases := []struct {
82 err error
83 want bool
84 }{
85 {
86 err: fmt.Errorf("random error"),
87 want: false,
88 },
89 {
90 err: io.EOF,
91 want: true,
92 },
93 {
94 err: status.Error(codes.Unavailable, "the connection is draining"),
95 want: true,
96 },
97 {
98 err: status.Error(codes.ResourceExhausted, "oof"),
99 want: false,
100 },
101 {
102 err: status.Error(codes.Canceled, "blah"),
103 want: true,
104 },
105 {
106 err: status.Error(codes.Aborted, "connection has been idle too long"),
107 want: true,
108 },
109 {
110 err: status.Error(codes.DeadlineExceeded, "blah"),
111 want: true,
112 },
113 {
114 err: func() error {
115
116 ai, _ := apierror.FromError(status.Error(codes.Unavailable, "the connection is draining"))
117 return ai
118 }(),
119 want: true,
120 },
121 }
122
123 for _, tc := range testCases {
124 if got := shouldReconnect(tc.err); got != tc.want {
125 t.Errorf("got %t, want %t for error: %+v", got, tc.want, tc.err)
126 }
127 }
128 }
129
View as plain text