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  }