github.com/true-sqn/fabric@v2.1.1+incompatible/core/ledger/cceventmgmt/mgmt_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package cceventmgmt 8 9 import ( 10 "os" 11 "testing" 12 13 "github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset" 14 "github.com/hyperledger/fabric/common/flogging" 15 "github.com/hyperledger/fabric/core/ledger" 16 "github.com/hyperledger/fabric/core/ledger/mock" 17 "github.com/stretchr/testify/assert" 18 ) 19 20 func TestMain(m *testing.M) { 21 flogging.ActivateSpec("eventmgmt=debug") 22 os.Exit(m.Run()) 23 } 24 25 func TestCCEventMgmt(t *testing.T) { 26 cc1Def := &ChaincodeDefinition{Name: "cc1", Version: "v1", Hash: []byte("cc1")} 27 cc1DBArtifactsTar := []byte("cc1DBArtifacts") 28 29 cc2Def := &ChaincodeDefinition{Name: "cc2", Version: "v1", Hash: []byte("cc2")} 30 cc2DBArtifactsTar := []byte("cc2DBArtifacts") 31 32 cc3Def := &ChaincodeDefinition{Name: "cc3", Version: "v1", Hash: []byte("cc3")} 33 cc3DBArtifactsTar := []byte("cc3DBArtifacts") 34 35 // cc1 is deployed and installed. cc2 is deployed but not installed. cc3 is not deployed but installed 36 mockProvider := newMockProvider() 37 mockProvider.setChaincodeInstalled(cc1Def, cc1DBArtifactsTar) 38 mockProvider.setChaincodeDeployed("channel1", cc1Def, true) 39 mockProvider.setChaincodeDeployed("channel1", cc2Def, true) 40 mockProvider.setChaincodeInstalled(cc3Def, cc3DBArtifactsTar) 41 setEventMgrForTest(newMgr(mockProvider)) 42 defer clearEventMgrForTest() 43 44 handler1, handler2, handler3 := &mockHandler{}, &mockHandler{}, &mockHandler{} 45 eventMgr := GetMgr() 46 assert.NotNil(t, eventMgr) 47 eventMgr.Register("channel1", handler1) 48 eventMgr.Register("channel2", handler2) 49 eventMgr.Register("channel1", handler3) 50 eventMgr.Register("channel2", handler3) 51 52 cc2ExpectedEvent := &mockEvent{cc2Def, cc2DBArtifactsTar} 53 _ = cc2ExpectedEvent 54 cc3ExpectedEvent := &mockEvent{cc3Def, cc3DBArtifactsTar} 55 56 // Deploy cc3 on chain1 - handler1 and handler3 should recieve event because cc3 is being deployed only on chain1 57 eventMgr.HandleChaincodeDeploy("channel1", []*ChaincodeDefinition{cc3Def}) 58 eventMgr.ChaincodeDeployDone("channel1") 59 assert.Contains(t, handler1.eventsRecieved, cc3ExpectedEvent) 60 assert.NotContains(t, handler2.eventsRecieved, cc3ExpectedEvent) 61 assert.Contains(t, handler3.eventsRecieved, cc3ExpectedEvent) 62 assert.Equal(t, 1, handler1.doneRecievedCount) 63 assert.Equal(t, 0, handler2.doneRecievedCount) 64 assert.Equal(t, 1, handler3.doneRecievedCount) 65 66 // Deploy cc3 on chain2 as well and this time handler2 should also recieve event 67 eventMgr.HandleChaincodeDeploy("channel2", []*ChaincodeDefinition{cc3Def}) 68 eventMgr.ChaincodeDeployDone("channel2") 69 assert.Contains(t, handler2.eventsRecieved, cc3ExpectedEvent) 70 assert.Equal(t, 1, handler1.doneRecievedCount) 71 assert.Equal(t, 1, handler2.doneRecievedCount) 72 assert.Equal(t, 2, handler3.doneRecievedCount) 73 74 // Install CC2 - handler1 and handler 3 should receive event because cc2 is deployed only on chain1 and not on chain2 75 eventMgr.HandleChaincodeInstall(cc2Def, cc2DBArtifactsTar) 76 eventMgr.ChaincodeInstallDone(true) 77 assert.Contains(t, handler1.eventsRecieved, cc2ExpectedEvent) 78 assert.NotContains(t, handler2.eventsRecieved, cc2ExpectedEvent) 79 assert.Contains(t, handler3.eventsRecieved, cc2ExpectedEvent) 80 assert.Equal(t, 2, handler1.doneRecievedCount) 81 assert.Equal(t, 1, handler2.doneRecievedCount) 82 assert.Equal(t, 3, handler3.doneRecievedCount) 83 84 // setting cc2Def as a new lifecycle definition should cause install not to trigger event 85 mockProvider.setChaincodeDeployed("channel1", cc2Def, false) 86 handler1.eventsRecieved = []*mockEvent{} 87 eventMgr.HandleChaincodeInstall(cc2Def, cc2DBArtifactsTar) 88 eventMgr.ChaincodeInstallDone(true) 89 assert.NotContains(t, handler1.eventsRecieved, cc2ExpectedEvent) 90 } 91 92 func TestLSCCListener(t *testing.T) { 93 channelName := "testChannel" 94 95 cc1Def := &ChaincodeDefinition{Name: "testChaincode1", Version: "v1", Hash: []byte("hash_testChaincode")} 96 cc2Def := &ChaincodeDefinition{Name: "testChaincode2", Version: "v1", Hash: []byte("hash_testChaincode")} 97 98 ccDBArtifactsTar := []byte("ccDBArtifacts") 99 100 // cc1, cc2 installed but not deployed 101 mockProvider := newMockProvider() 102 mockProvider.setChaincodeInstalled(cc1Def, ccDBArtifactsTar) 103 mockProvider.setChaincodeInstalled(cc2Def, ccDBArtifactsTar) 104 105 setEventMgrForTest(newMgr(mockProvider)) 106 defer clearEventMgrForTest() 107 handler1 := &mockHandler{} 108 GetMgr().Register(channelName, handler1) 109 110 mockInfoProvider := &mock.DeployedChaincodeInfoProvider{} 111 mockInfoProvider.UpdatedChaincodesStub = 112 func(map[string][]*kvrwset.KVWrite) ([]*ledger.ChaincodeLifecycleInfo, error) { 113 return []*ledger.ChaincodeLifecycleInfo{ 114 {Name: cc1Def.Name}, 115 {Name: cc2Def.Name}, 116 }, nil 117 } 118 mockInfoProvider.ChaincodeInfoStub = func(channelName, chaincodeName string, qe ledger.SimpleQueryExecutor) (*ledger.DeployedChaincodeInfo, error) { 119 switch chaincodeName { 120 case cc1Def.Name: 121 return &ledger.DeployedChaincodeInfo{ 122 Name: chaincodeName, 123 Hash: cc1Def.Hash, 124 Version: cc1Def.Version, 125 IsLegacy: true, // event for legacy chaincode lifecycle 126 }, nil 127 case cc2Def.Name: 128 return &ledger.DeployedChaincodeInfo{ 129 Name: chaincodeName, 130 Hash: cc1Def.Hash, 131 Version: cc1Def.Version, 132 IsLegacy: false, // event for new chaincode lifecycle 133 }, nil 134 default: 135 return nil, nil 136 } 137 } 138 lsccStateListener := &KVLedgerLSCCStateListener{mockInfoProvider} 139 140 // test1 regular deploy lscc event gets sent to handler 141 t.Run("DeployEvent", func(t *testing.T) { 142 lsccStateListener.HandleStateUpdates( 143 &ledger.StateUpdateTrigger{ 144 LedgerID: channelName, 145 }, 146 ) 147 // processes legacy event 148 assert.Contains(t, handler1.eventsRecieved, &mockEvent{cc1Def, ccDBArtifactsTar}) 149 // does not processes new lifecycle event 150 assert.NotContains(t, handler1.eventsRecieved, &mockEvent{cc2Def, ccDBArtifactsTar}) 151 }) 152 } 153 154 type mockProvider struct { 155 chaincodesDeployed map[[3]string]bool 156 chaincodesDeployedNewLifecycle map[[3]string]bool 157 chaincodesInstalled map[[2]string][]byte 158 } 159 160 type mockHandler struct { 161 eventsRecieved []*mockEvent 162 doneRecievedCount int 163 } 164 165 type mockEvent struct { 166 def *ChaincodeDefinition 167 dbArtifactsTar []byte 168 } 169 170 func (l *mockHandler) HandleChaincodeDeploy(chaincodeDefinition *ChaincodeDefinition, dbArtifactsTar []byte) error { 171 l.eventsRecieved = append(l.eventsRecieved, &mockEvent{def: chaincodeDefinition, dbArtifactsTar: dbArtifactsTar}) 172 return nil 173 } 174 175 func (l *mockHandler) ChaincodeDeployDone(succeeded bool) { 176 l.doneRecievedCount++ 177 } 178 179 func newMockProvider() *mockProvider { 180 return &mockProvider{ 181 make(map[[3]string]bool), 182 make(map[[3]string]bool), 183 make(map[[2]string][]byte), 184 } 185 } 186 187 func (p *mockProvider) setChaincodeDeployed(chainid string, chaincodeDefinition *ChaincodeDefinition, isLegacy bool) { 188 p.chaincodesDeployed[[3]string{chainid, chaincodeDefinition.Name, chaincodeDefinition.Version}] = isLegacy 189 } 190 191 func (p *mockProvider) setChaincodeInstalled(chaincodeDefinition *ChaincodeDefinition, dbArtifactsTar []byte) { 192 p.chaincodesInstalled[[2]string{chaincodeDefinition.Name, chaincodeDefinition.Version}] = dbArtifactsTar 193 } 194 195 func (p *mockProvider) GetDeployedChaincodeInfo(chainid string, chaincodeDefinition *ChaincodeDefinition) (*ledger.DeployedChaincodeInfo, error) { 196 isLegacy, ok := p.chaincodesDeployed[[3]string{chainid, chaincodeDefinition.Name, chaincodeDefinition.Version}] 197 if !ok { 198 return nil, nil 199 } 200 return &ledger.DeployedChaincodeInfo{ 201 Name: chaincodeDefinition.Name, 202 Version: chaincodeDefinition.Version, 203 IsLegacy: isLegacy, 204 }, nil 205 } 206 207 func (p *mockProvider) RetrieveChaincodeArtifacts(chaincodeDefinition *ChaincodeDefinition) (installed bool, dbArtifactsTar []byte, err error) { 208 dbArtifactsTar, ok := p.chaincodesInstalled[[2]string{chaincodeDefinition.Name, chaincodeDefinition.Version}] 209 if !ok { 210 return false, nil, nil 211 } 212 return true, dbArtifactsTar, nil 213 } 214 215 func setEventMgrForTest(eventMgr *Mgr) { 216 mgr = eventMgr 217 } 218 219 func clearEventMgrForTest() { 220 mgr = nil 221 }