github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/core/chaincode/exectransaction_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 chaincode 18 19 import ( 20 "fmt" 21 "net" 22 "os" 23 "path/filepath" 24 "strconv" 25 "strings" 26 "sync" 27 "testing" 28 "time" 29 30 "github.com/golang/protobuf/proto" 31 "github.com/hyperledger/fabric/common/util" 32 "github.com/hyperledger/fabric/core/common/ccprovider" 33 "github.com/hyperledger/fabric/core/container" 34 "github.com/hyperledger/fabric/core/container/ccintf" 35 "github.com/hyperledger/fabric/core/ledger" 36 "github.com/hyperledger/fabric/core/ledger/ledgerconfig" 37 "github.com/hyperledger/fabric/core/ledger/ledgermgmt" 38 "github.com/hyperledger/fabric/core/peer" 39 "github.com/hyperledger/fabric/core/scc" 40 "github.com/hyperledger/fabric/msp" 41 mspmgmt "github.com/hyperledger/fabric/msp/mgmt" 42 "github.com/hyperledger/fabric/msp/mgmt/testtools" 43 "github.com/hyperledger/fabric/protos/common" 44 pb "github.com/hyperledger/fabric/protos/peer" 45 putils "github.com/hyperledger/fabric/protos/utils" 46 "github.com/spf13/viper" 47 "golang.org/x/net/context" 48 "google.golang.org/grpc" 49 "google.golang.org/grpc/credentials" 50 ) 51 52 //initialize peer and start up. If security==enabled, login as vp 53 func initPeer(chainIDs ...string) (net.Listener, error) { 54 //start clean 55 finitPeer(nil, chainIDs...) 56 57 peer.MockInitialize() 58 59 var opts []grpc.ServerOption 60 if viper.GetBool("peer.tls.enabled") { 61 creds, err := credentials.NewServerTLSFromFile(viper.GetString("peer.tls.cert.file"), viper.GetString("peer.tls.key.file")) 62 if err != nil { 63 return nil, fmt.Errorf("Failed to generate credentials %v", err) 64 } 65 opts = []grpc.ServerOption{grpc.Creds(creds)} 66 } 67 grpcServer := grpc.NewServer(opts...) 68 69 peerAddress, err := peer.GetLocalAddress() 70 if err != nil { 71 return nil, fmt.Errorf("Error obtaining peer address: %s", err) 72 } 73 lis, err := net.Listen("tcp", peerAddress) 74 if err != nil { 75 return nil, fmt.Errorf("Error starting peer listener %s", err) 76 } 77 78 getPeerEndpoint := func() (*pb.PeerEndpoint, error) { 79 return &pb.PeerEndpoint{Id: &pb.PeerID{Name: "testpeer"}, Address: peerAddress}, nil 80 } 81 82 ccStartupTimeout := time.Duration(chaincodeStartupTimeoutDefault) * time.Millisecond 83 pb.RegisterChaincodeSupportServer(grpcServer, NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout)) 84 85 scc.RegisterSysCCs() 86 87 for _, id := range chainIDs { 88 scc.DeDeploySysCCs(id) 89 if err = peer.MockCreateChain(id); err != nil { 90 closeListenerAndSleep(lis) 91 return nil, err 92 } 93 scc.DeploySysCCs(id) 94 } 95 96 go grpcServer.Serve(lis) 97 98 return lis, nil 99 } 100 101 func finitPeer(lis net.Listener, chainIDs ...string) { 102 if lis != nil { 103 for _, c := range chainIDs { 104 scc.DeDeploySysCCs(c) 105 if lgr := peer.GetLedger(c); lgr != nil { 106 lgr.Close() 107 } 108 } 109 closeListenerAndSleep(lis) 110 } 111 ledgermgmt.CleanupTestEnv() 112 ledgerPath := viper.GetString("peer.fileSystemPath") 113 os.RemoveAll(ledgerPath) 114 os.RemoveAll(filepath.Join(os.TempDir(), "hyperledger")) 115 } 116 117 func startTxSimulation(ctxt context.Context, chainID string) (context.Context, ledger.TxSimulator, error) { 118 lgr := peer.GetLedger(chainID) 119 txsim, err := lgr.NewTxSimulator() 120 if err != nil { 121 return nil, nil, err 122 } 123 124 ctxt = context.WithValue(ctxt, TXSimulatorKey, txsim) 125 return ctxt, txsim, nil 126 } 127 128 func endTxSimulationCDS(chainID string, _ string, txsim ledger.TxSimulator, payload []byte, commit bool, cds *pb.ChaincodeDeploymentSpec, blockNumber uint64) error { 129 // get serialized version of the signer 130 ss, err := signer.Serialize() 131 if err != nil { 132 return err 133 } 134 // get a proposal - we need it to get a transaction 135 prop, _, err := putils.CreateDeployProposalFromCDS(chainID, cds, ss, nil, nil, nil) 136 if err != nil { 137 return err 138 } 139 140 return endTxSimulation(chainID, txsim, payload, commit, prop, blockNumber) 141 } 142 143 func endTxSimulationCIS(chainID string, _ string, txsim ledger.TxSimulator, payload []byte, commit bool, cis *pb.ChaincodeInvocationSpec, blockNumber uint64) error { 144 // get serialized version of the signer 145 ss, err := signer.Serialize() 146 if err != nil { 147 return err 148 } 149 // get a proposal - we need it to get a transaction 150 prop, _, err := putils.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, chainID, cis, ss) 151 if err != nil { 152 return err 153 } 154 155 return endTxSimulation(chainID, txsim, payload, commit, prop, blockNumber) 156 } 157 158 //getting a crash from ledger.Commit when doing concurrent invokes 159 //It is likely intentional that ledger.Commit is serial (ie, the real 160 //Committer will invoke this serially on each block). Mimic that here 161 //by forcing serialization of the ledger.Commit call. 162 // 163 //NOTE-this should NOT have any effect on the older serial tests. 164 //This affects only the tests in concurrent_test.go which call these 165 //concurrently (100 concurrent invokes followed by 100 concurrent queries) 166 var _commitLock_ sync.Mutex 167 168 func endTxSimulation(chainID string, txsim ledger.TxSimulator, _ []byte, commit bool, prop *pb.Proposal, blockNumber uint64) error { 169 txsim.Done() 170 if lgr := peer.GetLedger(chainID); lgr != nil { 171 if commit { 172 var txSimulationResults []byte 173 var err error 174 175 //get simulation results 176 if txSimulationResults, err = txsim.GetTxSimulationResults(); err != nil { 177 return err 178 } 179 180 // assemble a (signed) proposal response message 181 resp, err := putils.CreateProposalResponse(prop.Header, prop.Payload, &pb.Response{Status: 200}, txSimulationResults, nil, nil, signer) 182 if err != nil { 183 return err 184 } 185 186 // get the envelope 187 env, err := putils.CreateSignedTx(prop, signer, resp) 188 if err != nil { 189 return err 190 } 191 192 envBytes, err := putils.GetBytesEnvelope(env) 193 if err != nil { 194 return err 195 } 196 197 //create the block with 1 transaction 198 block := common.NewBlock(blockNumber, []byte{}) 199 block.Data.Data = [][]byte{envBytes} 200 //commit the block 201 202 //see comment on _commitLock_ 203 _commitLock_.Lock() 204 defer _commitLock_.Unlock() 205 if err := lgr.Commit(block); err != nil { 206 return err 207 } 208 } 209 } 210 211 return nil 212 } 213 214 // Build a chaincode. 215 func getDeploymentSpec(_ context.Context, spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) { 216 fmt.Printf("getting deployment spec for chaincode spec: %v\n", spec) 217 codePackageBytes, err := container.GetChaincodePackageBytes(spec) 218 if err != nil { 219 return nil, err 220 } 221 cdDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes} 222 return cdDeploymentSpec, nil 223 } 224 225 //getDeployLCCCSpec gets the spec for the chaincode deployment to be sent to LCCC 226 func getDeployLCCCSpec(chainID string, cds *pb.ChaincodeDeploymentSpec) (*pb.ChaincodeInvocationSpec, error) { 227 b, err := proto.Marshal(cds) 228 if err != nil { 229 return nil, err 230 } 231 232 sysCCVers := util.GetSysCCVersion() 233 234 //wrap the deployment in an invocation spec to lccc... 235 lcccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: "lccc", Version: sysCCVers}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("deploy"), []byte(chainID), b}}}} 236 237 return lcccSpec, nil 238 } 239 240 // Deploy a chaincode - i.e., build and initialize. 241 func deploy(ctx context.Context, cccid *ccprovider.CCContext, spec *pb.ChaincodeSpec, blockNumber uint64) (b []byte, err error) { 242 // First build and get the deployment spec 243 cdDeploymentSpec, err := getDeploymentSpec(ctx, spec) 244 if err != nil { 245 return nil, err 246 } 247 248 return deploy2(ctx, cccid, cdDeploymentSpec, blockNumber) 249 } 250 251 func deploy2(ctx context.Context, cccid *ccprovider.CCContext, chaincodeDeploymentSpec *pb.ChaincodeDeploymentSpec, blockNumber uint64) (b []byte, err error) { 252 cis, err := getDeployLCCCSpec(cccid.ChainID, chaincodeDeploymentSpec) 253 if err != nil { 254 return nil, fmt.Errorf("Error creating lccc spec : %s\n", err) 255 } 256 257 ctx, txsim, err := startTxSimulation(ctx, cccid.ChainID) 258 if err != nil { 259 return nil, fmt.Errorf("Failed to get handle to simulator: %s ", err) 260 } 261 262 uuid := util.GenerateUUID() 263 264 cccid.TxID = uuid 265 266 defer func() { 267 //no error, lets try commit 268 if err == nil { 269 //capture returned error from commit 270 err = endTxSimulationCDS(cccid.ChainID, uuid, txsim, []byte("deployed"), true, chaincodeDeploymentSpec, blockNumber) 271 } else { 272 //there was an error, just close simulation and return that 273 endTxSimulationCDS(cccid.ChainID, uuid, txsim, []byte("deployed"), false, chaincodeDeploymentSpec, blockNumber) 274 } 275 }() 276 277 //ignore existence errors 278 ccprovider.PutChaincodeIntoFS(chaincodeDeploymentSpec) 279 280 sysCCVers := util.GetSysCCVersion() 281 lcccid := ccprovider.NewCCContext(cccid.ChainID, cis.ChaincodeSpec.ChaincodeId.Name, sysCCVers, uuid, true, nil, nil) 282 283 //write to lccc 284 if _, _, err = ExecuteWithErrorFilter(ctx, lcccid, cis); err != nil { 285 return nil, fmt.Errorf("Error deploying chaincode: %s", err) 286 } 287 288 if b, _, err = ExecuteWithErrorFilter(ctx, cccid, chaincodeDeploymentSpec); err != nil { 289 return nil, fmt.Errorf("Error deploying chaincode: %s", err) 290 } 291 292 return b, nil 293 } 294 295 // Invoke a chaincode. 296 func invoke(ctx context.Context, chainID string, spec *pb.ChaincodeSpec, blockNumber uint64) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) { 297 return invokeWithVersion(ctx, chainID, "0", spec, blockNumber) 298 } 299 300 // Invoke a chaincode with version (needed for upgrade) 301 func invokeWithVersion(ctx context.Context, chainID string, version string, spec *pb.ChaincodeSpec, blockNumber uint64) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) { 302 cdInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 303 304 // Now create the Transactions message and send to Peer. 305 uuid = util.GenerateUUID() 306 307 var txsim ledger.TxSimulator 308 ctx, txsim, err = startTxSimulation(ctx, chainID) 309 if err != nil { 310 return nil, uuid, nil, fmt.Errorf("Failed to get handle to simulator: %s ", err) 311 } 312 313 defer func() { 314 //no error, lets try commit 315 if err == nil { 316 //capture returned error from commit 317 err = endTxSimulationCIS(chainID, uuid, txsim, []byte("invoke"), true, cdInvocationSpec, blockNumber) 318 } else { 319 //there was an error, just close simulation and return that 320 endTxSimulationCIS(chainID, uuid, txsim, []byte("invoke"), false, cdInvocationSpec, blockNumber) 321 } 322 }() 323 324 cccid := ccprovider.NewCCContext(chainID, cdInvocationSpec.ChaincodeSpec.ChaincodeId.Name, version, uuid, false, nil, nil) 325 retval, ccevt, err = ExecuteWithErrorFilter(ctx, cccid, cdInvocationSpec) 326 if err != nil { 327 return nil, uuid, nil, fmt.Errorf("Error invoking chaincode: %s", err) 328 } 329 330 return ccevt, uuid, retval, err 331 } 332 333 func closeListenerAndSleep(l net.Listener) { 334 if l != nil { 335 l.Close() 336 time.Sleep(2 * time.Second) 337 } 338 } 339 340 func executeDeployTransaction(t *testing.T, chainID string, name string, url string) { 341 lis, err := initPeer(chainID) 342 if err != nil { 343 t.Fail() 344 t.Logf("Error creating peer: %s", err) 345 } 346 347 defer finitPeer(lis, chainID) 348 349 var ctxt = context.Background() 350 351 f := "init" 352 args := util.ToChaincodeArgs(f, "a", "100", "b", "200") 353 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: name, Path: url, Version: "0"}, Input: &pb.ChaincodeInput{Args: args}} 354 355 cccid := ccprovider.NewCCContext(chainID, name, "0", "", false, nil, nil) 356 357 _, err = deploy(ctxt, cccid, spec, 0) 358 359 cID := spec.ChaincodeId.Name 360 if err != nil { 361 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 362 t.Fail() 363 t.Logf("Error deploying <%s>: %s", cID, err) 364 return 365 } 366 367 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 368 } 369 370 // chaincodeQueryChaincode function 371 func _(chainID string, _ string) error { 372 var ctxt = context.Background() 373 374 // Deploy first chaincode 375 url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 376 377 cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"} 378 f := "init" 379 args := util.ToChaincodeArgs(f, "a", "100", "b", "200") 380 381 spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}} 382 383 cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil) 384 385 var nextBlockNumber uint64 386 387 _, err := deploy(ctxt, cccid1, spec1, nextBlockNumber) 388 nextBlockNumber++ 389 390 ccID1 := spec1.ChaincodeId.Name 391 if err != nil { 392 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 393 return fmt.Errorf("Error initializing chaincode %s(%s)", ccID1, err) 394 } 395 396 time.Sleep(time.Second) 397 398 // Deploy second chaincode 399 url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example05" 400 401 cID2 := &pb.ChaincodeID{Name: "example05", Path: url2, Version: "0"} 402 f = "init" 403 args = util.ToChaincodeArgs(f, "sum", "0") 404 405 spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 406 407 cccid2 := ccprovider.NewCCContext(chainID, "example05", "0", "", false, nil, nil) 408 409 _, err = deploy(ctxt, cccid2, spec2, nextBlockNumber) 410 nextBlockNumber++ 411 ccID2 := spec2.ChaincodeId.Name 412 if err != nil { 413 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 414 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 415 return fmt.Errorf("Error initializing chaincode %s(%s)", ccID2, err) 416 } 417 418 time.Sleep(time.Second) 419 420 // Invoke second chaincode, which will inturn query the first chaincode 421 f = "invoke" 422 args = util.ToChaincodeArgs(f, ccID1, "sum") 423 424 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 425 // Invoke chaincode 426 var retVal []byte 427 _, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber) 428 nextBlockNumber++ 429 430 if err != nil { 431 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 432 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 433 return fmt.Errorf("Error invoking <%s>: %s", ccID2, err) 434 } 435 436 // Check the return value 437 result, err := strconv.Atoi(string(retVal)) 438 if err != nil || result != 300 { 439 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 440 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 441 return fmt.Errorf("Incorrect final state after transaction for <%s>: %s", ccID1, err) 442 } 443 444 // Query second chaincode, which will inturn query the first chaincode 445 f = "query" 446 args = util.ToChaincodeArgs(f, ccID1, "sum") 447 448 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 449 // Invoke chaincode 450 _, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber) 451 452 if err != nil { 453 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 454 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 455 return fmt.Errorf("Error querying <%s>: %s", ccID2, err) 456 } 457 458 // Check the return value 459 result, err = strconv.Atoi(string(retVal)) 460 if err != nil || result != 300 { 461 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 462 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 463 return fmt.Errorf("Incorrect final value after query for <%s>: %s", ccID1, err) 464 } 465 466 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 467 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 468 469 return nil 470 } 471 472 // Test deploy of a transaction 473 func TestExecuteDeployTransaction(t *testing.T) { 474 chainID := util.GetTestChainID() 475 476 executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01") 477 } 478 479 // Test deploy of a transaction with a GOPATH with multiple elements 480 func TestGopathExecuteDeployTransaction(t *testing.T) { 481 chainID := util.GetTestChainID() 482 483 // add a trailing slash to GOPATH 484 // and a couple of elements - it doesn't matter what they are 485 os.Setenv("GOPATH", os.Getenv("GOPATH")+string(os.PathSeparator)+string(os.PathListSeparator)+"/tmp/foo"+string(os.PathListSeparator)+"/tmp/bar") 486 executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01") 487 } 488 489 // Disable this temporarily. 490 // TODO: Need to enable this after update chaincode interface of chaincode repo. 491 // Test deploy of a transaction with a chaincode over HTTP. 492 //func TestHTTPExecuteDeployTransaction(t *testing.T) { 493 // chainID := util.GetTestChainID() 494 495 // // The chaincode used here cannot be from the fabric repo 496 // // itself or it won't be downloaded because it will be found 497 // // in GOPATH, which would defeat the test 498 // executeDeployTransaction(t, chainID, "example01", "http://gopkg.in/mastersingh24/fabric-test-resources.v1") 499 //} 500 501 // Check the correctness of the final state after transaction execution. 502 func checkFinalState(cccid *ccprovider.CCContext) error { 503 _, txsim, err := startTxSimulation(context.Background(), cccid.ChainID) 504 if err != nil { 505 return fmt.Errorf("Failed to get handle to simulator: %s ", err) 506 } 507 508 defer txsim.Done() 509 510 cName := cccid.GetCanonicalName() 511 512 // Invoke ledger to get state 513 var Aval, Bval int 514 resbytes, resErr := txsim.GetState(cccid.Name, "a") 515 if resErr != nil { 516 return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr) 517 } 518 fmt.Printf("Got string: %s\n", string(resbytes)) 519 Aval, resErr = strconv.Atoi(string(resbytes)) 520 if resErr != nil { 521 return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr) 522 } 523 if Aval != 90 { 524 return fmt.Errorf("Incorrect result. Aval %d != 90 <%s>", Aval, cName) 525 } 526 527 resbytes, resErr = txsim.GetState(cccid.Name, "b") 528 if resErr != nil { 529 return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr) 530 } 531 Bval, resErr = strconv.Atoi(string(resbytes)) 532 if resErr != nil { 533 return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr) 534 } 535 if Bval != 210 { 536 return fmt.Errorf("Incorrect result. Bval %d != 210 <%s>", Bval, cName) 537 } 538 539 // Success 540 fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) 541 return nil 542 } 543 544 // Invoke chaincode_example02 545 func invokeExample02Transaction(ctxt context.Context, cccid *ccprovider.CCContext, cID *pb.ChaincodeID, args []string, destroyImage bool) error { 546 547 var nextBlockNumber uint64 548 549 f := "init" 550 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 551 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: argsDeploy}} 552 _, err := deploy(ctxt, cccid, spec, nextBlockNumber) 553 nextBlockNumber++ 554 ccID := spec.ChaincodeId.Name 555 if err != nil { 556 return fmt.Errorf("Error deploying <%s>: %s", ccID, err) 557 } 558 559 time.Sleep(time.Second) 560 561 if destroyImage { 562 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 563 dir := container.DestroyImageReq{CCID: ccintf.CCID{ChaincodeSpec: spec, NetworkID: theChaincodeSupport.peerNetworkID, PeerID: theChaincodeSupport.peerID, ChainID: cccid.ChainID}, Force: true, NoPrune: true} 564 565 _, err = container.VMCProcess(ctxt, container.DOCKER, dir) 566 if err != nil { 567 err = fmt.Errorf("Error destroying image: %s", err) 568 return err 569 } 570 } 571 572 f = "invoke" 573 invokeArgs := append([]string{f}, args...) 574 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 575 _, uuid, _, err := invoke(ctxt, cccid.ChainID, spec, nextBlockNumber) 576 nextBlockNumber++ 577 if err != nil { 578 return fmt.Errorf("Error invoking <%s>: %s", cccid.Name, err) 579 } 580 581 cccid.TxID = uuid 582 err = checkFinalState(cccid) 583 if err != nil { 584 return fmt.Errorf("Incorrect final state after transaction for <%s>: %s", ccID, err) 585 } 586 587 // Test for delete state 588 f = "delete" 589 delArgs := util.ToChaincodeArgs(f, "a") 590 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: delArgs}} 591 _, _, _, err = invoke(ctxt, cccid.ChainID, spec, nextBlockNumber) 592 if err != nil { 593 return fmt.Errorf("Error deleting state in <%s>: %s", cccid.Name, err) 594 } 595 596 return nil 597 } 598 599 func TestExecuteInvokeTransaction(t *testing.T) { 600 chainID := util.GetTestChainID() 601 602 lis, err := initPeer(chainID) 603 if err != nil { 604 t.Fail() 605 t.Logf("Error creating peer: %s", err) 606 } 607 608 defer finitPeer(lis, chainID) 609 610 var ctxt = context.Background() 611 612 cccid := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil) 613 url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 614 ccID := &pb.ChaincodeID{Name: "example02", Path: url, Version: "0"} 615 616 args := []string{"a", "b", "10"} 617 err = invokeExample02Transaction(ctxt, cccid, ccID, args, true) 618 if err != nil { 619 t.Fail() 620 t.Logf("Error invoking transaction: %s", err) 621 } else { 622 fmt.Print("Invoke test passed\n") 623 t.Log("Invoke test passed") 624 } 625 626 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}}) 627 } 628 629 // Test the execution of an invalid transaction. 630 func TestExecuteInvokeInvalidTransaction(t *testing.T) { 631 chainID := util.GetTestChainID() 632 633 lis, err := initPeer(chainID) 634 if err != nil { 635 t.Fail() 636 t.Logf("Error creating peer: %s", err) 637 } 638 639 defer finitPeer(lis, chainID) 640 641 var ctxt = context.Background() 642 643 url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 644 ccID := &pb.ChaincodeID{Name: "example02", Path: url, Version: "0"} 645 646 cccid := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil) 647 648 //FAIL, FAIL! 649 args := []string{"x", "-1"} 650 err = invokeExample02Transaction(ctxt, cccid, ccID, args, false) 651 652 //this HAS to fail with expectedDeltaStringPrefix 653 if err != nil { 654 errStr := err.Error() 655 t.Logf("Got error %s\n", errStr) 656 t.Log("InvalidInvoke test passed") 657 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}}) 658 659 return 660 } 661 662 t.Fail() 663 t.Logf("Error invoking transaction %s", err) 664 665 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}}) 666 } 667 668 // Test the execution of a chaincode that invokes another chaincode. 669 func TestChaincodeInvokeChaincode(t *testing.T) { 670 chainID := util.GetTestChainID() 671 672 lis, err := initPeer(chainID) 673 if err != nil { 674 t.Fail() 675 t.Logf("Error creating peer: %s", err) 676 } 677 678 defer finitPeer(lis, chainID) 679 680 err = runChaincodeInvokeChaincode(t, chainID, "") 681 if err != nil { 682 t.Fail() 683 t.Logf("Failed chaincode invoke chaincode : %s", err) 684 closeListenerAndSleep(lis) 685 return 686 } 687 688 closeListenerAndSleep(lis) 689 } 690 691 func runChaincodeInvokeChaincode(t *testing.T, chainID string, _ string) (err error) { 692 var ctxt = context.Background() 693 694 // Deploy first chaincode 695 url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 696 697 cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"} 698 f := "init" 699 args := util.ToChaincodeArgs(f, "a", "100", "b", "200") 700 701 spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}} 702 703 cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil) 704 705 var nextBlockNumber uint64 706 707 _, err = deploy(ctxt, cccid1, spec1, nextBlockNumber) 708 nextBlockNumber++ 709 ccID1 := spec1.ChaincodeId.Name 710 if err != nil { 711 t.Fail() 712 t.Logf("Error initializing chaincode %s(%s)", ccID1, err) 713 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 714 return 715 } 716 717 t.Logf("deployed chaincode_example02 got cID1:% s,\n ccID1:% s", cID1, ccID1) 718 719 time.Sleep(time.Second) 720 721 // Deploy second chaincode 722 url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example04" 723 724 cID2 := &pb.ChaincodeID{Name: "example04", Path: url2, Version: "0"} 725 f = "init" 726 args = util.ToChaincodeArgs(f, "e", "0") 727 728 spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 729 730 cccid2 := ccprovider.NewCCContext(chainID, "example04", "0", "", false, nil, nil) 731 732 _, err = deploy(ctxt, cccid2, spec2, nextBlockNumber) 733 nextBlockNumber++ 734 ccID2 := spec2.ChaincodeId.Name 735 if err != nil { 736 t.Fail() 737 t.Logf("Error initializing chaincode %s(%s)", ccID2, err) 738 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 739 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 740 return 741 } 742 743 time.Sleep(time.Second) 744 745 // Invoke second chaincode passing the first chaincode's name as first param, 746 // which will inturn invoke the first chaincode 747 f = "invoke" 748 cid := spec1.ChaincodeId.Name 749 args = util.ToChaincodeArgs(f, cid, "e", "1") 750 751 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 752 // Invoke chaincode 753 var uuid string 754 _, uuid, _, err = invoke(ctxt, chainID, spec2, nextBlockNumber) 755 756 if err != nil { 757 t.Fail() 758 t.Logf("Error invoking <%s>: %s", ccID2, err) 759 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 760 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 761 return 762 } 763 764 cccid1.TxID = uuid 765 766 // Check the state in the ledger 767 err = checkFinalState(cccid1) 768 if err != nil { 769 t.Fail() 770 t.Logf("Incorrect final state after transaction for <%s>: %s", ccID1, err) 771 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 772 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 773 return 774 } 775 776 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 777 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 778 779 return 780 } 781 782 // Test the execution of a chaincode that invokes another chaincode with wrong parameters. Should receive error from 783 // from the called chaincode 784 func TestChaincodeInvokeChaincodeErrorCase(t *testing.T) { 785 chainID := util.GetTestChainID() 786 787 lis, err := initPeer(chainID) 788 if err != nil { 789 t.Fail() 790 t.Logf("Error creating peer: %s", err) 791 } 792 793 defer finitPeer(lis, chainID) 794 795 var ctxt = context.Background() 796 797 // Deploy first chaincode 798 url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 799 800 cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"} 801 f := "init" 802 args := util.ToChaincodeArgs(f, "a", "100", "b", "200") 803 804 spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}} 805 806 cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil) 807 808 var nextBlockNumber uint64 809 810 _, err = deploy(ctxt, cccid1, spec1, nextBlockNumber) 811 nextBlockNumber++ 812 ccID1 := spec1.ChaincodeId.Name 813 if err != nil { 814 t.Fail() 815 t.Logf("Error initializing chaincode %s(%s)", ccID1, err) 816 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 817 return 818 } 819 820 time.Sleep(time.Second) 821 822 // Deploy second chaincode 823 url2 := "github.com/hyperledger/fabric/examples/chaincode/go/passthru" 824 825 cID2 := &pb.ChaincodeID{Name: "pthru", Path: url2, Version: "0"} 826 f = "init" 827 args = util.ToChaincodeArgs(f) 828 829 spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 830 831 cccid2 := ccprovider.NewCCContext(chainID, "pthru", "0", "", false, nil, nil) 832 833 _, err = deploy(ctxt, cccid2, spec2, nextBlockNumber) 834 nextBlockNumber++ 835 ccID2 := spec2.ChaincodeId.Name 836 if err != nil { 837 t.Fail() 838 t.Logf("Error initializing chaincode %s(%s)", ccID2, err) 839 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 840 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 841 return 842 } 843 844 time.Sleep(time.Second) 845 846 // Invoke second chaincode, which will inturn invoke the first chaincode but pass bad params 847 f = ccID1 848 args = util.ToChaincodeArgs(f, "invoke", "a") 849 850 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 851 // Invoke chaincode 852 _, _, _, err = invoke(ctxt, chainID, spec2, nextBlockNumber) 853 854 if err == nil { 855 t.Fail() 856 t.Logf("Error invoking <%s>: %s", ccID2, err) 857 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 858 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 859 return 860 } 861 862 if strings.Index(err.Error(), "Error invoking chaincode: Incorrect number of arguments. Expecting 3") < 0 { 863 t.Fail() 864 t.Logf("Unexpected error %s", err) 865 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 866 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 867 return 868 } 869 870 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 871 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 872 } 873 874 // Test the invocation of a transaction. 875 func TestQueries(t *testing.T) { 876 877 chainID := util.GetTestChainID() 878 879 lis, err := initPeer(chainID) 880 if err != nil { 881 t.Fail() 882 t.Logf("Error creating peer: %s", err) 883 } 884 885 defer finitPeer(lis, chainID) 886 887 var ctxt = context.Background() 888 889 url := "github.com/hyperledger/fabric/examples/chaincode/go/map" 890 cID := &pb.ChaincodeID{Name: "tmap", Path: url, Version: "0"} 891 892 f := "init" 893 args := util.ToChaincodeArgs(f) 894 895 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 896 897 cccid := ccprovider.NewCCContext(chainID, "tmap", "0", "", false, nil, nil) 898 899 var nextBlockNumber uint64 900 _, err = deploy(ctxt, cccid, spec, nextBlockNumber) 901 nextBlockNumber++ 902 ccID := spec.ChaincodeId.Name 903 if err != nil { 904 t.Fail() 905 t.Logf("Error initializing chaincode %s(%s)", ccID, err) 906 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 907 return 908 } 909 910 // Invoke second chaincode, which will inturn invoke the first chaincode 911 f = "put" 912 args = util.ToChaincodeArgs(f, "key1", "{\"shipmentID\":\"161003PKC7300\",\"customsInvoice\":{\"methodOfTransport\":\"GROUND\",\"invoiceNumber\":\"00091622\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}") 913 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 914 _, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber) 915 nextBlockNumber++ 916 917 if err != nil { 918 t.Fail() 919 t.Logf("Error invoking <%s>: %s", ccID, err) 920 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 921 return 922 } 923 924 f = "put" 925 args = util.ToChaincodeArgs(f, "key2", "{\"shipmentID\":\"161003PKC7300\",\"customsInvoice\":{\"methodOfTransport\":\"GROUND\",\"invoiceNumber\":\"00091622\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}") 926 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 927 _, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber) 928 nextBlockNumber++ 929 930 if err != nil { 931 t.Fail() 932 t.Logf("Error invoking <%s>: %s", ccID, err) 933 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 934 return 935 } 936 937 f = "put" 938 args = util.ToChaincodeArgs(f, "key3", "{\"shipmentID\":\"161003PKC7300\",\"customsInvoice\":{\"methodOfTransport\":\"GROUND\",\"invoiceNumber\":\"00091622\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}") 939 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 940 _, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber) 941 nextBlockNumber++ 942 if err != nil { 943 t.Fail() 944 t.Logf("Error invoking <%s>: %s", ccID, err) 945 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 946 return 947 } 948 949 f = "keys" 950 args = util.ToChaincodeArgs(f, "key0", "key3") 951 952 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 953 _, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber) 954 nextBlockNumber++ 955 if err != nil { 956 t.Fail() 957 t.Logf("Error invoking <%s>: %s", ccID, err) 958 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 959 return 960 } 961 962 if ledgerconfig.IsCouchDBEnabled() == true { 963 f = "query" 964 args = util.ToChaincodeArgs(f, "{\"selector\":{\"currency\":\"USD\"}}") 965 966 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 967 _, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber) 968 if err != nil { 969 t.Fail() 970 t.Logf("Error invoking <%s>: %s", ccID, err) 971 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 972 return 973 } 974 } 975 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 976 } 977 978 func TestGetEvent(t *testing.T) { 979 chainID := util.GetTestChainID() 980 981 lis, err := initPeer(chainID) 982 if err != nil { 983 t.Fail() 984 t.Logf("Error creating peer: %s", err) 985 } 986 987 defer finitPeer(lis, chainID) 988 989 var ctxt = context.Background() 990 991 url := "github.com/hyperledger/fabric/examples/chaincode/go/eventsender" 992 993 cID := &pb.ChaincodeID{Name: "esender", Path: url, Version: "0"} 994 f := "init" 995 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(f)}} 996 997 cccid := ccprovider.NewCCContext(chainID, "esender", "0", "", false, nil, nil) 998 var nextBlockNumber uint64 999 _, err = deploy(ctxt, cccid, spec, nextBlockNumber) 1000 nextBlockNumber++ 1001 ccID := spec.ChaincodeId.Name 1002 if err != nil { 1003 t.Fail() 1004 t.Logf("Error initializing chaincode %s(%s)", ccID, err) 1005 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1006 return 1007 } 1008 1009 time.Sleep(time.Second) 1010 1011 args := util.ToChaincodeArgs("invoke", "i", "am", "satoshi") 1012 1013 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1014 1015 var ccevt *pb.ChaincodeEvent 1016 ccevt, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber) 1017 1018 if err != nil { 1019 t.Logf("Error invoking chaincode %s(%s)", ccID, err) 1020 t.Fail() 1021 } 1022 1023 if ccevt == nil { 1024 t.Logf("Error ccevt is nil %s(%s)", ccID, err) 1025 t.Fail() 1026 } 1027 1028 if ccevt.ChaincodeId != ccID { 1029 t.Logf("Error ccevt id(%s) != cid(%s)", ccevt.ChaincodeId, ccID) 1030 t.Fail() 1031 } 1032 1033 if strings.Index(string(ccevt.Payload), "i,am,satoshi") < 0 { 1034 t.Logf("Error expected event not found (%s)", string(ccevt.Payload)) 1035 t.Fail() 1036 } 1037 1038 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1039 } 1040 1041 // Test the execution of a chaincode that queries another chaincode 1042 // example02 implements "query" as a function in Invoke. example05 calls example02 1043 func TestChaincodeQueryChaincodeUsingInvoke(t *testing.T) { 1044 chainID := util.GetTestChainID() 1045 1046 var peerLis net.Listener 1047 var err error 1048 if peerLis, err = initPeer(chainID); err != nil { 1049 t.Fail() 1050 t.Logf("Error registering user %s", err) 1051 return 1052 } 1053 1054 defer finitPeer(peerLis, chainID) 1055 1056 var ctxt = context.Background() 1057 1058 // Deploy first chaincode 1059 url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 1060 1061 cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"} 1062 f := "init" 1063 args := util.ToChaincodeArgs(f, "a", "100", "b", "200") 1064 1065 spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}} 1066 1067 cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil) 1068 var nextBlockNumber uint64 1069 _, err = deploy(ctxt, cccid1, spec1, nextBlockNumber) 1070 nextBlockNumber++ 1071 ccID1 := spec1.ChaincodeId.Name 1072 if err != nil { 1073 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1074 t.Fail() 1075 t.Logf("Error initializing chaincode %s(%s)", ccID1, err) 1076 return 1077 } 1078 1079 time.Sleep(time.Second) 1080 1081 // Deploy second chaincode 1082 url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example05" 1083 1084 cID2 := &pb.ChaincodeID{Name: "example05", Path: url2, Version: "0"} 1085 f = "init" 1086 args = util.ToChaincodeArgs(f, "sum", "0") 1087 1088 spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 1089 1090 cccid2 := ccprovider.NewCCContext(chainID, "example05", "0", "", false, nil, nil) 1091 1092 _, err = deploy(ctxt, cccid2, spec2, nextBlockNumber) 1093 nextBlockNumber++ 1094 ccID2 := spec2.ChaincodeId.Name 1095 if err != nil { 1096 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1097 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1098 t.Fail() 1099 t.Logf("Error initializing chaincode %s(%s)", ccID2, err) 1100 return 1101 } 1102 1103 time.Sleep(time.Second) 1104 1105 // Invoke second chaincode, which will inturn query the first chaincode 1106 f = "invoke" 1107 args = util.ToChaincodeArgs(f, ccID1, "sum") 1108 1109 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 1110 // Invoke chaincode 1111 var retVal []byte 1112 _, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber) 1113 nextBlockNumber++ 1114 if err != nil { 1115 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1116 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1117 t.Fail() 1118 t.Logf("Error invoking <%s>: %s", ccID2, err) 1119 return 1120 } 1121 1122 // Check the return value 1123 result, err := strconv.Atoi(string(retVal)) 1124 if err != nil || result != 300 { 1125 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1126 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1127 t.Fail() 1128 t.Logf("Incorrect final state after transaction for <%s>: %s", ccID1, err) 1129 return 1130 } 1131 1132 // Query second chaincode, which will inturn query the first chaincode 1133 f = "query" 1134 args = util.ToChaincodeArgs(f, ccID1, "sum") 1135 1136 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 1137 // Invoke chaincode 1138 _, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber) 1139 1140 if err != nil { 1141 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1142 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1143 t.Fail() 1144 t.Logf("Error querying <%s>: %s", ccID2, err) 1145 return 1146 } 1147 1148 // Check the return value 1149 result, err = strconv.Atoi(string(retVal)) 1150 if err != nil || result != 300 { 1151 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1152 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1153 t.Fail() 1154 t.Logf("Incorrect final value after query for <%s>: %s", ccID1, err) 1155 return 1156 } 1157 1158 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1159 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1160 } 1161 1162 var signer msp.SigningIdentity 1163 1164 func TestMain(m *testing.M) { 1165 var err error 1166 1167 // setup the MSP manager so that we can sign/verify 1168 mspMgrConfigDir := "../../msp/sampleconfig/" 1169 msptesttools.LoadMSPSetupForTesting(mspMgrConfigDir) 1170 signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity() 1171 if err != nil { 1172 os.Exit(-1) 1173 fmt.Print("Could not initialize msp/signer") 1174 return 1175 } 1176 1177 SetupTestConfig() 1178 os.Exit(m.Run()) 1179 }