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 }