forked from grpc-ecosystem/go-grpc-middleware
-
Notifications
You must be signed in to change notification settings - Fork 0
/
client_test.go
116 lines (98 loc) · 5.56 KB
/
client_test.go
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
// Copyright (c) The go-grpc-middleware Authors.
// Licensed under the Apache License 2.0.
package prometheus
import (
"io"
"testing"
"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
func TestClientInterceptorSuite(t *testing.T) {
c := NewClientMetrics(WithClientHandlingTimeHistogram())
suite.Run(t, &ClientInterceptorTestSuite{
InterceptorTestSuite: &testpb.InterceptorTestSuite{
TestService: &testpb.TestPingService{},
ClientOpts: []grpc.DialOption{
grpc.WithUnaryInterceptor(c.UnaryClientInterceptor()),
grpc.WithStreamInterceptor(c.StreamClientInterceptor()),
},
},
clientMetrics: c,
})
}
type ClientInterceptorTestSuite struct {
*testpb.InterceptorTestSuite
clientMetrics *ClientMetrics
}
func (s *ClientInterceptorTestSuite) SetupTest() {
s.clientMetrics.clientStartedCounter.Reset()
s.clientMetrics.clientHandledCounter.Reset()
s.clientMetrics.clientHandledHistogram.Reset()
s.clientMetrics.clientStreamMsgReceived.Reset()
s.clientMetrics.clientStreamMsgSent.Reset()
}
func (s *ClientInterceptorTestSuite) TestUnaryIncrementsMetrics() {
_, err := s.Client.PingEmpty(s.SimpleCtx(), &testpb.PingEmptyRequest{})
require.NoError(s.T(), err)
requireValue(s.T(), 1, s.clientMetrics.clientStartedCounter.WithLabelValues("unary", testpb.TestServiceFullName, "PingEmpty"))
requireValue(s.T(), 1, s.clientMetrics.clientHandledCounter.WithLabelValues("unary", testpb.TestServiceFullName, "PingEmpty", "OK"))
requireValueHistCount(s.T(), 1, s.clientMetrics.clientHandledHistogram.WithLabelValues("unary", testpb.TestServiceFullName, "PingEmpty"))
_, err = s.Client.PingError(s.SimpleCtx(), &testpb.PingErrorRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)})
require.Error(s.T(), err)
requireValue(s.T(), 1, s.clientMetrics.clientStartedCounter.WithLabelValues("unary", testpb.TestServiceFullName, "PingError"))
requireValue(s.T(), 1, s.clientMetrics.clientHandledCounter.WithLabelValues("unary", testpb.TestServiceFullName, "PingError", "FailedPrecondition"))
requireValueHistCount(s.T(), 1, s.clientMetrics.clientHandledHistogram.WithLabelValues("unary", testpb.TestServiceFullName, "PingError"))
}
func (s *ClientInterceptorTestSuite) TestStartedStreamingIncrementsStarted() {
_, err := s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{})
require.NoError(s.T(), err)
requireValue(s.T(), 1, s.clientMetrics.clientStartedCounter.WithLabelValues("server_stream", testpb.TestServiceFullName, "PingList"))
_, err = s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)})
require.NoError(s.T(), err, "PingList must not fail immediately")
requireValue(s.T(), 2, s.clientMetrics.clientStartedCounter.WithLabelValues("server_stream", testpb.TestServiceFullName, "PingList"))
}
func (s *ClientInterceptorTestSuite) TestStreamingIncrementsMetrics() {
ss, err := s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{})
require.NoError(s.T(), err)
// Do a read, just for kicks.
count := 0
for {
_, err = ss.Recv()
if err == io.EOF {
break
}
require.NoError(s.T(), err, "reading pingList shouldn't fail")
count++
}
require.EqualValues(s.T(), testpb.ListResponseCount, count, "Number of received msg on the wire must match")
requireValue(s.T(), 1, s.clientMetrics.clientStartedCounter.WithLabelValues("server_stream", testpb.TestServiceFullName, "PingList"))
requireValue(s.T(), 1, s.clientMetrics.clientHandledCounter.WithLabelValues("server_stream", testpb.TestServiceFullName, "PingList", "OK"))
requireValue(s.T(), testpb.ListResponseCount+1 /* + EOF */, s.clientMetrics.clientStreamMsgReceived.WithLabelValues("server_stream", testpb.TestServiceFullName, "PingList"))
requireValue(s.T(), 1, s.clientMetrics.clientStreamMsgSent.WithLabelValues("server_stream", testpb.TestServiceFullName, "PingList"))
requireValueHistCount(s.T(), 1, s.clientMetrics.clientHandledHistogram.WithLabelValues("server_stream", testpb.TestServiceFullName, "PingList"))
ss, err = s.Client.PingList(s.SimpleCtx(), &testpb.PingListRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)})
require.NoError(s.T(), err, "PingList must not fail immediately")
// Do a read, just to progate errors.
_, err = ss.Recv()
st, _ := status.FromError(err)
require.Equal(s.T(), codes.FailedPrecondition, st.Code(), "Recv must return FailedPrecondition, otherwise the test is wrong")
requireValue(s.T(), 2, s.clientMetrics.clientStartedCounter.WithLabelValues("server_stream", testpb.TestServiceFullName, "PingList"))
requireValue(s.T(), 1, s.clientMetrics.clientHandledCounter.WithLabelValues("server_stream", testpb.TestServiceFullName, "PingList", "FailedPrecondition"))
requireValueHistCount(s.T(), 2, s.clientMetrics.clientHandledHistogram.WithLabelValues("server_stream", testpb.TestServiceFullName, "PingList"))
}
func (s *ClientInterceptorTestSuite) TestWithSubsystem() {
counterOpts := []CounterOption{
WithSubsystem("subsystem1"),
}
histOpts := []HistogramOption{
WithHistogramSubsystem("subsystem1"),
}
clientCounterOpts := WithClientCounterOptions(counterOpts...)
clientMetrics := NewClientMetrics(clientCounterOpts, WithClientHandlingTimeHistogram(histOpts...))
requireSubsystemName(s.T(), "subsystem1", clientMetrics.clientStartedCounter.WithLabelValues("unary", testpb.TestServiceFullName, "dummy"))
requireHistSubsystemName(s.T(), "subsystem1", clientMetrics.clientHandledHistogram.WithLabelValues("unary", testpb.TestServiceFullName, "dummy"))
}