github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/cceventmgmt/mgmt_test.go (about) 1 /* 2 Copyright hechain. 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/hechain20/hechain/common/flogging" 14 "github.com/hechain20/hechain/core/ledger" 15 "github.com/hechain20/hechain/core/ledger/mock" 16 "github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset" 17 "github.com/stretchr/testify/require" 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 require.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 cc1ExpectedEvent := &mockEvent{cc1Def, cc1DBArtifactsTar} 53 cc2ExpectedEvent := &mockEvent{cc2Def, cc2DBArtifactsTar} 54 cc3ExpectedEvent := &mockEvent{cc3Def, cc3DBArtifactsTar} 55 56 // Deploy cc3 on chain1 - handler1 and handler3 should receive event because cc3 is being deployed only on chain1 57 require.NoError(t, 58 eventMgr.HandleChaincodeDeploy("channel1", []*ChaincodeDefinition{cc3Def}), 59 ) 60 eventMgr.ChaincodeDeployDone("channel1") 61 require.Contains(t, handler1.eventsRecieved, cc3ExpectedEvent) 62 require.NotContains(t, handler2.eventsRecieved, cc3ExpectedEvent) 63 require.Contains(t, handler3.eventsRecieved, cc3ExpectedEvent) 64 require.Equal(t, 1, handler1.doneRecievedCount) 65 require.Equal(t, 0, handler2.doneRecievedCount) 66 require.Equal(t, 1, handler3.doneRecievedCount) 67 68 // Deploy cc3 on chain2 as well and this time handler2 should also receive event 69 require.NoError(t, 70 eventMgr.HandleChaincodeDeploy("channel2", []*ChaincodeDefinition{cc3Def}), 71 ) 72 eventMgr.ChaincodeDeployDone("channel2") 73 require.Contains(t, handler2.eventsRecieved, cc3ExpectedEvent) 74 require.Equal(t, 1, handler1.doneRecievedCount) 75 require.Equal(t, 1, handler2.doneRecievedCount) 76 require.Equal(t, 2, handler3.doneRecievedCount) 77 78 // Install CC2 - handler1 and handler 3 should receive event because cc2 is deployed only on chain1 and not on chain2 79 require.NoError(t, 80 eventMgr.HandleChaincodeInstall(cc2Def, cc2DBArtifactsTar), 81 ) 82 eventMgr.ChaincodeInstallDone(true) 83 require.Contains(t, handler1.eventsRecieved, cc2ExpectedEvent) 84 require.NotContains(t, handler2.eventsRecieved, cc2ExpectedEvent) 85 require.Contains(t, handler3.eventsRecieved, cc2ExpectedEvent) 86 require.Equal(t, 2, handler1.doneRecievedCount) 87 require.Equal(t, 1, handler2.doneRecievedCount) 88 require.Equal(t, 3, handler3.doneRecievedCount) 89 90 // setting cc2Def as a new lifecycle definition should cause install not to trigger event 91 mockProvider.setChaincodeDeployed("channel1", cc2Def, false) 92 handler1.eventsRecieved = []*mockEvent{} 93 require.NoError(t, 94 eventMgr.HandleChaincodeInstall(cc2Def, cc2DBArtifactsTar), 95 ) 96 eventMgr.ChaincodeInstallDone(true) 97 require.NotContains(t, handler1.eventsRecieved, cc2ExpectedEvent) 98 99 mockListener := &mockHandler{} 100 require.NoError(t, 101 mgr.RegisterAndInvokeFor([]*ChaincodeDefinition{cc1Def, cc2Def, cc3Def}, 102 "test-ledger", mockListener, 103 ), 104 ) 105 require.Contains(t, mockListener.eventsRecieved, cc1ExpectedEvent) 106 require.Contains(t, mockListener.eventsRecieved, cc3ExpectedEvent) 107 require.NotContains(t, mockListener.eventsRecieved, cc2ExpectedEvent) 108 require.Equal(t, 2, mockListener.doneRecievedCount) 109 require.Contains(t, mgr.ccLifecycleListeners["test-ledger"], mockListener) 110 } 111 112 func TestLSCCListener(t *testing.T) { 113 channelName := "testChannel" 114 115 cc1Def := &ChaincodeDefinition{Name: "testChaincode1", Version: "v1", Hash: []byte("hash_testChaincode")} 116 cc2Def := &ChaincodeDefinition{Name: "testChaincode2", Version: "v1", Hash: []byte("hash_testChaincode")} 117 118 ccDBArtifactsTar := []byte("ccDBArtifacts") 119 120 // cc1, cc2 installed but not deployed 121 mockProvider := newMockProvider() 122 mockProvider.setChaincodeInstalled(cc1Def, ccDBArtifactsTar) 123 mockProvider.setChaincodeInstalled(cc2Def, ccDBArtifactsTar) 124 125 setEventMgrForTest(newMgr(mockProvider)) 126 defer clearEventMgrForTest() 127 handler1 := &mockHandler{} 128 GetMgr().Register(channelName, handler1) 129 130 mockInfoProvider := &mock.DeployedChaincodeInfoProvider{} 131 mockInfoProvider.UpdatedChaincodesStub = 132 func(map[string][]*kvrwset.KVWrite) ([]*ledger.ChaincodeLifecycleInfo, error) { 133 return []*ledger.ChaincodeLifecycleInfo{ 134 {Name: cc1Def.Name}, 135 {Name: cc2Def.Name}, 136 }, nil 137 } 138 mockInfoProvider.ChaincodeInfoStub = func(channelName, chaincodeName string, qe ledger.SimpleQueryExecutor) (*ledger.DeployedChaincodeInfo, error) { 139 switch chaincodeName { 140 case cc1Def.Name: 141 return &ledger.DeployedChaincodeInfo{ 142 Name: chaincodeName, 143 Hash: cc1Def.Hash, 144 Version: cc1Def.Version, 145 IsLegacy: true, // event for legacy chaincode lifecycle 146 }, nil 147 case cc2Def.Name: 148 return &ledger.DeployedChaincodeInfo{ 149 Name: chaincodeName, 150 Hash: cc1Def.Hash, 151 Version: cc1Def.Version, 152 IsLegacy: false, // event for new chaincode lifecycle 153 }, nil 154 default: 155 return nil, nil 156 } 157 } 158 lsccStateListener := &KVLedgerLSCCStateListener{mockInfoProvider} 159 160 // test1 regular deploy lscc event gets sent to handler 161 t.Run("DeployEvent", func(t *testing.T) { 162 require.NoError(t, 163 lsccStateListener.HandleStateUpdates( 164 &ledger.StateUpdateTrigger{ 165 LedgerID: channelName, 166 }, 167 ), 168 ) 169 // processes legacy event 170 require.Contains(t, handler1.eventsRecieved, &mockEvent{cc1Def, ccDBArtifactsTar}) 171 // does not processes new lifecycle event 172 require.NotContains(t, handler1.eventsRecieved, &mockEvent{cc2Def, ccDBArtifactsTar}) 173 }) 174 } 175 176 type mockProvider struct { 177 chaincodesDeployed map[[3]string]bool 178 chaincodesDeployedNewLifecycle map[[3]string]bool 179 chaincodesInstalled map[[2]string][]byte 180 } 181 182 type mockHandler struct { 183 eventsRecieved []*mockEvent 184 doneRecievedCount int 185 } 186 187 type mockEvent struct { 188 def *ChaincodeDefinition 189 dbArtifactsTar []byte 190 } 191 192 func (l *mockHandler) HandleChaincodeDeploy(chaincodeDefinition *ChaincodeDefinition, dbArtifactsTar []byte) error { 193 l.eventsRecieved = append(l.eventsRecieved, &mockEvent{def: chaincodeDefinition, dbArtifactsTar: dbArtifactsTar}) 194 return nil 195 } 196 197 func (l *mockHandler) ChaincodeDeployDone(succeeded bool) { 198 l.doneRecievedCount++ 199 } 200 201 func newMockProvider() *mockProvider { 202 return &mockProvider{ 203 make(map[[3]string]bool), 204 make(map[[3]string]bool), 205 make(map[[2]string][]byte), 206 } 207 } 208 209 func (p *mockProvider) setChaincodeDeployed(chainid string, chaincodeDefinition *ChaincodeDefinition, isLegacy bool) { 210 p.chaincodesDeployed[[3]string{chainid, chaincodeDefinition.Name, chaincodeDefinition.Version}] = isLegacy 211 } 212 213 func (p *mockProvider) setChaincodeInstalled(chaincodeDefinition *ChaincodeDefinition, dbArtifactsTar []byte) { 214 p.chaincodesInstalled[[2]string{chaincodeDefinition.Name, chaincodeDefinition.Version}] = dbArtifactsTar 215 } 216 217 func (p *mockProvider) GetDeployedChaincodeInfo(chainid string, chaincodeDefinition *ChaincodeDefinition) (*ledger.DeployedChaincodeInfo, error) { 218 isLegacy, ok := p.chaincodesDeployed[[3]string{chainid, chaincodeDefinition.Name, chaincodeDefinition.Version}] 219 if !ok { 220 return nil, nil 221 } 222 return &ledger.DeployedChaincodeInfo{ 223 Name: chaincodeDefinition.Name, 224 Version: chaincodeDefinition.Version, 225 IsLegacy: isLegacy, 226 }, nil 227 } 228 229 func (p *mockProvider) RetrieveChaincodeArtifacts(chaincodeDefinition *ChaincodeDefinition) (installed bool, dbArtifactsTar []byte, err error) { 230 dbArtifactsTar, ok := p.chaincodesInstalled[[2]string{chaincodeDefinition.Name, chaincodeDefinition.Version}] 231 if !ok { 232 return false, nil, nil 233 } 234 return true, dbArtifactsTar, nil 235 } 236 237 func setEventMgrForTest(eventMgr *Mgr) { 238 mgr = eventMgr 239 } 240 241 func clearEventMgrForTest() { 242 mgr = nil 243 }