github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/common/configvalues/channel/orderer/sharedconfig_test.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package orderer 18 19 import ( 20 "os" 21 "os/exec" 22 "reflect" 23 "testing" 24 "time" 25 26 "github.com/stretchr/testify/assert" 27 28 cb "github.com/hyperledger/fabric/protos/common" 29 ab "github.com/hyperledger/fabric/protos/orderer" 30 31 logging "github.com/op/go-logging" 32 ) 33 34 func init() { 35 logging.SetLevel(logging.DEBUG, "") 36 } 37 38 func invalidMessage() *cb.ConfigValue { 39 return &cb.ConfigValue{ 40 Value: []byte("Garbage Data"), 41 } 42 } 43 44 func groupToKeyValue(configGroup *cb.ConfigGroup) (string, *cb.ConfigValue) { 45 for key, value := range configGroup.Groups[GroupKey].Values { 46 return key, value 47 } 48 panic("No value encoded") 49 } 50 51 func doesFuncCrash(crasher func(), test string) bool { 52 // Adapted from https://talks.golang.org/2014/testing.slide#23 to test os.Exit() functionality 53 if os.Getenv("BE_CRASHER") == "1" { 54 crasher() 55 return false 56 } 57 cmd := exec.Command(os.Args[0], "-test.run="+test) 58 cmd.Env = append(os.Environ(), "BE_CRASHER=1") 59 err := cmd.Run() 60 if e, ok := err.(*exec.ExitError); ok && !e.Success() { 61 return true 62 } 63 return false 64 } 65 66 func TestDoubleBegin(t *testing.T) { 67 crashes := doesFuncCrash(func() { 68 m := NewManagerImpl(nil) 69 m.BeginValueProposals(nil) 70 m.BeginValueProposals(nil) 71 }, "TestDoubleBegin") 72 73 if !crashes { 74 t.Fatalf("Should have crashed on multiple begin configs") 75 } 76 } 77 78 func TestCommitWithoutBegin(t *testing.T) { 79 crashes := doesFuncCrash(func() { 80 m := NewManagerImpl(nil) 81 m.CommitProposals() 82 }, "TestCommitWithoutBegin") 83 84 if !crashes { 85 t.Fatalf("Should have crashed on multiple begin configs") 86 } 87 } 88 89 func TestRollback(t *testing.T) { 90 m := NewManagerImpl(nil) 91 m.pendingConfig = &ordererConfig{} 92 m.RollbackProposals() 93 if m.pendingConfig != nil { 94 t.Fatalf("Should have cleared pending config on rollback") 95 } 96 } 97 98 func TestConsensusType(t *testing.T) { 99 endType := "foo" 100 invalidMessage := invalidMessage() 101 validMessage := TemplateConsensusType(endType) 102 otherValidMessage := TemplateConsensusType("bar") 103 104 m := NewManagerImpl(nil) 105 m.BeginValueProposals(nil) 106 107 err := m.ProposeValue(groupToKeyValue(validMessage)) 108 if err != nil { 109 t.Fatalf("Error applying valid config: %s", err) 110 } 111 112 m.CommitProposals() 113 m.BeginValueProposals(nil) 114 115 err = m.ProposeValue(ConsensusTypeKey, invalidMessage) 116 if err == nil { 117 t.Fatalf("Should have failed on invalid message") 118 } 119 120 err = m.ProposeValue(groupToKeyValue(validMessage)) 121 if err != nil { 122 t.Fatalf("Error re-applying valid config: %s", err) 123 } 124 125 err = m.ProposeValue(groupToKeyValue(otherValidMessage)) 126 if err == nil { 127 t.Fatalf("Should not have applied config with different consensus type after it was initially set") 128 } 129 130 m.CommitProposals() 131 132 if nowType := m.ConsensusType(); nowType != endType { 133 t.Fatalf("Consensus type should have ended as %s but was %s", endType, nowType) 134 } 135 } 136 137 func TestBatchSize(t *testing.T) { 138 139 validMaxMessageCount := uint32(10) 140 validAbsoluteMaxBytes := uint32(1000) 141 validPreferredMaxBytes := uint32(500) 142 143 t.Run("ValidConfig", func(t *testing.T) { 144 m := NewManagerImpl(nil) 145 m.BeginValueProposals(nil) 146 err := m.ProposeValue( 147 groupToKeyValue(TemplateBatchSize(&ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validPreferredMaxBytes})), 148 ) 149 assert.Nil(t, err, "Error applying valid config: %s", err) 150 m.CommitProposals() 151 if m.BatchSize().MaxMessageCount != validMaxMessageCount { 152 t.Fatalf("Got batch size max message count of %d. Expected: %d", m.BatchSize().MaxMessageCount, validMaxMessageCount) 153 } 154 if m.BatchSize().AbsoluteMaxBytes != validAbsoluteMaxBytes { 155 t.Fatalf("Got batch size absolute max bytes of %d. Expected: %d", m.BatchSize().AbsoluteMaxBytes, validAbsoluteMaxBytes) 156 } 157 if m.BatchSize().PreferredMaxBytes != validPreferredMaxBytes { 158 t.Fatalf("Got batch size preferred max bytes of %d. Expected: %d", m.BatchSize().PreferredMaxBytes, validPreferredMaxBytes) 159 } 160 }) 161 162 t.Run("UnserializableConfig", func(t *testing.T) { 163 m := NewManagerImpl(nil) 164 m.BeginValueProposals(nil) 165 err := m.ProposeValue(BatchSizeKey, invalidMessage()) 166 assert.NotNil(t, err, "Should have failed on invalid message") 167 m.CommitProposals() 168 }) 169 170 t.Run("ZeroMaxMessageCount", func(t *testing.T) { 171 m := NewManagerImpl(nil) 172 m.BeginValueProposals(nil) 173 err := m.ProposeValue(groupToKeyValue(TemplateBatchSize(&ab.BatchSize{MaxMessageCount: 0, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validPreferredMaxBytes}))) 174 assert.NotNil(t, err, "Should have rejected batch size max message count of 0") 175 m.CommitProposals() 176 }) 177 178 t.Run("ZeroAbsoluteMaxBytes", func(t *testing.T) { 179 m := NewManagerImpl(nil) 180 m.BeginValueProposals(nil) 181 err := m.ProposeValue(groupToKeyValue(TemplateBatchSize(&ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: 0, PreferredMaxBytes: validPreferredMaxBytes}))) 182 assert.NotNil(t, err, "Should have rejected batch size absolute max message bytes of 0") 183 m.CommitProposals() 184 }) 185 186 t.Run("TooLargePreferredMaxBytes", func(t *testing.T) { 187 m := NewManagerImpl(nil) 188 m.BeginValueProposals(nil) 189 err := m.ProposeValue(groupToKeyValue(TemplateBatchSize(&ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validAbsoluteMaxBytes + 1}))) 190 assert.NotNil(t, err, "Should have rejected batch size preferred max message bytes greater than absolute max message bytes") 191 m.CommitProposals() 192 }) 193 } 194 195 func TestBatchTimeout(t *testing.T) { 196 endBatchTimeout, _ := time.ParseDuration("1s") 197 invalidMessage := invalidMessage() 198 negativeBatchTimeout := TemplateBatchTimeout("-1s") 199 zeroBatchTimeout := TemplateBatchTimeout("0s") 200 validMessage := TemplateBatchTimeout(endBatchTimeout.String()) 201 202 m := NewManagerImpl(nil) 203 m.BeginValueProposals(nil) 204 205 err := m.ProposeValue(groupToKeyValue(validMessage)) 206 if err != nil { 207 t.Fatalf("Error applying valid config: %s", err) 208 } 209 210 err = m.ProposeValue(BatchTimeoutKey, invalidMessage) 211 if err == nil { 212 t.Fatalf("Should have failed on invalid message") 213 } 214 215 err = m.ProposeValue(groupToKeyValue(negativeBatchTimeout)) 216 if err == nil { 217 t.Fatalf("Should have rejected negative batch timeout: %s", err) 218 } 219 220 err = m.ProposeValue(groupToKeyValue(zeroBatchTimeout)) 221 if err == nil { 222 t.Fatalf("Should have rejected batch timeout of 0") 223 } 224 225 m.CommitProposals() 226 227 if nowBatchTimeout := m.BatchTimeout(); nowBatchTimeout != endBatchTimeout { 228 t.Fatalf("Got batch timeout of %s when expecting batch size of %s", nowBatchTimeout.String(), endBatchTimeout.String()) 229 } 230 } 231 232 func TestKafkaBrokers(t *testing.T) { 233 endList := []string{"127.0.0.1:9092", "foo.bar:9092"} 234 235 invalidMessage := invalidMessage() 236 zeroBrokers := TemplateKafkaBrokers([]string{}) 237 badList := []string{"127.0.0.1", "foo.bar", "127.0.0.1:-1", "localhost:65536", "foo.bar.:9092", ".127.0.0.1:9092", "-foo.bar:9092"} 238 badMessages := []*cb.ConfigGroup{} 239 for _, badAddress := range badList { 240 badMessages = append(badMessages, TemplateKafkaBrokers([]string{badAddress})) 241 } 242 243 validMessage := TemplateKafkaBrokers(endList) 244 245 m := NewManagerImpl(nil) 246 m.BeginValueProposals(nil) 247 248 err := m.ProposeValue(groupToKeyValue(validMessage)) 249 if err != nil { 250 t.Fatalf("Error applying valid config: %s", err) 251 } 252 253 err = m.ProposeValue(KafkaBrokersKey, invalidMessage) 254 if err == nil { 255 t.Fatalf("Should have failed on invalid message") 256 } 257 258 err = m.ProposeValue(groupToKeyValue(zeroBrokers)) 259 if err == nil { 260 t.Fatalf("Should have rejected empty brokers list") 261 } 262 263 for i := range badMessages { 264 err = m.ProposeValue(groupToKeyValue(badMessages[i])) 265 if err == nil { 266 t.Fatalf("Should have rejected broker address which is obviously malformed") 267 } 268 } 269 270 m.CommitProposals() 271 272 nowList := m.KafkaBrokers() 273 switch { 274 case len(nowList) != len(endList), nowList[0] != endList[0]: 275 t.Fatalf("Got brokers list %s when expecting brokers list %s", nowList, endList) 276 default: 277 return 278 } 279 } 280 281 func testPolicyNames(m *ManagerImpl, key string, initializer func(val []string) *cb.ConfigGroup, retriever func() []string, t *testing.T) { 282 endPolicy := []string{"foo", "bar"} 283 invalidMessage := invalidMessage() 284 validMessage := initializer(endPolicy) 285 286 m.BeginValueProposals(nil) 287 288 err := m.ProposeValue(groupToKeyValue(validMessage)) 289 if err != nil { 290 t.Fatalf("Error applying valid config: %s", err) 291 } 292 293 m.CommitProposals() 294 m.BeginValueProposals(nil) 295 296 err = m.ProposeValue(key, invalidMessage) 297 if err == nil { 298 t.Fatalf("Should have failed on invalid message") 299 } 300 301 err = m.ProposeValue(groupToKeyValue(validMessage)) 302 if err != nil { 303 t.Fatalf("Error re-applying valid config: %s", err) 304 } 305 306 m.CommitProposals() 307 308 if nowPolicy := retriever(); !reflect.DeepEqual(nowPolicy, endPolicy) { 309 t.Fatalf("%s should have ended as %s but was %s", key, endPolicy, nowPolicy) 310 } 311 } 312 313 func TestIngressPolicyNames(t *testing.T) { 314 m := NewManagerImpl(nil) 315 testPolicyNames(m, IngressPolicyNamesKey, TemplateIngressPolicyNames, m.IngressPolicyNames, t) 316 } 317 318 func TestEgressPolicyNames(t *testing.T) { 319 m := NewManagerImpl(nil) 320 testPolicyNames(m, EgressPolicyNamesKey, TemplateEgressPolicyNames, m.EgressPolicyNames, t) 321 } 322 323 func TestChainCreationPolicyNames(t *testing.T) { 324 m := NewManagerImpl(nil) 325 testPolicyNames(m, ChainCreationPolicyNamesKey, TemplateChainCreationPolicyNames, m.ChainCreationPolicyNames, t) 326 } 327 328 func TestEmptyChainCreationPolicyNames(t *testing.T) { 329 m := NewManagerImpl(nil) 330 331 m.BeginValueProposals(nil) 332 333 err := m.ProposeValue(groupToKeyValue(TemplateChainCreationPolicyNames(nil))) 334 if err != nil { 335 t.Fatalf("Error applying valid config: %s", err) 336 } 337 338 m.CommitProposals() 339 340 if m.ChainCreationPolicyNames() == nil { 341 t.Fatalf("Should have gotten back empty slice, not nil") 342 } 343 }