github.com/defanghe/fabric@v2.1.1+incompatible/common/grpcmetrics/interceptor_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package grpcmetrics_test 8 9 import ( 10 "context" 11 "errors" 12 "io" 13 "net" 14 15 "github.com/hyperledger/fabric/common/grpcmetrics" 16 "github.com/hyperledger/fabric/common/grpcmetrics/fakes" 17 "github.com/hyperledger/fabric/common/grpcmetrics/testpb" 18 "github.com/hyperledger/fabric/common/metrics/metricsfakes" 19 . "github.com/onsi/ginkgo" 20 . "github.com/onsi/gomega" 21 "google.golang.org/grpc" 22 "google.golang.org/grpc/codes" 23 "google.golang.org/grpc/status" 24 ) 25 26 var _ = Describe("Interceptor", func() { 27 var ( 28 fakeEchoService *fakes.EchoServiceServer 29 echoServiceClient testpb.EchoServiceClient 30 31 fakeRequestDuration *metricsfakes.Histogram 32 fakeRequestsReceived *metricsfakes.Counter 33 fakeRequestsCompleted *metricsfakes.Counter 34 fakeMessagesSent *metricsfakes.Counter 35 fakeMessagesReceived *metricsfakes.Counter 36 37 unaryMetrics *grpcmetrics.UnaryMetrics 38 streamMetrics *grpcmetrics.StreamMetrics 39 40 listener net.Listener 41 serveCompleteCh chan error 42 server *grpc.Server 43 ) 44 45 BeforeEach(func() { 46 var err error 47 listener, err = net.Listen("tcp", "127.0.0.1:0") 48 Expect(err).NotTo(HaveOccurred()) 49 50 fakeEchoService = &fakes.EchoServiceServer{} 51 fakeEchoService.EchoStub = func(ctx context.Context, msg *testpb.Message) (*testpb.Message, error) { 52 msg.Sequence++ 53 return msg, nil 54 } 55 fakeEchoService.EchoStreamStub = func(stream testpb.EchoService_EchoStreamServer) error { 56 for { 57 msg, err := stream.Recv() 58 if err == io.EOF { 59 return nil 60 } 61 if err != nil { 62 return err 63 } 64 65 msg.Sequence++ 66 err = stream.Send(msg) 67 if err != nil { 68 return err 69 } 70 } 71 } 72 73 fakeRequestDuration = &metricsfakes.Histogram{} 74 fakeRequestDuration.WithReturns(fakeRequestDuration) 75 fakeRequestsReceived = &metricsfakes.Counter{} 76 fakeRequestsReceived.WithReturns(fakeRequestsReceived) 77 fakeRequestsCompleted = &metricsfakes.Counter{} 78 fakeRequestsCompleted.WithReturns(fakeRequestsCompleted) 79 fakeMessagesSent = &metricsfakes.Counter{} 80 fakeMessagesSent.WithReturns(fakeMessagesSent) 81 fakeMessagesReceived = &metricsfakes.Counter{} 82 fakeMessagesReceived.WithReturns(fakeMessagesReceived) 83 84 unaryMetrics = &grpcmetrics.UnaryMetrics{ 85 RequestDuration: fakeRequestDuration, 86 RequestsReceived: fakeRequestsReceived, 87 RequestsCompleted: fakeRequestsCompleted, 88 } 89 90 streamMetrics = &grpcmetrics.StreamMetrics{ 91 RequestDuration: fakeRequestDuration, 92 RequestsReceived: fakeRequestsReceived, 93 RequestsCompleted: fakeRequestsCompleted, 94 MessagesSent: fakeMessagesSent, 95 MessagesReceived: fakeMessagesReceived, 96 } 97 98 server = grpc.NewServer( 99 grpc.StreamInterceptor(grpcmetrics.StreamServerInterceptor(streamMetrics)), 100 grpc.UnaryInterceptor(grpcmetrics.UnaryServerInterceptor(unaryMetrics)), 101 ) 102 103 testpb.RegisterEchoServiceServer(server, fakeEchoService) 104 serveCompleteCh = make(chan error, 1) 105 go func() { serveCompleteCh <- server.Serve(listener) }() 106 107 cc, err := grpc.Dial(listener.Addr().String(), grpc.WithInsecure(), grpc.WithBlock()) 108 Expect(err).NotTo(HaveOccurred()) 109 echoServiceClient = testpb.NewEchoServiceClient(cc) 110 }) 111 112 AfterEach(func() { 113 err := listener.Close() 114 Expect(err).NotTo(HaveOccurred()) 115 Eventually(serveCompleteCh).Should(Receive()) 116 }) 117 118 Describe("Unary Metrics", func() { 119 It("records request duration", func() { 120 resp, err := echoServiceClient.Echo(context.Background(), &testpb.Message{Message: "yo"}) 121 Expect(err).NotTo(HaveOccurred()) 122 Expect(resp).To(Equal(&testpb.Message{Message: "yo", Sequence: 1})) 123 124 Expect(fakeRequestDuration.WithCallCount()).To(Equal(1)) 125 labelValues := fakeRequestDuration.WithArgsForCall(0) 126 Expect(labelValues).To(Equal([]string{ 127 "service", "testpb_EchoService", 128 "method", "Echo", 129 "code", "OK", 130 })) 131 Expect(fakeRequestDuration.ObserveCallCount()).To(Equal(1)) 132 Expect(fakeRequestDuration.ObserveArgsForCall(0)).NotTo(BeZero()) 133 Expect(fakeRequestDuration.ObserveArgsForCall(0)).To(BeNumerically("<", 1.0)) 134 }) 135 136 It("records requests received before requests completed", func() { 137 fakeRequestsReceived.AddStub = func(delta float64) { 138 defer GinkgoRecover() 139 Expect(fakeRequestsCompleted.AddCallCount()).To(Equal(0)) 140 } 141 142 resp, err := echoServiceClient.Echo(context.Background(), &testpb.Message{Message: "yo"}) 143 Expect(err).NotTo(HaveOccurred()) 144 Expect(resp).To(Equal(&testpb.Message{Message: "yo", Sequence: 1})) 145 146 Expect(fakeRequestsReceived.WithCallCount()).To(Equal(1)) 147 labelValues := fakeRequestsReceived.WithArgsForCall(0) 148 Expect(labelValues).To(Equal([]string{ 149 "service", "testpb_EchoService", 150 "method", "Echo", 151 })) 152 Expect(fakeRequestsReceived.AddCallCount()).To(Equal(1)) 153 Expect(fakeRequestsReceived.AddArgsForCall(0)).To(BeNumerically("~", 1.0)) 154 }) 155 156 It("records requests completed after requests received", func() { 157 fakeRequestsCompleted.AddStub = func(delta float64) { 158 defer GinkgoRecover() 159 Expect(fakeRequestsReceived.AddCallCount()).To(Equal(1)) 160 } 161 162 resp, err := echoServiceClient.Echo(context.Background(), &testpb.Message{Message: "yo"}) 163 Expect(err).NotTo(HaveOccurred()) 164 Expect(resp).To(Equal(&testpb.Message{Message: "yo", Sequence: 1})) 165 166 Expect(fakeRequestsCompleted.WithCallCount()).To(Equal(1)) 167 labelValues := fakeRequestsCompleted.WithArgsForCall(0) 168 Expect(labelValues).To(Equal([]string{ 169 "service", "testpb_EchoService", 170 "method", "Echo", 171 "code", "OK", 172 })) 173 Expect(fakeRequestsCompleted.AddCallCount()).To(Equal(1)) 174 Expect(fakeRequestsCompleted.AddArgsForCall(0)).To(BeNumerically("~", 1.0)) 175 }) 176 }) 177 178 Describe("Stream Metrics", func() { 179 It("records request duration", func() { 180 streamClient, err := echoServiceClient.EchoStream(context.Background()) 181 Expect(err).NotTo(HaveOccurred()) 182 streamMessages(streamClient) 183 184 Expect(fakeRequestDuration.WithCallCount()).To(Equal(1)) 185 labelValues := fakeRequestDuration.WithArgsForCall(0) 186 Expect(labelValues).To(Equal([]string{ 187 "service", "testpb_EchoService", 188 "method", "EchoStream", 189 "code", "OK", 190 })) 191 Expect(fakeRequestDuration.ObserveCallCount()).To(Equal(1)) 192 Expect(fakeRequestDuration.ObserveArgsForCall(0)).NotTo(BeZero()) 193 Expect(fakeRequestDuration.ObserveArgsForCall(0)).To(BeNumerically("<", 1.0)) 194 }) 195 196 It("records requests received before requests completed", func() { 197 fakeRequestsReceived.AddStub = func(delta float64) { 198 defer GinkgoRecover() 199 Expect(fakeRequestsCompleted.AddCallCount()).To(Equal(0)) 200 } 201 202 streamClient, err := echoServiceClient.EchoStream(context.Background()) 203 Expect(err).NotTo(HaveOccurred()) 204 streamMessages(streamClient) 205 206 Expect(fakeRequestsReceived.WithCallCount()).To(Equal(1)) 207 labelValues := fakeRequestDuration.WithArgsForCall(0) 208 Expect(labelValues).To(Equal([]string{ 209 "service", "testpb_EchoService", 210 "method", "EchoStream", 211 "code", "OK", 212 })) 213 Expect(fakeRequestsReceived.AddCallCount()).To(Equal(1)) 214 Expect(fakeRequestsReceived.AddArgsForCall(0)).To(BeNumerically("~", 1.0)) 215 }) 216 217 It("records requests completed after requests received", func() { 218 fakeRequestsCompleted.AddStub = func(delta float64) { 219 defer GinkgoRecover() 220 Expect(fakeRequestsReceived.AddCallCount()).To(Equal(1)) 221 } 222 223 streamClient, err := echoServiceClient.EchoStream(context.Background()) 224 Expect(err).NotTo(HaveOccurred()) 225 streamMessages(streamClient) 226 227 Expect(fakeRequestsReceived.WithCallCount()).To(Equal(1)) 228 labelValues := fakeRequestDuration.WithArgsForCall(0) 229 Expect(labelValues).To(Equal([]string{ 230 "service", "testpb_EchoService", 231 "method", "EchoStream", 232 "code", "OK", 233 })) 234 Expect(fakeRequestsReceived.AddCallCount()).To(Equal(1)) 235 Expect(fakeRequestsReceived.AddArgsForCall(0)).To(BeNumerically("~", 1.0)) 236 }) 237 238 It("records messages sent", func() { 239 streamClient, err := echoServiceClient.EchoStream(context.Background()) 240 Expect(err).NotTo(HaveOccurred()) 241 streamMessages(streamClient) 242 243 Expect(fakeMessagesSent.WithCallCount()).To(Equal(1)) 244 labelValues := fakeMessagesSent.WithArgsForCall(0) 245 Expect(labelValues).To(Equal([]string{ 246 "service", "testpb_EchoService", 247 "method", "EchoStream", 248 })) 249 250 Expect(fakeMessagesSent.AddCallCount()).To(Equal(2)) 251 for i := 0; i < fakeMessagesSent.AddCallCount(); i++ { 252 Expect(fakeMessagesSent.AddArgsForCall(0)).To(BeNumerically("~", 1.0)) 253 } 254 }) 255 256 It("records messages received", func() { 257 streamClient, err := echoServiceClient.EchoStream(context.Background()) 258 Expect(err).NotTo(HaveOccurred()) 259 streamMessages(streamClient) 260 261 Expect(fakeMessagesReceived.WithCallCount()).To(Equal(1)) 262 labelValues := fakeMessagesReceived.WithArgsForCall(0) 263 Expect(labelValues).To(Equal([]string{ 264 "service", "testpb_EchoService", 265 "method", "EchoStream", 266 })) 267 268 Expect(fakeMessagesReceived.AddCallCount()).To(Equal(2)) 269 for i := 0; i < fakeMessagesReceived.AddCallCount(); i++ { 270 Expect(fakeMessagesReceived.AddArgsForCall(0)).To(BeNumerically("~", 1.0)) 271 } 272 }) 273 274 Context("when stream recv returns an error", func() { 275 var errCh chan error 276 277 BeforeEach(func() { 278 errCh = make(chan error) 279 fakeEchoService.EchoStreamStub = func(svs testpb.EchoService_EchoStreamServer) error { 280 return <-errCh 281 } 282 }) 283 284 It("does not increment the update count", func() { 285 streamClient, err := echoServiceClient.EchoStream(context.Background()) 286 Expect(err).NotTo(HaveOccurred()) 287 288 err = streamClient.Send(&testpb.Message{Message: "hello"}) 289 Expect(err).NotTo(HaveOccurred()) 290 291 errCh <- errors.New("oh bother") 292 _, err = streamClient.Recv() 293 Expect(err).To(MatchError(status.Errorf(codes.Unknown, "oh bother"))) 294 295 err = streamClient.CloseSend() 296 Expect(err).NotTo(HaveOccurred()) 297 298 _, err = streamClient.Recv() 299 Expect(err).To(MatchError(status.Errorf(codes.Unknown, "oh bother"))) 300 301 Expect(fakeMessagesReceived.AddCallCount()).To(Equal(0)) 302 }) 303 }) 304 }) 305 }) 306 307 func streamMessages(streamClient testpb.EchoService_EchoStreamClient) { 308 err := streamClient.Send(&testpb.Message{Message: "hello"}) 309 Expect(err).NotTo(HaveOccurred()) 310 err = streamClient.Send(&testpb.Message{Message: "hello", Sequence: 2}) 311 Expect(err).NotTo(HaveOccurred()) 312 313 msg, err := streamClient.Recv() 314 Expect(err).NotTo(HaveOccurred()) 315 Expect(msg).To(Equal(&testpb.Message{Message: "hello", Sequence: 1})) 316 msg, err = streamClient.Recv() 317 Expect(err).NotTo(HaveOccurred()) 318 Expect(msg).To(Equal(&testpb.Message{Message: "hello", Sequence: 3})) 319 320 err = streamClient.CloseSend() 321 Expect(err).NotTo(HaveOccurred()) 322 323 msg, err = streamClient.Recv() 324 Expect(err).To(Equal(io.EOF)) 325 Expect(msg).To(BeNil()) 326 }