github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/orderer/common/broadcast/broadcast_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package broadcast_test 8 9 import ( 10 "context" 11 "fmt" 12 "io" 13 14 "github.com/golang/protobuf/proto" 15 . "github.com/onsi/ginkgo" 16 . "github.com/onsi/gomega" 17 18 "github.com/hechain20/hechain/orderer/common/broadcast" 19 "github.com/hechain20/hechain/orderer/common/broadcast/mock" 20 "github.com/hechain20/hechain/orderer/common/msgprocessor" 21 cb "github.com/hyperledger/fabric-protos-go/common" 22 ab "github.com/hyperledger/fabric-protos-go/orderer" 23 ) 24 25 var _ = Describe("Broadcast", func() { 26 var ( 27 fakeSupportRegistrar *mock.ChannelSupportRegistrar 28 handler *broadcast.Handler 29 fakeValidateHistogram *mock.MetricsHistogram 30 fakeEnqueueHistogram *mock.MetricsHistogram 31 fakeProcessedCounter *mock.MetricsCounter 32 ) 33 34 BeforeEach(func() { 35 fakeSupportRegistrar = &mock.ChannelSupportRegistrar{} 36 37 fakeValidateHistogram = &mock.MetricsHistogram{} 38 fakeValidateHistogram.WithReturns(fakeValidateHistogram) 39 40 fakeEnqueueHistogram = &mock.MetricsHistogram{} 41 fakeEnqueueHistogram.WithReturns(fakeEnqueueHistogram) 42 43 fakeProcessedCounter = &mock.MetricsCounter{} 44 fakeProcessedCounter.WithReturns(fakeProcessedCounter) 45 46 handler = &broadcast.Handler{ 47 SupportRegistrar: fakeSupportRegistrar, 48 Metrics: &broadcast.Metrics{ 49 ValidateDuration: fakeValidateHistogram, 50 EnqueueDuration: fakeEnqueueHistogram, 51 ProcessedCount: fakeProcessedCounter, 52 }, 53 } 54 }) 55 56 Describe("Handle", func() { 57 var ( 58 fakeABServer *mock.ABServer 59 fakeSupport *mock.ChannelSupport 60 fakeMsg *cb.Envelope 61 ) 62 63 BeforeEach(func() { 64 fakeMsg = &cb.Envelope{} 65 66 fakeABServer = &mock.ABServer{} 67 fakeABServer.ContextReturns(context.TODO()) 68 fakeABServer.RecvReturns(fakeMsg, nil) 69 fakeABServer.RecvReturnsOnCall(1, nil, io.EOF) 70 71 fakeSupport = &mock.ChannelSupport{} 72 fakeSupport.ProcessNormalMsgReturns(5, nil) 73 74 fakeSupportRegistrar.BroadcastChannelSupportReturns(&cb.ChannelHeader{ 75 Type: 3, 76 ChannelId: "fake-channel", 77 }, false, fakeSupport, nil) 78 }) 79 80 It("enqueues the message to the consenter", func() { 81 err := handler.Handle(fakeABServer) 82 Expect(err).NotTo(HaveOccurred()) 83 84 Expect(fakeABServer.RecvCallCount()).To(Equal(2)) 85 Expect(fakeSupportRegistrar.BroadcastChannelSupportCallCount()).To(Equal(1)) 86 Expect(fakeSupportRegistrar.BroadcastChannelSupportArgsForCall(0)).To(Equal(fakeMsg)) 87 88 Expect(fakeSupport.ProcessNormalMsgCallCount()).To(Equal(1)) 89 Expect(fakeSupport.ProcessNormalMsgArgsForCall(0)).To(Equal(fakeMsg)) 90 91 Expect(fakeSupport.WaitReadyCallCount()).To(Equal(1)) 92 93 Expect(fakeSupport.OrderCallCount()).To(Equal(1)) 94 orderedMsg, seq := fakeSupport.OrderArgsForCall(0) 95 Expect(orderedMsg).To(Equal(fakeMsg)) 96 Expect(seq).To(Equal(uint64(5))) 97 98 Expect(fakeValidateHistogram.WithCallCount()).To(Equal(1)) 99 Expect(fakeValidateHistogram.WithArgsForCall(0)).To(Equal([]string{ 100 "status", "SUCCESS", 101 "channel", "fake-channel", 102 "type", "ENDORSER_TRANSACTION", 103 })) 104 Expect(fakeValidateHistogram.ObserveCallCount()).To(Equal(1)) 105 Expect(fakeValidateHistogram.ObserveArgsForCall(0)).To(BeNumerically(">", 0)) 106 Expect(fakeValidateHistogram.ObserveArgsForCall(0)).To(BeNumerically("<", 1)) 107 108 Expect(fakeEnqueueHistogram.WithCallCount()).To(Equal(1)) 109 Expect(fakeEnqueueHistogram.WithArgsForCall(0)).To(Equal([]string{ 110 "status", "SUCCESS", 111 "channel", "fake-channel", 112 "type", "ENDORSER_TRANSACTION", 113 })) 114 Expect(fakeEnqueueHistogram.ObserveCallCount()).To(Equal(1)) 115 Expect(fakeEnqueueHistogram.ObserveArgsForCall(0)).To(BeNumerically(">", 0)) 116 Expect(fakeEnqueueHistogram.ObserveArgsForCall(0)).To(BeNumerically("<", 1)) 117 118 Expect(fakeProcessedCounter.WithCallCount()).To(Equal(1)) 119 Expect(fakeProcessedCounter.WithArgsForCall(0)).To(Equal([]string{ 120 "status", "SUCCESS", 121 "channel", "fake-channel", 122 "type", "ENDORSER_TRANSACTION", 123 })) 124 Expect(fakeProcessedCounter.AddCallCount()).To(Equal(1)) 125 Expect(fakeProcessedCounter.AddArgsForCall(0)).To(Equal(float64(1))) 126 127 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 128 Expect(proto.Equal(fakeABServer.SendArgsForCall(0), &ab.BroadcastResponse{Status: cb.Status_SUCCESS})).To(BeTrue()) 129 }) 130 131 Context("when the channel support cannot be retrieved", func() { 132 BeforeEach(func() { 133 fakeSupportRegistrar.BroadcastChannelSupportReturns(&cb.ChannelHeader{ 134 Type: 2, 135 ChannelId: "fake-channel", 136 }, false, nil, fmt.Errorf("support-error")) 137 }) 138 139 It("returns the error to the client with a bad status", func() { 140 err := handler.Handle(fakeABServer) 141 Expect(err).NotTo(HaveOccurred()) 142 143 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 144 Expect(proto.Equal( 145 fakeABServer.SendArgsForCall(0), 146 &ab.BroadcastResponse{Status: cb.Status_BAD_REQUEST, Info: "support-error"}), 147 ).To(BeTrue()) 148 }) 149 150 Context("when the channel header is not validly decoded", func() { 151 BeforeEach(func() { 152 fakeSupportRegistrar.BroadcastChannelSupportReturns(nil, false, nil, fmt.Errorf("support-error")) 153 }) 154 155 It("does not crash", func() { 156 err := handler.Handle(fakeABServer) 157 Expect(err).NotTo(HaveOccurred()) 158 159 Expect(fakeValidateHistogram.WithCallCount()).To(Equal(1)) 160 Expect(fakeValidateHistogram.WithArgsForCall(0)).To(Equal([]string{ 161 "status", "BAD_REQUEST", 162 "channel", "unknown", 163 "type", "unknown", 164 })) 165 Expect(fakeEnqueueHistogram.WithCallCount()).To(Equal(0)) 166 Expect(fakeProcessedCounter.WithCallCount()).To(Equal(1)) 167 }) 168 }) 169 }) 170 171 Context("when the receive from the client fails", func() { 172 BeforeEach(func() { 173 fakeABServer.RecvReturns(nil, fmt.Errorf("recv-error")) 174 }) 175 176 It("returns the error", func() { 177 err := handler.Handle(fakeABServer) 178 Expect(err).To(MatchError("recv-error")) 179 }) 180 }) 181 182 Context("when the consenter is not ready for the request", func() { 183 BeforeEach(func() { 184 fakeSupport.WaitReadyReturns(fmt.Errorf("not-ready")) 185 }) 186 187 It("returns the error to the client with a service unavailable status", func() { 188 err := handler.Handle(fakeABServer) 189 Expect(err).NotTo(HaveOccurred()) 190 191 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 192 Expect(proto.Equal( 193 fakeABServer.SendArgsForCall(0), 194 &ab.BroadcastResponse{Status: cb.Status_SERVICE_UNAVAILABLE, Info: "not-ready"}), 195 ).To(BeTrue()) 196 }) 197 }) 198 199 Context("when the send to the client fails", func() { 200 BeforeEach(func() { 201 fakeABServer.SendReturns(fmt.Errorf("send-error")) 202 }) 203 204 It("returns the error", func() { 205 err := handler.Handle(fakeABServer) 206 Expect(err).To(MatchError("send-error")) 207 }) 208 }) 209 210 Context("when the consenter cannot enqueue the message", func() { 211 BeforeEach(func() { 212 fakeSupport.OrderReturns(fmt.Errorf("consenter-error")) 213 }) 214 215 It("returns the error", func() { 216 err := handler.Handle(fakeABServer) 217 Expect(err).NotTo(HaveOccurred()) 218 219 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 220 Expect(proto.Equal( 221 fakeABServer.SendArgsForCall(0), 222 &ab.BroadcastResponse{Status: cb.Status_SERVICE_UNAVAILABLE, Info: "consenter-error"}), 223 ).To(BeTrue()) 224 }) 225 }) 226 227 Context("when the message processor returns an error", func() { 228 BeforeEach(func() { 229 fakeSupport.ProcessNormalMsgReturns(0, fmt.Errorf("normal-messsage-processing-error")) 230 }) 231 232 It("returns the error and an error status", func() { 233 err := handler.Handle(fakeABServer) 234 Expect(err).NotTo(HaveOccurred()) 235 236 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 237 Expect(proto.Equal( 238 fakeABServer.SendArgsForCall(0), 239 &ab.BroadcastResponse{Status: cb.Status_BAD_REQUEST, Info: "normal-messsage-processing-error"}, 240 )).To(BeTrue()) 241 }) 242 243 Context("when the error cause is msgprocessor.ErrChannelDoesNotExist", func() { 244 BeforeEach(func() { 245 fakeSupport.ProcessNormalMsgReturns(0, msgprocessor.ErrChannelDoesNotExist) 246 }) 247 248 It("returns the error and a not found status", func() { 249 err := handler.Handle(fakeABServer) 250 Expect(err).NotTo(HaveOccurred()) 251 252 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 253 Expect(proto.Equal( 254 fakeABServer.SendArgsForCall(0), 255 &ab.BroadcastResponse{Status: cb.Status_NOT_FOUND, Info: msgprocessor.ErrChannelDoesNotExist.Error()}, 256 )).To(BeTrue()) 257 }) 258 }) 259 260 Context("when the error cause is msgprocessor.ErrPermissionDenied", func() { 261 BeforeEach(func() { 262 fakeSupport.ProcessNormalMsgReturns(0, msgprocessor.ErrPermissionDenied) 263 }) 264 265 It("returns the error and a not found status", func() { 266 err := handler.Handle(fakeABServer) 267 Expect(err).NotTo(HaveOccurred()) 268 269 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 270 Expect(proto.Equal( 271 fakeABServer.SendArgsForCall(0), 272 &ab.BroadcastResponse{Status: cb.Status_FORBIDDEN, Info: msgprocessor.ErrPermissionDenied.Error()}, 273 )).To(BeTrue()) 274 }) 275 }) 276 }) 277 278 Context("when the message is a config message", func() { 279 var fakeConfig *cb.Envelope 280 281 BeforeEach(func() { 282 fakeConfig = &cb.Envelope{} 283 284 fakeSupportRegistrar.BroadcastChannelSupportReturns(&cb.ChannelHeader{ 285 Type: 1, 286 ChannelId: "fake-channel", 287 }, true, fakeSupport, nil) 288 289 fakeSupport.ProcessConfigUpdateMsgReturns(fakeConfig, 3, nil) 290 }) 291 292 It("enqueues the message as a config message to the consenter", func() { 293 err := handler.Handle(fakeABServer) 294 Expect(err).NotTo(HaveOccurred()) 295 296 Expect(fakeSupport.ProcessNormalMsgCallCount()).To(Equal(0)) 297 Expect(fakeSupport.ProcessConfigUpdateMsgCallCount()).To(Equal(1)) 298 Expect(fakeSupport.ProcessConfigUpdateMsgArgsForCall(0)).To(Equal(fakeMsg)) 299 300 Expect(fakeSupport.WaitReadyCallCount()).To(Equal(1)) 301 302 Expect(fakeSupport.OrderCallCount()).To(Equal(0)) 303 Expect(fakeSupport.ConfigureCallCount()).To(Equal(1)) 304 configMsg, seq := fakeSupport.ConfigureArgsForCall(0) 305 Expect(configMsg).To(Equal(fakeConfig)) 306 Expect(seq).To(Equal(uint64(3))) 307 308 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 309 Expect(proto.Equal(fakeABServer.SendArgsForCall(0), &ab.BroadcastResponse{Status: cb.Status_SUCCESS})).To(BeTrue()) 310 }) 311 312 Context("when the consenter is not ready for the request", func() { 313 BeforeEach(func() { 314 fakeSupport.WaitReadyReturns(fmt.Errorf("not-ready")) 315 }) 316 317 It("returns the error to the client with a service unavailable status", func() { 318 err := handler.Handle(fakeABServer) 319 Expect(err).NotTo(HaveOccurred()) 320 321 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 322 Expect(proto.Equal( 323 fakeABServer.SendArgsForCall(0), 324 &ab.BroadcastResponse{Status: cb.Status_SERVICE_UNAVAILABLE, Info: "not-ready"}), 325 ).To(BeTrue()) 326 }) 327 }) 328 329 Context("when the consenter cannot enqueue the message", func() { 330 BeforeEach(func() { 331 fakeSupport.ConfigureReturns(fmt.Errorf("consenter-error")) 332 }) 333 334 It("returns the error", func() { 335 err := handler.Handle(fakeABServer) 336 Expect(err).NotTo(HaveOccurred()) 337 338 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 339 Expect(proto.Equal( 340 fakeABServer.SendArgsForCall(0), 341 &ab.BroadcastResponse{Status: cb.Status_SERVICE_UNAVAILABLE, Info: "consenter-error"}), 342 ).To(BeTrue()) 343 }) 344 }) 345 346 Context("when the processing of the config update fails", func() { 347 BeforeEach(func() { 348 fakeSupport.ProcessConfigUpdateMsgReturns(nil, 0, fmt.Errorf("config-processing-error")) 349 }) 350 351 It("returns the error with a bad_status", func() { 352 err := handler.Handle(fakeABServer) 353 Expect(err).NotTo(HaveOccurred()) 354 355 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 356 Expect(proto.Equal( 357 fakeABServer.SendArgsForCall(0), 358 &ab.BroadcastResponse{Status: cb.Status_BAD_REQUEST, Info: "config-processing-error"}, 359 )).To(BeTrue()) 360 }) 361 362 Context("when the error cause is msgprocessor.ErrChannelDoesNotExist", func() { 363 BeforeEach(func() { 364 fakeSupport.ProcessConfigUpdateMsgReturns(nil, 0, msgprocessor.ErrChannelDoesNotExist) 365 }) 366 367 It("returns the error and a not found status", func() { 368 err := handler.Handle(fakeABServer) 369 Expect(err).NotTo(HaveOccurred()) 370 371 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 372 Expect(proto.Equal( 373 fakeABServer.SendArgsForCall(0), 374 &ab.BroadcastResponse{Status: cb.Status_NOT_FOUND, Info: msgprocessor.ErrChannelDoesNotExist.Error()}, 375 )).To(BeTrue()) 376 }) 377 }) 378 379 Context("when the error cause is msgprocessor.ErrPermissionDenied", func() { 380 BeforeEach(func() { 381 fakeSupport.ProcessConfigUpdateMsgReturns(nil, 0, msgprocessor.ErrPermissionDenied) 382 }) 383 384 It("returns the error and a not found status", func() { 385 err := handler.Handle(fakeABServer) 386 Expect(err).NotTo(HaveOccurred()) 387 388 Expect(fakeABServer.SendCallCount()).To(Equal(1)) 389 Expect(proto.Equal( 390 fakeABServer.SendArgsForCall(0), 391 &ab.BroadcastResponse{Status: cb.Status_FORBIDDEN, Info: msgprocessor.ErrPermissionDenied.Error()}, 392 )).To(BeTrue()) 393 }) 394 }) 395 }) 396 }) 397 }) 398 })