github.com/lzy4123/fabric@v2.1.1+incompatible/orderer/consensus/kafka/consenter_test.go (about) 1 /* 2 Copyright IBM Corp. 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 cb "github.com/hyperledger/fabric-protos-go/common" 18 ab "github.com/hyperledger/fabric-protos-go/orderer" 19 "github.com/hyperledger/fabric/common/channelconfig" 20 "github.com/hyperledger/fabric/common/flogging" 21 "github.com/hyperledger/fabric/common/metrics/disabled" 22 "github.com/hyperledger/fabric/orderer/common/localconfig" 23 "github.com/hyperledger/fabric/orderer/consensus" 24 "github.com/hyperledger/fabric/orderer/consensus/kafka/mock" 25 mockmultichannel "github.com/hyperledger/fabric/orderer/mocks/common/multichannel" 26 "github.com/hyperledger/fabric/protoutil" 27 "github.com/stretchr/testify/assert" 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 assert.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 mockConsenter commonConsenter 122 var mockLocalConfig *localconfig.TopLevel 123 var mockBrokerConfig *sarama.Config 124 125 func extractEncodedOffset(marshalledOrdererMetadata []byte) int64 { 126 omd := &cb.Metadata{} 127 _ = proto.Unmarshal(marshalledOrdererMetadata, omd) 128 kmd := &ab.KafkaMetadata{} 129 _ = proto.Unmarshal(omd.GetValue(), kmd) 130 return kmd.LastOffsetPersisted 131 } 132 133 func newMockBrokerConfig( 134 tlsConfig localconfig.TLS, 135 saslPlain localconfig.SASLPlain, 136 retryOptions localconfig.Retry, 137 kafkaVersion sarama.KafkaVersion, 138 chosenStaticPartition int32) *sarama.Config { 139 140 brokerConfig := newBrokerConfig( 141 tlsConfig, 142 saslPlain, 143 retryOptions, 144 kafkaVersion, 145 chosenStaticPartition) 146 brokerConfig.ClientID = "test" 147 return brokerConfig 148 } 149 150 func newMockConsenter(brokerConfig *sarama.Config, tlsConfig localconfig.TLS, retryOptions localconfig.Retry, kafkaVersion sarama.KafkaVersion) *consenterImpl { 151 return &consenterImpl{ 152 brokerConfigVal: brokerConfig, 153 tlsConfigVal: tlsConfig, 154 retryOptionsVal: retryOptions, 155 kafkaVersionVal: kafkaVersion, 156 metrics: NewMetrics(&disabled.Provider{}, nil), 157 } 158 } 159 160 func newMockConsumerMessage(wrappedMessage *ab.KafkaMessage) *sarama.ConsumerMessage { 161 return &sarama.ConsumerMessage{ 162 Value: sarama.ByteEncoder(protoutil.MarshalOrPanic(wrappedMessage)), 163 } 164 } 165 166 func newMockEnvelope(content string) *cb.Envelope { 167 return &cb.Envelope{Payload: protoutil.MarshalOrPanic(&cb.Payload{ 168 Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{ChannelId: "foo"})}, 169 Data: []byte(content), 170 })} 171 } 172 173 func newMockLocalConfig( 174 enableTLS bool, 175 saslPlain localconfig.SASLPlain, 176 retryOptions localconfig.Retry, 177 verboseLog bool) *localconfig.TopLevel { 178 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 }