github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/core/common/ccprovider/cdspackage_test.go (about)

     1  /*
     2  Copyright IBM Corp. 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  	pb "github.com/hyperledger/fabric-protos-go/peer"
    16  	"github.com/hyperledger/fabric/bccsp/sw"
    17  	"github.com/hyperledger/fabric/protoutil"
    18  	"github.com/stretchr/testify/assert"
    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{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
    75  		Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
    76  
    77  	ccpack, b, _, err := processCDS(cds, true)
    78  	if err != nil {
    79  		t.Fatalf("error putting CDS to FS %s", err)
    80  		return
    81  	}
    82  
    83  	//validate with invalid name
    84  	if err = ccpack.ValidateCC(&ChaincodeData{Name: "invalname", Version: "0"}); err == nil {
    85  		t.Fatalf("expected error validating package")
    86  		return
    87  	}
    88  	//remove the buffer
    89  	ccpack.buf = nil
    90  	if err = ccpack.PutChaincodeToFS(); err == nil {
    91  		t.Fatalf("expected error putting package on the FS")
    92  		return
    93  	}
    94  
    95  	//put back  the buffer but remove the depspec
    96  	ccpack.buf = b
    97  	savDepSpec := ccpack.depSpec
    98  	ccpack.depSpec = nil
    99  	if err = ccpack.PutChaincodeToFS(); err == nil {
   100  		t.Fatalf("expected error putting package on the FS")
   101  		return
   102  	}
   103  
   104  	//put back dep spec
   105  	ccpack.depSpec = savDepSpec
   106  
   107  	//...but remove the chaincode directory
   108  	os.RemoveAll(ccdir)
   109  	if err = ccpack.PutChaincodeToFS(); err == nil {
   110  		t.Fatalf("expected error putting package on the FS")
   111  		return
   112  	}
   113  }
   114  
   115  func TestCDSGetCCPackage(t *testing.T) {
   116  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
   117  
   118  	b := protoutil.MarshalOrPanic(cds)
   119  
   120  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   121  	assert.NoError(t, err)
   122  
   123  	ccpack, err := GetCCPackage(b, cryptoProvider)
   124  	if err != nil {
   125  		t.Fatalf("failed to get CDS CCPackage %s", err)
   126  		return
   127  	}
   128  
   129  	cccdspack, ok := ccpack.(*CDSPackage)
   130  	if !ok || cccdspack == nil {
   131  		t.Fatalf("failed to get CDS CCPackage")
   132  		return
   133  	}
   134  
   135  	cds2 := cccdspack.GetDepSpec()
   136  	if cds2 == nil {
   137  		t.Fatalf("nil dep spec in CDS CCPackage")
   138  		return
   139  	}
   140  
   141  	if cds2.ChaincodeSpec.ChaincodeId.Name != cds.ChaincodeSpec.ChaincodeId.Name || cds2.ChaincodeSpec.ChaincodeId.Version != cds.ChaincodeSpec.ChaincodeId.Version {
   142  		t.Fatalf("dep spec in CDS CCPackage does not match %v != %v", cds, cds2)
   143  		return
   144  	}
   145  }
   146  
   147  //switch the chaincodes on the FS and validate
   148  func TestCDSSwitchChaincodes(t *testing.T) {
   149  	ccdir := setupccdir()
   150  	defer os.RemoveAll(ccdir)
   151  
   152  	//someone modified the code on the FS with "badcode"
   153  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("badcode")}
   154  
   155  	//write the bad code to the fs
   156  	badccpack, _, _, err := processCDS(cds, true)
   157  	if err != nil {
   158  		t.Fatalf("error putting CDS to FS %s", err)
   159  		return
   160  	}
   161  
   162  	//mimic the good code ChaincodeData from the instantiate...
   163  	cds.CodePackage = []byte("goodcode")
   164  
   165  	//...and generate the CD for it (don't overwrite the bad code)
   166  	_, _, goodcd, err := processCDS(cds, false)
   167  	if err != nil {
   168  		t.Fatalf("error putting CDS to FS %s", err)
   169  		return
   170  	}
   171  
   172  	if err = badccpack.ValidateCC(goodcd); err == nil {
   173  		t.Fatalf("expected goodcd to fail against bad package but succeeded!")
   174  		return
   175  	}
   176  }
   177  
   178  func TestPutChaincodeToFSErrorPaths(t *testing.T) {
   179  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   180  	assert.NoError(t, err)
   181  	ccpack := &CDSPackage{GetHasher: cryptoProvider}
   182  	err = ccpack.PutChaincodeToFS()
   183  	assert.Error(t, err)
   184  	assert.Contains(t, err.Error(), "uninitialized package", "Unexpected error returned")
   185  
   186  	ccpack.buf = []byte("hello")
   187  	err = ccpack.PutChaincodeToFS()
   188  	assert.Error(t, err)
   189  	assert.Contains(t, err.Error(), "id cannot be nil if buf is not nil", "Unexpected error returned")
   190  
   191  	ccpack.id = []byte("cc123")
   192  	err = ccpack.PutChaincodeToFS()
   193  	assert.Error(t, err)
   194  	assert.Contains(t, err.Error(), "depspec cannot be nil if buf is not nil", "Unexpected error returned")
   195  
   196  	ccpack.depSpec = &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
   197  		Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
   198  	err = ccpack.PutChaincodeToFS()
   199  	assert.Error(t, err)
   200  	assert.Contains(t, err.Error(), "nil data", "Unexpected error returned")
   201  
   202  	ccpack.data = &CDSData{}
   203  	err = ccpack.PutChaincodeToFS()
   204  	assert.Error(t, err)
   205  	assert.Contains(t, err.Error(), "nil data bytes", "Unexpected error returned")
   206  }
   207  
   208  func TestValidateCCErrorPaths(t *testing.T) {
   209  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   210  	assert.NoError(t, err)
   211  	cpack := &CDSPackage{GetHasher: cryptoProvider}
   212  	ccdata := &ChaincodeData{}
   213  	err = cpack.ValidateCC(ccdata)
   214  	assert.Error(t, err)
   215  	assert.Contains(t, err.Error(), "uninitialized package", "Unexpected error returned")
   216  
   217  	cpack.depSpec = &pb.ChaincodeDeploymentSpec{
   218  		CodePackage: []byte("code"),
   219  		ChaincodeSpec: &pb.ChaincodeSpec{
   220  			Type:        1,
   221  			ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
   222  			Input:       &pb.ChaincodeInput{Args: [][]byte{[]byte("")}},
   223  		},
   224  	}
   225  	err = cpack.ValidateCC(ccdata)
   226  	assert.Error(t, err)
   227  	assert.Contains(t, err.Error(), "nil data", "Unexpected error returned")
   228  
   229  	// invalid encoded name
   230  	cpack = &CDSPackage{GetHasher: cryptoProvider}
   231  	ccdata = &ChaincodeData{Name: "\027"}
   232  	cpack.depSpec = &pb.ChaincodeDeploymentSpec{
   233  		CodePackage: []byte("code"),
   234  		ChaincodeSpec: &pb.ChaincodeSpec{
   235  			ChaincodeId: &pb.ChaincodeID{Name: ccdata.Name, Version: "0"},
   236  		},
   237  	}
   238  	cpack.data = &CDSData{}
   239  	err = cpack.ValidateCC(ccdata)
   240  	assert.Error(t, err)
   241  	assert.Contains(t, err.Error(), `invalid chaincode name: "\x17"`)
   242  
   243  	// mismatched names
   244  	cpack = &CDSPackage{GetHasher: cryptoProvider}
   245  	ccdata = &ChaincodeData{Name: "Tom"}
   246  	cpack.depSpec = &pb.ChaincodeDeploymentSpec{
   247  		CodePackage: []byte("code"),
   248  		ChaincodeSpec: &pb.ChaincodeSpec{
   249  			ChaincodeId: &pb.ChaincodeID{Name: "Jerry", Version: "0"},
   250  		},
   251  	}
   252  	cpack.data = &CDSData{}
   253  	err = cpack.ValidateCC(ccdata)
   254  	assert.Error(t, err)
   255  	assert.Contains(t, err.Error(), `invalid chaincode data name:"Tom"  (name:"Jerry" version:"0" )`)
   256  
   257  	// mismatched versions
   258  	cpack = &CDSPackage{GetHasher: cryptoProvider}
   259  	ccdata = &ChaincodeData{Name: "Tom", Version: "1"}
   260  	cpack.depSpec = &pb.ChaincodeDeploymentSpec{
   261  		CodePackage: []byte("code"),
   262  		ChaincodeSpec: &pb.ChaincodeSpec{
   263  			ChaincodeId: &pb.ChaincodeID{Name: ccdata.Name, Version: "0"},
   264  		},
   265  	}
   266  	cpack.data = &CDSData{}
   267  	err = cpack.ValidateCC(ccdata)
   268  	assert.Error(t, err)
   269  	assert.Contains(t, err.Error(), `invalid chaincode data name:"Tom" version:"1"  (name:"Tom" version:"0" )`)
   270  }