github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/common/ccprovider/cdspackage_test.go (about)

     1  /*
     2  Copyright hechain. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package ccprovider
     8  
     9  import (
    10  	"fmt"
    11  	"io/ioutil"
    12  	"os"
    13  	"testing"
    14  
    15  	"github.com/hechain20/hechain/bccsp/sw"
    16  	"github.com/hechain20/hechain/protoutil"
    17  	pb "github.com/hyperledger/fabric-protos-go/peer"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func setupccdir() string {
    22  	tempDir, err := ioutil.TempDir("/tmp", "ccprovidertest")
    23  	if err != nil {
    24  		panic(err)
    25  	}
    26  	SetChaincodesPath(tempDir)
    27  	return tempDir
    28  }
    29  
    30  func processCDS(cds *pb.ChaincodeDeploymentSpec, tofs bool) (*CDSPackage, []byte, *ChaincodeData, error) {
    31  	b := protoutil.MarshalOrPanic(cds)
    32  
    33  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    34  	if err != nil {
    35  		return nil, nil, nil, fmt.Errorf("error creating bootBCCSP: %s", err)
    36  	}
    37  	ccpack := &CDSPackage{GetHasher: cryptoProvider}
    38  	cd, err := ccpack.InitFromBuffer(b)
    39  	if err != nil {
    40  		return nil, nil, nil, fmt.Errorf("error owner creating package %s", err)
    41  	}
    42  
    43  	if tofs {
    44  		if err = ccpack.PutChaincodeToFS(); err != nil {
    45  			return nil, nil, nil, fmt.Errorf("error putting package on the FS %s", err)
    46  		}
    47  	}
    48  
    49  	return ccpack, b, cd, nil
    50  }
    51  
    52  func TestPutCDSCC(t *testing.T) {
    53  	ccdir := setupccdir()
    54  	defer os.RemoveAll(ccdir)
    55  
    56  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
    57  
    58  	ccpack, _, cd, err := processCDS(cds, true)
    59  	if err != nil {
    60  		t.Fatalf("error putting CDS to FS %s", err)
    61  		return
    62  	}
    63  
    64  	if err = ccpack.ValidateCC(cd); err != nil {
    65  		t.Fatalf("error validating package %s", err)
    66  		return
    67  	}
    68  }
    69  
    70  func TestPutCDSErrorPaths(t *testing.T) {
    71  	ccdir := setupccdir()
    72  	defer os.RemoveAll(ccdir)
    73  
    74  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{
    75  		Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
    76  		Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}},
    77  	}, CodePackage: []byte("code")}
    78  
    79  	ccpack, b, _, err := processCDS(cds, true)
    80  	if err != nil {
    81  		t.Fatalf("error putting CDS to FS %s", err)
    82  		return
    83  	}
    84  
    85  	// validate with invalid name
    86  	if err = ccpack.ValidateCC(&ChaincodeData{Name: "invalname", Version: "0"}); err == nil {
    87  		t.Fatalf("expected error validating package")
    88  		return
    89  	}
    90  	// remove the buffer
    91  	ccpack.buf = nil
    92  	if err = ccpack.PutChaincodeToFS(); err == nil {
    93  		t.Fatalf("expected error putting package on the FS")
    94  		return
    95  	}
    96  
    97  	// put back  the buffer but remove the depspec
    98  	ccpack.buf = b
    99  	savDepSpec := ccpack.depSpec
   100  	ccpack.depSpec = nil
   101  	if err = ccpack.PutChaincodeToFS(); err == nil {
   102  		t.Fatalf("expected error putting package on the FS")
   103  		return
   104  	}
   105  
   106  	// put back dep spec
   107  	ccpack.depSpec = savDepSpec
   108  
   109  	//...but remove the chaincode directory
   110  	os.RemoveAll(ccdir)
   111  	if err = ccpack.PutChaincodeToFS(); err == nil {
   112  		t.Fatalf("expected error putting package on the FS")
   113  		return
   114  	}
   115  }
   116  
   117  func TestCDSGetCCPackage(t *testing.T) {
   118  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
   119  
   120  	b := protoutil.MarshalOrPanic(cds)
   121  
   122  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   123  	require.NoError(t, err)
   124  
   125  	ccpack, err := GetCCPackage(b, cryptoProvider)
   126  	if err != nil {
   127  		t.Fatalf("failed to get CDS CCPackage %s", err)
   128  		return
   129  	}
   130  
   131  	cccdspack, ok := ccpack.(*CDSPackage)
   132  	if !ok || cccdspack == nil {
   133  		t.Fatalf("failed to get CDS CCPackage")
   134  		return
   135  	}
   136  
   137  	cds2 := cccdspack.GetDepSpec()
   138  	if cds2 == nil {
   139  		t.Fatalf("nil dep spec in CDS CCPackage")
   140  		return
   141  	}
   142  
   143  	if cds2.ChaincodeSpec.ChaincodeId.Name != cds.ChaincodeSpec.ChaincodeId.Name || cds2.ChaincodeSpec.ChaincodeId.Version != cds.ChaincodeSpec.ChaincodeId.Version {
   144  		t.Fatalf("dep spec in CDS CCPackage does not match %v != %v", cds, cds2)
   145  		return
   146  	}
   147  }
   148  
   149  // switch the chaincodes on the FS and validate
   150  func TestCDSSwitchChaincodes(t *testing.T) {
   151  	ccdir := setupccdir()
   152  	defer os.RemoveAll(ccdir)
   153  
   154  	// someone modified the code on the FS with "badcode"
   155  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("badcode")}
   156  
   157  	// write the bad code to the fs
   158  	badccpack, _, _, err := processCDS(cds, true)
   159  	if err != nil {
   160  		t.Fatalf("error putting CDS to FS %s", err)
   161  		return
   162  	}
   163  
   164  	// mimic the good code ChaincodeData from the instantiate...
   165  	cds.CodePackage = []byte("goodcode")
   166  
   167  	//...and generate the CD for it (don't overwrite the bad code)
   168  	_, _, goodcd, err := processCDS(cds, false)
   169  	if err != nil {
   170  		t.Fatalf("error putting CDS to FS %s", err)
   171  		return
   172  	}
   173  
   174  	if err = badccpack.ValidateCC(goodcd); err == nil {
   175  		t.Fatalf("expected goodcd to fail against bad package but succeeded!")
   176  		return
   177  	}
   178  }
   179  
   180  func TestPutChaincodeToFSErrorPaths(t *testing.T) {
   181  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   182  	require.NoError(t, err)
   183  	ccpack := &CDSPackage{GetHasher: cryptoProvider}
   184  	err = ccpack.PutChaincodeToFS()
   185  	require.Error(t, err)
   186  	require.Contains(t, err.Error(), "uninitialized package", "Unexpected error returned")
   187  
   188  	ccpack.buf = []byte("hello")
   189  	err = ccpack.PutChaincodeToFS()
   190  	require.Error(t, err)
   191  	require.Contains(t, err.Error(), "id cannot be nil if buf is not nil", "Unexpected error returned")
   192  
   193  	ccpack.id = []byte("cc123")
   194  	err = ccpack.PutChaincodeToFS()
   195  	require.Error(t, err)
   196  	require.Contains(t, err.Error(), "depspec cannot be nil if buf is not nil", "Unexpected error returned")
   197  
   198  	ccpack.depSpec = &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{
   199  		Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
   200  		Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}},
   201  	}, CodePackage: []byte("code")}
   202  	err = ccpack.PutChaincodeToFS()
   203  	require.Error(t, err)
   204  	require.Contains(t, err.Error(), "nil data", "Unexpected error returned")
   205  
   206  	ccpack.data = &CDSData{}
   207  	err = ccpack.PutChaincodeToFS()
   208  	require.Error(t, err)
   209  	require.Contains(t, err.Error(), "nil data bytes", "Unexpected error returned")
   210  }
   211  
   212  func TestValidateCCErrorPaths(t *testing.T) {
   213  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   214  	require.NoError(t, err)
   215  	cpack := &CDSPackage{GetHasher: cryptoProvider}
   216  	ccdata := &ChaincodeData{}
   217  	err = cpack.ValidateCC(ccdata)
   218  	require.Error(t, err)
   219  	require.Contains(t, err.Error(), "uninitialized package", "Unexpected error returned")
   220  
   221  	cpack.depSpec = &pb.ChaincodeDeploymentSpec{
   222  		CodePackage: []byte("code"),
   223  		ChaincodeSpec: &pb.ChaincodeSpec{
   224  			Type:        1,
   225  			ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
   226  			Input:       &pb.ChaincodeInput{Args: [][]byte{[]byte("")}},
   227  		},
   228  	}
   229  	err = cpack.ValidateCC(ccdata)
   230  	require.Error(t, err)
   231  	require.Contains(t, err.Error(), "nil data", "Unexpected error returned")
   232  
   233  	// invalid encoded name
   234  	cpack = &CDSPackage{GetHasher: cryptoProvider}
   235  	ccdata = &ChaincodeData{Name: "\027"}
   236  	cpack.depSpec = &pb.ChaincodeDeploymentSpec{
   237  		CodePackage: []byte("code"),
   238  		ChaincodeSpec: &pb.ChaincodeSpec{
   239  			ChaincodeId: &pb.ChaincodeID{Name: ccdata.Name, Version: "0"},
   240  		},
   241  	}
   242  	cpack.data = &CDSData{}
   243  	err = cpack.ValidateCC(ccdata)
   244  	require.Error(t, err)
   245  	require.Contains(t, err.Error(), `invalid chaincode name: "\x17"`)
   246  
   247  	// mismatched names
   248  	cpack = &CDSPackage{GetHasher: cryptoProvider}
   249  	ccdata = &ChaincodeData{Name: "Tom"}
   250  	cpack.depSpec = &pb.ChaincodeDeploymentSpec{
   251  		CodePackage: []byte("code"),
   252  		ChaincodeSpec: &pb.ChaincodeSpec{
   253  			ChaincodeId: &pb.ChaincodeID{Name: "Jerry", Version: "0"},
   254  		},
   255  	}
   256  	cpack.data = &CDSData{}
   257  	err = cpack.ValidateCC(ccdata)
   258  	require.Error(t, err)
   259  	require.Contains(t, err.Error(), `invalid chaincode data name:"Tom"  (name:"Jerry" version:"0" )`)
   260  
   261  	// mismatched versions
   262  	cpack = &CDSPackage{GetHasher: cryptoProvider}
   263  	ccdata = &ChaincodeData{Name: "Tom", Version: "1"}
   264  	cpack.depSpec = &pb.ChaincodeDeploymentSpec{
   265  		CodePackage: []byte("code"),
   266  		ChaincodeSpec: &pb.ChaincodeSpec{
   267  			ChaincodeId: &pb.ChaincodeID{Name: ccdata.Name, Version: "0"},
   268  		},
   269  	}
   270  	cpack.data = &CDSData{}
   271  	err = cpack.ValidateCC(ccdata)
   272  	require.Error(t, err)
   273  	require.Contains(t, err.Error(), `invalid chaincode data name:"Tom" version:"1"  (name:"Tom" version:"0" )`)
   274  }