github.com/inklabsfoundation/inkchain@v0.17.1-0.20181025012015-c3cef8062f19/core/common/ccprovider/sigcdspackage_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package ccprovider
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"testing"
    23  
    24  	"github.com/inklabsfoundation/inkchain/core/common/ccpackage"
    25  	"github.com/inklabsfoundation/inkchain/protos/common"
    26  	pb "github.com/inklabsfoundation/inkchain/protos/peer"
    27  	"github.com/inklabsfoundation/inkchain/protos/utils"
    28  	"github.com/stretchr/testify/assert"
    29  )
    30  
    31  func processSignedCDS(cds *pb.ChaincodeDeploymentSpec, policy *common.SignaturePolicyEnvelope, tofs bool) (*SignedCDSPackage, []byte, *ChaincodeData, error) {
    32  	env, err := ccpackage.OwnerCreateSignedCCDepSpec(cds, policy, nil)
    33  	if err != nil {
    34  		return nil, nil, nil, fmt.Errorf("could not create package %s", err)
    35  	}
    36  
    37  	b := utils.MarshalOrPanic(env)
    38  
    39  	ccpack := &SignedCDSPackage{}
    40  	cd, err := ccpack.InitFromBuffer(b)
    41  	if err != nil {
    42  		return nil, nil, nil, fmt.Errorf("error owner creating package %s", err)
    43  	}
    44  
    45  	if tofs {
    46  		if err = ccpack.PutChaincodeToFS(); err != nil {
    47  			return nil, nil, nil, fmt.Errorf("error putting package on the FS %s", err)
    48  		}
    49  	}
    50  
    51  	return ccpack, b, cd, nil
    52  }
    53  
    54  func TestPutSigCDSCC(t *testing.T) {
    55  	ccdir := setupccdir()
    56  	defer os.RemoveAll(ccdir)
    57  
    58  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
    59  
    60  	ccpack, _, cd, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, true)
    61  	if err != nil {
    62  		t.Fatalf("cannot create package %s", err)
    63  		return
    64  	}
    65  
    66  	if err = ccpack.ValidateCC(cd); err != nil {
    67  		t.Fatalf("error validating package %s", err)
    68  		return
    69  	}
    70  }
    71  
    72  func TestPutSignedCDSErrorPaths(t *testing.T) {
    73  	ccdir := setupccdir()
    74  	defer os.RemoveAll(ccdir)
    75  
    76  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
    77  		Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
    78  
    79  	ccpack, b, _, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, true)
    80  	if err != nil {
    81  		t.Fatalf("cannot create package %s", err)
    82  		return
    83  	}
    84  
    85  	// remove the buffer
    86  	ccpack.buf = nil
    87  	err = ccpack.PutChaincodeToFS()
    88  	assert.Error(t, err)
    89  	assert.Contains(t, err.Error(), "uninitialized package", "Unexpected error putting package on the FS")
    90  
    91  	// put back the buffer
    92  	ccpack.buf = b
    93  	id := ccpack.id
    94  	ccpack.id = nil // remove the id
    95  	err = ccpack.PutChaincodeToFS()
    96  	assert.Error(t, err)
    97  	assert.Contains(t, err.Error(), "id cannot be nil if buf is not nil", "Unexpected error putting package on the FS")
    98  
    99  	assert.Panics(t, func() {
   100  		ccpack.GetId()
   101  	}, "GetId should have paniced if chaincode package ID is nil")
   102  
   103  	// put back the id
   104  	ccpack.id = id
   105  	id1 := ccpack.GetId()
   106  	assert.Equal(t, id, id1)
   107  
   108  	savDepSpec := ccpack.sDepSpec
   109  	ccpack.sDepSpec = nil // remove the signed chaincode deployment spec
   110  	err = ccpack.PutChaincodeToFS()
   111  	assert.Error(t, err)
   112  	assert.Contains(t, err.Error(), "depspec cannot be nil if buf is not nil", "Unexpected error putting package on the FS")
   113  	assert.Panics(t, func() {
   114  		ccpack.GetInstantiationPolicy()
   115  	}, "GetChaincodeData should have paniced if signed chaincode deployment spec is nil")
   116  	assert.Panics(t, func() {
   117  		ccpack.GetDepSpecBytes()
   118  	}, "GetDepSpecBytes should have paniced if signed chaincode deployment spec is nil")
   119  	ccpack.sDepSpec = savDepSpec // put back dep spec
   120  	sdepspec1 := ccpack.GetInstantiationPolicy()
   121  	assert.NotNil(t, sdepspec1)
   122  	depspecBytes := ccpack.GetDepSpecBytes()
   123  	assert.NotNil(t, depspecBytes)
   124  
   125  	// put back the signed chaincode deployment spec
   126  	depSpec := ccpack.depSpec
   127  	ccpack.depSpec = nil // remove the chaincode deployment spec
   128  	assert.Panics(t, func() {
   129  		ccpack.GetDepSpec()
   130  	}, "GetDepSec should have paniced if chaincode deployment spec is nil")
   131  	assert.Panics(t, func() {
   132  		ccpack.GetChaincodeData()
   133  	}, "GetChaincodeData should have paniced if chaincode deployment spec is nil")
   134  	ccpack.depSpec = depSpec // put back the chaincode deployment spec
   135  	depSpec1 := ccpack.GetDepSpec()
   136  	assert.NotNil(t, depSpec1)
   137  
   138  	env := ccpack.env
   139  	ccpack.env = nil // remove the envelope
   140  	err = ccpack.PutChaincodeToFS()
   141  	assert.Error(t, err)
   142  	assert.Contains(t, err.Error(), "env cannot be nil if buf and depspec are not nil", "Unexpected error putting package on the FS")
   143  	ccpack.env = env // put back the envelope
   144  	env1 := ccpack.GetPackageObject()
   145  	assert.Equal(t, env, env1)
   146  
   147  	data := ccpack.data
   148  	ccpack.data = nil // remove the data
   149  	err = ccpack.PutChaincodeToFS()
   150  	assert.Error(t, err)
   151  	assert.Contains(t, err.Error(), "nil data", "Unexpected error putting package on the FS")
   152  	ccpack.data = data // put back the data
   153  
   154  	datab := ccpack.datab
   155  	ccpack.datab = nil // remove the data bytes
   156  	err = ccpack.PutChaincodeToFS()
   157  	assert.Error(t, err)
   158  	assert.Contains(t, err.Error(), "nil data bytes", "Unexpected error putting package on the FS")
   159  	ccpack.datab = datab // put back the data bytes
   160  
   161  	// remove the chaincode directory
   162  	os.RemoveAll(ccdir)
   163  	err = ccpack.PutChaincodeToFS()
   164  	assert.Error(t, err, "Expected error putting package on the FS")
   165  }
   166  
   167  func TestGetCDSDataErrorPaths(t *testing.T) {
   168  	ccdir := setupccdir()
   169  	defer os.RemoveAll(ccdir)
   170  
   171  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
   172  		Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
   173  
   174  	ccpack, _, _, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, true)
   175  	if err != nil {
   176  		t.Fatalf("cannot create package %s", err)
   177  		return
   178  	}
   179  
   180  	// Error case 1: signed chaincode deployment spec passed to getCDSData is nil
   181  	assert.Panics(t, func() {
   182  		_, _, _, err = ccpack.getCDSData(nil)
   183  	}, "getCDSData should have paniced when called with nil signed chaincode deployment spec")
   184  
   185  	// Error case 2: bad chaincode deployment spec
   186  	scdp := &pb.SignedChaincodeDeploymentSpec{ChaincodeDeploymentSpec: []byte("bad spec")}
   187  	_, _, _, err = ccpack.getCDSData(scdp)
   188  	assert.Error(t, err)
   189  
   190  	// Error case 3: instantiation policy is nil
   191  	instPolicy := ccpack.sDepSpec.InstantiationPolicy
   192  	ccpack.sDepSpec.InstantiationPolicy = nil
   193  	_, _, _, err = ccpack.getCDSData(ccpack.sDepSpec)
   194  	assert.Error(t, err)
   195  	assert.Contains(t, err.Error(), "instantiation policy cannot be nil for chaincode", "Unexpected error returned by getCDSData")
   196  	ccpack.sDepSpec.InstantiationPolicy = instPolicy
   197  
   198  	ccpack.sDepSpec.OwnerEndorsements = make([]*pb.Endorsement, 1)
   199  	ccpack.sDepSpec.OwnerEndorsements[0] = &pb.Endorsement{}
   200  	_, _, _, err = ccpack.getCDSData(ccpack.sDepSpec)
   201  	assert.NoError(t, err)
   202  }
   203  
   204  func TestInitFromBufferErrorPaths(t *testing.T) {
   205  	ccdir := setupccdir()
   206  	defer os.RemoveAll(ccdir)
   207  
   208  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
   209  		Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
   210  
   211  	ccpack, _, _, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, true)
   212  	if err != nil {
   213  		t.Fatalf("cannot create package %s", err)
   214  		return
   215  	}
   216  
   217  	_, err = ccpack.InitFromBuffer([]byte("bad buffer"))
   218  	assert.Error(t, err)
   219  	assert.Contains(t, err.Error(), "failed to unmarshal envelope from bytes", "Unexpected error returned by InitFromBuffer")
   220  }
   221  
   222  func TestValidateSignedCCErrorPaths(t *testing.T) {
   223  	ccdir := setupccdir()
   224  	defer os.RemoveAll(ccdir)
   225  
   226  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
   227  		Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
   228  
   229  	ccpack, _, _, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, true)
   230  	if err != nil {
   231  		t.Fatalf("cannot create package %s", err)
   232  		return
   233  	}
   234  
   235  	//validate with invalid name
   236  	cd := &ChaincodeData{Name: "invalname", Version: "0"}
   237  	err = ccpack.ValidateCC(cd)
   238  	assert.Error(t, err)
   239  	assert.Contains(t, err.Error(), "invalid chaincode data", "Unexpected error validating package")
   240  
   241  	savDepSpec := ccpack.sDepSpec
   242  	ccpack.sDepSpec = nil
   243  	err = ccpack.ValidateCC(cd)
   244  	assert.Error(t, err)
   245  	assert.Contains(t, err.Error(), "uninitialized package", "Unexpected error validating package")
   246  	ccpack.sDepSpec = savDepSpec
   247  
   248  	cdspec := ccpack.sDepSpec.ChaincodeDeploymentSpec
   249  	ccpack.sDepSpec.ChaincodeDeploymentSpec = nil
   250  	err = ccpack.ValidateCC(cd)
   251  	assert.Error(t, err)
   252  	assert.Contains(t, err.Error(), "signed chaincode deployment spec cannot be nil in a package", "Unexpected error validating package")
   253  	ccpack.sDepSpec.ChaincodeDeploymentSpec = cdspec
   254  
   255  	depspec := ccpack.depSpec
   256  	ccpack.depSpec = nil
   257  	err = ccpack.ValidateCC(cd)
   258  	assert.Error(t, err)
   259  	assert.Contains(t, err.Error(), "chaincode deployment spec cannot be nil in a package", "Unexpected error validating package")
   260  	ccpack.depSpec = depspec
   261  }
   262  
   263  func TestSigCDSGetCCPackage(t *testing.T) {
   264  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
   265  
   266  	env, err := ccpackage.OwnerCreateSignedCCDepSpec(cds, &common.SignaturePolicyEnvelope{Version: 1}, nil)
   267  	if err != nil {
   268  		t.Fatalf("cannot create package")
   269  		return
   270  	}
   271  
   272  	b := utils.MarshalOrPanic(env)
   273  
   274  	ccpack, err := GetCCPackage(b)
   275  	if err != nil {
   276  		t.Fatalf("failed to get CCPackage %s", err)
   277  		return
   278  	}
   279  
   280  	cccdspack, ok := ccpack.(*CDSPackage)
   281  	if ok || cccdspack != nil {
   282  		t.Fatalf("expected CDSPackage type cast to fail but succeeded")
   283  		return
   284  	}
   285  
   286  	ccsignedcdspack, ok := ccpack.(*SignedCDSPackage)
   287  	if !ok || ccsignedcdspack == nil {
   288  		t.Fatalf("failed to get Signed CDS CCPackage")
   289  		return
   290  	}
   291  
   292  	cds2 := ccsignedcdspack.GetDepSpec()
   293  	if cds2 == nil {
   294  		t.Fatalf("nil dep spec in Signed CDS CCPackage")
   295  		return
   296  	}
   297  
   298  	if cds2.ChaincodeSpec.ChaincodeId.Name != cds.ChaincodeSpec.ChaincodeId.Name || cds2.ChaincodeSpec.ChaincodeId.Version != cds.ChaincodeSpec.ChaincodeId.Version {
   299  		t.Fatalf("dep spec in Signed CDS CCPackage does not match %v != %v", cds, cds2)
   300  		return
   301  	}
   302  }
   303  
   304  func TestInvalidSigCDSGetCCPackage(t *testing.T) {
   305  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
   306  
   307  	b := utils.MarshalOrPanic(cds)
   308  
   309  	ccpack, err := GetCCPackage(b)
   310  	if err != nil {
   311  		t.Fatalf("failed to get CCPackage %s", err)
   312  		return
   313  	}
   314  
   315  	ccsignedcdspack, ok := ccpack.(*SignedCDSPackage)
   316  	if ok || ccsignedcdspack != nil {
   317  		t.Fatalf("expected failure to get Signed CDS CCPackage but succeeded")
   318  		return
   319  	}
   320  }
   321  
   322  //switch the chaincodes on the FS and validate
   323  func TestSignedCDSSwitchChaincodes(t *testing.T) {
   324  	ccdir := setupccdir()
   325  	defer os.RemoveAll(ccdir)
   326  
   327  	//someone modifyed the code on the FS with "badcode"
   328  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("badcode")}
   329  
   330  	//write the bad code to the fs
   331  	badccpack, _, _, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, true)
   332  	if err != nil {
   333  		t.Fatalf("error putting CDS to FS %s", err)
   334  		return
   335  	}
   336  
   337  	//mimic the good code ChaincodeData from the instantiate...
   338  	cds.CodePackage = []byte("goodcode")
   339  
   340  	//...and generate the CD for it (don't overwrite the bad code)
   341  	_, _, goodcd, err := processSignedCDS(cds, &common.SignaturePolicyEnvelope{Version: 1}, false)
   342  	if err != nil {
   343  		t.Fatalf("error putting CDS to FS %s", err)
   344  		return
   345  	}
   346  
   347  	if err = badccpack.ValidateCC(goodcd); err == nil {
   348  		t.Fatalf("expected goodcd to fail against bad package but succeeded!")
   349  		return
   350  	}
   351  }