github.com/Hnampk/my-fabric@v0.0.0-20201028083322-75069da399c0/core/peer/configtx_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package peer 8 9 import ( 10 "io/ioutil" 11 "os" 12 "testing" 13 14 "github.com/golang/protobuf/proto" 15 "github.com/hyperledger/fabric-protos-go/common" 16 "github.com/hyperledger/fabric/bccsp/sw" 17 "github.com/hyperledger/fabric/common/capabilities" 18 "github.com/hyperledger/fabric/common/channelconfig" 19 configtxtest "github.com/hyperledger/fabric/common/configtx/test" 20 "github.com/hyperledger/fabric/common/ledger/testutil" 21 "github.com/hyperledger/fabric/core/config/configtest" 22 "github.com/hyperledger/fabric/core/ledger" 23 "github.com/hyperledger/fabric/protoutil" 24 "github.com/hyperledger/fabric/usable-inter-nal/configtxgen/encoder" 25 "github.com/hyperledger/fabric/usable-inter-nal/configtxgen/genesisconfig" 26 "github.com/stretchr/testify/assert" 27 "github.com/stretchr/testify/require" 28 ) 29 30 func TestConfigTxCreateLedger(t *testing.T) { 31 helper := newTestHelper(t) 32 channelID := "testchain1" 33 tempdir, err := ioutil.TempDir("", "peer-test") 34 require.NoError(t, err, "failed to create temporary directory") 35 36 ledgerMgr, err := constructLedgerMgrWithTestDefaults(tempdir) 37 if err != nil { 38 t.Fatalf("Failed to create test environment: %s", err) 39 } 40 41 defer func() { 42 ledgerMgr.Close() 43 os.RemoveAll(tempdir) 44 }() 45 46 chanConf := helper.sampleChannelConfig(1, true) 47 genesisTx := helper.constructGenesisTx(t, channelID, chanConf) 48 genesisBlock := helper.constructBlock(genesisTx, 0, nil) 49 ledger, err := ledgerMgr.CreateLedger(channelID, genesisBlock) 50 assert.NoError(t, err) 51 52 retrievedchanConf, err := retrievePersistedChannelConfig(ledger) 53 assert.NoError(t, err) 54 assert.Equal(t, proto.CompactTextString(chanConf), proto.CompactTextString(retrievedchanConf)) 55 } 56 57 func TestConfigTxErrorScenarios(t *testing.T) { 58 configTxProcessor := &ConfigTxProcessor{} 59 // wrong tx type 60 configEnvWrongTxType := &common.ConfigEnvelope{} 61 txEnvelope, err := protoutil.CreateSignedEnvelope(common.HeaderType_PEER_ADMIN_OPERATION, "channelID", nil, configEnvWrongTxType, 0, 0) 62 require.NoError(t, err) 63 err = configTxProcessor.GenerateSimulationResults(txEnvelope, nil, false) 64 require.EqualError(t, err, "tx type [PEER_ADMIN_OPERATION] is not expected") 65 66 // empty channelConfig 67 txEnvelope, err = protoutil.CreateSignedEnvelope(common.HeaderType_CONFIG, "channelID", nil, &common.ConfigEnvelope{}, 0, 0) 68 require.NoError(t, err) 69 err = configTxProcessor.GenerateSimulationResults(txEnvelope, nil, false) 70 require.EqualError(t, err, "channel config found nil") 71 } 72 73 func TestConfigTxUpdateChanConfig(t *testing.T) { 74 helper := newTestHelper(t) 75 channelID := "testchain1" 76 tempdir, err := ioutil.TempDir("", "peer-test") 77 require.NoError(t, err, "failed to create temporary directory") 78 79 ledgerMgr, err := constructLedgerMgrWithTestDefaults(tempdir) 80 if err != nil { 81 t.Fatalf("Failed to create test environment: %s", err) 82 } 83 84 defer func() { 85 ledgerMgr.Close() 86 os.RemoveAll(tempdir) 87 }() 88 89 chanConf := helper.sampleChannelConfig(1, true) 90 genesisTx := helper.constructGenesisTx(t, channelID, chanConf) 91 genesisBlock := helper.constructBlock(genesisTx, 0, nil) 92 lgr, err := ledgerMgr.CreateLedger(channelID, genesisBlock) 93 assert.NoError(t, err) 94 95 retrievedchanConf, err := retrievePersistedChannelConfig(lgr) 96 assert.NoError(t, err) 97 assert.Equal(t, proto.CompactTextString(chanConf), proto.CompactTextString(retrievedchanConf)) 98 99 helper.mockCreateChain(t, channelID, lgr) 100 defer helper.clearMockChains() 101 102 bs := helper.peer.channels[channelID].bundleSource 103 inMemoryChanConf := bs.ConfigtxValidator().ConfigProto() 104 assert.Equal(t, proto.CompactTextString(chanConf), proto.CompactTextString(inMemoryChanConf)) 105 106 retrievedchanConf, err = retrievePersistedChannelConfig(lgr) 107 assert.NoError(t, err) 108 assert.Equal(t, proto.CompactTextString(bs.ConfigtxValidator().ConfigProto()), proto.CompactTextString(retrievedchanConf)) 109 110 lgr.Close() 111 helper.clearMockChains() 112 _, err = ledgerMgr.OpenLedger(channelID) 113 assert.NoError(t, err) 114 } 115 116 func TestGenesisBlockCreateLedger(t *testing.T) { 117 b, err := configtxtest.MakeGenesisBlock("testchain") 118 assert.NoError(t, err) 119 tempdir, err := ioutil.TempDir("", "peer-test") 120 require.NoError(t, err, "failed to create temporary directory") 121 122 ledgerMgr, err := constructLedgerMgrWithTestDefaults(tempdir) 123 if err != nil { 124 t.Fatalf("Failed to create test environment: %s", err) 125 } 126 127 defer func() { 128 ledgerMgr.Close() 129 os.RemoveAll(tempdir) 130 }() 131 132 lgr, err := ledgerMgr.CreateLedger("testchain", b) 133 assert.NoError(t, err) 134 chanConf, err := retrievePersistedChannelConfig(lgr) 135 assert.NoError(t, err) 136 assert.NotNil(t, chanConf) 137 t.Logf("chanConf = %s", chanConf) 138 } 139 140 type testHelper struct { 141 t *testing.T 142 peer *Peer 143 } 144 145 func newTestHelper(t *testing.T) *testHelper { 146 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 147 assert.NoError(t, err) 148 return &testHelper{ 149 t: t, 150 peer: &Peer{CryptoProvider: cryptoProvider}, 151 } 152 } 153 154 func (h *testHelper) sampleChannelConfig(sequence uint64, enableV11Capability bool) *common.Config { 155 profile := genesisconfig.Load(genesisconfig.SampleDevModeSoloProfile, configtest.GetDevConfigDir()) 156 if enableV11Capability { 157 profile.Orderer.Capabilities = make(map[string]bool) 158 profile.Orderer.Capabilities[capabilities.ApplicationV1_1] = true 159 profile.Application.Capabilities = make(map[string]bool) 160 profile.Application.Capabilities[capabilities.ApplicationV1_2] = true 161 } 162 channelGroup, _ := encoder.NewChannelGroup(profile) 163 return &common.Config{ 164 Sequence: sequence, 165 ChannelGroup: channelGroup, 166 } 167 } 168 169 func (h *testHelper) constructGenesisTx(t *testing.T, channelID string, chanConf *common.Config) *common.Envelope { 170 configEnvelop := &common.ConfigEnvelope{ 171 Config: chanConf, 172 LastUpdate: h.constructLastUpdateField(channelID), 173 } 174 txEnvelope, err := protoutil.CreateSignedEnvelope(common.HeaderType_CONFIG, channelID, nil, configEnvelop, 0, 0) 175 assert.NoError(t, err) 176 return txEnvelope 177 } 178 179 func (h *testHelper) constructBlock(txEnvelope *common.Envelope, blockNum uint64, previousHash []byte) *common.Block { 180 return testutil.NewBlock([]*common.Envelope{txEnvelope}, blockNum, previousHash) 181 } 182 183 func (h *testHelper) constructLastUpdateField(channelID string) *common.Envelope { 184 configUpdate := protoutil.MarshalOrPanic(&common.ConfigUpdate{ 185 ChannelId: channelID, 186 }) 187 envelopeForLastUpdateField, _ := protoutil.CreateSignedEnvelope( 188 common.HeaderType_CONFIG_UPDATE, 189 channelID, 190 nil, 191 &common.ConfigUpdateEnvelope{ConfigUpdate: configUpdate}, 192 0, 193 0, 194 ) 195 return envelopeForLastUpdateField 196 } 197 198 func (h *testHelper) mockCreateChain(t *testing.T, channelID string, ledger ledger.PeerLedger) { 199 chanBundle, err := h.constructChannelBundle(channelID, ledger) 200 assert.NoError(t, err) 201 if h.peer.channels == nil { 202 h.peer.channels = map[string]*Channel{} 203 } 204 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 205 assert.NoError(t, err) 206 h.peer.channels[channelID] = &Channel{ 207 bundleSource: channelconfig.NewBundleSource(chanBundle), 208 ledger: ledger, 209 cryptoProvider: cryptoProvider, 210 } 211 } 212 213 func (h *testHelper) clearMockChains() { 214 h.peer.channels = make(map[string]*Channel) 215 } 216 217 func (h *testHelper) constructChannelBundle(channelID string, ledger ledger.PeerLedger) (*channelconfig.Bundle, error) { 218 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 219 if err != nil { 220 return nil, err 221 } 222 223 chanConf, err := retrievePersistedChannelConfig(ledger) 224 if err != nil { 225 return nil, err 226 } 227 228 return channelconfig.NewBundle(channelID, chanConf, cryptoProvider) 229 }