client_test.go 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // Copyright 2016 Michal Witkowski. All Rights Reserved.
  2. // See LICENSE for licensing terms.
  3. package grpc_prometheus
  4. import (
  5. "net"
  6. "testing"
  7. "time"
  8. "io"
  9. pb_testproto "github.com/grpc-ecosystem/go-grpc-prometheus/examples/testproto"
  10. "github.com/stretchr/testify/assert"
  11. "github.com/stretchr/testify/require"
  12. "github.com/stretchr/testify/suite"
  13. "golang.org/x/net/context"
  14. "google.golang.org/grpc"
  15. "google.golang.org/grpc/codes"
  16. )
  17. func TestClientInterceptorSuite(t *testing.T) {
  18. suite.Run(t, &ClientInterceptorTestSuite{})
  19. }
  20. type ClientInterceptorTestSuite struct {
  21. suite.Suite
  22. serverListener net.Listener
  23. server *grpc.Server
  24. clientConn *grpc.ClientConn
  25. testClient pb_testproto.TestServiceClient
  26. ctx context.Context
  27. }
  28. func (s *ClientInterceptorTestSuite) SetupSuite() {
  29. var err error
  30. EnableClientHandlingTimeHistogram()
  31. s.serverListener, err = net.Listen("tcp", "127.0.0.1:0")
  32. require.NoError(s.T(), err, "must be able to allocate a port for serverListener")
  33. // This is the point where we hook up the interceptor
  34. s.server = grpc.NewServer()
  35. pb_testproto.RegisterTestServiceServer(s.server, &testService{t: s.T()})
  36. go func() {
  37. s.server.Serve(s.serverListener)
  38. }()
  39. s.clientConn, err = grpc.Dial(
  40. s.serverListener.Addr().String(),
  41. grpc.WithInsecure(),
  42. grpc.WithBlock(),
  43. grpc.WithUnaryInterceptor(UnaryClientInterceptor),
  44. grpc.WithStreamInterceptor(StreamClientInterceptor),
  45. grpc.WithTimeout(2*time.Second))
  46. require.NoError(s.T(), err, "must not error on client Dial")
  47. s.testClient = pb_testproto.NewTestServiceClient(s.clientConn)
  48. }
  49. func (s *ClientInterceptorTestSuite) SetupTest() {
  50. // Make all RPC calls last at most 2 sec, meaning all async issues or deadlock will not kill tests.
  51. s.ctx, _ = context.WithTimeout(context.TODO(), 2*time.Second)
  52. }
  53. func (s *ClientInterceptorTestSuite) TearDownSuite() {
  54. if s.serverListener != nil {
  55. s.server.Stop()
  56. s.T().Logf("stopped grpc.Server at: %v", s.serverListener.Addr().String())
  57. s.serverListener.Close()
  58. }
  59. if s.clientConn != nil {
  60. s.clientConn.Close()
  61. }
  62. }
  63. func (s *ClientInterceptorTestSuite) TestUnaryIncrementsStarted() {
  64. var before int
  65. var after int
  66. before = sumCountersForMetricAndLabels(s.T(), "grpc_client_started_total", "PingEmpty", "unary")
  67. s.testClient.PingEmpty(s.ctx, &pb_testproto.Empty{})
  68. after = sumCountersForMetricAndLabels(s.T(), "grpc_client_started_total", "PingEmpty", "unary")
  69. assert.EqualValues(s.T(), before+1, after, "grpc_client_started_total should be incremented for PingEmpty")
  70. before = sumCountersForMetricAndLabels(s.T(), "grpc_client_started_total", "PingError", "unary")
  71. s.testClient.PingError(s.ctx, &pb_testproto.PingRequest{ErrorCodeReturned: uint32(codes.Unavailable)})
  72. after = sumCountersForMetricAndLabels(s.T(), "grpc_client_started_total", "PingError", "unary")
  73. assert.EqualValues(s.T(), before+1, after, "grpc_client_started_total should be incremented for PingError")
  74. }
  75. func (s *ClientInterceptorTestSuite) TestUnaryIncrementsHandled() {
  76. var before int
  77. var after int
  78. before = sumCountersForMetricAndLabels(s.T(), "grpc_client_handled_total", "PingEmpty", "unary", "OK")
  79. s.testClient.PingEmpty(s.ctx, &pb_testproto.Empty{}) // should return with code=OK
  80. after = sumCountersForMetricAndLabels(s.T(), "grpc_client_handled_total", "PingEmpty", "unary", "OK")
  81. assert.EqualValues(s.T(), before+1, after, "grpc_client_handled_count should be incremented for PingEmpty")
  82. before = sumCountersForMetricAndLabels(s.T(), "grpc_client_handled_total", "PingError", "unary", "FailedPrecondition")
  83. s.testClient.PingError(s.ctx, &pb_testproto.PingRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)}) // should return with code=FailedPrecondition
  84. after = sumCountersForMetricAndLabels(s.T(), "grpc_client_handled_total", "PingError", "unary", "FailedPrecondition")
  85. assert.EqualValues(s.T(), before+1, after, "grpc_client_handled_total should be incremented for PingError")
  86. }
  87. func (s *ClientInterceptorTestSuite) TestUnaryIncrementsHistograms() {
  88. var before int
  89. var after int
  90. before = sumCountersForMetricAndLabels(s.T(), "grpc_client_handling_seconds_count", "PingEmpty", "unary")
  91. s.testClient.PingEmpty(s.ctx, &pb_testproto.Empty{}) // should return with code=OK
  92. after = sumCountersForMetricAndLabels(s.T(), "grpc_client_handling_seconds_count", "PingEmpty", "unary")
  93. assert.EqualValues(s.T(), before+1, after, "grpc_client_handled_count should be incremented for PingEmpty")
  94. before = sumCountersForMetricAndLabels(s.T(), "grpc_client_handling_seconds_count", "PingError", "unary")
  95. s.testClient.PingError(s.ctx, &pb_testproto.PingRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)}) // should return with code=FailedPrecondition
  96. after = sumCountersForMetricAndLabels(s.T(), "grpc_client_handling_seconds_count", "PingError", "unary")
  97. assert.EqualValues(s.T(), before+1, after, "grpc_client_handling_seconds_count should be incremented for PingError")
  98. }
  99. func (s *ClientInterceptorTestSuite) TestStreamingIncrementsStarted() {
  100. var before int
  101. var after int
  102. before = sumCountersForMetricAndLabels(s.T(), "grpc_client_started_total", "PingList", "server_stream")
  103. s.testClient.PingList(s.ctx, &pb_testproto.PingRequest{})
  104. after = sumCountersForMetricAndLabels(s.T(), "grpc_client_started_total", "PingList", "server_stream")
  105. assert.EqualValues(s.T(), before+1, after, "grpc_client_started_total should be incremented for PingList")
  106. }
  107. func (s *ClientInterceptorTestSuite) TestStreamingIncrementsHistograms() {
  108. var before int
  109. var after int
  110. before = sumCountersForMetricAndLabels(s.T(), "grpc_client_handling_seconds_count", "PingList", "server_stream")
  111. ss, _ := s.testClient.PingList(s.ctx, &pb_testproto.PingRequest{}) // should return with code=OK
  112. // Do a read, just for kicks.
  113. for {
  114. _, err := ss.Recv()
  115. if err == io.EOF {
  116. break
  117. }
  118. require.NoError(s.T(), err, "reading pingList shouldn't fail")
  119. }
  120. after = sumCountersForMetricAndLabels(s.T(), "grpc_client_handling_seconds_count", "PingList", "server_stream")
  121. assert.EqualValues(s.T(), before+1, after, "grpc_client_handling_seconds_count should be incremented for PingList OK")
  122. before = sumCountersForMetricAndLabels(s.T(), "grpc_client_handling_seconds_count", "PingList", "server_stream")
  123. ss, err := s.testClient.PingList(s.ctx, &pb_testproto.PingRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)}) // should return with code=FailedPrecondition
  124. require.NoError(s.T(), err, "PingList must not fail immedietely")
  125. // Do a read, just to progate errors.
  126. _, err = ss.Recv()
  127. require.Equal(s.T(), codes.FailedPrecondition, grpc.Code(err), "Recv must return FailedPrecondition, otherwise the test is wrong")
  128. after = sumCountersForMetricAndLabels(s.T(), "grpc_client_handling_seconds_count", "PingList", "server_stream")
  129. assert.EqualValues(s.T(), before+1, after, "grpc_client_handling_seconds_count should be incremented for PingList FailedPrecondition")
  130. }
  131. func (s *ClientInterceptorTestSuite) TestStreamingIncrementsHandled() {
  132. var before int
  133. var after int
  134. before = sumCountersForMetricAndLabels(s.T(), "grpc_client_handled_total", "PingList", "server_stream", "OK")
  135. ss, _ := s.testClient.PingList(s.ctx, &pb_testproto.PingRequest{}) // should return with code=OK
  136. // Do a read, just for kicks.
  137. for {
  138. _, err := ss.Recv()
  139. if err == io.EOF {
  140. break
  141. }
  142. require.NoError(s.T(), err, "reading pingList shouldn't fail")
  143. }
  144. after = sumCountersForMetricAndLabels(s.T(), "grpc_client_handled_total", "PingList", "server_stream", "OK")
  145. assert.EqualValues(s.T(), before+1, after, "grpc_client_handled_total should be incremented for PingList OK")
  146. before = sumCountersForMetricAndLabels(s.T(), "grpc_client_handled_total", "PingList", "server_stream", "FailedPrecondition")
  147. ss, err := s.testClient.PingList(s.ctx, &pb_testproto.PingRequest{ErrorCodeReturned: uint32(codes.FailedPrecondition)}) // should return with code=FailedPrecondition
  148. require.NoError(s.T(), err, "PingList must not fail immedietely")
  149. // Do a read, just to progate errors.
  150. _, err = ss.Recv()
  151. require.Equal(s.T(), codes.FailedPrecondition, grpc.Code(err), "Recv must return FailedPrecondition, otherwise the test is wrong")
  152. after = sumCountersForMetricAndLabels(s.T(), "grpc_client_handled_total", "PingList", "server_stream", "FailedPrecondition")
  153. assert.EqualValues(s.T(), before+1, after, "grpc_client_handled_total should be incremented for PingList FailedPrecondition")
  154. }
  155. func (s *ClientInterceptorTestSuite) TestStreamingIncrementsMessageCounts() {
  156. beforeRecv := sumCountersForMetricAndLabels(s.T(), "grpc_client_msg_received_total", "PingList", "server_stream")
  157. beforeSent := sumCountersForMetricAndLabels(s.T(), "grpc_client_msg_sent_total", "PingList", "server_stream")
  158. ss, _ := s.testClient.PingList(s.ctx, &pb_testproto.PingRequest{}) // should return with code=OK
  159. // Do a read, just for kicks.
  160. count := 0
  161. for {
  162. _, err := ss.Recv()
  163. if err == io.EOF {
  164. break
  165. }
  166. require.NoError(s.T(), err, "reading pingList shouldn't fail")
  167. count += 1
  168. }
  169. require.EqualValues(s.T(), countListResponses, count, "Number of received msg on the wire must match")
  170. afterSent := sumCountersForMetricAndLabels(s.T(), "grpc_client_msg_sent_total", "PingList", "server_stream")
  171. afterRecv := sumCountersForMetricAndLabels(s.T(), "grpc_client_msg_received_total", "PingList", "server_stream")
  172. assert.EqualValues(s.T(), beforeSent+1, afterSent, "grpc_client_msg_sent_total should be incremented 20 times for PingList")
  173. assert.EqualValues(s.T(), beforeRecv+countListResponses, afterRecv, "grpc_client_msg_sent_total should be incremented ones for PingList ")
  174. }