@@ -8,9 +8,11 @@ import (
8
8
"testing"
9
9
10
10
"github.com/go-kit/log"
11
+ "github.com/gogo/status"
11
12
"github.com/grafana/dskit/httpgrpc"
12
13
"github.com/stretchr/testify/require"
13
14
"go.uber.org/atomic"
15
+ "google.golang.org/grpc/codes"
14
16
15
17
"github.com/grafana/loki/v3/pkg/util/constants"
16
18
)
@@ -19,10 +21,11 @@ func TestRetry(t *testing.T) {
19
21
var try atomic.Int32
20
22
21
23
for _ , tc := range []struct {
22
- name string
23
- handler Handler
24
- resp Response
25
- err error
24
+ name string
25
+ handler Handler
26
+ resp Response
27
+ err error
28
+ expectedCalls int
26
29
}{
27
30
{
28
31
name : "retry failures" ,
@@ -32,21 +35,26 @@ func TestRetry(t *testing.T) {
32
35
}
33
36
return nil , fmt .Errorf ("fail" )
34
37
}),
35
- resp : & PrometheusResponse {Status : "Hello World" },
38
+ resp : & PrometheusResponse {Status : "Hello World" },
39
+ expectedCalls : 5 ,
36
40
},
37
41
{
38
42
name : "don't retry 400s" ,
39
43
handler : HandlerFunc (func (_ context.Context , req Request ) (Response , error ) {
44
+ try .Inc ()
40
45
return nil , httpgrpc .Errorf (http .StatusBadRequest , "Bad Request" )
41
46
}),
42
- err : httpgrpc .Errorf (http .StatusBadRequest , "Bad Request" ),
47
+ err : httpgrpc .Errorf (http .StatusBadRequest , "Bad Request" ),
48
+ expectedCalls : 1 ,
43
49
},
44
50
{
45
51
name : "retry 500s" ,
46
52
handler : HandlerFunc (func (_ context.Context , req Request ) (Response , error ) {
53
+ try .Inc ()
47
54
return nil , httpgrpc .Errorf (http .StatusInternalServerError , "Internal Server Error" )
48
55
}),
49
- err : httpgrpc .Errorf (http .StatusInternalServerError , "Internal Server Error" ),
56
+ err : httpgrpc .Errorf (http .StatusInternalServerError , "Internal Server Error" ),
57
+ expectedCalls : 5 ,
50
58
},
51
59
{
52
60
name : "last error" ,
@@ -56,7 +64,28 @@ func TestRetry(t *testing.T) {
56
64
}
57
65
return nil , httpgrpc .Errorf (http .StatusInternalServerError , "Internal Server Error" )
58
66
}),
59
- err : httpgrpc .Errorf (http .StatusBadRequest , "Bad Request" ),
67
+ err : httpgrpc .Errorf (http .StatusBadRequest , "Bad Request" ),
68
+ expectedCalls : 5 ,
69
+ },
70
+ // previous entires in this table use httpgrpc.Errorf for generating the error which also populates the Details field with the marshalled http response.
71
+ // Next set of tests validate the retry behavior when using protobuf encoding where the status does not include the details.
72
+ {
73
+ name : "protobuf enc don't retry 400s" ,
74
+ handler : HandlerFunc (func (_ context.Context , req Request ) (Response , error ) {
75
+ try .Inc ()
76
+ return nil , status .New (codes .Code (http .StatusBadRequest ), "Bad Request" ).Err ()
77
+ }),
78
+ err : status .New (codes .Code (http .StatusBadRequest ), "Bad Request" ).Err (),
79
+ expectedCalls : 1 ,
80
+ },
81
+ {
82
+ name : "protobuf enc retry 500s" ,
83
+ handler : HandlerFunc (func (_ context.Context , req Request ) (Response , error ) {
84
+ try .Inc ()
85
+ return nil , status .New (codes .Code (http .StatusInternalServerError ), "Internal Server Error" ).Err ()
86
+ }),
87
+ err : status .New (codes .Code (http .StatusInternalServerError ), "Internal Server Error" ).Err (),
88
+ expectedCalls : 5 ,
60
89
},
61
90
} {
62
91
t .Run (tc .name , func (t * testing.T ) {
@@ -68,6 +97,7 @@ func TestRetry(t *testing.T) {
68
97
resp , err := h .Do (context .Background (), req )
69
98
require .Equal (t , tc .err , err )
70
99
require .Equal (t , tc .resp , resp )
100
+ require .EqualValues (t , tc .expectedCalls , try .Load ())
71
101
})
72
102
}
73
103
}
0 commit comments