github.com/ewagmig/fabric@v2.1.1+incompatible/common/channelconfig/bundle_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package channelconfig 8 9 import ( 10 "testing" 11 12 cb "github.com/hyperledger/fabric-protos-go/common" 13 ab "github.com/hyperledger/fabric-protos-go/orderer" 14 cc "github.com/hyperledger/fabric/common/capabilities" 15 "github.com/stretchr/testify/assert" 16 ) 17 18 func TestValidateNew(t *testing.T) { 19 t.Run("DisappearingOrdererConfig", func(t *testing.T) { 20 cb := &Bundle{ 21 channelConfig: &ChannelConfig{ 22 ordererConfig: &OrdererConfig{}, 23 }, 24 } 25 26 nb := &Bundle{ 27 channelConfig: &ChannelConfig{}, 28 } 29 30 err := cb.ValidateNew(nb) 31 assert.Error(t, err) 32 assert.Regexp(t, "current config has orderer section, but new config does not", err.Error()) 33 }) 34 35 t.Run("DisappearingApplicationConfig", func(t *testing.T) { 36 cb := &Bundle{ 37 channelConfig: &ChannelConfig{ 38 appConfig: &ApplicationConfig{}, 39 }, 40 } 41 42 nb := &Bundle{ 43 channelConfig: &ChannelConfig{}, 44 } 45 46 err := cb.ValidateNew(nb) 47 assert.Error(t, err) 48 assert.Regexp(t, "current config has application section, but new config does not", err.Error()) 49 }) 50 51 t.Run("DisappearingConsortiumsConfig", func(t *testing.T) { 52 cb := &Bundle{ 53 channelConfig: &ChannelConfig{ 54 consortiumsConfig: &ConsortiumsConfig{}, 55 }, 56 } 57 58 nb := &Bundle{ 59 channelConfig: &ChannelConfig{}, 60 } 61 62 err := cb.ValidateNew(nb) 63 assert.Error(t, err) 64 assert.Regexp(t, "current config has consortiums section, but new config does not", err.Error()) 65 }) 66 67 t.Run("Prevent adding ConsortiumsConfig to standard channel", func(t *testing.T) { 68 cb := &Bundle{ 69 channelConfig: &ChannelConfig{}, 70 } 71 72 nb := &Bundle{ 73 channelConfig: &ChannelConfig{ 74 consortiumsConfig: &ConsortiumsConfig{}, 75 }, 76 } 77 78 err := cb.ValidateNew(nb) 79 assert.EqualError(t, err, "current config has no consortiums section, but new config does") 80 }) 81 82 t.Run("ConsensusTypeChange", func(t *testing.T) { 83 currb := &Bundle{ 84 channelConfig: &ChannelConfig{ 85 ordererConfig: &OrdererConfig{ 86 protos: &OrdererProtos{ 87 ConsensusType: &ab.ConsensusType{ 88 Type: "type1", 89 }, 90 Capabilities: &cb.Capabilities{}, 91 }, 92 }, 93 protos: &ChannelProtos{ 94 Capabilities: &cb.Capabilities{}, 95 }, 96 }, 97 } 98 99 newb := &Bundle{ 100 channelConfig: &ChannelConfig{ 101 ordererConfig: &OrdererConfig{ 102 protos: &OrdererProtos{ 103 ConsensusType: &ab.ConsensusType{ 104 Type: "type2", 105 }, 106 Capabilities: &cb.Capabilities{}, 107 }, 108 }, 109 protos: &ChannelProtos{ 110 Capabilities: &cb.Capabilities{}, 111 }, 112 }, 113 } 114 115 err := currb.ValidateNew(newb) 116 assert.Error(t, err) 117 assert.Contains(t, err.Error(), "attempted to change consensus type from") 118 }) 119 120 t.Run("OrdererOrgMSPIDChange", func(t *testing.T) { 121 currb := &Bundle{ 122 channelConfig: &ChannelConfig{ 123 ordererConfig: &OrdererConfig{ 124 protos: &OrdererProtos{ 125 ConsensusType: &ab.ConsensusType{ 126 Type: "type1", 127 }, 128 Capabilities: &cb.Capabilities{}, 129 }, 130 orgs: map[string]OrdererOrg{ 131 "org1": &OrdererOrgConfig{OrganizationConfig: &OrganizationConfig{mspID: "org1msp"}}, 132 "org2": &OrdererOrgConfig{OrganizationConfig: &OrganizationConfig{mspID: "org2msp"}}, 133 "org3": &OrdererOrgConfig{OrganizationConfig: &OrganizationConfig{mspID: "org3msp"}}, 134 }, 135 }, 136 protos: &ChannelProtos{ 137 Capabilities: &cb.Capabilities{}, 138 }, 139 }, 140 } 141 142 newb := &Bundle{ 143 channelConfig: &ChannelConfig{ 144 ordererConfig: &OrdererConfig{ 145 protos: &OrdererProtos{ 146 ConsensusType: &ab.ConsensusType{ 147 Type: "type1", 148 }, 149 Capabilities: &cb.Capabilities{}, 150 }, 151 orgs: map[string]OrdererOrg{ 152 "org1": &OrdererOrgConfig{OrganizationConfig: &OrganizationConfig{mspID: "org1msp"}}, 153 "org3": &OrdererOrgConfig{OrganizationConfig: &OrganizationConfig{mspID: "org2msp"}}, 154 }, 155 }, 156 protos: &ChannelProtos{ 157 Capabilities: &cb.Capabilities{}, 158 }, 159 }, 160 } 161 162 err := currb.ValidateNew(newb) 163 assert.Error(t, err) 164 assert.Regexp(t, "orderer org org3 attempted to change MSP ID from", err.Error()) 165 }) 166 167 t.Run("ApplicationOrgMSPIDChange", func(t *testing.T) { 168 currb := &Bundle{ 169 channelConfig: &ChannelConfig{ 170 appConfig: &ApplicationConfig{ 171 applicationOrgs: map[string]ApplicationOrg{ 172 "org1": &ApplicationOrgConfig{OrganizationConfig: &OrganizationConfig{mspID: "org1msp"}}, 173 "org2": &ApplicationOrgConfig{OrganizationConfig: &OrganizationConfig{mspID: "org2msp"}}, 174 "org3": &ApplicationOrgConfig{OrganizationConfig: &OrganizationConfig{mspID: "org3msp"}}, 175 }, 176 }, 177 protos: &ChannelProtos{ 178 Capabilities: &cb.Capabilities{}, 179 }, 180 }, 181 } 182 183 nb := &Bundle{ 184 channelConfig: &ChannelConfig{ 185 appConfig: &ApplicationConfig{ 186 applicationOrgs: map[string]ApplicationOrg{ 187 "org1": &ApplicationOrgConfig{OrganizationConfig: &OrganizationConfig{mspID: "org1msp"}}, 188 "org3": &ApplicationOrgConfig{OrganizationConfig: &OrganizationConfig{mspID: "org2msp"}}, 189 }, 190 }, 191 protos: &ChannelProtos{ 192 Capabilities: &cb.Capabilities{}, 193 }, 194 }, 195 } 196 197 err := currb.ValidateNew(nb) 198 assert.Error(t, err) 199 assert.Regexp(t, "application org org3 attempted to change MSP ID from", err.Error()) 200 }) 201 202 t.Run("ConsortiumOrgMSPIDChange", func(t *testing.T) { 203 currb := &Bundle{ 204 channelConfig: &ChannelConfig{ 205 consortiumsConfig: &ConsortiumsConfig{ 206 consortiums: map[string]Consortium{ 207 "consortium1": &ConsortiumConfig{ 208 orgs: map[string]Org{ 209 "org1": &OrganizationConfig{mspID: "org1msp"}, 210 "org2": &OrganizationConfig{mspID: "org2msp"}, 211 "org3": &OrganizationConfig{mspID: "org3msp"}, 212 }, 213 }, 214 "consortium2": &ConsortiumConfig{}, 215 "consortium3": &ConsortiumConfig{}, 216 }, 217 }, 218 protos: &ChannelProtos{ 219 Capabilities: &cb.Capabilities{}, 220 }, 221 }, 222 } 223 224 nb := &Bundle{ 225 channelConfig: &ChannelConfig{ 226 consortiumsConfig: &ConsortiumsConfig{ 227 consortiums: map[string]Consortium{ 228 "consortium1": &ConsortiumConfig{ 229 orgs: map[string]Org{ 230 "org1": &OrganizationConfig{mspID: "org1msp"}, 231 "org3": &OrganizationConfig{mspID: "org2msp"}, 232 }, 233 }, 234 }, 235 }, 236 protos: &ChannelProtos{ 237 Capabilities: &cb.Capabilities{}, 238 }, 239 }, 240 } 241 242 err := currb.ValidateNew(nb) 243 assert.Error(t, err) 244 assert.Regexp(t, "consortium consortium1 org org3 attempted to change MSP ID from", err.Error()) 245 }) 246 } 247 248 func TestValidateNewWithConsensusMigration(t *testing.T) { 249 t.Run("ConsensusTypeMigration Green Path", func(t *testing.T) { 250 for _, sysChan := range []bool{false, true} { 251 b0 := generateMigrationBundle(sysChan, "kafka", ab.ConsensusType_STATE_NORMAL) 252 b1 := generateMigrationBundle(sysChan, "kafka", ab.ConsensusType_STATE_NORMAL) 253 err := b0.ValidateNew(b1) 254 assert.NoError(t, err) 255 256 b2 := generateMigrationBundle(sysChan, "kafka", ab.ConsensusType_STATE_MAINTENANCE) 257 err = b1.ValidateNew(b2) 258 assert.NoError(t, err) 259 260 b3 := generateMigrationBundle(sysChan, "etcdraft", ab.ConsensusType_STATE_MAINTENANCE) 261 err = b2.ValidateNew(b3) 262 assert.NoError(t, err) 263 264 b4 := generateMigrationBundle(sysChan, "etcdraft", ab.ConsensusType_STATE_NORMAL) 265 err = b3.ValidateNew(b4) 266 assert.NoError(t, err) 267 268 b5 := generateMigrationBundle(sysChan, "etcdraft", ab.ConsensusType_STATE_NORMAL) 269 err = b4.ValidateNew(b5) 270 assert.NoError(t, err) 271 } 272 }) 273 274 t.Run("ConsensusTypeMigration Abort Path", func(t *testing.T) { 275 for _, sysChan := range []bool{false, true} { 276 b1 := generateMigrationBundle(sysChan, "kafka", ab.ConsensusType_STATE_NORMAL) 277 b2 := generateMigrationBundle(sysChan, "kafka", ab.ConsensusType_STATE_MAINTENANCE) 278 err := b1.ValidateNew(b2) 279 assert.NoError(t, err) 280 281 b3 := generateMigrationBundle(sysChan, "kafka", ab.ConsensusType_STATE_NORMAL) 282 err = b2.ValidateNew(b3) 283 assert.NoError(t, err) 284 } 285 }) 286 } 287 288 func generateMigrationBundle(sysChan bool, cType string, cState ab.ConsensusType_State) *Bundle { 289 b := &Bundle{ 290 channelConfig: &ChannelConfig{ 291 ordererConfig: &OrdererConfig{ 292 protos: &OrdererProtos{ 293 ConsensusType: &ab.ConsensusType{ 294 Type: cType, 295 State: cState, 296 }, 297 Capabilities: &cb.Capabilities{ 298 Capabilities: map[string]*cb.Capability{ 299 cc.OrdererV1_4_2: {}, 300 }, 301 }, 302 }, 303 }, 304 protos: &ChannelProtos{ 305 Capabilities: &cb.Capabilities{ 306 Capabilities: map[string]*cb.Capability{ 307 cc.ChannelV1_4_2: {}, 308 }, 309 }, 310 }, 311 }, 312 } 313 314 if sysChan { 315 b.channelConfig.consortiumsConfig = &ConsortiumsConfig{} 316 } 317 318 return b 319 } 320 321 func TestPrevalidation(t *testing.T) { 322 t.Run("NilConfig", func(t *testing.T) { 323 err := preValidate(nil) 324 325 assert.Error(t, err) 326 assert.Regexp(t, "channelconfig Config cannot be nil", err.Error()) 327 }) 328 329 t.Run("NilChannelGroup", func(t *testing.T) { 330 err := preValidate(&cb.Config{}) 331 332 assert.Error(t, err) 333 assert.Regexp(t, "config must contain a channel group", err.Error()) 334 }) 335 336 t.Run("BadChannelCapabilities", func(t *testing.T) { 337 err := preValidate(&cb.Config{ 338 ChannelGroup: &cb.ConfigGroup{ 339 Groups: map[string]*cb.ConfigGroup{ 340 OrdererGroupKey: {}, 341 }, 342 Values: map[string]*cb.ConfigValue{ 343 CapabilitiesKey: {}, 344 }, 345 }, 346 }) 347 348 assert.Error(t, err) 349 assert.Regexp(t, "cannot enable channel capabilities without orderer support first", err.Error()) 350 }) 351 352 t.Run("BadApplicationCapabilities", func(t *testing.T) { 353 err := preValidate(&cb.Config{ 354 ChannelGroup: &cb.ConfigGroup{ 355 Groups: map[string]*cb.ConfigGroup{ 356 ApplicationGroupKey: { 357 Values: map[string]*cb.ConfigValue{ 358 CapabilitiesKey: {}, 359 }, 360 }, 361 OrdererGroupKey: {}, 362 }, 363 }, 364 }) 365 366 assert.Error(t, err) 367 assert.Regexp(t, "cannot enable application capabilities without orderer support first", err.Error()) 368 }) 369 370 t.Run("ValidCapabilities", func(t *testing.T) { 371 err := preValidate(&cb.Config{ 372 ChannelGroup: &cb.ConfigGroup{ 373 Groups: map[string]*cb.ConfigGroup{ 374 ApplicationGroupKey: { 375 Values: map[string]*cb.ConfigValue{ 376 CapabilitiesKey: {}, 377 }, 378 }, 379 OrdererGroupKey: { 380 Values: map[string]*cb.ConfigValue{ 381 CapabilitiesKey: {}, 382 }, 383 }, 384 }, 385 Values: map[string]*cb.ConfigValue{ 386 CapabilitiesKey: {}, 387 }, 388 }, 389 }) 390 391 assert.NoError(t, err) 392 }) 393 }