github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/orderer/consensus/kafka/consenter_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package kafka 8 9 import ( 10 "fmt" 11 "strings" 12 "testing" 13 "time" 14 15 "github.com/Shopify/sarama" 16 "github.com/golang/protobuf/proto" 17 "github.com/hechain20/hechain/common/channelconfig" 18 "github.com/hechain20/hechain/common/flogging" 19 "github.com/hechain20/hechain/common/metrics/disabled" 20 "github.com/hechain20/hechain/orderer/common/localconfig" 21 "github.com/hechain20/hechain/orderer/consensus" 22 "github.com/hechain20/hechain/orderer/consensus/kafka/mock" 23 mockmultichannel "github.com/hechain20/hechain/orderer/mocks/common/multichannel" 24 "github.com/hechain20/hechain/protoutil" 25 cb "github.com/hyperledger/fabric-protos-go/common" 26 ab "github.com/hyperledger/fabric-protos-go/orderer" 27 "github.com/stretchr/testify/require" 28 ) 29 30 //go:generate counterfeiter -o mock/orderer_config.go --fake-name OrdererConfig . ordererConfig 31 32 type ordererConfig interface { 33 channelconfig.Orderer 34 } 35 36 var mockRetryOptions = localconfig.Retry{ 37 ShortInterval: 50 * time.Millisecond, 38 ShortTotal: 100 * time.Millisecond, 39 LongInterval: 60 * time.Millisecond, 40 LongTotal: 120 * time.Millisecond, 41 NetworkTimeouts: localconfig.NetworkTimeouts{ 42 DialTimeout: 40 * time.Millisecond, 43 ReadTimeout: 40 * time.Millisecond, 44 WriteTimeout: 40 * time.Millisecond, 45 }, 46 Metadata: localconfig.Metadata{ 47 RetryMax: 2, 48 RetryBackoff: 40 * time.Millisecond, 49 }, 50 Producer: localconfig.Producer{ 51 RetryMax: 2, 52 RetryBackoff: 40 * time.Millisecond, 53 }, 54 Consumer: localconfig.Consumer{ 55 RetryBackoff: 40 * time.Millisecond, 56 }, 57 } 58 59 func init() { 60 mockLocalConfig = newMockLocalConfig( 61 false, 62 localconfig.SASLPlain{Enabled: false}, 63 mockRetryOptions, 64 false) 65 mockBrokerConfig = newMockBrokerConfig( 66 mockLocalConfig.General.TLS, 67 mockLocalConfig.Kafka.SASLPlain, 68 mockLocalConfig.Kafka.Retry, 69 mockLocalConfig.Kafka.Version, 70 defaultPartition) 71 mockConsenter = newMockConsenter( 72 mockBrokerConfig, 73 mockLocalConfig.General.TLS, 74 mockLocalConfig.Kafka.Retry, 75 mockLocalConfig.Kafka.Version) 76 setupTestLogging("ERROR") 77 } 78 79 func TestNew(t *testing.T) { 80 c, _ := New(mockLocalConfig.Kafka, &mock.MetricsProvider{}, &mock.HealthChecker{}, nil, func(string) {}) 81 _ = consensus.Consenter(c) 82 } 83 84 func TestHandleChain(t *testing.T) { 85 consenter, _ := New(mockLocalConfig.Kafka, &disabled.Provider{}, &mock.HealthChecker{}, nil, func(string) {}) 86 87 oldestOffset := int64(0) 88 newestOffset := int64(5) 89 message := sarama.StringEncoder("messageFoo") 90 91 mockChannel := newChannel(channelNameForTest(t), defaultPartition) 92 93 mockBroker := sarama.NewMockBroker(t, 0) 94 mockBroker.SetHandlerByMap(map[string]sarama.MockResponse{ 95 "MetadataRequest": sarama.NewMockMetadataResponse(t). 96 SetBroker(mockBroker.Addr(), mockBroker.BrokerID()). 97 SetLeader(mockChannel.topic(), mockChannel.partition(), mockBroker.BrokerID()), 98 "ProduceRequest": sarama.NewMockProduceResponse(t). 99 SetError(mockChannel.topic(), mockChannel.partition(), sarama.ErrNoError), 100 "OffsetRequest": sarama.NewMockOffsetResponse(t). 101 SetOffset(mockChannel.topic(), mockChannel.partition(), sarama.OffsetOldest, oldestOffset). 102 SetOffset(mockChannel.topic(), mockChannel.partition(), sarama.OffsetNewest, newestOffset), 103 "FetchRequest": sarama.NewMockFetchResponse(t, 1). 104 SetMessage(mockChannel.topic(), mockChannel.partition(), newestOffset, message), 105 }) 106 107 mockOrderer := &mock.OrdererConfig{} 108 mockOrderer.KafkaBrokersReturns([]string{mockBroker.Addr()}) 109 mockSupport := &mockmultichannel.ConsenterSupport{ 110 ChannelIDVal: mockChannel.topic(), 111 SharedConfigVal: mockOrderer, 112 } 113 114 mockMetadata := &cb.Metadata{Value: protoutil.MarshalOrPanic(&ab.KafkaMetadata{LastOffsetPersisted: newestOffset - 1})} 115 _, err := consenter.HandleChain(mockSupport, mockMetadata) 116 require.NoError(t, err, "Expected the HandleChain call to return without errors") 117 } 118 119 // Test helper functions and mock objects defined here 120 121 var ( 122 mockConsenter commonConsenter 123 mockLocalConfig *localconfig.TopLevel 124 mockBrokerConfig *sarama.Config 125 ) 126 127 func extractEncodedOffset(marshalledOrdererMetadata []byte) int64 { 128 omd := &cb.Metadata{} 129 _ = proto.Unmarshal(marshalledOrdererMetadata, omd) 130 kmd := &ab.KafkaMetadata{} 131 _ = proto.Unmarshal(omd.GetValue(), kmd) 132 return kmd.LastOffsetPersisted 133 } 134 135 func newMockBrokerConfig( 136 tlsConfig localconfig.TLS, 137 saslPlain localconfig.SASLPlain, 138 retryOptions localconfig.Retry, 139 kafkaVersion sarama.KafkaVersion, 140 chosenStaticPartition int32) *sarama.Config { 141 brokerConfig := newBrokerConfig( 142 tlsConfig, 143 saslPlain, 144 retryOptions, 145 kafkaVersion, 146 chosenStaticPartition) 147 brokerConfig.ClientID = "test" 148 return brokerConfig 149 } 150 151 func newMockConsenter(brokerConfig *sarama.Config, tlsConfig localconfig.TLS, retryOptions localconfig.Retry, kafkaVersion sarama.KafkaVersion) *consenterImpl { 152 return &consenterImpl{ 153 brokerConfigVal: brokerConfig, 154 tlsConfigVal: tlsConfig, 155 retryOptionsVal: retryOptions, 156 kafkaVersionVal: kafkaVersion, 157 metrics: NewMetrics(&disabled.Provider{}, nil), 158 } 159 } 160 161 func newMockConsumerMessage(wrappedMessage *ab.KafkaMessage) *sarama.ConsumerMessage { 162 return &sarama.ConsumerMessage{ 163 Value: sarama.ByteEncoder(protoutil.MarshalOrPanic(wrappedMessage)), 164 } 165 } 166 167 func newMockEnvelope(content string) *cb.Envelope { 168 return &cb.Envelope{Payload: protoutil.MarshalOrPanic(&cb.Payload{ 169 Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{ChannelId: "foo"})}, 170 Data: []byte(content), 171 })} 172 } 173 174 func newMockLocalConfig( 175 enableTLS bool, 176 saslPlain localconfig.SASLPlain, 177 retryOptions localconfig.Retry, 178 verboseLog bool) *localconfig.TopLevel { 179 return &localconfig.TopLevel{ 180 General: localconfig.General{ 181 TLS: localconfig.TLS{ 182 Enabled: enableTLS, 183 }, 184 }, 185 Kafka: localconfig.Kafka{ 186 TLS: localconfig.TLS{ 187 Enabled: enableTLS, 188 }, 189 SASLPlain: saslPlain, 190 Retry: retryOptions, 191 Verbose: verboseLog, 192 Version: sarama.V0_9_0_1, // sarama.MockBroker only produces messages compatible with version < 0.10 193 }, 194 } 195 } 196 197 func setupTestLogging(logLevel string) { 198 // This call allows us to (a) get the logging backend initialization that 199 // takes place in the `flogging` package, and (b) adjust the verbosity of 200 // the logs when running tests on this package. 201 spec := fmt.Sprintf("orderer.consensus.kafka=%s", logLevel) 202 flogging.ActivateSpec(spec) 203 } 204 205 func tamperBytes(original []byte) []byte { 206 byteCount := len(original) 207 return original[:byteCount-1] 208 } 209 210 func channelNameForTest(t *testing.T) string { 211 return fmt.Sprintf("%s.channel", strings.Replace(strings.ToLower(t.Name()), "/", ".", -1)) 212 }