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