github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/core/endorser/endorser_test.go (about) 1 /* 2 Copyright IBM Corp. 2016 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 endorser 18 19 import ( 20 "flag" 21 "fmt" 22 "io/ioutil" 23 "net" 24 "os" 25 "runtime" 26 "strings" 27 "testing" 28 "time" 29 30 "path/filepath" 31 32 "errors" 33 34 "github.com/golang/protobuf/proto" 35 "github.com/hyperledger/fabric/bccsp/factory" 36 mockpolicies "github.com/hyperledger/fabric/common/mocks/policies" 37 "github.com/hyperledger/fabric/common/policies" 38 "github.com/hyperledger/fabric/common/util" 39 "github.com/hyperledger/fabric/core/chaincode" 40 "github.com/hyperledger/fabric/core/common/ccprovider" 41 "github.com/hyperledger/fabric/core/config" 42 "github.com/hyperledger/fabric/core/container" 43 "github.com/hyperledger/fabric/core/peer" 44 syscc "github.com/hyperledger/fabric/core/scc" 45 "github.com/hyperledger/fabric/core/testutil" 46 "github.com/hyperledger/fabric/msp" 47 mspmgmt "github.com/hyperledger/fabric/msp/mgmt" 48 "github.com/hyperledger/fabric/msp/mgmt/testtools" 49 "github.com/hyperledger/fabric/protos/common" 50 pb "github.com/hyperledger/fabric/protos/peer" 51 pbutils "github.com/hyperledger/fabric/protos/utils" 52 "github.com/spf13/viper" 53 "golang.org/x/net/context" 54 "google.golang.org/grpc" 55 56 "github.com/stretchr/testify/assert" 57 "google.golang.org/grpc/credentials" 58 ) 59 60 var endorserServer pb.EndorserServer 61 var signer msp.SigningIdentity 62 63 type testEnvironment struct { 64 tempDir string 65 listener net.Listener 66 } 67 68 //initialize peer and start up. If security==enabled, login as vp 69 func initPeer(chainID string) (*testEnvironment, error) { 70 //start clean 71 // finitPeer(nil) 72 var opts []grpc.ServerOption 73 if viper.GetBool("peer.tls.enabled") { 74 creds, err := credentials.NewServerTLSFromFile(config.GetPath("peer.tls.cert.file"), config.GetPath("peer.tls.key.file")) 75 if err != nil { 76 return nil, fmt.Errorf("Failed to generate credentials %v", err) 77 } 78 opts = []grpc.ServerOption{grpc.Creds(creds)} 79 } 80 grpcServer := grpc.NewServer(opts...) 81 82 tempDir := newTempDir() 83 viper.Set("peer.fileSystemPath", filepath.Join(tempDir, "hyperledger", "production")) 84 85 peerAddress, err := peer.GetLocalAddress() 86 if err != nil { 87 return nil, fmt.Errorf("Error obtaining peer address: %s", err) 88 } 89 lis, err := net.Listen("tcp", peerAddress) 90 if err != nil { 91 return nil, fmt.Errorf("Error starting peer listener %s", err) 92 } 93 94 //initialize ledger 95 peer.MockInitialize() 96 97 mspGetter := func(cid string) []string { 98 return []string{"DEFAULT"} 99 } 100 101 peer.MockSetMSPIDGetter(mspGetter) 102 103 getPeerEndpoint := func() (*pb.PeerEndpoint, error) { 104 return &pb.PeerEndpoint{Id: &pb.PeerID{Name: "testpeer"}, Address: peerAddress}, nil 105 } 106 107 ccStartupTimeout := time.Duration(30000) * time.Millisecond 108 pb.RegisterChaincodeSupportServer(grpcServer, chaincode.NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout)) 109 110 syscc.RegisterSysCCs() 111 112 if err = peer.MockCreateChain(chainID); err != nil { 113 closeListenerAndSleep(lis) 114 return nil, err 115 } 116 117 syscc.DeploySysCCs(chainID) 118 119 go grpcServer.Serve(lis) 120 121 return &testEnvironment{tempDir: tempDir, listener: lis}, nil 122 } 123 124 func finitPeer(tev *testEnvironment) { 125 closeListenerAndSleep(tev.listener) 126 os.RemoveAll(tev.tempDir) 127 } 128 129 func closeListenerAndSleep(l net.Listener) { 130 if l != nil { 131 l.Close() 132 time.Sleep(2 * time.Second) 133 } 134 } 135 136 // getInvokeProposal gets the proposal for the chaincode invocation 137 // Currently supported only for Invokes 138 // It returns the proposal and the transaction id associated to the proposal 139 func getInvokeProposal(cis *pb.ChaincodeInvocationSpec, chainID string, creator []byte) (*pb.Proposal, string, error) { 140 return pbutils.CreateChaincodeProposal(common.HeaderType_ENDORSER_TRANSACTION, chainID, cis, creator) 141 } 142 143 // getInvokeProposalOverride allows to get a proposal for the chaincode invocation 144 // overriding transaction id and nonce which are by default auto-generated. 145 // It returns the proposal and the transaction id associated to the proposal 146 func getInvokeProposalOverride(txid string, cis *pb.ChaincodeInvocationSpec, chainID string, nonce, creator []byte) (*pb.Proposal, string, error) { 147 return pbutils.CreateChaincodeProposalWithTxIDNonceAndTransient(txid, common.HeaderType_ENDORSER_TRANSACTION, chainID, cis, nonce, creator, nil) 148 } 149 150 func getDeployProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte) (*pb.Proposal, error) { 151 return getDeployOrUpgradeProposal(cds, chainID, creator, false) 152 } 153 154 func getUpgradeProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte) (*pb.Proposal, error) { 155 return getDeployOrUpgradeProposal(cds, chainID, creator, true) 156 } 157 158 //getDeployOrUpgradeProposal gets the proposal for the chaincode deploy or upgrade 159 //the payload is a ChaincodeDeploymentSpec 160 func getDeployOrUpgradeProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte, upgrade bool) (*pb.Proposal, error) { 161 //we need to save off the chaincode as we have to instantiate with nil CodePackage 162 var err error 163 if err = ccprovider.PutChaincodeIntoFS(cds); err != nil { 164 return nil, err 165 } 166 167 cds.CodePackage = nil 168 169 b, err := proto.Marshal(cds) 170 if err != nil { 171 return nil, err 172 } 173 174 var propType string 175 if upgrade { 176 propType = "upgrade" 177 } else { 178 propType = "deploy" 179 } 180 sccver := util.GetSysCCVersion() 181 //wrap the deployment in an invocation spec to lscc... 182 lsccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: "lscc", Version: sccver}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte(propType), []byte(chainID), b}}}} 183 184 //...and get the proposal for it 185 var prop *pb.Proposal 186 if prop, _, err = getInvokeProposal(lsccSpec, chainID, creator); err != nil { 187 return nil, err 188 } 189 190 return prop, nil 191 } 192 193 func getSignedProposal(prop *pb.Proposal, signer msp.SigningIdentity) (*pb.SignedProposal, error) { 194 propBytes, err := pbutils.GetBytesProposal(prop) 195 if err != nil { 196 return nil, err 197 } 198 199 signature, err := signer.Sign(propBytes) 200 if err != nil { 201 return nil, err 202 } 203 204 return &pb.SignedProposal{ProposalBytes: propBytes, Signature: signature}, nil 205 } 206 207 func getDeploymentSpec(context context.Context, spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) { 208 codePackageBytes, err := container.GetChaincodePackageBytes(spec) 209 if err != nil { 210 return nil, err 211 } 212 chaincodeDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes} 213 return chaincodeDeploymentSpec, nil 214 } 215 216 func deploy(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec)) (*pb.ProposalResponse, *pb.Proposal, error) { 217 return deployOrUpgrade(endorserServer, chainID, spec, f, false) 218 } 219 220 func upgrade(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec)) (*pb.ProposalResponse, *pb.Proposal, error) { 221 return deployOrUpgrade(endorserServer, chainID, spec, f, true) 222 } 223 224 func deployOrUpgrade(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec), upgrade bool) (*pb.ProposalResponse, *pb.Proposal, error) { 225 var err error 226 var depSpec *pb.ChaincodeDeploymentSpec 227 228 ctxt := context.Background() 229 depSpec, err = getDeploymentSpec(ctxt, spec) 230 if err != nil { 231 return nil, nil, err 232 } 233 234 if f != nil { 235 f(depSpec) 236 } 237 238 creator, err := signer.Serialize() 239 if err != nil { 240 return nil, nil, err 241 } 242 243 var prop *pb.Proposal 244 if upgrade { 245 prop, err = getUpgradeProposal(depSpec, chainID, creator) 246 } else { 247 prop, err = getDeployProposal(depSpec, chainID, creator) 248 } 249 if err != nil { 250 return nil, nil, err 251 } 252 253 var signedProp *pb.SignedProposal 254 signedProp, err = getSignedProposal(prop, signer) 255 if err != nil { 256 return nil, nil, err 257 } 258 259 var resp *pb.ProposalResponse 260 resp, err = endorserServer.ProcessProposal(context.Background(), signedProp) 261 262 return resp, prop, err 263 } 264 265 func invoke(chainID string, spec *pb.ChaincodeSpec) (*pb.Proposal, *pb.ProposalResponse, string, []byte, error) { 266 invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 267 268 creator, err := signer.Serialize() 269 if err != nil { 270 return nil, nil, "", nil, err 271 } 272 273 var prop *pb.Proposal 274 prop, txID, err := getInvokeProposal(invocation, chainID, creator) 275 if err != nil { 276 return nil, nil, "", nil, fmt.Errorf("Error creating proposal %s: %s\n", spec.ChaincodeId, err) 277 } 278 279 nonce, err := pbutils.GetNonce(prop) 280 if err != nil { 281 return nil, nil, "", nil, fmt.Errorf("Failed getting nonce %s: %s\n", spec.ChaincodeId, err) 282 } 283 284 var signedProp *pb.SignedProposal 285 signedProp, err = getSignedProposal(prop, signer) 286 if err != nil { 287 return nil, nil, "", nil, err 288 } 289 290 resp, err := endorserServer.ProcessProposal(context.Background(), signedProp) 291 if err != nil { 292 return nil, nil, "", nil, err 293 } 294 295 return prop, resp, txID, nonce, err 296 } 297 298 func invokeWithOverride(txid string, chainID string, spec *pb.ChaincodeSpec, nonce []byte) (*pb.ProposalResponse, error) { 299 invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 300 301 creator, err := signer.Serialize() 302 if err != nil { 303 return nil, err 304 } 305 306 var prop *pb.Proposal 307 prop, _, err = getInvokeProposalOverride(txid, invocation, chainID, nonce, creator) 308 if err != nil { 309 return nil, fmt.Errorf("Error creating proposal with override %s %s: %s\n", txid, spec.ChaincodeId, err) 310 } 311 312 var signedProp *pb.SignedProposal 313 signedProp, err = getSignedProposal(prop, signer) 314 if err != nil { 315 return nil, err 316 } 317 318 resp, err := endorserServer.ProcessProposal(context.Background(), signedProp) 319 if err != nil { 320 return nil, fmt.Errorf("Error endorsing %s %s: %s\n", txid, spec.ChaincodeId, err) 321 } 322 323 return resp, err 324 } 325 326 func deleteChaincodeOnDisk(chaincodeID string) { 327 os.RemoveAll(filepath.Join(config.GetPath("peer.fileSystemPath"), "chaincodes", chaincodeID)) 328 } 329 330 //begin tests. Note that we rely upon the system chaincode and peer to be created 331 //once and be used for all the tests. In order to avoid dependencies / collisions 332 //due to deployed chaincodes, trying to use different chaincodes for different 333 //tests 334 335 //TestDeploy deploy chaincode example01 336 func TestDeploy(t *testing.T) { 337 chainID := util.GetTestChainID() 338 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "ex01", Path: "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}} 339 defer deleteChaincodeOnDisk("ex01.0") 340 341 cccid := ccprovider.NewCCContext(chainID, "ex01", "0", "", false, nil, nil) 342 343 _, _, err := deploy(endorserServer, chainID, spec, nil) 344 if err != nil { 345 t.Fail() 346 t.Logf("Deploy-error in deploy %s", err) 347 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 348 return 349 } 350 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 351 } 352 353 //REMOVE WHEN JAVA CC IS ENABLED 354 func TestJavaDeploy(t *testing.T) { 355 chainID := util.GetTestChainID() 356 //pretend this is a java CC (type 4) 357 spec := &pb.ChaincodeSpec{Type: 4, ChaincodeId: &pb.ChaincodeID{Name: "javacc", Path: "../../examples/chaincode/java/chaincode_example02", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}} 358 defer deleteChaincodeOnDisk("javacc.0") 359 360 cccid := ccprovider.NewCCContext(chainID, "javacc", "0", "", false, nil, nil) 361 362 _, _, err := deploy(endorserServer, chainID, spec, nil) 363 if err == nil { 364 t.Fail() 365 t.Logf("expected java CC deploy to fail") 366 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 367 return 368 } 369 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 370 } 371 372 //TestRedeploy - deploy two times, second time should fail but example02 should remain deployed 373 func TestRedeploy(t *testing.T) { 374 chainID := util.GetTestChainID() 375 376 //invalid arguments 377 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "ex02", Path: "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}} 378 379 defer deleteChaincodeOnDisk("ex02.0") 380 381 cccid := ccprovider.NewCCContext(chainID, "ex02", "0", "", false, nil, nil) 382 383 _, _, err := deploy(endorserServer, chainID, spec, nil) 384 if err != nil { 385 t.Fail() 386 t.Logf("error in endorserServer.ProcessProposal %s", err) 387 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 388 return 389 } 390 391 deleteChaincodeOnDisk("ex02.0") 392 393 //second time should not fail as we are just simulating 394 _, _, err = deploy(endorserServer, chainID, spec, nil) 395 if err != nil { 396 t.Fail() 397 t.Logf("error in endorserServer.ProcessProposal %s", err) 398 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 399 return 400 } 401 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 402 } 403 404 // TestDeployAndInvoke deploys and invokes chaincode_example01 405 func TestDeployAndInvoke(t *testing.T) { 406 chainID := util.GetTestChainID() 407 var ctxt = context.Background() 408 409 url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01" 410 chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01", Version: "0"} 411 412 defer deleteChaincodeOnDisk("ex01.0") 413 414 args := []string{"10"} 415 416 f := "init" 417 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 418 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}} 419 420 cccid := ccprovider.NewCCContext(chainID, "ex01", "0", "", false, nil, nil) 421 422 resp, prop, err := deploy(endorserServer, chainID, spec, nil) 423 chaincodeID1 := spec.ChaincodeId.Name 424 if err != nil { 425 t.Fail() 426 t.Logf("Error deploying <%s>: %s", chaincodeID1, err) 427 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 428 return 429 } 430 var nextBlockNumber uint64 = 1 // first block needs to be block number = 1. Genesis block is block 0 431 err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber) 432 if err != nil { 433 t.Fail() 434 t.Logf("Error committing deploy <%s>: %s", chaincodeID1, err) 435 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 436 return 437 } 438 439 f = "invoke" 440 invokeArgs := append([]string{f}, args...) 441 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 442 prop, resp, txid, nonce, err := invoke(chainID, spec) 443 if err != nil { 444 t.Fail() 445 t.Logf("Error invoking transaction: %s", err) 446 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 447 return 448 } 449 // Commit invoke 450 nextBlockNumber++ 451 err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber) 452 if err != nil { 453 t.Fail() 454 t.Logf("Error committing first invoke <%s>: %s", chaincodeID1, err) 455 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 456 return 457 } 458 459 // Now test for an invalid TxID 460 f = "invoke" 461 invokeArgs = append([]string{f}, args...) 462 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 463 _, err = invokeWithOverride("invalid_tx_id", chainID, spec, nonce) 464 if err == nil { 465 t.Fail() 466 t.Log("Replay attack protection faild. Transaction with invalid txid passed") 467 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 468 return 469 } 470 471 // Now test for duplicated TxID 472 f = "invoke" 473 invokeArgs = append([]string{f}, args...) 474 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 475 _, err = invokeWithOverride(txid, chainID, spec, nonce) 476 if err == nil { 477 t.Fail() 478 t.Log("Replay attack protection faild. Transaction with duplicaged txid passed") 479 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 480 return 481 } 482 483 // Test chaincode endorsement failure when invalid function name supplied 484 f = "invokeinvalid" 485 invokeArgs = append([]string{f}, args...) 486 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 487 prop, resp, txid, nonce, err = invoke(chainID, spec) 488 if err == nil { 489 t.Fail() 490 t.Logf("expecting fabric to report error from chaincode failure") 491 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 492 return 493 } else if _, ok := err.(*chaincodeError); !ok { 494 t.Fail() 495 t.Logf("expecting chaincode error but found %v", err) 496 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 497 return 498 } 499 500 if resp != nil { 501 assert.Equal(t, int32(500), resp.Response.Status, "Unexpected response status") 502 } 503 504 t.Logf("Invoke test passed") 505 506 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 507 } 508 509 // TestUpgradeAndInvoke deploys chaincode_example01, upgrade it with chaincode_example02, then invoke it 510 func TestDeployAndUpgrade(t *testing.T) { 511 chainID := util.GetTestChainID() 512 var ctxt = context.Background() 513 514 url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01" 515 url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 516 chaincodeID1 := &pb.ChaincodeID{Path: url1, Name: "upgradeex01", Version: "0"} 517 chaincodeID2 := &pb.ChaincodeID{Path: url2, Name: "upgradeex01", Version: "1"} 518 519 defer deleteChaincodeOnDisk("upgradeex01.0") 520 defer deleteChaincodeOnDisk("upgradeex01.1") 521 522 f := "init" 523 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 524 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID1, Input: &pb.ChaincodeInput{Args: argsDeploy}} 525 526 cccid1 := ccprovider.NewCCContext(chainID, "upgradeex01", "0", "", false, nil, nil) 527 cccid2 := ccprovider.NewCCContext(chainID, "upgradeex01", "1", "", false, nil, nil) 528 529 resp, prop, err := deploy(endorserServer, chainID, spec, nil) 530 531 chaincodeName := spec.ChaincodeId.Name 532 if err != nil { 533 t.Fail() 534 chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}}) 535 chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}}) 536 t.Logf("Error deploying <%s>: %s", chaincodeName, err) 537 return 538 } 539 540 var nextBlockNumber uint64 = 3 // something above created block 0 541 err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber) 542 if err != nil { 543 t.Fail() 544 chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}}) 545 chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}}) 546 t.Logf("Error committing <%s>: %s", chaincodeName, err) 547 return 548 } 549 550 argsUpgrade := util.ToChaincodeArgs(f, "a", "150", "b", "300") 551 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID2, Input: &pb.ChaincodeInput{Args: argsUpgrade}} 552 _, _, err = upgrade(endorserServer, chainID, spec, nil) 553 if err != nil { 554 t.Fail() 555 chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}}) 556 chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}}) 557 t.Logf("Error upgrading <%s>: %s", chaincodeName, err) 558 return 559 } 560 561 t.Logf("Upgrade test passed") 562 563 chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}}) 564 chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}}) 565 } 566 567 // TestWritersACLFail deploys a chaincode and then tries to invoke it; 568 // however we inject a special policy for writers to simulate 569 // the scenario in which the creator of this proposal is not among 570 // the writers for the chain 571 func TestWritersACLFail(t *testing.T) { 572 //skip pending FAB-2457 fix 573 t.Skip() 574 chainID := util.GetTestChainID() 575 var ctxt = context.Background() 576 577 url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01" 578 chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01-fail", Version: "0"} 579 580 defer deleteChaincodeOnDisk("ex01-fail.0") 581 582 args := []string{"10"} 583 584 f := "init" 585 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 586 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}} 587 588 cccid := ccprovider.NewCCContext(chainID, "ex01-fail", "0", "", false, nil, nil) 589 590 resp, prop, err := deploy(endorserServer, chainID, spec, nil) 591 chaincodeID1 := spec.ChaincodeId.Name 592 if err != nil { 593 t.Fail() 594 t.Logf("Error deploying <%s>: %s", chaincodeID1, err) 595 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 596 return 597 } 598 var nextBlockNumber uint64 = 3 // The tests that ran before this test created blocks 0-2 599 err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber) 600 if err != nil { 601 t.Fail() 602 t.Logf("Error committing deploy <%s>: %s", chaincodeID1, err) 603 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 604 return 605 } 606 607 // here we inject a reject policy for writers 608 // to simulate the scenario in which the invoker 609 // is not authorized to issue this proposal 610 rejectpolicy := &mockpolicies.Policy{ 611 Err: errors.New("The creator of this proposal does not fulfil the writers policy of this chain"), 612 } 613 pm := peer.GetPolicyManager(chainID) 614 pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{policies.ChannelApplicationWriters: rejectpolicy} 615 616 f = "invoke" 617 invokeArgs := append([]string{f}, args...) 618 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 619 prop, resp, _, _, err = invoke(chainID, spec) 620 if err == nil { 621 t.Fail() 622 t.Logf("Invocation should have failed") 623 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 624 return 625 } 626 627 t.Logf("TestWritersACLFail passed") 628 629 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 630 } 631 632 // TestAdminACLFail deploys tried to deploy a chaincode; 633 // however we inject a special policy for admins to simulate 634 // the scenario in which the creator of this proposal is not among 635 // the admins for the chain 636 func TestAdminACLFail(t *testing.T) { 637 //skip pending FAB-2457 fix 638 t.Skip() 639 chainID := util.GetTestChainID() 640 641 // here we inject a reject policy for admins 642 // to simulate the scenario in which the invoker 643 // is not authorized to issue this proposal 644 rejectpolicy := &mockpolicies.Policy{ 645 Err: errors.New("The creator of this proposal does not fulfil the writers policy of this chain"), 646 } 647 pm := peer.GetPolicyManager(chainID) 648 pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{policies.ChannelApplicationAdmins: rejectpolicy} 649 650 var ctxt = context.Background() 651 652 url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01" 653 chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01-fail1", Version: "0"} 654 655 defer deleteChaincodeOnDisk("ex01-fail1.0") 656 657 f := "init" 658 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 659 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}} 660 661 cccid := ccprovider.NewCCContext(chainID, "ex01-fail1", "0", "", false, nil, nil) 662 663 _, _, err := deploy(endorserServer, chainID, spec, nil) 664 if err == nil { 665 t.Fail() 666 t.Logf("Deploying chaincode should have failed!") 667 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 668 return 669 } 670 671 t.Logf("TestATestAdminACLFailCLFail passed") 672 673 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 674 } 675 676 // TestInvokeSccFail makes sure that invoking a system chaincode fails 677 func TestInvokeSccFail(t *testing.T) { 678 chainID := util.GetTestChainID() 679 680 chaincodeID := &pb.ChaincodeID{Name: "escc"} 681 args := util.ToChaincodeArgs("someFunc", "someArg") 682 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}} 683 _, _, _, _, err := invoke(chainID, spec) 684 if err == nil { 685 t.Logf("Invoking escc should have failed!") 686 t.Fail() 687 return 688 } 689 } 690 691 func newTempDir() string { 692 tempDir, err := ioutil.TempDir("", "fabric-") 693 if err != nil { 694 panic(err) 695 } 696 return tempDir 697 } 698 699 func TestMain(m *testing.M) { 700 setupTestConfig() 701 702 chainID := util.GetTestChainID() 703 tev, err := initPeer(chainID) 704 if err != nil { 705 os.Exit(-1) 706 fmt.Printf("Could not initialize tests") 707 finitPeer(tev) 708 return 709 } 710 711 endorserServer = NewEndorserServer() 712 713 // setup the MSP manager so that we can sign/verify 714 err = msptesttools.LoadMSPSetupForTesting() 715 if err != nil { 716 fmt.Printf("Could not initialize msp/signer, err %s", err) 717 finitPeer(tev) 718 os.Exit(-1) 719 return 720 } 721 signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity() 722 if err != nil { 723 fmt.Printf("Could not initialize msp/signer") 724 finitPeer(tev) 725 os.Exit(-1) 726 return 727 } 728 729 retVal := m.Run() 730 731 finitPeer(tev) 732 733 os.Exit(retVal) 734 } 735 736 func setupTestConfig() { 737 flag.Parse() 738 739 // Now set the configuration file 740 viper.SetEnvPrefix("CORE") 741 viper.AutomaticEnv() 742 replacer := strings.NewReplacer(".", "_") 743 viper.SetEnvKeyReplacer(replacer) 744 viper.SetConfigName("endorser_test") // name of config file (without extension) 745 viper.AddConfigPath("./") // path to look for the config file in 746 err := viper.ReadInConfig() // Find and read the config file 747 if err != nil { // Handle errors reading the config file 748 panic(fmt.Errorf("Fatal error config file: %s \n", err)) 749 } 750 751 testutil.SetupTestLogging() 752 753 // Set the number of maxprocs 754 runtime.GOMAXPROCS(viper.GetInt("peer.gomaxprocs")) 755 756 // Init the BCCSP 757 var bccspConfig *factory.FactoryOpts 758 err = viper.UnmarshalKey("peer.BCCSP", &bccspConfig) 759 if err != nil { 760 bccspConfig = nil 761 } 762 763 msp.SetupBCCSPKeystoreConfig(bccspConfig, viper.GetString("peer.mspConfigPath")+"/keystore") 764 765 err = factory.InitFactories(bccspConfig) 766 if err != nil { 767 panic(fmt.Errorf("Could not initialize BCCSP Factories [%s]", err)) 768 } 769 }