diff --git a/core/chaincode/concurrency_test.go b/core/chaincode/concurrency_test.go deleted file mode 100644 index 5a2b8ea7318..00000000000 --- a/core/chaincode/concurrency_test.go +++ /dev/null @@ -1,145 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package chaincode - -import ( - "fmt" - "sync" - "testing" - - "github.com/hyperledger/fabric/common/util" - "github.com/hyperledger/fabric/core/common/ccprovider" - pb "github.com/hyperledger/fabric/protos/peer" - - "golang.org/x/net/context" -) - -//TestExecuteConcurrentInvokes deploys newkeyperinvoke and runs 100 concurrent invokes -//followed by concurrent 100 queries to validate -func TestExecuteConcurrentInvokes(t *testing.T) { - //this test fails occasionally. FAB-1600 is opened to track this issue - //skip meanwhile so as to not block CI - - t.Skip() - chainID := util.GetTestChainID() - - _, chaincodeSupport, cleanup, err := initPeer(chainID) - if err != nil { - t.Fail() - t.Logf("Error creating peer: %s", err) - } - - defer cleanup() - - var ctxt = context.Background() - - url := "github.com/hyperledger/fabric/examples/ccchecker/chaincodes/newkeyperinvoke" - - chaincodeID := &pb.ChaincodeID{Name: "nkpi", Path: url, Version: "0"} - - args := util.ToChaincodeArgs("init", "") - - spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}} - - cccid := ccprovider.NewCCContext(chainID, "nkpi", "0", "", false, nil, nil) - - ccci := &ccprovider.ChaincodeContainerInfo{ - Type: "GOLANG", - Name: "nkpi", - Version: "0", - Path: url, - ContainerType: "DOCKER", - } - defer chaincodeSupport.Stop(ccci) - - var nextBlockNumber uint64 - _, err = deploy(ctxt, cccid, spec, nextBlockNumber, chaincodeSupport) - nextBlockNumber++ - if err != nil { - t.Fail() - t.Logf("Error initializing chaincode %s(%s)", chaincodeID, err) - return - } - - var wg sync.WaitGroup - - //run 100 invokes in parallel - numTrans := 100 - - results := make([][]byte, numTrans) - errs := make([]error, numTrans) - - e := func(inv bool, qnum int) { - defer wg.Done() - - newkey := fmt.Sprintf("%d", qnum) - - var args [][]byte - if inv { - args = util.ToChaincodeArgs("put", newkey, newkey) - } else { - args = util.ToChaincodeArgs("get", newkey) - } - - spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}} - - //start with a new background - _, _, results[qnum], err = invoke(context.Background(), chainID, spec, nextBlockNumber, nil, chaincodeSupport) - - if err != nil { - errs[qnum] = fmt.Errorf("Error executing <%s>: %s", chaincodeID.Name, err) - return - } - } - - wg.Add(numTrans) - - //execute transactions concurrently. - for i := 0; i < numTrans; i++ { - go e(true, i) - } - - wg.Wait() - - for i := 0; i < numTrans; i++ { - if errs[i] != nil { - t.Fail() - t.Logf("Error invoking chaincode iter %d %s(%s)", i, chaincodeID.Name, errs[i]) - } - if results[i] == nil || string(results[i]) != "OK" { - t.Fail() - t.Logf("Error concurrent invoke %d %s", i, chaincodeID.Name) - return - } - } - - wg.Add(numTrans) - - //execute queries concurrently. - for i := 0; i < numTrans; i++ { - go e(false, i) - } - - wg.Wait() - - for i := 0; i < numTrans; i++ { - if errs[i] != nil { - t.Fail() - t.Logf("Error querying chaincode iter %d %s(%s)", i, chaincodeID.Name, errs[i]) - return - } - if results[i] == nil || string(results[i]) != fmt.Sprintf("%d", i) { - t.Fail() - if results[i] == nil { - t.Logf("Error concurrent query %d(%s)", i, chaincodeID.Name) - } else { - t.Logf("Error concurrent query %d(%s, %s, %v)", i, chaincodeID.Name, string(results[i]), results[i]) - } - return - } - } -} diff --git a/core/chaincode/exectransaction_test.go b/core/chaincode/exectransaction_test.go index 96022418104..e4c11a31bb2 100644 --- a/core/chaincode/exectransaction_test.go +++ b/core/chaincode/exectransaction_test.go @@ -68,15 +68,6 @@ import ( "google.golang.org/grpc/credentials" ) -var runTests bool - -func testForSkip(t *testing.T) { - //run tests - if !runTests { - t.SkipNow() - } -} - //initialize peer and start up. If security==enabled, login as vp func initPeer(chainIDs ...string) (net.Listener, *ChaincodeSupport, func(), error) { //start clean @@ -800,127 +791,7 @@ func runChaincodeInvokeChaincode(t *testing.T, channel1 string, channel2 string, return nextBlockNumber1, nextBlockNumber2 } -// Test deploy of a transaction -func TestExecuteDeployTransaction(t *testing.T) { - //chaincoe is deployed as part of many tests. No need for a separate one for this - t.Skip() - chainID := util.GetTestChainID() - - executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01") -} - -// Test deploy of a transaction with a GOPATH with multiple elements -func TestGopathExecuteDeployTransaction(t *testing.T) { - //this is no longer critical as chaincode is assembled in the client side (SDK) - t.Skip() - chainID := util.GetTestChainID() - - // add a trailing slash to GOPATH - // and a couple of elements - it doesn't matter what they are - os.Setenv("GOPATH", os.Getenv("GOPATH")+string(os.PathSeparator)+string(os.PathListSeparator)+"/tmp/foo"+string(os.PathListSeparator)+"/tmp/bar") - executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01") -} - -func TestExecuteInvokeTransaction(t *testing.T) { - testForSkip(t) - - testCases := []struct { - chaincodeType pb.ChaincodeSpec_Type - chaincodePath string - }{ - {pb.ChaincodeSpec_GOLANG, chaincodeExample02GolangPath}, - {pb.ChaincodeSpec_JAVA, chaincodeExample02JavaPath}, - } - - for _, tc := range testCases { - t.Run(tc.chaincodeType.String(), func(t *testing.T) { - - if tc.chaincodeType == pb.ChaincodeSpec_JAVA && runtime.GOARCH != "amd64" { - t.Skip("No Java chaincode support yet on non-amd64.") - } - - chainID := util.GetTestChainID() - - _, chaincodeSupport, cleanup, err := initPeer(chainID) - if err != nil { - t.Fail() - t.Logf("Error creating peer: %s", err) - } - - var ctxt = context.Background() - chaincodeName := generateChaincodeName(tc.chaincodeType) - chaincodeVersion := "1.0.0.0" - cccid := ccprovider.NewCCContext(chainID, chaincodeName, chaincodeVersion, "", false, nil, nil) - ccID := &pb.ChaincodeID{Name: chaincodeName, Path: tc.chaincodePath, Version: chaincodeVersion} - - args := []string{"a", "b", "10"} - err = invokeExample02Transaction(ctxt, cccid, ccID, tc.chaincodeType, args, chaincodeSupport) - if err != nil { - t.Fail() - t.Logf("Error invoking transaction: %s", err) - } else { - fmt.Print("Invoke test passed\n") - t.Log("Invoke test passed") - } - - chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: ccID.Name, - Path: ccID.Path, - Version: cccid.Version, - ContainerType: "DOCKER", - Type: "GOLANG", - }) - cleanup() - }) - } - -} - // Test the execution of an invalid transaction. -func TestExecuteInvokeInvalidTransaction(t *testing.T) { - testForSkip(t) - - chainID := util.GetTestChainID() - - _, chaincodeSupport, cleanup, err := initPeer(chainID) - if err != nil { - t.Fail() - t.Logf("Error creating peer: %s", err) - } - - defer cleanup() - - var ctxt = context.Background() - - url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" - ccID := &pb.ChaincodeID{Name: "example02", Path: url, Version: "0"} - - cccid := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil) - - defer chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: ccID.Name, - Version: cccid.Version, - Path: ccID.Path, - ContainerType: "DOCKER", - Type: "GOLANG", - }) - - //FAIL, FAIL! - args := []string{"x", "-1"} - err = invokeExample02Transaction(ctxt, cccid, ccID, pb.ChaincodeSpec_GOLANG, args, chaincodeSupport) - - //this HAS to fail with expectedDeltaStringPrefix - if err != nil { - errStr := err.Error() - t.Logf("Got error %s\n", errStr) - t.Log("InvalidInvoke test passed") - return - } - - t.Fail() - t.Logf("Error invoking transaction %s", err) -} - // testcase parameters for TestChaincodeInvokeChaincode type tcicTc struct { chaincodeType pb.ChaincodeSpec_Type @@ -1430,399 +1301,6 @@ func TestQueries(t *testing.T) { } } -func TestGetEvent(t *testing.T) { - testForSkip(t) - testCases := []struct { - chaincodeType pb.ChaincodeSpec_Type - chaincodePath string - }{ - {pb.ChaincodeSpec_GOLANG, chaincodeEventSenderGolangPath}, - {pb.ChaincodeSpec_JAVA, chaincodeEventSenderJavaPath}, - } - - chainID := util.GetTestChainID() - var nextBlockNumber uint64 - - _, chaincodeSupport, cleanup, err := initPeer(chainID) - if err != nil { - t.Fail() - t.Logf("Error creating peer: %s", err) - } - - nextBlockNumber++ - - defer cleanup() - - for _, tc := range testCases { - t.Run(tc.chaincodeType.String(), func(t *testing.T) { - - if tc.chaincodeType == pb.ChaincodeSpec_JAVA && runtime.GOARCH != "amd64" { - t.Skip("No Java chaincode support yet on non-amd64.") - } - - var ctxt = context.Background() - - cID := &pb.ChaincodeID{Name: generateChaincodeName(tc.chaincodeType), Path: tc.chaincodePath, Version: "0"} - f := "init" - spec := &pb.ChaincodeSpec{Type: tc.chaincodeType, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(f)}} - - cccid := ccprovider.NewCCContext(chainID, cID.Name, cID.Version, "", false, nil, nil) - defer chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: cID.Name, - Version: cID.Version, - Path: tc.chaincodePath, - Type: "GOLANG", - ContainerType: "DOCKER", - }) - _, err = deploy(ctxt, cccid, spec, nextBlockNumber, chaincodeSupport) - nextBlockNumber++ - ccID := spec.ChaincodeId.Name - if err != nil { - t.Fail() - t.Logf("Error initializing chaincode %s(%s)", ccID, err) - return - } - - time.Sleep(time.Second) - - args := util.ToChaincodeArgs("invoke", "i", "am", "satoshi") - - spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} - - var ccevt *pb.ChaincodeEvent - ccevt, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil, chaincodeSupport) - nextBlockNumber++ - - if err != nil { - t.Logf("Error invoking chaincode %s(%s)", ccID, err) - t.Fail() - } - - if ccevt == nil { - t.Logf("Error ccevt is nil %s(%s)", ccID, err) - t.Fail() - } - - if ccevt.ChaincodeId != ccID { - t.Logf("Error ccevt id(%s) != cid(%s)", ccevt.ChaincodeId, ccID) - t.Fail() - } - - if strings.Index(string(ccevt.Payload), "i,am,satoshi") < 0 { - t.Logf("Error expected event not found (%s)", string(ccevt.Payload)) - t.Fail() - } - }) - } - -} - -// Test the execution of a chaincode that queries another chaincode -// example02 implements "query" as a function in Invoke. example05 calls example02 -func TestChaincodeQueryChaincodeUsingInvoke(t *testing.T) { - testForSkip(t) - //this is essentially same as the ChaincodeInvokeChaincode now that - //we don't distinguish between Invoke and Query (there's no separate "Query") - t.Skip() - chainID := util.GetTestChainID() - - _, chaincodeSupport, cleanup, err := initPeer(chainID) - if err != nil { - t.Fail() - t.Logf("Error registering user %s", err) - return - } - - defer cleanup() - - var ctxt = context.Background() - - // Deploy first chaincode - url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" - - cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"} - f := "init" - args := util.ToChaincodeArgs(f, "a", "100", "b", "200") - - spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}} - - sProp, prop := putils.MockSignedEndorserProposalOrPanic(util.GetTestChainID(), spec1, []byte([]byte("Alice")), nil) - cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, sProp, prop) - var nextBlockNumber uint64 - defer chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: cID1.Name, - Version: cID1.Version, - Path: cID1.Path, - Type: "GOLANG", - ContainerType: "DOCKER", - }) - _, err = deploy(ctxt, cccid1, spec1, nextBlockNumber, chaincodeSupport) - nextBlockNumber++ - ccID1 := spec1.ChaincodeId.Name - if err != nil { - t.Fail() - t.Logf("Error initializing chaincode %s(%s)", ccID1, err) - return - } - - time.Sleep(time.Second) - - // Deploy second chaincode - url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example05" - - cID2 := &pb.ChaincodeID{Name: "example05", Path: url2, Version: "0"} - f = "init" - args = util.ToChaincodeArgs(f, "sum", "0") - - spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} - - cccid2 := ccprovider.NewCCContext(chainID, "example05", "0", "", false, sProp, prop) - - defer chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: cID2.Name, - Version: cID2.Version, - Path: cID2.Path, - Type: "GOLANG", - ContainerType: "DOCKER", - }) - _, err = deploy(ctxt, cccid2, spec2, nextBlockNumber, chaincodeSupport) - nextBlockNumber++ - ccID2 := spec2.ChaincodeId.Name - if err != nil { - t.Fail() - t.Logf("Error initializing chaincode %s(%s)", ccID2, err) - return - } - - time.Sleep(time.Second) - - // Invoke second chaincode, which will inturn query the first chaincode - f = "invoke" - args = util.ToChaincodeArgs(f, ccID1, "sum") - - spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} - // Invoke chaincode - var retVal []byte - _, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber, []byte("Alice"), chaincodeSupport) - nextBlockNumber++ - if err != nil { - t.Fail() - t.Logf("Error invoking <%s>: %s", ccID2, err) - return - } - - // Check the return value - result, err := strconv.Atoi(string(retVal)) - if err != nil || result != 300 { - t.Fail() - t.Logf("Incorrect final state after transaction for <%s>: %s", ccID1, err) - return - } - - // Query second chaincode, which will inturn query the first chaincode - f = "query" - args = util.ToChaincodeArgs(f, ccID1, "sum") - - spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} - // Invoke chaincode - _, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber, []byte("Alice"), chaincodeSupport) - - if err != nil { - t.Fail() - t.Logf("Error querying <%s>: %s", ccID2, err) - return - } - - // Check the return value - result, err = strconv.Atoi(string(retVal)) - if err != nil || result != 300 { - t.Fail() - t.Logf("Incorrect final value after query for <%s>: %s", ccID1, err) - return - } -} - -// test that invoking a security-sensitive system chaincode fails -func TestChaincodeInvokesForbiddenSystemChaincode(t *testing.T) { - testForSkip(t) - chainID := util.GetTestChainID() - - _, chaincodeSupport, cleanup, err := initPeer(chainID) - if err != nil { - t.Fail() - t.Logf("Error creating peer: %s", err) - } - - defer cleanup() - - var ctxt = context.Background() - - var nextBlockNumber uint64 = 1 - - // Deploy second chaincode - url := "github.com/hyperledger/fabric/examples/chaincode/go/passthru" - - cID := &pb.ChaincodeID{Name: "pthru", Path: url, Version: "0"} - f := "init" - args := util.ToChaincodeArgs(f) - - spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} - - cccid := ccprovider.NewCCContext(chainID, "pthru", "0", "", false, nil, nil) - - defer chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: cID.Name, - Version: cID.Version, - Path: cID.Path, - Type: "GOLANG", - ContainerType: "DOCKER", - }) - _, err = deploy(ctxt, cccid, spec, nextBlockNumber, chaincodeSupport) - nextBlockNumber++ - ccID := spec.ChaincodeId.Name - if err != nil { - t.Fail() - t.Logf("Error initializing chaincode %s(%s)", ccID, err) - return - } - - time.Sleep(time.Second) - - // send an invoke to pass thru to invoke "escc" system chaincode - // this should fail - args = util.ToChaincodeArgs("escc/"+chainID, "getid", chainID, "pthru") - - spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} - // Invoke chaincode - _, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil, chaincodeSupport) - if err == nil { - t.Logf("invoking <%s> should have failed", ccID) - t.Fail() - return - } -} - -// Test the execution of a chaincode that invokes system chaincode -// uses the "pthru" chaincode to query "lscc" for the "pthru" chaincode -func TestChaincodeInvokesSystemChaincode(t *testing.T) { - testForSkip(t) - chainID := util.GetTestChainID() - - _, chaincodeSupport, cleanup, err := initPeer(chainID) - if err != nil { - t.Fail() - t.Logf("Error creating peer: %s", err) - } - - defer cleanup() - - var ctxt = context.Background() - - var nextBlockNumber uint64 = 1 - - // Deploy second chaincode - url := "github.com/hyperledger/fabric/examples/chaincode/go/passthru" - - cID := &pb.ChaincodeID{Name: "pthru", Path: url, Version: "0"} - f := "init" - args := util.ToChaincodeArgs(f) - - spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} - - cccid := ccprovider.NewCCContext(chainID, "pthru", "0", "", false, nil, nil) - - defer chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: cID.Name, - Version: cID.Version, - Path: cID.Path, - Type: "GOLANG", - ContainerType: "DOCKER", - }) - _, err = deploy(ctxt, cccid, spec, nextBlockNumber, chaincodeSupport) - nextBlockNumber++ - ccID := spec.ChaincodeId.Name - if err != nil { - t.Fail() - t.Logf("Error initializing chaincode %s(%s)", ccID, err) - return - } - - time.Sleep(time.Second) - - //send an invoke to pass thru to query "lscc" system chaincode on chainID to get - //information about "pthru" - args = util.ToChaincodeArgs("lscc/"+chainID, "getid", chainID, "pthru") - - spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} - // Invoke chaincode - _, _, retval, err := invoke(ctxt, chainID, spec, nextBlockNumber, nil, chaincodeSupport) - - if err != nil { - t.Fail() - t.Logf("Error invoking <%s>: %s", ccID, err) - return - } - - if string(retval) != "pthru" { - t.Fail() - t.Logf("Expected to get back \"pthru\" from lscc but got back %s", string(retval)) - return - } -} - -func TestChaincodeInitializeInitError(t *testing.T) { - testForSkip(t) - testCases := []struct { - name string - chaincodeType pb.ChaincodeSpec_Type - chaincodePath string - args []string - }{ - {"NotSuccessResponse", pb.ChaincodeSpec_GOLANG, chaincodeExample02GolangPath, []string{"init", "not", "enough", "args"}}, - {"NotSuccessResponse", pb.ChaincodeSpec_JAVA, chaincodeExample02JavaPath, []string{"init", "not", "enough", "args"}}, - {"RuntimeException", pb.ChaincodeSpec_JAVA, chaincodeExample06JavaPath, []string{"runtimeException"}}, - } - - channel := util.GetTestChainID() - - for _, tc := range testCases { - t.Run(tc.name+"_"+tc.chaincodeType.String(), func(t *testing.T) { - - if tc.chaincodeType == pb.ChaincodeSpec_JAVA && runtime.GOARCH != "amd64" { - t.Skip("No Java chaincode support yet on non-amd64.") - } - - // initialize peer - listener, chaincodeSupport, cleanup, err := initPeer(channel) - if err != nil { - t.Errorf("Error creating peer: %s", err) - } else { - defer finitPeer(listener, channel) - } - - var nextBlockNumber uint64 - - // the chaincode to install and instantiate - chaincodeName := generateChaincodeName(tc.chaincodeType) - chaincodePath := tc.chaincodePath - chaincodeVersion := "1.0.0.0" - chaincodeType := tc.chaincodeType - chaincodeDeployArgs := util.ArrayToChaincodeArgs(tc.args) - - // attempt to deploy chaincode - _, chaincodeCtx, err := deployChaincode(context.Background(), chaincodeName, chaincodeVersion, chaincodeType, chaincodePath, chaincodeDeployArgs, nil, channel, nextBlockNumber, chaincodeSupport) - - // deploy should of failed - if err == nil { - stopChaincode(context.Background(), chaincodeCtx, chaincodeSupport) - t.Fatal("Deployment should have failed.") - } - t.Log(err) - cleanup() - }) - } -} - func TestMain(m *testing.M) { var err error diff --git a/core/chaincode/multichains_test.go b/core/chaincode/multichains_test.go deleted file mode 100644 index 5cc36ff41a3..00000000000 --- a/core/chaincode/multichains_test.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package chaincode - -import ( - "testing" - - "github.com/hyperledger/fabric/core/common/ccprovider" - pb "github.com/hyperledger/fabric/protos/peer" - - "golang.org/x/net/context" -) - -func TestExecuteInvokeOnManyChains(t *testing.T) { - testForSkip(t) - //lets use 2 chains to test multi chains - chains := []string{"chain1", "chain2"} - _, chaincodeSupport, cleanup, err := initPeer(chains...) - if err != nil { - t.Fail() - t.Logf("Error creating peer: %s", err) - } - - defer cleanup() - - var ctxt = context.Background() - - url := "github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd" - chaincodeID := &pb.ChaincodeID{Name: "example02", Path: url, Version: "0"} - - args := []string{"a", "b", "10"} - for _, c := range chains { - cccid := ccprovider.NewCCContext(c, "example02", "0", "", false, nil, nil) - err = invokeExample02Transaction(ctxt, cccid, chaincodeID, pb.ChaincodeSpec_GOLANG, args, chaincodeSupport) - if err != nil { - t.Fail() - t.Logf("Error invoking transaction: %s", err) - } else { - t.Logf("Invoke test passed for chain %s", c) - } - chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: chaincodeID.Name, - Version: chaincodeID.Version, - Path: chaincodeID.Path, - Type: "GOLANG", - ContainerType: "DOCKER", - }) - } - -} diff --git a/core/chaincode/systemchaincode_test.go b/core/chaincode/systemchaincode_test.go deleted file mode 100644 index 2302d9b882b..00000000000 --- a/core/chaincode/systemchaincode_test.go +++ /dev/null @@ -1,295 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package chaincode - -import ( - "net" - "os" - "testing" - "time" - - "github.com/hyperledger/fabric/common/crypto/tlsgen" - "github.com/hyperledger/fabric/common/util" - "github.com/hyperledger/fabric/core/chaincode/accesscontrol" - "github.com/hyperledger/fabric/core/chaincode/platforms" - "github.com/hyperledger/fabric/core/chaincode/platforms/golang" - "github.com/hyperledger/fabric/core/chaincode/shim" - "github.com/hyperledger/fabric/core/common/ccprovider" - "github.com/hyperledger/fabric/core/container" - "github.com/hyperledger/fabric/core/container/dockercontroller" - "github.com/hyperledger/fabric/core/container/inproccontroller" - "github.com/hyperledger/fabric/core/peer" - "github.com/hyperledger/fabric/core/scc" - pb "github.com/hyperledger/fabric/protos/peer" - "github.com/spf13/viper" - "golang.org/x/net/context" - "google.golang.org/grpc" -) - -type oldSysCCInfo struct { - origSystemCC []*scc.SystemChaincode - origSysCCWhitelist map[string]string -} - -func (osyscc *oldSysCCInfo) reset() { - viper.Set("chaincode.system", osyscc.origSysCCWhitelist) -} - -type SampleSysCC struct{} - -func (t *SampleSysCC) Init(stub shim.ChaincodeStubInterface) pb.Response { - return shim.Success(nil) -} - -func (t *SampleSysCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response { - f, args := stub.GetFunctionAndParameters() - - switch f { - case "putval": - if len(args) != 2 { - return shim.Error("need 2 args (key and a value)") - } - - // Initialize the chaincode - key := args[0] - val := args[1] - - _, err := stub.GetState(key) - if err != nil { - jsonResp := "{\"Error\":\"Failed to get val for " + key + "\"}" - return shim.Error(jsonResp) - } - - // Write the state to the ledger - err = stub.PutState(key, []byte(val)) - if err != nil { - return shim.Error(err.Error()) - } - - return shim.Success(nil) - case "getval": - var err error - - if len(args) != 1 { - return shim.Error("Incorrect number of arguments. Expecting key to query") - } - - key := args[0] - - // Get the state from the ledger - valbytes, err := stub.GetState(key) - if err != nil { - jsonResp := "{\"Error\":\"Failed to get state for " + key + "\"}" - return shim.Error(jsonResp) - } - - if valbytes == nil { - jsonResp := "{\"Error\":\"Nil val for " + key + "\"}" - return shim.Error(jsonResp) - } - - return shim.Success(valbytes) - default: - jsonResp := "{\"Error\":\"Unknown function " + f + "\"}" - return shim.Error(jsonResp) - } -} - -func initSysCCTests() (*oldSysCCInfo, net.Listener, *ChaincodeSupport, error) { - var opts []grpc.ServerOption - grpcServer := grpc.NewServer(opts...) - viper.Set("peer.fileSystemPath", "/tmp/hyperledger/test/tmpdb") - defer os.RemoveAll("/tmp/hyperledger/test/tmpdb") - - peer.MockInitialize() - - mspGetter := func(cid string) []string { - return []string{"SampleOrg"} - } - - peer.MockSetMSPIDGetter(mspGetter) - - //use a different address than what we usually use for "peer" - //we override the peerAddress set in chaincode_support.go - // FIXME: Use peer.GetLocalAddress() - peerAddress := "0.0.0.0:21726" - lis, err := net.Listen("tcp", peerAddress) - if err != nil { - return nil, nil, nil, err - } - - ca, _ := tlsgen.NewCA() - certGenerator := accesscontrol.NewAuthenticator(ca) - config := GlobalConfig() - config.ExecuteTimeout = 5 * time.Second - ipRegistry := inproccontroller.NewRegistry() - sccp := &scc.Provider{Peer: peer.Default, PeerSupport: peer.DefaultSupport, Registrar: ipRegistry} - chaincodeSupport := NewChaincodeSupport( - config, - peerAddress, - false, - ca.CertBytes(), - certGenerator, - &ccprovider.CCInfoFSImpl{}, - nil, - mockAclProvider, - container.NewVMController( - map[string]container.VMProvider{ - dockercontroller.ContainerType: dockercontroller.NewProvider("", ""), - inproccontroller.ContainerType: ipRegistry, - }, - ), - sccp, - platforms.NewRegistry(&golang.Platform{}), - ) - ipRegistry.ChaincodeSupport = chaincodeSupport - pb.RegisterChaincodeSupportServer(grpcServer, chaincodeSupport) - - go grpcServer.Serve(lis) - - //set systemChaincodes to sample - syscc := &scc.SysCCWrapper{ - SCC: &scc.SystemChaincode{ - Enabled: true, - Name: "sample_syscc", - Path: "github.com/hyperledger/fabric/core/scc/samplesyscc", - InitArgs: [][]byte{}, - Chaincode: &SampleSysCC{}, - }, - } - - sysccinfo := &oldSysCCInfo{origSysCCWhitelist: viper.GetStringMapString("chaincode.system")} - - // System chaincode has to be enabled - viper.Set("chaincode.system", map[string]string{"sample_syscc": "true"}) - - sccp.RegisterSysCC(syscc) - - /////^^^ system initialization completed ^^^ - return sysccinfo, lis, chaincodeSupport, nil -} - -func deploySampleSysCC(t *testing.T, ctxt context.Context, chainID string, chaincodeSupport *ChaincodeSupport) error { - ccp := &CCProviderImpl{cs: chaincodeSupport} - chaincodeSupport.SystemCCProvider.(*scc.Provider).DeploySysCCs(chainID, ccp) - - defer chaincodeSupport.SystemCCProvider.(*scc.Provider).DeDeploySysCCs(chainID, ccp) - - url := "github.com/hyperledger/fabric/core/scc/sample_syscc" - - sysCCVers := util.GetSysCCVersion() - - f := "putval" - args := util.ToChaincodeArgs(f, "greeting", "hey there") - - spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "sample_syscc", Path: url, Version: sysCCVers}, Input: &pb.ChaincodeInput{Args: args}} - // the ledger is created with genesis block. Start block number 1 onwards - var nextBlockNumber uint64 = 1 - _, _, _, err := invokeWithVersion(ctxt, chainID, sysCCVers, spec, nextBlockNumber, nil, chaincodeSupport) - nextBlockNumber++ - - defer chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: spec.ChaincodeId.Name, - Version: spec.ChaincodeId.Version, - Path: spec.ChaincodeId.Path, - Type: "GOLANG", - ContainerType: "SYSTEM", - }) - if err != nil { - t.Logf("Error invoking sample_syscc: %s", err) - return err - } - - f = "getval" - args = util.ToChaincodeArgs(f, "greeting") - spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "sample_syscc", Path: url, Version: sysCCVers}, Input: &pb.ChaincodeInput{Args: args}} - _, _, _, err = invokeWithVersion(ctxt, chainID, sysCCVers, spec, nextBlockNumber, nil, chaincodeSupport) - if err != nil { - t.Logf("Error invoking sample_syscc: %s", err) - return err - } - - return nil -} - -// Test deploy of a transaction. -func TestExecuteDeploySysChaincode(t *testing.T) { - testForSkip(t) - sysccinfo, lis, chaincodeSupport, err := initSysCCTests() - if err != nil { - t.Fail() - return - } - - defer func() { - sysccinfo.reset() - }() - - chainID := util.GetTestChainID() - - if err = peer.MockCreateChain(chainID); err != nil { - closeListenerAndSleep(lis) - return - } - - var ctxt = context.Background() - - err = deploySampleSysCC(t, ctxt, chainID, chaincodeSupport) - if err != nil { - closeListenerAndSleep(lis) - t.Fail() - return - } - - closeListenerAndSleep(lis) -} - -// Test multichains -func TestMultichains(t *testing.T) { - testForSkip(t) - sysccinfo, lis, chaincodeSupport, err := initSysCCTests() - if err != nil { - t.Fail() - return - } - - defer func() { - sysccinfo.reset() - }() - - chainID := "chain1" - - if err = peer.MockCreateChain(chainID); err != nil { - closeListenerAndSleep(lis) - return - } - - var ctxt = context.Background() - - err = deploySampleSysCC(t, ctxt, chainID, chaincodeSupport) - if err != nil { - closeListenerAndSleep(lis) - t.Fail() - return - } - - chainID = "chain2" - - if err = peer.MockCreateChain(chainID); err != nil { - closeListenerAndSleep(lis) - return - } - - err = deploySampleSysCC(t, ctxt, chainID, chaincodeSupport) - if err != nil { - closeListenerAndSleep(lis) - t.Fail() - return - } - - closeListenerAndSleep(lis) -} diff --git a/core/chaincode/upgrade_test.go b/core/chaincode/upgrade_test.go deleted file mode 100644 index 5346e1c1f69..00000000000 --- a/core/chaincode/upgrade_test.go +++ /dev/null @@ -1,261 +0,0 @@ -/* -Copyright IBM Corp. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package chaincode - -import ( - "fmt" - "strings" - "testing" - - "github.com/hyperledger/fabric/common/util" - "github.com/hyperledger/fabric/core/common/ccprovider" - pb "github.com/hyperledger/fabric/protos/peer" - putils "github.com/hyperledger/fabric/protos/utils" - - "github.com/golang/protobuf/proto" - "golang.org/x/net/context" -) - -//getUpgradeLSCCSpec gets the spec for the chaincode upgrade to be sent to LSCC -func getUpgradeLSCCSpec(chainID string, cds *pb.ChaincodeDeploymentSpec) (*pb.ChaincodeInvocationSpec, error) { - b, err := proto.Marshal(cds) - if err != nil { - return nil, err - } - - //wrap the deployment in an invocation spec to lscc... - lsccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: "lscc"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("upgrade"), []byte(chainID), b}}}} - - return lsccSpec, nil -} - -// upgrade a chaincode - i.e., build and initialize. -func upgrade(ctx context.Context, cccid *ccprovider.CCContext, spec *pb.ChaincodeSpec, blockNumber uint64, chaincodeSupport *ChaincodeSupport) (*ccprovider.CCContext, error) { - // First build and get the deployment spec - chaincodeDeploymentSpec, err := getDeploymentSpec(ctx, spec) - if err != nil { - return nil, err - } - - return upgrade2(ctx, cccid, chaincodeDeploymentSpec, blockNumber, chaincodeSupport) -} - -func upgrade2(ctx context.Context, cccid *ccprovider.CCContext, - chaincodeDeploymentSpec *pb.ChaincodeDeploymentSpec, blockNumber uint64, chaincodeSupport *ChaincodeSupport) (newcccid *ccprovider.CCContext, err error) { - cis, err := getUpgradeLSCCSpec(cccid.ChainID, chaincodeDeploymentSpec) - if err != nil { - return nil, fmt.Errorf("Error creating lscc spec : %s\n", err) - } - - uuid := util.GenerateUUID() - cccid.TxID = uuid - ctx, txsim, err := startTxSimulation(ctx, cccid.ChainID, cccid.TxID) - if err != nil { - return nil, fmt.Errorf("Failed to get handle to simulator: %s ", err) - } - - defer func() { - //no error, lets try commit - if err == nil { - //capture returned error from commit - err = endTxSimulationCDS(cccid.ChainID, uuid, txsim, []byte("upgraded"), true, chaincodeDeploymentSpec, blockNumber) - } else { - //there was an error, just close simulation and return that - endTxSimulationCDS(cccid.ChainID, uuid, txsim, []byte("upgraded"), false, chaincodeDeploymentSpec, blockNumber) - } - }() - - //ignore existence errors - ccprovider.PutChaincodeIntoFS(chaincodeDeploymentSpec) - - sysCCVers := util.GetSysCCVersion() - sprop, prop := putils.MockSignedEndorserProposal2OrPanic(cccid.ChainID, cis.ChaincodeSpec, signer) - lsccid := ccprovider.NewCCContext(cccid.ChainID, cis.ChaincodeSpec.ChaincodeId.Name, sysCCVers, uuid, true, sprop, prop) - - //write to lscc - var resp *pb.Response - if resp, _, err = chaincodeSupport.Execute(ctx, lsccid, cis); err != nil { - return nil, fmt.Errorf("Error executing LSCC for upgrade: %s", err) - } - - cdbytes := resp.Payload - if cdbytes == nil { - return nil, fmt.Errorf("Expected ChaincodeData back from LSCC but got nil") - } - - cd := &ccprovider.ChaincodeData{} - if err = proto.Unmarshal(cdbytes, cd); err != nil { - return nil, fmt.Errorf("getting ChaincodeData failed") - } - - newVersion := string(cd.Version) - if newVersion == cccid.Version { - return nil, fmt.Errorf("Expected new version from LSCC but got same %s(%s)", newVersion, cccid.Version) - } - - newcccid = ccprovider.NewCCContext(cccid.ChainID, chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeId.Name, newVersion, uuid, false, nil, nil) - - if _, _, err = chaincodeSupport.ExecuteInit(ctx, newcccid, chaincodeDeploymentSpec); err != nil { - return nil, fmt.Errorf("Error deploying chaincode for upgrade: %s", err) - } - return -} - -//TestUpgradeCC - test basic upgrade -// deploy example01 -// do a query against 01 that'll fail -// upgrade to exampl02 -// show the upgrade worked using the same query successfully -//This test a variety of things in addition to basic upgrade -// uses next version from lscc -// re-initializtion of the same chaincode "mycc" -// upgrade when "mycc" is up and running (test version based namespace) -func TestUpgradeCC(t *testing.T) { - testForSkip(t) - chainID := util.GetTestChainID() - - _, chaincodeSupport, cleanup, err := initPeer(chainID) - if err != nil { - t.Fail() - t.Logf("Error creating peer: %s", err) - } - - defer cleanup() - - var ctxt = context.Background() - - ccName := "mycc" - url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01" - chaincodeID := &pb.ChaincodeID{Name: ccName, Path: url, Version: "0"} - - f := "init" - args := util.ToChaincodeArgs(f, "a", "100", "b", "200") - - spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}} - - cccid := ccprovider.NewCCContext(chainID, ccName, "0", "", false, nil, nil) - var nextBlockNumber uint64 = 1 - defer chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: chaincodeID.Name, - Version: chaincodeID.Version, - Path: chaincodeID.Path, - Type: "GOLANG", - ContainerType: "DOCKER", - }) - _, err = deploy(ctxt, cccid, spec, nextBlockNumber, chaincodeSupport) - - if err != nil { - t.Fail() - t.Logf("Error deploying chaincode %s(%s)", chaincodeID, err) - return - } - - // Query example01, which should fail - qArgs := util.ToChaincodeArgs("query", "a") - - spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: qArgs}} - - //Do not increment block number here because, the block will not be committted because of error - _, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil, chaincodeSupport) - if err == nil { - t.Fail() - t.Logf("querying chaincode exampl01 should fail transaction: %s", err) - return - } else if !strings.Contains(err.Error(), "Invalid invoke function name. Expecting \"invoke\"") { - t.Fail() - t.Logf("expected found <%s>", err) - return - } - - //now upgrade to example02 which takes the same args as example01 but inits state vars - //and also allows query. - url = "github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd" - - //Note ccName hasn't changed... - chaincodeID = &pb.ChaincodeID{Name: ccName, Path: url, Version: "1"} - spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}} - - //...and get back the ccid with the new version - nextBlockNumber++ - chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: chaincodeID.Name, - Version: chaincodeID.Version, - Path: chaincodeID.Path, - Type: "GOLANG", - ContainerType: "DOCKER", - }) - cccid2, err := upgrade(ctxt, cccid, spec, nextBlockNumber, chaincodeSupport) - if err != nil { - t.Fail() - t.Logf("Error upgrading chaincode %s(%s)", chaincodeID, err) - return - } - - //go back and do the same query now - spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: qArgs}} - nextBlockNumber++ - _, _, _, err = invokeWithVersion(ctxt, chainID, cccid2.Version, spec, nextBlockNumber, nil, chaincodeSupport) - - if err != nil { - t.Fail() - t.Logf("querying chaincode exampl02 did not succeed: %s", err) - return - } -} - -//TestInvalUpgradeCC - test basic upgrade -// upgrade to exampl02 when "mycc" is not deployed -// look for "not found" failure -func TestInvalUpgradeCC(t *testing.T) { - testForSkip(t) - chainID := util.GetTestChainID() - - _, chaincodeSupport, cleanup, err := initPeer(chainID) - if err != nil { - t.Fail() - t.Logf("Error creating peer: %s", err) - } - - defer cleanup() - - var ctxt = context.Background() - - ccName := "mycc" - url := "github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd" - - f := "init" - args := util.ToChaincodeArgs(f, "a", "100", "b", "200") - - cccid := ccprovider.NewCCContext(chainID, ccName, "0", "", false, nil, nil) - - //Note ccName hasn't changed... - chaincodeID := &pb.ChaincodeID{Name: ccName, Path: url, Version: "1"} - spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}} - - //...and get back the ccid with the new version - var nextBlockNumber uint64 - cccid2, err := upgrade(ctxt, cccid, spec, nextBlockNumber, chaincodeSupport) - defer chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: cccid.Name, - Version: cccid.Version, - Path: url, - ContainerType: "DOCKER", - Type: "GOLANG", - }) - defer chaincodeSupport.Stop(&ccprovider.ChaincodeContainerInfo{ - Name: cccid2.Name, - Version: cccid2.Version, - Path: url, - ContainerType: "DOCKER", - Type: "GOLANG", - }) - if err == nil { - t.Fail() - t.Logf("Error expected upgrading to fail but it succeeded%s(%s)", chaincodeID, err) - return - } -}