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  })