github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/scc/lscc/deployedcc_infoprovider_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package lscc_test 8 9 import ( 10 "fmt" 11 "testing" 12 13 "github.com/golang/protobuf/proto" 14 "github.com/hechain20/hechain/core/common/ccprovider" 15 "github.com/hechain20/hechain/core/common/privdata" 16 "github.com/hechain20/hechain/core/ledger" 17 "github.com/hechain20/hechain/core/scc/lscc" 18 "github.com/hechain20/hechain/core/scc/lscc/mock" 19 "github.com/hyperledger/fabric-protos-go/ledger/queryresult" 20 "github.com/hyperledger/fabric-protos-go/peer" 21 "github.com/stretchr/testify/require" 22 ) 23 24 func TestNamespaces(t *testing.T) { 25 ccInfoProvdier := &lscc.DeployedCCInfoProvider{} 26 namespaces := ccInfoProvdier.Namespaces() 27 require.Len(t, namespaces, 1) 28 require.Equal(t, "lscc", namespaces[0]) 29 } 30 31 func TestChaincodeInfo(t *testing.T) { 32 cc1 := &ledger.DeployedChaincodeInfo{ 33 Name: "cc1", 34 Version: "cc1_version", 35 Hash: []byte("cc1_hash"), 36 } 37 38 cc2 := &ledger.DeployedChaincodeInfo{ 39 Name: "cc2", 40 Version: "cc2_version", 41 Hash: []byte("cc2_hash"), 42 ExplicitCollectionConfigPkg: prepapreCollectionConfigPkg([]string{"cc2_coll1", "cc2_coll2"}), 43 } 44 45 mockQE := prepareMockQE(t, []*ledger.DeployedChaincodeInfo{cc1, cc2}) 46 ccInfoProvdier := &lscc.DeployedCCInfoProvider{} 47 48 ccInfo1, err := ccInfoProvdier.ChaincodeInfo("", "cc1", mockQE) 49 require.NoError(t, err) 50 expectedCCInfo1 := cc1 51 expectedCCInfo1.IsLegacy = true 52 require.Equal(t, expectedCCInfo1, ccInfo1) 53 54 ccInfo2, err := ccInfoProvdier.ChaincodeInfo("", "cc2", mockQE) 55 require.NoError(t, err) 56 require.Equal(t, cc2.Name, ccInfo2.Name) 57 require.True(t, proto.Equal(cc2.ExplicitCollectionConfigPkg, ccInfo2.ExplicitCollectionConfigPkg)) 58 59 ccInfo3, err := ccInfoProvdier.ChaincodeInfo("", "cc3", mockQE) 60 require.NoError(t, err) 61 require.Nil(t, ccInfo3) 62 } 63 64 func TestAllChaincodesInfo(t *testing.T) { 65 cc1 := &ledger.DeployedChaincodeInfo{ 66 Name: "cc1", 67 Version: "cc1_version", 68 Hash: []byte("cc1_hash"), 69 IsLegacy: true, 70 } 71 72 cc2 := &ledger.DeployedChaincodeInfo{ 73 Name: "cc2", 74 Version: "cc2_version", 75 Hash: []byte("cc2_hash"), 76 ExplicitCollectionConfigPkg: prepapreCollectionConfigPkg([]string{"cc2_coll1", "cc2_coll2"}), 77 IsLegacy: true, 78 } 79 80 mockQE := prepareMockQE(t, []*ledger.DeployedChaincodeInfo{cc1, cc2}) 81 82 // create a fake ResultsIterator to mock range query result, which should have 2 kinds of keys: "cc" and "cc~collection" 83 expectedKeysInlscc := []string{"cc1", "cc2", "cc2~collection"} 84 fakeResultsIterator := &mock.ResultsIterator{} 85 for i, key := range expectedKeysInlscc { 86 fakeResultsIterator.NextReturnsOnCall(i, &queryresult.KV{Key: key}, nil) 87 } 88 mockQE.GetStateRangeScanIteratorReturns(fakeResultsIterator, nil) 89 90 ccInfoProvider := &lscc.DeployedCCInfoProvider{} 91 deployedChaincodesInfo, err := ccInfoProvider.AllChaincodesInfo("testchannel", mockQE) 92 require.NoError(t, err) 93 require.Equal(t, 2, len(deployedChaincodesInfo)) 94 require.Equal(t, cc1, deployedChaincodesInfo["cc1"]) 95 96 // because ExplicitCollectionConfigPkg is a protobuf object, we have to compare individual fields for cc2 97 ccInfo := deployedChaincodesInfo["cc2"] 98 require.True(t, proto.Equal(cc2.ExplicitCollectionConfigPkg, ccInfo.ExplicitCollectionConfigPkg)) 99 require.Equal(t, cc2.Name, ccInfo.Name) 100 require.Equal(t, cc2.Version, ccInfo.Version) 101 require.Equal(t, cc2.Hash, ccInfo.Hash) 102 require.Equal(t, cc2.IsLegacy, ccInfo.IsLegacy) 103 104 mockQE.GetStateRangeScanIteratorReturns(nil, fmt.Errorf("fake-rangescan-error")) 105 _, err = ccInfoProvider.AllChaincodesInfo("testchannel", mockQE) 106 require.EqualError(t, err, "fake-rangescan-error") 107 } 108 109 func TestCollectionInfo(t *testing.T) { 110 cc1 := &ledger.DeployedChaincodeInfo{ 111 Name: "cc1", 112 Version: "cc1_version", 113 Hash: []byte("cc1_hash"), 114 } 115 116 cc2 := &ledger.DeployedChaincodeInfo{ 117 Name: "cc2", 118 Version: "cc2_version", 119 Hash: []byte("cc2_hash"), 120 ExplicitCollectionConfigPkg: prepapreCollectionConfigPkg([]string{"cc2_coll1", "cc2_coll2"}), 121 } 122 123 mockQE := prepareMockQE(t, []*ledger.DeployedChaincodeInfo{cc1, cc2}) 124 ccInfoProvdier := &lscc.DeployedCCInfoProvider{} 125 126 collInfo1, err := ccInfoProvdier.CollectionInfo("", "cc1", "non-existing-coll-in-cc1", mockQE) 127 require.NoError(t, err) 128 require.Nil(t, collInfo1) 129 130 collInfo2, err := ccInfoProvdier.CollectionInfo("", "cc2", "cc2_coll1", mockQE) 131 require.NoError(t, err) 132 require.Equal(t, "cc2_coll1", collInfo2.Name) 133 134 collInfo3, err := ccInfoProvdier.CollectionInfo("", "cc2", "non-existing-coll-in-cc2", mockQE) 135 require.NoError(t, err) 136 require.Nil(t, collInfo3) 137 138 ccPkg1, err := ccInfoProvdier.AllCollectionsConfigPkg("", "cc1", mockQE) 139 require.NoError(t, err) 140 require.Nil(t, ccPkg1) 141 142 ccPkg2, err := ccInfoProvdier.AllCollectionsConfigPkg("", "cc2", mockQE) 143 require.NoError(t, err) 144 require.Equal(t, prepapreCollectionConfigPkg([]string{"cc2_coll1", "cc2_coll2"}), ccPkg2) 145 } 146 147 func prepareMockQE(t *testing.T, deployedChaincodes []*ledger.DeployedChaincodeInfo) *mock.QueryExecutor { 148 mockQE := &mock.QueryExecutor{} 149 lsccTable := map[string][]byte{} 150 for _, cc := range deployedChaincodes { 151 chaincodeData := &ccprovider.ChaincodeData{Name: cc.Name, Version: cc.Version, Id: cc.Hash} 152 chaincodeDataBytes, err := proto.Marshal(chaincodeData) 153 require.NoError(t, err) 154 lsccTable[cc.Name] = chaincodeDataBytes 155 156 if cc.ExplicitCollectionConfigPkg != nil { 157 collConfigPkgByte, err := proto.Marshal(cc.ExplicitCollectionConfigPkg) 158 require.NoError(t, err) 159 lsccTable[privdata.BuildCollectionKVSKey(cc.Name)] = collConfigPkgByte 160 } 161 } 162 163 mockQE.GetStateStub = func(ns, key string) ([]byte, error) { 164 return lsccTable[key], nil 165 } 166 return mockQE 167 } 168 169 func prepapreCollectionConfigPkg(collNames []string) *peer.CollectionConfigPackage { 170 pkg := &peer.CollectionConfigPackage{} 171 for _, collName := range collNames { 172 sCollConfig := &peer.CollectionConfig_StaticCollectionConfig{ 173 StaticCollectionConfig: &peer.StaticCollectionConfig{ 174 Name: collName, 175 }, 176 } 177 config := &peer.CollectionConfig{Payload: sCollConfig} 178 pkg.Config = append(pkg.Config, config) 179 } 180 return pkg 181 }