From f34cc66b8c69f9b0db8d2b9fdaf513a82945459e Mon Sep 17 00:00:00 2001 From: huangjiehua Date: Wed, 5 Aug 2020 03:18:16 +0800 Subject: [PATCH] [FABG 998]Integration tests (#136) * Integration tests include: package cc, install cc, get installed cc package, query installed cc, approve cc, query approve cc, check commit readiness, commit cc, query committed cc Signed-off-by: Jiehua Huang --- Makefile | 12 +- pkg/client/channel/api.go | 1 + pkg/client/channel/invoke/api.go | 1 + pkg/client/channel/invoke/txnhandler.go | 1 + pkg/common/providers/fab/proposer.go | 2 + pkg/fab/txn/proposal.go | 2 +- .../dockerenv/docker-compose-negative.yaml | 1 + .../docker-compose-nopkcs11-test.yaml | 1 + .../dockerenv/docker-compose-pkcs11-test.yaml | 1 + .../fixtures/fabric/v2.2/config/configtx.yaml | 63 ++- test/integration/base_test_setup.go | 22 + test/integration/e2e/end_to_end.go | 188 +++++++- .../multi_orgs_ch_update_signatures_test.go | 52 ++- .../e2e/orgs/multiple_orgs_test.go | 402 ++++++++++++++++- .../negative/revoked/revoked_test.go | 239 ++++++---- .../client/channel/channel_client_pvt_test.go | 200 +++++---- .../pkg/client/channel/channel_client_test.go | 37 +- .../common/discovery/discoveryclient_test.go | 83 ++-- .../common/selection/fabricselection_test.go | 92 ++-- .../pkg/client/ledger/channel_ledger_test.go | 15 +- .../resmgmt/resmgmt_queries_pvt_test.go | 10 +- .../client/resmgmt/resmgmt_queries_test.go | 78 ++-- .../pkg/fab/install_chaincode_test.go | 6 +- .../pkg/fab/resource_queries_test.go | 22 +- .../provider/custom_cryptosuite_test.go | 13 +- .../pkg/fabsdk/provider/sdk_provider_test.go | 18 +- test/integration/prepare.go | 408 ++++++++++++++++++ test/integration/util/runner/runner.go | 14 +- test/metadata/metadata.go | 5 +- test/scripts/integration-pkcs11.sh | 2 + test/scripts/integration.sh | 4 +- test/scripts/negative.sh | 3 +- 32 files changed, 1661 insertions(+), 337 deletions(-) diff --git a/Makefile b/Makefile index 2c23ec6ce5..cb12a3818c 100644 --- a/Makefile +++ b/Makefile @@ -108,6 +108,10 @@ FABRIC_CRYPTOCONFIG_VER ?= v$(FABRIC_PREV_VERSION_MAJOR) FABRIC_CODELEVEL_UNITTEST_TAG ?= $(FABRIC_STABLE_CODELEVEL_TAG) FABRIC_CODELEVEL_UNITTEST_VER ?= $(FABRIC_STABLE_CODELEVEL_VER) +# CC_MODE +CC_MODE_LIFECYCLE = lifecycle +CC_MODE_LSCC = lscc + # Local variables used by makefile PROJECT_NAME := fabric-sdk-go ARCH := $(shell uname -m) @@ -317,7 +321,7 @@ integration-tests-stable: clean-tests depend-noforce populate-noforce cd $(FIXTURE_DOCKERENV_PATH) && \ TEST_CHANGED_ONLY=$(FABRIC_SDKGO_TEST_CHANGED) FABRIC_SDKGO_CODELEVEL_VER=$(FABRIC_STABLE_CODELEVEL_VER) FABRIC_SDKGO_CODELEVEL_TAG=$(FABRIC_STABLE_CODELEVEL_TAG) FABRIC_DOCKER_REGISTRY=$(FABRIC_RELEASE_REGISTRY) \ FABRIC_FIXTURE_VERSION=v$(FABRIC_STABLE_VERSION_MINOR) FABRIC_CRYPTOCONFIG_VERSION=$(FABRIC_CRYPTOCONFIG_VER) \ - GO_TESTFLAGS="$(GO_TESTFLAGS_INTEGRATION)" \ + GO_TESTFLAGS="$(GO_TESTFLAGS_INTEGRATION)" CC_MODE="$(CC_MODE_LIFECYCLE)"\ $(DOCKER_COMPOSE_CMD) $(BASE_DOCKER_COMPOSE_FILES) -f docker-compose-nopkcs11-test.yaml up $(DOCKER_COMPOSE_UP_TEST_FLAGS) @cd $(FIXTURE_DOCKERENV_PATH) && FABRIC_DOCKER_REGISTRY=$(FABRIC_RELEASE_REGISTRY) $(FIXTURE_SCRIPTS_PATH)/check_status.sh "$(BASE_DOCKER_COMPOSE_FILES) -f ./docker-compose-nopkcs11-test.yaml" @@ -328,7 +332,7 @@ integration-tests-prev: clean-tests depend-noforce populate-fixtures-prev-noforc cd $(FIXTURE_DOCKERENV_PATH) && \ TEST_CHANGED_ONLY=$(FABRIC_SDKGO_TEST_CHANGED) E2E_ONLY="false" FABRIC_SDKGO_CODELEVEL_VER=$(FABRIC_PREV_CODELEVEL_VER) FABRIC_SDKGO_CODELEVEL_TAG=$(FABRIC_PREV_CODELEVEL_TAG) FABRIC_DOCKER_REGISTRY=$(FABRIC_RELEASE_REGISTRY) \ FABRIC_FIXTURE_VERSION=v$(FABRIC_PREV_VERSION_MINOR) FABRIC_CRYPTOCONFIG_VERSION=$(FABRIC_CRYPTOCONFIG_VER) \ - GO_TESTFLAGS="$(GO_TESTFLAGS_INTEGRATION)" \ + GO_TESTFLAGS="$(GO_TESTFLAGS_INTEGRATION)" CC_MODE="$(CC_MODE_LSCC)" \ $(DOCKER_COMPOSE_CMD) $(BASE_DOCKER_COMPOSE_FILES) -f docker-compose-nopkcs11-test.yaml up $(DOCKER_COMPOSE_UP_TEST_FLAGS) @cd $(FIXTURE_DOCKERENV_PATH) && FABRIC_DOCKER_REGISTRY=$(FABRIC_RELEASE_REGISTRY) $(FIXTURE_SCRIPTS_PATH)/check_status.sh "$(BASE_DOCKER_COMPOSE_FILES) -f ./docker-compose-nopkcs11-test.yaml" @@ -363,7 +367,7 @@ integration-tests-stable-negative: clean-tests depend-noforce populate-noforce cd $(FIXTURE_DOCKERENV_PATH) && \ TEST_CHANGED_ONLY=$(FABRIC_SDKGO_TEST_CHANGED) FABRIC_SDKGO_CODELEVEL_VER=$(FABRIC_STABLE_CODELEVEL_VER) FABRIC_SDKGO_CODELEVEL_TAG=$(FABRIC_STABLE_CODELEVEL_TAG) FABRIC_DOCKER_REGISTRY=$(FABRIC_RELEASE_REGISTRY) \ FABRIC_FIXTURE_VERSION=v$(FABRIC_STABLE_VERSION_MINOR) FABRIC_CRYPTOCONFIG_VERSION=$(FABRIC_CRYPTOCONFIG_VER) \ - GO_TESTFLAGS="$(GO_TESTFLAGS_INTEGRATION)" \ + GO_TESTFLAGS="$(GO_TESTFLAGS_INTEGRATION)" CC_MODE="$(CC_MODE_LIFECYCLE)"\ $(DOCKER_COMPOSE_CMD) $(BASE_DOCKER_COMPOSE_FILES) -f docker-compose-negative.yaml up $(DOCKER_COMPOSE_UP_TEST_FLAGS) @cd $(FIXTURE_DOCKERENV_PATH) && FABRIC_DOCKER_REGISTRY=$(FABRIC_RELEASE_REGISTRY) $(FIXTURE_SCRIPTS_PATH)/check_status.sh "$(BASE_DOCKER_COMPOSE_FILES) -f ./docker-compose-negative.yaml" @@ -374,7 +378,7 @@ integration-tests-stable-pkcs11: clean-tests depend-noforce populate-noforce cd $(FIXTURE_DOCKERENV_PATH) && \ TEST_CHANGED_ONLY=$(FABRIC_SDKGO_TEST_CHANGED) FABRIC_SDKGO_CODELEVEL_VER=$(FABRIC_STABLE_CODELEVEL_VER) FABRIC_SDKGO_CODELEVEL_TAG=$(FABRIC_STABLE_CODELEVEL_TAG) FABRIC_DOCKER_REGISTRY=$(FABRIC_RELEASE_REGISTRY) \ FABRIC_FIXTURE_VERSION=v$(FABRIC_STABLE_VERSION_MINOR) FABRIC_CRYPTOCONFIG_VERSION=$(FABRIC_CRYPTOCONFIG_VER) \ - GO_TESTFLAGS="$(GO_TESTFLAGS_INTEGRATION)" \ + GO_TESTFLAGS="$(GO_TESTFLAGS_INTEGRATION)" CC_MODE="$(CC_MODE_LIFECYCLE)"\ $(DOCKER_COMPOSE_CMD) $(BASE_DOCKER_COMPOSE_FILES) -f docker-compose-pkcs11-test.yaml up $(DOCKER_COMPOSE_UP_TEST_FLAGS) @cd $(FIXTURE_DOCKERENV_PATH) && FABRIC_DOCKER_REGISTRY=$(FABRIC_RELEASE_REGISTRY) $(FIXTURE_SCRIPTS_PATH)/check_status.sh "$(BASE_DOCKER_COMPOSE_FILES) -f ./docker-compose-pkcs11-test.yaml" diff --git a/pkg/client/channel/api.go b/pkg/client/channel/api.go index effd8c8398..5bba1af094 100644 --- a/pkg/client/channel/api.go +++ b/pkg/client/channel/api.go @@ -50,6 +50,7 @@ type Request struct { // The invoked chaincode (specified by ChaincodeID) may optionally be added to the invocation // chain along with any collections, otherwise it may be omitted. InvocationChain []*fab.ChaincodeCall + IsInit bool } //Response contains response parameters for query and execute an invocation transaction diff --git a/pkg/client/channel/invoke/api.go b/pkg/client/channel/invoke/api.go index 6157317ffb..17c8aafe7d 100644 --- a/pkg/client/channel/invoke/api.go +++ b/pkg/client/channel/invoke/api.go @@ -50,6 +50,7 @@ type Request struct { // The invoked chaincode (specified by ChaincodeID) may optionally be added to the invocation // chain along with any collections, otherwise it may be omitted. InvocationChain []*fab.ChaincodeCall + IsInit bool } //Response contains response parameters for query and execute transaction diff --git a/pkg/client/channel/invoke/txnhandler.go b/pkg/client/channel/invoke/txnhandler.go index 83badef224..7c1868aadc 100644 --- a/pkg/client/channel/invoke/txnhandler.go +++ b/pkg/client/channel/invoke/txnhandler.go @@ -281,6 +281,7 @@ func createAndSendTransactionProposal(transactor fab.ProposalSender, chrequest * Fcn: chrequest.Fcn, Args: chrequest.Args, TransientMap: chrequest.TransientMap, + IsInit: chrequest.IsInit, } txh, err := transactor.CreateTransactionHeader(opts...) diff --git a/pkg/common/providers/fab/proposer.go b/pkg/common/providers/fab/proposer.go index 95faf5430b..18ad9128e9 100644 --- a/pkg/common/providers/fab/proposer.go +++ b/pkg/common/providers/fab/proposer.go @@ -64,12 +64,14 @@ type TransactionHeader interface { } // ChaincodeInvokeRequest contains the parameters for sending a transaction proposal. +// nolint: maligned type ChaincodeInvokeRequest struct { ChaincodeID string Lang pb.ChaincodeSpec_Type TransientMap map[string][]byte Fcn string Args [][]byte + IsInit bool } // TransactionProposal contains a marashalled transaction proposal. diff --git a/pkg/fab/txn/proposal.go b/pkg/fab/txn/proposal.go index 1d8f91e6b0..56a501b64d 100644 --- a/pkg/fab/txn/proposal.go +++ b/pkg/fab/txn/proposal.go @@ -42,7 +42,7 @@ func CreateChaincodeInvokeProposal(txh fab.TransactionHeader, request fab.Chainc // create invocation spec to target a chaincode with arguments ccis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{ Type: request.Lang, ChaincodeId: &pb.ChaincodeID{Name: request.ChaincodeID}, - Input: &pb.ChaincodeInput{Args: argsArray}}} + Input: &pb.ChaincodeInput{Args: argsArray, IsInit: request.IsInit}}} proposal, _, err := protoutil.CreateChaincodeProposalWithTxIDNonceAndTransient(string(txh.TransactionID()), common.HeaderType_ENDORSER_TRANSACTION, txh.ChannelID(), ccis, txh.Nonce(), txh.Creator(), request.TransientMap) if err != nil { diff --git a/test/fixtures/dockerenv/docker-compose-negative.yaml b/test/fixtures/dockerenv/docker-compose-negative.yaml index 2dd8455e80..2bbbb11322 100644 --- a/test/fixtures/dockerenv/docker-compose-negative.yaml +++ b/test/fixtures/dockerenv/docker-compose-negative.yaml @@ -20,6 +20,7 @@ services: - FABRIC_SDK_CLIENT_EVENTSERVICE_TYPE - TEST_CHANGED_ONLY - CORE_VM_ENDPOINT + - CC_MODE volumes: - ${GOPATH}/pkg/mod:/opt/gopath/pkg/mod - ../../../:/opt/workspace/fabric-sdk-go diff --git a/test/fixtures/dockerenv/docker-compose-nopkcs11-test.yaml b/test/fixtures/dockerenv/docker-compose-nopkcs11-test.yaml index aaeaf1fc3b..0645a1daec 100644 --- a/test/fixtures/dockerenv/docker-compose-nopkcs11-test.yaml +++ b/test/fixtures/dockerenv/docker-compose-nopkcs11-test.yaml @@ -22,6 +22,7 @@ services: - E2E_ONLY - TEST_CHANGED_ONLY - CORE_VM_ENDPOINT + - CC_MODE volumes: - ${GOPATH}/pkg/mod:/opt/gopath/pkg/mod - ../../../:/opt/workspace/fabric-sdk-go diff --git a/test/fixtures/dockerenv/docker-compose-pkcs11-test.yaml b/test/fixtures/dockerenv/docker-compose-pkcs11-test.yaml index cb9f47f91d..c2b501a0f5 100644 --- a/test/fixtures/dockerenv/docker-compose-pkcs11-test.yaml +++ b/test/fixtures/dockerenv/docker-compose-pkcs11-test.yaml @@ -21,6 +21,7 @@ services: - FABRIC_SDK_CLIENT_EVENTSERVICE_TYPE - TEST_CHANGED_ONLY - CORE_VM_ENDPOINT + - CC_MODE volumes: - ${GOPATH}/pkg/mod:/opt/gopath/pkg/mod - ../../../:/opt/workspace/fabric-sdk-go diff --git a/test/fixtures/fabric/v2.2/config/configtx.yaml b/test/fixtures/fabric/v2.2/config/configtx.yaml index 39bd6fa511..43236ddd08 100644 --- a/test/fixtures/fabric/v2.2/config/configtx.yaml +++ b/test/fixtures/fabric/v2.2/config/configtx.yaml @@ -147,34 +147,41 @@ Organizations: # ################################################################################ Capabilities: - # Global capabilities apply to both the orderers and the peers and must be - # supported by both. Set the value of the capability to true to require it. + # Channel capabilities apply to both the orderers and the peers and must be + # supported by both. + # Set the value of the capability to true to require it. Channel: &ChannelCapabilities - # V1.1 for Global is a catchall flag for behavior which has been - # determined to be desired for all orderers and peers running v1.0.x, - # but the modification of which would cause imcompatibilities. Users - # should leave this flag set to true. - V1_1: true + # V2_0 capability ensures that orderers and peers behave according + # to v2.0 channel capabilities. Orderers and peers from + # prior releases would behave in an incompatible way, and are therefore + # not able to participate in channels at v2.0 capability. + # Prior to enabling V2.0 channel capabilities, ensure that all + # orderers and peers on a channel are at v2.0.0 or later. + V2_0: true # Orderer capabilities apply only to the orderers, and may be safely - # manipulated without concern for upgrading peers. Set the value of the - # capability to true to require it. + # used with prior release peers. + # Set the value of the capability to true to require it. Orderer: &OrdererCapabilities - # V1.1 for Order is a catchall flag for behavior which has been - # determined to be desired for all orderers running v1.0.x, but the - # modification of which would cause imcompatibilities. Users should - # leave this flag set to true. - V1_1: true + # V2_0 orderer capability ensures that orderers behave according + # to v2.0 orderer capabilities. Orderers from + # prior releases would behave in an incompatible way, and are therefore + # not able to participate in channels at v2.0 orderer capability. + # Prior to enabling V2.0 orderer capabilities, ensure that all + # orderers on channel are at v2.0.0 or later. + V2_0: true # Application capabilities apply only to the peer network, and may be safely - # manipulated without concern for upgrading orderers. Set the value of the - # capability to true to require it. + # used with prior release orderers. + # Set the value of the capability to true to require it. Application: &ApplicationCapabilities - # V1.1 for Application is a catchall flag for behavior which has been - # determined to be desired for all peers running v1.0.x, but the - # modification of which would cause incompatibilities. Users should - # leave this flag set to true. - V1_2: true + # V2_0 application capability ensures that peers behave according + # to v2.0 application capabilities. Peers from + # prior releases would behave in an incompatible way, and are therefore + # not able to participate in channels at v2.0 application capability. + # Prior to enabling V2.0 application capabilities, ensure that all + # peers on channel are at v2.0.0 or later. + V2_0: true ################################################################################ @@ -271,6 +278,20 @@ Application: &ApplicationDefaults #User's can override these defaults with their own policy mapping by defining the #mapping under ACLs in their channel definition + #---New Lifecycle System Chaincode (_lifecycle) function to policy mapping for access control--# + + # ACL policy for _lifecycle's "CheckCommitReadiness" function + _lifecycle/CheckCommitReadiness: /Channel/Application/Writers + + # ACL policy for _lifecycle's "CommitChaincodeDefinition" function + _lifecycle/CommitChaincodeDefinition: /Channel/Application/Writers + + # ACL policy for _lifecycle's "QueryChaincodeDefinition" function + _lifecycle/QueryChaincodeDefinition: /Channel/Application/Readers + + # ACL policy for _lifecycle's "QueryChaincodeDefinitions" function + _lifecycle/QueryChaincodeDefinitions: /Channel/Application/Readers + #---Lifecycle System Chaincode (lscc) function to policy mapping for access control---# #ACL policy for lscc's "getid" function diff --git a/test/integration/base_test_setup.go b/test/integration/base_test_setup.go index e6e8cd191a..fb6e1757f4 100644 --- a/test/integration/base_test_setup.go +++ b/test/integration/base_test_setup.go @@ -95,11 +95,21 @@ func ExampleCCInitArgs() [][]byte { return initArgs } +//ExampleCCInitArgsLc returns example cc initialization args +func ExampleCCInitArgsLc() [][]byte { + return initArgs[1:] +} + //ExampleCCUpgradeArgs returns example cc upgrade args func ExampleCCUpgradeArgs() [][]byte { return upgradeArgs } +//ExampleCCUpgradeArgsLc returns example cc upgrade args +func ExampleCCUpgradeArgsLc() [][]byte { + return upgradeArgs[1:] +} + // IsJoinedChannel returns true if the given peer has joined the given channel func IsJoinedChannel(channelID string, resMgmtClient *resmgmt.Client, peer fabAPI.Peer) (bool, error) { resp, err := resMgmtClient.QueryChannels(resmgmt.WithTargets(peer)) @@ -168,6 +178,18 @@ func GetDeployPath() string { return filepath.Join(metadata.GetProjectPath(), ccPath) } +// GetLcDeployPath returns the path to the chaincode fixtures +func GetLcDeployPath() string { + const ccPath = "test/fixtures/testdata/go/src/github.com/example_cc" + return filepath.Join(metadata.GetProjectPath(), ccPath) +} + +// GetLcPvtDeployPath returns the path to the chaincode fixtures +func GetLcPvtDeployPath() string { + const ccPath = "test/fixtures/testdata/go/src/github.com/example_pvt_cc" + return filepath.Join(metadata.GetProjectPath(), ccPath) +} + // GetJavaDeployPath returns the path to the java chaincode fixtrues func GetJavaDeployPath() string { const ccPath = "test/fixtures/testdata/java" diff --git a/test/integration/e2e/end_to_end.go b/test/integration/e2e/end_to_end.go index d6572a9550..1d18728b43 100644 --- a/test/integration/e2e/end_to_end.go +++ b/test/integration/e2e/end_to_end.go @@ -17,6 +17,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/test/metadata" "github.com/stretchr/testify/require" + pb "github.com/hyperledger/fabric-protos-go/peer" "github.com/hyperledger/fabric-sdk-go/test/integration" "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/policydsl" @@ -27,6 +28,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core" packager "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/gopackager" + lcpackager "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/lifecycle" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" ) @@ -35,6 +37,7 @@ const ( orgName = "Org1" orgAdmin = "Admin" ordererOrgName = "OrdererOrg" + peer1 = "peer0.org1.example.com" ) var ( @@ -125,7 +128,11 @@ func createChannelAndCC(t *testing.T, sdk *fabsdk.FabricSDK) { } // Create chaincode package for example cc - createCC(t, orgResMgmt) + if metadata.CCMode == "lscc" { + createCC(t, orgResMgmt) + } else { + createCCLifecycle(t, orgResMgmt, sdk) + } } func moveFunds(t *testing.T, client *channel.Client) *fab.CCEvent { @@ -227,3 +234,182 @@ func createChannel(t *testing.T, sdk *fabsdk.FabricSDK, resMgmtClient *resmgmt.C require.Nil(t, err, "error should be nil") require.NotEmpty(t, txID, "transaction ID should be populated") } + +// createCCLifecycle package cc, install cc, get installed cc package, query installed cc +// approve cc, query approve cc, check commit readiness, commit cc, query committed cc +func createCCLifecycle(t *testing.T, orgResMgmt *resmgmt.Client, sdk *fabsdk.FabricSDK) { + // Package cc + label, ccPkg := packageCC(t) + packageID := lcpackager.ComputePackageID(label, ccPkg) + + // Install cc + installCC(t, label, ccPkg, orgResMgmt) + + // Get installed cc package + getInstalledCCPackage(t, packageID, ccPkg, orgResMgmt) + + // Query installed cc + queryInstalled(t, label, packageID, orgResMgmt) + + // Approve cc + approveCC(t, packageID, orgResMgmt) + + // Query approve cc + queryApprovedCC(t, orgResMgmt) + + // Check commit readiness + checkCCCommitReadiness(t, packageID, orgResMgmt) + + // Commit cc + commitCC(t, orgResMgmt) + + // Query committed cc + queryCommittedCC(t, orgResMgmt) + + // Init cc + initCC(t, sdk) + +} + +func packageCC(t *testing.T) (string, []byte) { + desc := &lcpackager.Descriptor{ + Path: integration.GetLcDeployPath(), + Type: pb.ChaincodeSpec_GOLANG, + Label: "example_cc_fabtest_e2e_0", + } + ccPkg, err := lcpackager.NewCCPackage(desc) + if err != nil { + t.Fatal(err) + } + return desc.Label, ccPkg +} + +func installCC(t *testing.T, label string, ccPkg []byte, orgResMgmt *resmgmt.Client) { + installCCReq := resmgmt.LifecycleInstallCCRequest{ + Label: label, + Package: ccPkg, + } + + packageID := lcpackager.ComputePackageID(installCCReq.Label, installCCReq.Package) + + resp, err := orgResMgmt.LifecycleInstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.Equal(t, packageID, resp[0].PackageID) +} + +func getInstalledCCPackage(t *testing.T, packageID string, ccPkg []byte, orgResMgmt *resmgmt.Client) { + resp, err := orgResMgmt.LifecycleGetInstalledCCPackage(packageID, resmgmt.WithTargetEndpoints(peer1), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.Equal(t, ccPkg, resp) +} + +func queryInstalled(t *testing.T, label string, packageID string, orgResMgmt *resmgmt.Client) { + resp, err := orgResMgmt.LifecycleQueryInstalledCC(resmgmt.WithTargetEndpoints(peer1), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.Equal(t, packageID, resp[0].PackageID) + require.Equal(t, label, resp[0].Label) +} + +func approveCC(t *testing.T, packageID string, orgResMgmt *resmgmt.Client) { + ccPolicy := policydsl.SignedByAnyMember([]string{"Org1MSP"}) + approveCCReq := resmgmt.LifecycleApproveCCRequest{ + Name: ccID, + Version: "0", + PackageID: packageID, + Sequence: 1, + EndorsementPlugin: "escc", + ValidationPlugin: "vscc", + SignaturePolicy: ccPolicy, + InitRequired: true, + } + + txnID, err := orgResMgmt.LifecycleApproveCC(channelID, approveCCReq, resmgmt.WithTargetEndpoints(peer1), resmgmt.WithOrdererEndpoint("orderer.example.com"), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.NotEmpty(t, txnID) +} + +func queryApprovedCC(t *testing.T, orgResMgmt *resmgmt.Client) { + queryApprovedCCReq := resmgmt.LifecycleQueryApprovedCCRequest{ + Name: ccID, + Sequence: 1, + } + resp, err := orgResMgmt.LifecycleQueryApprovedCC(channelID, queryApprovedCCReq, resmgmt.WithTargetEndpoints(peer1), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.NotNil(t, resp) +} + +func checkCCCommitReadiness(t *testing.T, packageID string, orgResMgmt *resmgmt.Client) { + ccPolicy := policydsl.SignedByAnyMember([]string{"Org1MSP"}) + req := resmgmt.LifecycleCheckCCCommitReadinessRequest{ + Name: ccID, + Version: "0", + PackageID: packageID, + EndorsementPlugin: "escc", + ValidationPlugin: "vscc", + SignaturePolicy: ccPolicy, + Sequence: 1, + InitRequired: true, + } + resp, err := orgResMgmt.LifecycleCheckCCCommitReadiness(channelID, req, resmgmt.WithTargetEndpoints(peer1), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.NotNil(t, resp) +} + +func commitCC(t *testing.T, orgResMgmt *resmgmt.Client) { + ccPolicy := policydsl.SignedByAnyMember([]string{"Org1MSP"}) + req := resmgmt.LifecycleCommitCCRequest{ + Name: ccID, + Version: "0", + Sequence: 1, + EndorsementPlugin: "escc", + ValidationPlugin: "vscc", + SignaturePolicy: ccPolicy, + InitRequired: true, + } + txnID, err := orgResMgmt.LifecycleCommitCC(channelID, req, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithTargetEndpoints(peer1), resmgmt.WithOrdererEndpoint("orderer.example.com")) + if err != nil { + t.Fatal(err) + } + require.NotEmpty(t, txnID) +} + +func queryCommittedCC(t *testing.T, orgResMgmt *resmgmt.Client) { + req := resmgmt.LifecycleQueryCommittedCCRequest{ + Name: ccID, + } + resp, err := orgResMgmt.LifecycleQueryCommittedCC(channelID, req, resmgmt.WithTargetEndpoints(peer1), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.Equal(t, ccID, resp[0].Name) +} + +func initCC(t *testing.T, sdk *fabsdk.FabricSDK) { + //prepare channel client context using client context + clientChannelContext := sdk.ChannelContext(channelID, fabsdk.WithUser("User1"), fabsdk.WithOrg(orgName)) + // Channel client is used to query and execute transactions (Org1 is default org) + client, err := channel.New(clientChannelContext) + if err != nil { + t.Fatalf("Failed to create new channel client: %s", err) + } + + // init + _, err = client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "init", Args: integration.ExampleCCInitArgsLc(), IsInit: true}, + channel.WithRetry(retry.DefaultChannelOpts)) + if err != nil { + t.Fatalf("Failed to init: %s", err) + } + +} diff --git a/test/integration/e2e/orgs/multi_orgs_ch_update_signatures_test.go b/test/integration/e2e/orgs/multi_orgs_ch_update_signatures_test.go index 81ab49f546..9e6d575420 100644 --- a/test/integration/e2e/orgs/multi_orgs_ch_update_signatures_test.go +++ b/test/integration/e2e/orgs/multi_orgs_ch_update_signatures_test.go @@ -47,6 +47,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/provider/chpvdr" "github.com/hyperledger/fabric-sdk-go/pkg/util/test" "github.com/hyperledger/fabric-sdk-go/test/integration" + "github.com/hyperledger/fabric-sdk-go/test/metadata" ) const ( @@ -83,13 +84,14 @@ func DistributedSignaturesTests(t *testing.T, exampleCC string) { org2ClCtx := createDSClientCtx(t, org2) defer org2ClCtx.sdk.Close() - + ccID1 := integration.GenerateExampleID(true) // use SDK signing - e2eCreateAndQueryChannel(t, ordererClCtx, org1ClCtx, org2ClCtx, dsChannelSDK, exampleCC) + e2eCreateAndQueryChannel(t, ordererClCtx, org1ClCtx, org2ClCtx, dsChannelSDK, ccID1) if isOpensslAvailable(t) { + ccID2 := integration.GenerateExampleID(true) // use OpenSSL signing - e2eCreateAndQueryChannel(t, ordererClCtx, org1ClCtx, org2ClCtx, dsChannelExternal, exampleCC) + e2eCreateAndQueryChannel(t, ordererClCtx, org1ClCtx, org2ClCtx, dsChannelExternal, ccID2) } // modify channel config, must be endorsed by two orgs @@ -301,19 +303,37 @@ func e2eCreateAndQueryChannel(t *testing.T, ordererClCtx, org1ClCtx, org2ClCtx * require.NoError(t, err) ccVersion := "1" // ccVersion= 1 because previous test increased the ccVersion # on the peers. - - // instantiate example_CC on dschannel - instantiateCC(t, org1ClCtx.rsCl, exampleCC, ccVersion, channelID) - - // Ensure the CC is instantiated on all peers in both orgs - found := queryInstantiatedCC(t, org1, org1ClCtx.rsCl, channelID, exampleCC, ccVersion, org1Peers) - require.True(t, found, "Failed to find instantiated chaincode [%s:%s] in at least one peer in Org1 on channel [%s]", exampleCC, ccVersion, channelID) - - found = queryInstantiatedCC(t, org2, org2ClCtx.rsCl, channelID, exampleCC, ccVersion, org2Peers) - require.True(t, found, "Failed to find instantiated chaincode [%s:%s] in at least one peer in Org2 on channel [%s]", exampleCC, ccVersion, channelID) - - // test regular querying on dschannel from org1 and org2 - testQueryingOrgs(t, org1ClCtx.sdk, org2ClCtx.sdk, channelID, examplecc) + if metadata.CCMode == "lscc" { + // instantiate example_CC on dschannel + instantiateCC(t, org1ClCtx.rsCl, examplecc, ccVersion, channelID) + + // Ensure the CC is instantiated on all peers in both orgs + found := queryInstantiatedCC(t, org1, org1ClCtx.rsCl, channelID, examplecc, ccVersion, org1Peers) + require.True(t, found, "Failed to find instantiated chaincode [%s:%s] in at least one peer in Org1 on channel [%s]", examplecc, ccVersion, channelID) + + found = queryInstantiatedCC(t, org2, org2ClCtx.rsCl, channelID, examplecc, ccVersion, org2Peers) + require.True(t, found, "Failed to find instantiated chaincode [%s:%s] in at least one peer in Org2 on channel [%s]", examplecc, ccVersion, channelID) + // test regular querying on dschannel from org1 and org2 + testQueryingOrgs(t, org1ClCtx.sdk, org2ClCtx.sdk, channelID, examplecc) + } else { + // TODO: dsChannelExternal needs to be complete + if channelID == dsChannelSDK { + mc := &multiorgContext{ + // client contexts + ordererClientContext: ordererClCtx.clCtx, + org1AdminClientContext: org1ClCtx.clCtx, + org2AdminClientContext: org2ClCtx.clCtx, + org1ResMgmt: org1ClCtx.rsCl, + org2ResMgmt: org2ClCtx.rsCl, + ccName: examplecc, + ccVersion: ccVersion, + channelID: channelID, + } + createCCLifecycle(t, mc, examplecc, ccVersion, 1, true, channelID, org1ClCtx.sdk) + // test regular querying on dschannel from org1 and org2 + testQueryingOrgs(t, org1ClCtx.sdk, org2ClCtx.sdk, channelID, examplecc) + } + } } func generateSignatures(t *testing.T, org1ClCtx, org2ClCtx *dsClientCtx, chConfigPath, chConfigOrg1MSPPath, chConfigOrg2MSPPath, sigDir string, isSDKSigning bool) chCfgSignatures { diff --git a/test/integration/e2e/orgs/multiple_orgs_test.go b/test/integration/e2e/orgs/multiple_orgs_test.go index 7a5dad0d67..ba302dbe50 100644 --- a/test/integration/e2e/orgs/multiple_orgs_test.go +++ b/test/integration/e2e/orgs/multiple_orgs_test.go @@ -17,17 +17,20 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry" "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/status" contextAPI "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context" + "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp" packager "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/gopackager" + lcpackager "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/lifecycle" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/test/metadata" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + mb "github.com/hyperledger/fabric-protos-go/msp" + pb "github.com/hyperledger/fabric-protos-go/peer" "github.com/hyperledger/fabric-sdk-go/pkg/client/ledger" "github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt" - "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/hyperledger/fabric-sdk-go/test/integration" @@ -202,13 +205,19 @@ func testWithOrg1(t *testing.T, sdk *fabsdk.FabricSDK, mc *multiorgContext) int org1ChannelClientContext := sdk.ChannelContext(mc.channelID, fabsdk.WithUser(org1User), fabsdk.WithOrg(org1)) org2ChannelClientContext := sdk.ChannelContext(mc.channelID, fabsdk.WithUser(org2User), fabsdk.WithOrg(org2)) - ccPkg, err := packager.NewCCPackage(ccPath, integration.GetDeployPath()) - if err != nil { - t.Fatal(err) - } + var ccPkg *resource.CCPackage + var err error // Create chaincode package for example cc - createCC(t, mc, ccPkg, mc.ccName, mc.ccVersion) + if metadata.CCMode == "lscc" { + ccPkg, err = packager.NewCCPackage(ccPath, integration.GetDeployPath()) + if err != nil { + t.Fatal(err) + } + createCC(t, mc, ccPkg, mc.ccName, mc.ccVersion) + } else { + createCCLifecycle(t, mc, mc.ccName, mc.ccVersion, 1, false, mc.channelID, sdk) + } chClientOrg1User, chClientOrg2User := createOrgsChannelClients(org1ChannelClientContext, t, org2ChannelClientContext) @@ -237,7 +246,13 @@ func testWithOrg1(t *testing.T, sdk *fabsdk.FabricSDK, mc *multiorgContext) int checkLedgerInfo(ledgerClient, t, ledgerInfoBefore, transactionID) // Start chaincode upgrade process (install and instantiate new version of exampleCC) - upgradeCC(t, mc, ccPkg, mc.ccName, "1") + if metadata.CCMode == "lscc" { + upgradeCC(t, mc, ccPkg, mc.ccName, "1") + } else { + createCCLifecycle(t, mc, mc.ccName, "1", 2, true, mc.channelID, sdk) + //sleep 10s for chaincode cache + //time.Sleep(time.Duration(10) * time.Second) + } // Org2 user moves funds on org2 peer (cc policy fails since both Org1 and Org2 peers should participate) testCCPolicy(chClientOrg2User, t, mc.ccName) @@ -679,3 +694,376 @@ func loadOrgPeers(t *testing.T, ctxProvider contextAPI.ClientProvider) { } } + +// createCCLifecycle package cc, install cc, get installed cc package, query installed cc +// approve cc, query approve cc, check commit readiness, commit cc, query committed cc +func createCCLifecycle(t *testing.T, mc *multiorgContext, ccName, ccVersion string, sequence int64, upgrade bool, channelID string, sdk *fabsdk.FabricSDK) { + // Package cc + label, ccPkg := packageCC(t, ccName, ccVersion) + packageID := lcpackager.ComputePackageID(label, ccPkg) + + // Install cc + installCC(t, label, ccPkg, mc) + + // Get installed cc package + getInstalledCCPackage(t, packageID, ccPkg, mc) + + // Query installed cc + queryInstalled(t, label, packageID, mc) + + // Approve cc + approveCC(t, packageID, ccName, ccVersion, sequence, channelID, mc) + + // Query approve cc + queryApprovedCC(t, ccName, sequence, channelID, mc) + + // Check commit readiness + checkCCCommitReadiness(t, packageID, ccName, ccVersion, sequence, channelID, mc) + + // Commit cc + commitCC(t, ccName, ccVersion, sequence, channelID, mc) + + // Query committed cc + queryCommittedCC(t, ccName, channelID, sequence, mc) + + // Init cc + initCC(t, ccName, upgrade, channelID, sdk) +} + +func packageCC(t *testing.T, ccName, ccVersion string) (string, []byte) { + label := ccName + "_" + ccVersion + desc := &lcpackager.Descriptor{ + Path: integration.GetLcDeployPath(), + Type: pb.ChaincodeSpec_GOLANG, + Label: label, + } + ccPkg, err := lcpackager.NewCCPackage(desc) + if err != nil { + t.Fatal(err) + } + return desc.Label, ccPkg +} + +func installCC(t *testing.T, label string, ccPkg []byte, mc *multiorgContext) { + installCCReq := resmgmt.LifecycleInstallCCRequest{ + Label: label, + Package: ccPkg, + } + + packageID := lcpackager.ComputePackageID(installCCReq.Label, installCCReq.Package) + org1Peers, err := integration.DiscoverLocalPeers(mc.org1AdminClientContext, 2) + require.NoError(t, err) + if !checkInstalled(t, packageID, org1Peers[0], mc.org1ResMgmt) { + resp1, err := mc.org1ResMgmt.LifecycleInstallCC(installCCReq, resmgmt.WithTargets(org1Peers...), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.Equal(t, packageID, resp1[0].PackageID) + } + org2Peers, err := integration.DiscoverLocalPeers(mc.org2AdminClientContext, 2) + require.NoError(t, err) + if !checkInstalled(t, packageID, org2Peers[0], mc.org2ResMgmt) { + resp2, err := mc.org2ResMgmt.LifecycleInstallCC(installCCReq, resmgmt.WithTargets(org2Peers...), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.Equal(t, packageID, resp2[0].PackageID) + } +} + +func getInstalledCCPackage(t *testing.T, packageID string, ccPkg []byte, mc *multiorgContext) { + + org1Peers, err := integration.DiscoverLocalPeers(mc.org1AdminClientContext, 1) + require.NoError(t, err) + + resp1, err := mc.org1ResMgmt.LifecycleGetInstalledCCPackage(packageID, resmgmt.WithTargets([]fab.Peer{org1Peers[0]}...)) + if err != nil { + t.Fatal(err) + } + require.Equal(t, ccPkg, resp1) +} + +func queryInstalled(t *testing.T, label string, packageID string, mc *multiorgContext) { + org1Peers, err := integration.DiscoverLocalPeers(mc.org1AdminClientContext, 1) + require.NoError(t, err) + resp1, err := mc.org1ResMgmt.LifecycleQueryInstalledCC(resmgmt.WithTargets([]fab.Peer{org1Peers[0]}...)) + if err != nil { + t.Fatal(err) + } + packageID1 := "" + for _, t := range resp1 { + if t.PackageID == packageID { + packageID1 = t.PackageID + } + } + require.Equal(t, packageID, packageID1) + +} + +func checkInstalled(t *testing.T, packageID string, peer fab.Peer, client *resmgmt.Client) bool { + flag := false + resp1, err := client.LifecycleQueryInstalledCC(resmgmt.WithTargets(peer)) + if err != nil { + t.Fatal(err) + } + for _, t := range resp1 { + if t.PackageID == packageID { + flag = true + } + } + return flag +} + +func approveCC(t *testing.T, packageID string, ccName, ccVersion string, sequence int64, channelID string, mc *multiorgContext) { + org1Peers, err := integration.DiscoverLocalPeers(mc.org1AdminClientContext, 2) + require.NoError(t, err) + org2Peers, err := integration.DiscoverLocalPeers(mc.org2AdminClientContext, 2) + require.NoError(t, err) + ccPolicy := policydsl.SignedByNOutOfGivenRole(2, mb.MSPRole_MEMBER, []string{"Org1MSP", "Org2MSP"}) + approveCCReq := resmgmt.LifecycleApproveCCRequest{ + Name: ccName, + Version: ccVersion, + PackageID: packageID, + Sequence: sequence, + EndorsementPlugin: "escc", + ValidationPlugin: "vscc", + SignaturePolicy: ccPolicy, + InitRequired: true, + } + + txnID1, err := mc.org1ResMgmt.LifecycleApproveCC(channelID, approveCCReq, resmgmt.WithTargets(org1Peers...), resmgmt.WithOrdererEndpoint("orderer.example.com"), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.NotEmpty(t, txnID1) + + txnID2, err := mc.org2ResMgmt.LifecycleApproveCC(channelID, approveCCReq, resmgmt.WithTargets(org2Peers...), resmgmt.WithOrdererEndpoint("orderer.example.com"), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.NotEmpty(t, txnID2) +} + +func queryApprovedCC(t *testing.T, ccName string, sequence int64, channelID string, mc *multiorgContext) { + org1Peers, err := integration.DiscoverLocalPeers(mc.org1AdminClientContext, 2) + require.NoError(t, err) + org2Peers, err := integration.DiscoverLocalPeers(mc.org2AdminClientContext, 2) + require.NoError(t, err) + // Query approve cc + queryApprovedCCReq := resmgmt.LifecycleQueryApprovedCCRequest{ + Name: ccName, + Sequence: sequence, + } + for _, p := range org1Peers { + resp, err := retry.NewInvoker(retry.New(retry.TestRetryOpts)).Invoke( + func() (interface{}, error) { + resp1, err := mc.org1ResMgmt.LifecycleQueryApprovedCC(channelID, queryApprovedCCReq, resmgmt.WithTargets(p), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleQueryApprovedCC returned error: %v", err), nil) + } + return resp1, err + }, + ) + if err != nil { + t.Fatal(err) + } + require.NotNil(t, resp) + } + for _, p := range org2Peers { + resp, err := retry.NewInvoker(retry.New(retry.TestRetryOpts)).Invoke( + func() (interface{}, error) { + resp1, err := mc.org2ResMgmt.LifecycleQueryApprovedCC(channelID, queryApprovedCCReq, resmgmt.WithTargets(p), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleQueryApprovedCC returned error: %v", err), nil) + } + return resp1, err + }, + ) + if err != nil { + t.Fatal(err) + } + require.NotNil(t, resp) + } + +} + +func checkCCCommitReadiness(t *testing.T, packageID string, ccName, ccVersion string, sequence int64, channelID string, mc *multiorgContext) { + + org1Peers, err := integration.DiscoverLocalPeers(mc.org1AdminClientContext, 2) + require.NoError(t, err) + org2Peers, err := integration.DiscoverLocalPeers(mc.org2AdminClientContext, 2) + require.NoError(t, err) + + ccPolicy := policydsl.SignedByNOutOfGivenRole(2, mb.MSPRole_MEMBER, []string{"Org1MSP", "Org2MSP"}) + req := resmgmt.LifecycleCheckCCCommitReadinessRequest{ + Name: ccName, + Version: ccVersion, + PackageID: packageID, + EndorsementPlugin: "escc", + ValidationPlugin: "vscc", + SignaturePolicy: ccPolicy, + Sequence: sequence, + InitRequired: true, + } + /*resp1, err := mc.org1ResMgmt.LifecycleCheckCCCommitReadiness(channelID, req, resmgmt.WithTargets([]fab.Peer{org1Peers[0]}...), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.NotNil(t, resp1)*/ + for _, p := range org1Peers { + resp, err := retry.NewInvoker(retry.New(retry.TestRetryOpts)).Invoke( + func() (interface{}, error) { + resp1, err := mc.org1ResMgmt.LifecycleCheckCCCommitReadiness(channelID, req, resmgmt.WithTargets(p), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + fmt.Printf("LifecycleCheckCCCommitReadiness cc = %v, = %v\n", ccName, resp1) + if err != nil { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleCheckCCCommitReadiness returned error: %v", err), nil) + } + flag := true + for _, r := range resp1.Approvals { + flag = flag && r + } + if !flag { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleCheckCCCommitReadiness returned : %v", resp1), nil) + } + return resp1, err + }, + ) + if err != nil { + t.Fatal(err) + } + require.NotNil(t, resp) + } + for _, p := range org2Peers { + resp, err := retry.NewInvoker(retry.New(retry.TestRetryOpts)).Invoke( + func() (interface{}, error) { + resp1, err := mc.org2ResMgmt.LifecycleCheckCCCommitReadiness(channelID, req, resmgmt.WithTargets(p), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + fmt.Printf("LifecycleCheckCCCommitReadiness cc = %v, = %v\n", ccName, resp1) + if err != nil { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleCheckCCCommitReadiness returned error: %v", err), nil) + } + flag := true + for _, r := range resp1.Approvals { + flag = flag && r + } + if !flag { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleCheckCCCommitReadiness returned : %v", resp1), nil) + } + return resp1, err + }, + ) + if err != nil { + t.Fatal(err) + } + require.NotNil(t, resp) + } + +} + +func commitCC(t *testing.T, ccName, ccVersion string, sequence int64, channelID string, mc *multiorgContext) { + ccPolicy := policydsl.SignedByNOutOfGivenRole(2, mb.MSPRole_MEMBER, []string{"Org1MSP", "Org2MSP"}) + req := resmgmt.LifecycleCommitCCRequest{ + Name: ccName, + Version: ccVersion, + Sequence: sequence, + EndorsementPlugin: "escc", + ValidationPlugin: "vscc", + SignaturePolicy: ccPolicy, + InitRequired: true, + } + txnID, err := mc.org1ResMgmt.LifecycleCommitCC(channelID, req, resmgmt.WithOrdererEndpoint("orderer.example.com"), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.NotEmpty(t, txnID) +} + +func queryCommittedCC(t *testing.T, ccName string, channelID string, sequence int64, mc *multiorgContext) { + org1Peers, err := integration.DiscoverLocalPeers(mc.org1AdminClientContext, 2) + require.NoError(t, err) + org2Peers, err := integration.DiscoverLocalPeers(mc.org2AdminClientContext, 2) + require.NoError(t, err) + + req := resmgmt.LifecycleQueryCommittedCCRequest{ + Name: ccName, + } + /*resp1, err := mc.org1ResMgmt.LifecycleQueryCommittedCC(channelID, req, resmgmt.WithTargets(org1Peers[0]), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + }*/ + for _, p := range org1Peers { + resp, err := retry.NewInvoker(retry.New(retry.TestRetryOpts)).Invoke( + func() (interface{}, error) { + resp1, err := mc.org1ResMgmt.LifecycleQueryCommittedCC(channelID, req, resmgmt.WithTargets(p), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleQueryCommittedCC returned error: %v", err), nil) + } + flag := false + for _, r := range resp1 { + if r.Name == ccName && r.Sequence == sequence { + flag = true + break + } + } + if !flag { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleQueryCommittedCC returned : %v", resp1), nil) + } + return resp1, err + }, + ) + if err != nil { + t.Fatal(err) + } + require.NotNil(t, resp) + } + for _, p := range org2Peers { + resp, err := retry.NewInvoker(retry.New(retry.TestRetryOpts)).Invoke( + func() (interface{}, error) { + resp1, err := mc.org2ResMgmt.LifecycleQueryCommittedCC(channelID, req, resmgmt.WithTargets(p), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleQueryCommittedCC returned error: %v", err), nil) + } + flag := false + for _, r := range resp1 { + if r.Name == ccName && r.Sequence == sequence { + flag = true + break + } + } + if !flag { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleQueryCommittedCC returned : %v", resp1), nil) + } + return resp1, err + }, + ) + if err != nil { + t.Fatal(err) + } + require.NotNil(t, resp) + } + +} + +func initCC(t *testing.T, ccName string, upgrade bool, channelID string, sdk *fabsdk.FabricSDK) { + //prepare channel client context using client context + clientChannelContext := sdk.ChannelContext(channelID, fabsdk.WithUser(org1User), fabsdk.WithOrg(org1)) + // Channel client is used to query and execute transactions (Org1 is default org) + client, err := channel.New(clientChannelContext) + if err != nil { + t.Fatalf("Failed to create new channel client: %s", err) + } + + var args [][]byte + if upgrade { + args = integration.ExampleCCUpgradeArgsLc() + } else { + args = integration.ExampleCCInitArgsLc() + } + + // init + _, err = client.Execute(channel.Request{ChaincodeID: ccName, Fcn: "init", Args: args, IsInit: true}, + channel.WithRetry(retry.DefaultChannelOpts)) + if err != nil { + t.Fatalf("Failed to init: %s", err) + } + +} diff --git a/test/integration/negative/revoked/revoked_test.go b/test/integration/negative/revoked/revoked_test.go index cad77d3420..af434d9d5d 100644 --- a/test/integration/negative/revoked/revoked_test.go +++ b/test/integration/negative/revoked/revoked_test.go @@ -42,6 +42,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fab/resource" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/test/integration" + "github.com/hyperledger/fabric-sdk-go/test/metadata" "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/policydsl" ) @@ -108,7 +109,7 @@ func TestPeerAndUserRevoke(t *testing.T) { updateRevocationList(t, nil) } -//joinChannelAndInstallCC joins channel and install/instantiate/query 'exampleCC2' +//joinChannelAndInstallCC joins channel and install/instantiate/query 'example_cc_fabtest_e2e_2' func joinChannelAndInstallCC(t *testing.T) { sdk, err := fabsdk.New(config.FromFile(integration.GetConfigPath(configFilename))) require.NoError(t, err) @@ -123,11 +124,11 @@ func joinChannelAndInstallCC(t *testing.T) { joinChannel(t, sdk) //install & instantiate a chaincode before updating revocation list for later test - createCC(t, sdk, "exampleCC2", "github.com/example_cc", "0", true) + createCC(t, sdk, "example_cc_fabtest_e2e_2", "github.com/example_cc", "0", true) //query that chaincode to make sure everything is fine org2UserChannelClientContext := sdk.ChannelContext(channelID, fabsdk.WithUser(org2User), fabsdk.WithOrg(org2)) - queryCC(t, org2UserChannelClientContext, "exampleCC2", true, "") + queryCC(t, org2UserChannelClientContext, "example_cc_fabtest_e2e_2", true, "") } @@ -194,20 +195,20 @@ func testRevokedPeer(t *testing.T) { org2UserChannelClientContext := sdk1.ChannelContext(channelID, fabsdk.WithUser(org2User), fabsdk.WithOrg(org2)) // Create chaincode package for example cc - createCC(t, sdk1, "exampleCC", "github.com/example_cc", "1", false) + createCC(t, sdk1, "example_cc_fabtest_e2e", "github.com/example_cc", "1", false) //query with revoked user t.Log("query with revoked user - should fail with 'access denied'") - queryCC(t, org1UserChannelClientContext, "exampleCC", false, "access denied") + queryCC(t, org1UserChannelClientContext, "example_cc_fabtest_e2e", false, "access denied") //query with valid user - t.Log("query with valid user - should fail with 'chaincode exampleCC not found'") - queryCC(t, org2UserChannelClientContext, "exampleCC", false, "chaincode exampleCC not found") + t.Log("query with valid user - should fail with 'chaincode example_cc_fabtest_e2e not found'") + queryCC(t, org2UserChannelClientContext, "example_cc_fabtest_e2e", false, "chaincode example_cc_fabtest_e2e not found") //query already instantiated chaincode with revoked user t.Log("query already instantiated chaincode with revoked user - should fail with 'access denied'") - queryCC(t, org1UserChannelClientContext, "exampleCC2", false, "access denied") + queryCC(t, org1UserChannelClientContext, "example_cc_fabtest_e2e_2", false, "access denied") //query already instantiated chaincode with valid user t.Log("query already instantiated chaincode with valid user - should fail with 'signature validation failed'") - queryCC(t, org2UserChannelClientContext, "exampleCC2", false, "signature validation failed") + queryCC(t, org2UserChannelClientContext, "example_cc_fabtest_e2e_2", false, "signature validation failed") } //testRevokedUser performs revoke peer test @@ -367,43 +368,7 @@ func createConfigEnvelopeReader(t *testing.T, blockData []byte, configUpdateByte } func joinChannel(t *testing.T, sdk *fabsdk.FabricSDK) { - joinChannelFunc := func() error { - - org1AdminClientContext := sdk.Context(fabsdk.WithUser(org1AdminUser), fabsdk.WithOrg(org1)) - org2AdminClientContext := sdk.Context(fabsdk.WithUser(org2AdminUser), fabsdk.WithOrg(org2)) - - org1ResMgmt, err := resmgmt.New(org1AdminClientContext) - require.NoError(t, err) - - org2ResMgmt, err := resmgmt.New(org2AdminClientContext) - require.NoError(t, err) - - // Org1 peers join channel - if err := org1ResMgmt.JoinChannel("orgchannel", resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint("orderer.example.com")); err != nil { - return err - } - - // Org2 peers join channel - if err := org2ResMgmt.JoinChannel("orgchannel", resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint("orderer.example.com")); err != nil { - return err - } - - t.Log("joined channel successfully") - return nil - } - - //join channel - err := joinChannelFunc() - if err == nil { - return - } - - if !strings.Contains(err.Error(), "genesis block retrieval failed: Orderer Server Status Code: (404) NOT_FOUND.") { - t.Fatalf("Failed to join channel, error : %v", err) - } - - t.Logf("Failed to join channel due to : %v, \n Now performing save channel with orderer client and retrying", err) - + var lastConfigBlock uint64 ordererClientContext := sdk.Context(fabsdk.WithUser(ordererAdminUser), fabsdk.WithOrg(ordererOrgName)) ordererResMgmt, err := resmgmt.New(ordererClientContext) @@ -420,18 +385,61 @@ func joinChannel(t *testing.T, sdk *fabsdk.FabricSDK) { org2AdminIdenity, err := org2MspClient.GetSigningIdentity(org2AdminUser) require.NoError(t, err, "failed to get org2AdminIdentity") + org1AdminClientContext := sdk.Context(fabsdk.WithUser(org1AdminUser), fabsdk.WithOrg(org1)) + org2AdminClientContext := sdk.Context(fabsdk.WithUser(org2AdminUser), fabsdk.WithOrg(org2)) + + org1ResMgmt, err := resmgmt.New(org1AdminClientContext) + require.NoError(t, err) + + org2ResMgmt, err := resmgmt.New(org2AdminClientContext) + require.NoError(t, err) + + org1Peers, err := integration.DiscoverLocalPeers(org1AdminClientContext, 1) + require.NoError(t, err) + + joined, err := integration.IsJoinedChannel("orgchannel", org1ResMgmt, org1Peers[0]) + require.NoError(t, err) + + if joined { + return + } req := resmgmt.SaveChannelRequest{ChannelID: "orgchannel", ChannelConfigPath: integration.GetChannelConfigTxPath("orgchannel.tx"), SigningIdentities: []msp2.SigningIdentity{org1AdminIdentity, org2AdminIdenity}} - txID, err := ordererResMgmt.SaveChannel(req, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint("orderer.example.com")) + ordererResMgmt.SaveChannel(req, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint("orderer.example.com")) + + req1 := resmgmt.SaveChannelRequest{ + ChannelID: "orgchannel", + ChannelConfigPath: integration.GetChannelConfigTxPath("orgchannelOrg1MSPanchors.tx"), + SigningIdentities: []msp2.SigningIdentity{org1AdminIdentity}, + } + _, err = org1ResMgmt.SaveChannel(req1, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint("orderer.example.com")) require.Nil(t, err, "error should be nil") - require.NotEmpty(t, txID, "transaction ID should be populated") - //Try again now - err = joinChannelFunc() + lastConfigBlock = integration.WaitForOrdererConfigUpdate(t, org1ResMgmt, "orgchannel", false, lastConfigBlock) + + req2 := resmgmt.SaveChannelRequest{ + ChannelID: "orgchannel", + ChannelConfigPath: integration.GetChannelConfigTxPath("orgchannelOrg2MSPanchors.tx"), + SigningIdentities: []msp2.SigningIdentity{org2AdminIdenity}, + } + _, err = org2ResMgmt.SaveChannel(req2, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint("orderer.example.com")) + require.Nil(t, err, "error should be nil") + + lastConfigBlock = integration.WaitForOrdererConfigUpdate(t, org2ResMgmt, "orgchannel", false, lastConfigBlock) + + // Org1 peers join channel + err = org1ResMgmt.JoinChannel("orgchannel", resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint("orderer.example.com")) require.NoError(t, err, "failed to join channel...") + // Org2 peers join channel + err = org2ResMgmt.JoinChannel("orgchannel", resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint("orderer.example.com")) + require.NoError(t, err, "failed to join channel...") + + t.Log("joined channel successfully") + return + } func queryCC(t *testing.T, channelClientContext contextAPI.ChannelProvider, ccID string, success bool, expectedMsg string) { @@ -473,46 +481,101 @@ func createCC(t *testing.T, sdk1 *fabsdk.FabricSDK, name, path, version string, org2ResMgmt, err := resmgmt.New(org2AdminClientContext) require.NoError(t, err) - ccPkg, err := packager.NewCCPackage(path, integration.GetDeployPath()) - if err != nil { - t.Fatal(err) - } - installCCReq := resmgmt.InstallCCRequest{Name: name, Path: path, Version: version, Package: ccPkg} - // Install example cc to Org1 peers - _, err = org1ResMgmt.InstallCC(installCCReq) - if err != nil { - t.Fatal(err) - } - // Install example cc to Org2 peers - _, err = org2ResMgmt.InstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) - if err != nil { - t.Fatal(err) - } - // Set up chaincode policy to 'two-of-two msps' - ccPolicy, err := policydsl.FromString("AND ('Org1MSP.member','Org2MSP.member')") - require.NoErrorf(t, err, "Error creating cc policy with both orgs to approve") - // Org1 resource manager will instantiate 'example_cc' on 'orgchannel' - resp, err := org1ResMgmt.InstantiateCC( - "orgchannel", - resmgmt.InstantiateCCRequest{ - Name: name, - Path: path, - Version: version, - Args: integration.ExampleCCInitArgs(), - Policy: ccPolicy, - }, - resmgmt.WithTargetEndpoints("peer1.org1.example.com","peer0.org2.example.com"), - ) + if metadata.CCMode == "lscc" { - if success { - require.NoError(t, err) - require.NotEmpty(t, resp.TransactionID) + ccPkg, err := packager.NewCCPackage(path, integration.GetDeployPath()) + if err != nil { + t.Fatal(err) + } + installCCReq := resmgmt.InstallCCRequest{Name: name, Path: path, Version: version, Package: ccPkg} + // Install example cc to Org1 peers + _, err = org1ResMgmt.InstallCC(installCCReq) + if err != nil { + t.Fatal(err) + } + // Install example cc to Org2 peers + _, err = org2ResMgmt.InstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + // Set up chaincode policy to 'two-of-two msps' + ccPolicy, err := policydsl.FromString("AND ('Org1MSP.member','Org2MSP.member')") + require.NoErrorf(t, err, "Error creating cc policy with both orgs to approve") + // Org1 resource manager will instantiate 'example_cc' on 'orgchannel' + resp, err := org1ResMgmt.InstantiateCC( + "orgchannel", + resmgmt.InstantiateCCRequest{ + Name: name, + Path: path, + Version: version, + Args: integration.ExampleCCInitArgs(), + Policy: ccPolicy, + }, + resmgmt.WithTargetEndpoints("peer1.org1.example.com", "peer0.org2.example.com"), + ) + + if success { + require.NoError(t, err) + require.NotEmpty(t, resp.TransactionID) + } else { + require.Errorf(t, err, "Expecting error instantiating CC on peer with revoked certificate") + stat, ok := status.FromError(err) + require.Truef(t, ok, "Expecting error to be a status error, but got ", err) + require.Equalf(t, stat.Code, int32(status.SignatureVerificationFailed), "Expecting signature verification error due to revoked cert, but got", err) + require.Truef(t, strings.Contains(err.Error(), "the creator certificate is not valid"), "Expecting error message to contain 'the creator certificate is not valid' but got", err) + } } else { - require.Errorf(t, err, "Expecting error instantiating CC on peer with revoked certificate") - stat, ok := status.FromError(err) - require.Truef(t, ok, "Expecting error to be a status error, but got ", err) - require.Equalf(t, stat.Code, int32(status.SignatureVerificationFailed), "Expecting signature verification error due to revoked cert, but got", err) - require.Truef(t, strings.Contains(err.Error(), "the creator certificate is not valid"), "Expecting error message to contain 'the creator certificate is not valid' but got", err) + orgsContext := setupOrgContext(t, sdk1, org1AdminClientContext, org2AdminClientContext, org1ResMgmt, org2ResMgmt) + err = integration.InstantiateExampleChaincodeLc(sdk1, orgsContext, "orgchannel", name, "AND('Org1MSP.member','Org2MSP.member')") + if success { + require.NoError(t, err) + } else { + require.Errorf(t, err, "Expecting error instantiating CC on peer with revoked certificate") + stat, ok := status.FromError(err) + require.Truef(t, ok, "Expecting error to be a status error, but got ", err) + require.Equalf(t, stat.Code, int32(status.SignatureVerificationFailed), "Expecting signature verification error due to revoked cert, but got", err) + require.Truef(t, strings.Contains(err.Error(), "the creator certificate is not valid"), "Expecting error message to contain 'the creator certificate is not valid' but got", err) + } + } +} + +func setupOrgContext(t *testing.T, sdk1 *fabsdk.FabricSDK, org1AdminContext, org2AdminContext contextAPI.ClientProvider, org1ResMgmt, org2ResMgmt *resmgmt.Client) []*integration.OrgContext { + + sdk := sdk1 + org1MspClient, err := mspclient.New(sdk.Context(), mspclient.WithOrg(org1)) + require.NoError(t, err) + org1AdminUser, err := org1MspClient.GetSigningIdentity(org1AdminUser) + require.NoError(t, err) + + org2MspClient, err := mspclient.New(sdk.Context(), mspclient.WithOrg(org2)) + require.NoError(t, err) + org2AdminUser, err := org2MspClient.GetSigningIdentity(org2AdminUser) + require.NoError(t, err) + + // Ensure that Gossip has propagated it's view of local peers before invoking + // install since some peers may be missed if we call InstallCC too early + org1Peers, err := integration.DiscoverLocalPeers(org1AdminContext, 2) + require.NoError(t, err) + org2Peers, err := integration.DiscoverLocalPeers(org2AdminContext, 2) + require.NoError(t, err) + + return []*integration.OrgContext{ + { + OrgID: org1, + CtxProvider: org1AdminContext, + ResMgmt: org1ResMgmt, + Peers: org1Peers, + SigningIdentity: org1AdminUser, + AnchorPeerConfigFile: "orgchannelOrg1MSPanchors.tx", + }, + { + OrgID: org2, + CtxProvider: org2AdminContext, + ResMgmt: org2ResMgmt, + Peers: org2Peers, + SigningIdentity: org2AdminUser, + AnchorPeerConfigFile: "orgchannelOrg2MSPanchors.tx", + }, } } diff --git a/test/integration/pkg/client/channel/channel_client_pvt_test.go b/test/integration/pkg/client/channel/channel_client_pvt_test.go index 92a36ce6ea..1a74ee3e27 100644 --- a/test/integration/pkg/client/channel/channel_client_pvt_test.go +++ b/test/integration/pkg/client/channel/channel_client_pvt_test.go @@ -31,6 +31,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/test/integration" + "github.com/hyperledger/fabric-sdk-go/test/metadata" ) // TestPrivateDataPutAndGet tests put and get for private data @@ -46,10 +47,15 @@ func TestPrivateDataPutAndGet(t *testing.T) { collConfig, err := newCollectionConfig(coll1, "OR('Org1MSP.member','Org2MSP.member')", 0, 2, 1000) require.NoError(t, err) - err = integration.InstallExamplePvtChaincode(orgsContext, ccID) - require.NoError(t, err) - err = integration.InstantiateExamplePvtChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')", collConfig) - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExamplePvtChaincode(orgsContext, ccID) + require.NoError(t, err) + err = integration.InstantiateExamplePvtChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')", collConfig) + require.NoError(t, err) + } else { + err := integration.InstantiatePvtExampleChaincodeLc(sdk, orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')", collConfig) + require.NoError(t, err) + } ctxProvider := sdk.ChannelContext(orgChannelID, fabsdk.WithUser(org1User), fabsdk.WithOrg(org1Name)) @@ -160,10 +166,15 @@ func TestPrivateData(t *testing.T) { collConfig, err := newCollectionConfig(coll1, "OR('Org2MSP.member')", 0, 2, 1000) require.NoError(t, err) - err = integration.InstallExamplePvtChaincode(orgsContext, ccID) - require.NoError(t, err) - err = integration.InstantiateExamplePvtChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')", collConfig) - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExamplePvtChaincode(orgsContext, ccID) + require.NoError(t, err) + err = integration.InstantiateExamplePvtChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')", collConfig) + require.NoError(t, err) + } else { + err := integration.InstantiatePvtExampleChaincodeLc(sdk, orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')", collConfig) + require.NoError(t, err) + } ctxProvider := sdk.ChannelContext(orgChannelID, fabsdk.WithUser(org1User), fabsdk.WithOrg(org1Name)) @@ -206,6 +217,10 @@ func TestPrivateData(t *testing.T) { // none of the peers of a private collection's org being available. The chaincode policy is defined as (Org1MSP OR Org2MSP) // and the collection policy is defined as (Org2MSP). func TestPrivateDataWithOrgDown(t *testing.T) { + // 'ApproveChaincodeDefinitionForMyOrg' failed: error validating chaincode definition: collection-name: collection1 -- collection member 'Org3MSP' is not part of the channel + if metadata.CCMode != "lscc" { + t.Skip("this test is only valid for legacy chaincode") + } sdk := mainSDK orgsContext := setupMultiOrgContext(t, sdk) @@ -257,92 +272,98 @@ func TestPrivateDataWithOrgDown(t *testing.T) { t.Logf("Got %d response(s)", len(response.Responses)) require.NotEmptyf(t, response.Responses, "expecting at least one response") }) + } // Data in a private data collection must be left untouched if the client receives an MVCC_READ_CONFLICT error. // We test this by submitting two cumulative changes to a private data collection, ensuring that the MVCC_READ_CONFLICT error // is reproduced, then asserting that only one of the changes was applied. func TestChannelClientRollsBackPvtDataIfMvccReadConflict(t *testing.T) { - orgsContext := setupMultiOrgContext(t, mainSDK) - require.NoError(t, integration.EnsureChannelCreatedAndPeersJoined(t, mainSDK, orgChannelID, "orgchannel.tx", orgsContext)) - // private data collection used for test - const coll = "collection1" - // collection key used for test - const key = "collection_key" - ccID := integration.GenerateExamplePvtID(true) - collConfig, err := newCollectionConfig(coll, "OR('Org1MSP.member','Org2MSP.member','Org3MSP.member')", 0, 2, 1000) - require.NoError(t, err) - require.NoError(t, integration.InstallExamplePvtChaincode(orgsContext, ccID)) - require.NoError(t, integration.InstantiateExamplePvtChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member','Org3MSP.member')", collConfig)) - ctxProvider := mainSDK.ChannelContext(orgChannelID, fabsdk.WithUser(org1User), fabsdk.WithOrg(org1Name)) - chClient, err := channel.New(ctxProvider) - require.NoError(t, err) + // 'ApproveChaincodeDefinitionForMyOrg' failed: error validating chaincode definition: collection-name: collection1 -- collection member 'Org3MSP' is not part of the channel + if metadata.CCMode == "lscc" { + orgsContext := setupMultiOrgContext(t, mainSDK) + require.NoError(t, integration.EnsureChannelCreatedAndPeersJoined(t, mainSDK, orgChannelID, "orgchannel.tx", orgsContext)) + // private data collection used for test + const coll = "collection1" + // collection key used for test + const key = "collection_key" + ccID := integration.GenerateExamplePvtID(true) + collConfig, err := newCollectionConfig(coll, "OR('Org1MSP.member','Org2MSP.member','Org3MSP.member')", 0, 2, 1000) + require.NoError(t, err) - var errMtx sync.Mutex - errs := multi.Errors{} - var wg sync.WaitGroup + require.NoError(t, integration.InstallExamplePvtChaincode(orgsContext, ccID)) + require.NoError(t, integration.InstantiateExamplePvtChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member','Org3MSP.member')", collConfig)) - // test function; invokes a CC function that mutates the private data collection - changePvtData := func(amount int) { - defer wg.Done() - _, err := chClient.Execute( - channel.Request{ - ChaincodeID: ccID, - Fcn: "addToInt", - Args: [][]byte{[]byte(coll), []byte(key), []byte(strconv.Itoa(amount))}, - }, - ) - if err != nil { - errMtx.Lock() - errs = append(errs, err) - errMtx.Unlock() - return - } - } + ctxProvider := mainSDK.ChannelContext(orgChannelID, fabsdk.WithUser(org1User), fabsdk.WithOrg(org1Name)) + chClient, err := channel.New(ctxProvider) + require.NoError(t, err) + + var errMtx sync.Mutex + errs := multi.Errors{} + var wg sync.WaitGroup - // expected value at the end of the test - const expected = 10 - - wg.Add(2) - go changePvtData(expected) - go changePvtData(expected) - wg.Wait() - - // ensure the MVCC_READ_CONFLICT was reproduced - require.Truef(t, len(errs) > 0 && strings.Contains(errs[0].Error(), "MVCC_READ_CONFLICT"), "could not reproduce MVCC_READ_CONFLICT") - - // read current value of private data collection - //resp, err := chClient.Query( - // channel.Request{ - // ChaincodeID: ccID, - // Fcn: "getprivate", - // Args: [][]byte{[]byte(coll), []byte(key)}, - // }, - // channel.WithRetry(retry.TestRetryOpts), - //) - resp, err := retry.NewInvoker(retry.New(retry.TestRetryOpts)).Invoke( - func() (interface{}, error) { - b, e := chClient.Query( + // test function; invokes a CC function that mutates the private data collection + changePvtData := func(amount int) { + defer wg.Done() + _, err := chClient.Execute( channel.Request{ ChaincodeID: ccID, - Fcn: "getprivate", - Args: [][]byte{[]byte(coll), []byte(key)}, + Fcn: "addToInt", + Args: [][]byte{[]byte(coll), []byte(key), []byte(strconv.Itoa(amount))}, }, - channel.WithRetry(retry.TestRetryOpts), ) - if e != nil || strings.TrimSpace(string(b.Payload)) == "" { - return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("getprivate data returned error: %v", e), nil) + if err != nil { + errMtx.Lock() + errs = append(errs, err) + errMtx.Unlock() + return } - return b, e - }, - ) - require.NoErrorf(t, err, "error attempting to read private data") - require.NotEmptyf(t, strings.TrimSpace(string(resp.(channel.Response).Payload)), "reading private data returned empty response") + } - actual, err := strconv.Atoi(string(resp.(channel.Response).Payload)) - require.NoError(t, err) + // expected value at the end of the test + const expected = 10 + + wg.Add(2) + go changePvtData(expected) + go changePvtData(expected) + wg.Wait() + + // ensure the MVCC_READ_CONFLICT was reproduced + require.Truef(t, len(errs) > 0 && strings.Contains(errs[0].Error(), "MVCC_READ_CONFLICT"), "could not reproduce MVCC_READ_CONFLICT") + + // read current value of private data collection + //resp, err := chClient.Query( + // channel.Request{ + // ChaincodeID: ccID, + // Fcn: "getprivate", + // Args: [][]byte{[]byte(coll), []byte(key)}, + // }, + // channel.WithRetry(retry.TestRetryOpts), + //) + resp, err := retry.NewInvoker(retry.New(retry.TestRetryOpts)).Invoke( + func() (interface{}, error) { + b, e := chClient.Query( + channel.Request{ + ChaincodeID: ccID, + Fcn: "getprivate", + Args: [][]byte{[]byte(coll), []byte(key)}, + }, + channel.WithRetry(retry.TestRetryOpts), + ) + if e != nil || strings.TrimSpace(string(b.Payload)) == "" { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("getprivate data returned error: %v", e), nil) + } + return b, e + }, + ) + require.NoErrorf(t, err, "error attempting to read private data") + require.NotEmptyf(t, strings.TrimSpace(string(resp.(channel.Response).Payload)), "reading private data returned empty response") - assert.Truef(t, actual == expected, "Private data not rolled back during MVCC_READ_CONFLICT") + actual, err := strconv.Atoi(string(resp.(channel.Response).Payload)) + require.NoError(t, err) + + assert.Truef(t, actual == expected, "Private data not rolled back during MVCC_READ_CONFLICT") + } } func newCollectionConfig(colName, policy string, reqPeerCount, maxPeerCount int32, blockToLive uint64) (*pb.CollectionConfig, error) { @@ -394,10 +415,15 @@ func runPvtDataPreReconcilePutAndGet(t *testing.T, sdk *fabsdk.FabricSDK, orgsCo collConfig, err := newCollectionConfig(coll1, policy, 0, 2, 1000) require.NoError(t, err) - err = integration.InstallExamplePvtChaincode(orgsContext, ccID) - require.NoError(t, err) - err = integration.InstantiateExamplePvtChaincode(orgsContext, orgChannelID, ccID, policy, collConfig) - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExamplePvtChaincode(orgsContext, ccID) + require.NoError(t, err) + err = integration.InstantiateExamplePvtChaincode(orgsContext, orgChannelID, ccID, policy, collConfig) + require.NoError(t, err) + } else { + err := integration.InstantiatePvtExampleChaincodeLc(sdk, orgsContext, orgChannelID, ccID, policy, collConfig) + require.NoError(t, err) + } ctxProvider := sdk.ChannelContext(orgChannelID, fabsdk.WithUser(org1User), fabsdk.WithOrg(org1Name)) @@ -542,9 +568,13 @@ func runPvtDataPostReconcileGet(t *testing.T, sdk *fabsdk.FabricSDK, orgsContext // org2 peers are the only targets to test post reconciliation as they should have the pvt data after cc upgrade as per the new collection policy (multiOrgsPolicy) org2TargetOpts := channel.WithTargetEndpoints("peer0.org2.example.com", "peer1.org2.example.com") - - err = integration.UpgradeExamplePvtChaincode(orgsContext, orgChannelID, ccID, policy, collConfig) - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.UpgradeExamplePvtChaincode(orgsContext, orgChannelID, ccID, policy, collConfig) + require.NoError(t, err) + } else { + err = integration.UpgradeExamplePvtChaincodeLc(sdk, orgsContext, orgChannelID, ccID, policy, collConfig) + require.NoError(t, err) + } // wait for pvt data reconciliation occurs on peers of org2 time.Sleep(2 * time.Second) diff --git a/test/integration/pkg/client/channel/channel_client_test.go b/test/integration/pkg/client/channel/channel_client_test.go index 57756fed62..8d80704180 100644 --- a/test/integration/pkg/client/channel/channel_client_test.go +++ b/test/integration/pkg/client/channel/channel_client_test.go @@ -28,6 +28,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/test/integration" + "github.com/hyperledger/fabric-sdk-go/test/metadata" ) func TestChannelClient(t *testing.T) { @@ -82,8 +83,13 @@ func TestChannelClient(t *testing.T) { // transaction nestedCCID := integration.GenerateExampleID(true) - err = integration.PrepareExampleCC(sdk, fabsdk.WithUser("Admin"), testSetup.OrgID, nestedCCID) - require.Nil(t, err, "InstallAndInstantiateExampleCC return error") + if metadata.CCMode == "lscc" { + err = integration.PrepareExampleCC(sdk, fabsdk.WithUser("Admin"), testSetup.OrgID, nestedCCID) + require.Nil(t, err, "InstallAndInstantiateExampleCC return error") + } else { + err = integration.PrepareExampleCCLc(sdk, fabsdk.WithUser("Admin"), testSetup.OrgID, nestedCCID) + require.Nil(t, err, "InstallAndInstantiateExampleCC return error") + } //perform Transaction testTransaction(t, chClient, chaincodeID, nestedCCID, moveOneTx) @@ -241,16 +247,27 @@ func TestCCToCC(t *testing.T) { require.NoError(t, err) cc1ID := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, cc1ID) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, cc1ID, "OR('Org1MSP.member')") - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, cc1ID) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, cc1ID, "OR('Org1MSP.member')") + require.NoError(t, err) + } else { + err = integration.InstantiateExampleChaincodeLc(sdk, orgsContext, orgChannelID, cc1ID, "OR('Org1MSP.member')") + require.NoError(t, err) + } cc2ID := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, cc2ID) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, cc2ID, "AND('Org1MSP.member','Org2MSP.member')") - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, cc2ID) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, cc2ID, "AND('Org1MSP.member','Org2MSP.member')") + require.NoError(t, err) + } else { + + err = integration.InstantiateExampleChaincodeLc(sdk, orgsContext, orgChannelID, cc2ID, "AND('Org1MSP.member','Org2MSP.member')") + require.NoError(t, err) + } ctxProvider := sdk.ChannelContext(orgChannelID, fabsdk.WithUser(org1User), fabsdk.WithOrg(org1Name)) diff --git a/test/integration/pkg/client/common/discovery/discoveryclient_test.go b/test/integration/pkg/client/common/discovery/discoveryclient_test.go index 3c29fd1db8..9b09c50c13 100644 --- a/test/integration/pkg/client/common/discovery/discoveryclient_test.go +++ b/test/integration/pkg/client/common/discovery/discoveryclient_test.go @@ -22,6 +22,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fab/comm" "github.com/hyperledger/fabric-sdk-go/pkg/fab/discovery" "github.com/hyperledger/fabric-sdk-go/test/integration" + "github.com/hyperledger/fabric-sdk-go/test/metadata" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -171,10 +172,17 @@ func TestDiscoveryClientEndorsers(t *testing.T) { t.Run("Policy: Org1 Only", func(t *testing.T) { ccID := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, ccID) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member')") - require.NoError(t, err) + + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member')") + require.NoError(t, err) + } else { + + err = integration.InstantiateExampleChaincodeLc(mainSDK, orgsContext, orgChannelID, ccID, "OR('Org1MSP.member')") + require.NoError(t, err) + } testEndorsers( t, mainSDK, @@ -187,10 +195,16 @@ func TestDiscoveryClientEndorsers(t *testing.T) { t.Run("Policy: Org2 Only", func(t *testing.T) { ccID := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, ccID) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org2MSP.member')") - require.NoError(t, err) + + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org2MSP.member')") + require.NoError(t, err) + } else { + err = integration.InstantiateExampleChaincodeLc(mainSDK, orgsContext, orgChannelID, ccID, "OR('Org2MSP.member')") + require.NoError(t, err) + } testEndorsers( t, mainSDK, @@ -203,10 +217,16 @@ func TestDiscoveryClientEndorsers(t *testing.T) { t.Run("Policy: Org1 or Org2", func(t *testing.T) { ccID := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, ccID) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')") - require.NoError(t, err) + + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')") + require.NoError(t, err) + } else { + err = integration.InstantiateExampleChaincodeLc(mainSDK, orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')") + require.NoError(t, err) + } require.NoError(t, err) testEndorsers( @@ -222,10 +242,15 @@ func TestDiscoveryClientEndorsers(t *testing.T) { t.Run("Policy: Org1 and Org2", func(t *testing.T) { ccID := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, ccID) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "AND('Org1MSP.member','Org2MSP.member')") - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "AND('Org1MSP.member','Org2MSP.member')") + require.NoError(t, err) + } else { + err = integration.InstantiateExampleChaincodeLc(mainSDK, orgsContext, orgChannelID, ccID, "AND('Org1MSP.member','Org2MSP.member')") + require.NoError(t, err) + } testEndorsers( t, mainSDK, @@ -242,16 +267,26 @@ func TestDiscoveryClientEndorsers(t *testing.T) { t.Run("Policy: CC1(Org1 Only) to CC2(Org2 Only)", func(t *testing.T) { ccID1 := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, ccID1) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID1, "OR('Org1MSP.member')") - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID1) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID1, "OR('Org1MSP.member')") + require.NoError(t, err) + } else { + err = integration.InstantiateExampleChaincodeLc(mainSDK, orgsContext, orgChannelID, ccID1, "OR('Org1MSP.member')") + require.NoError(t, err) + } ccID2 := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, ccID2) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID2, "OR('Org2MSP.member')") - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID2) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID2, "OR('Org2MSP.member')") + require.NoError(t, err) + } else { + err = integration.InstantiateExampleChaincodeLc(mainSDK, orgsContext, orgChannelID, ccID2, "OR('Org2MSP.member')") + require.NoError(t, err) + } testEndorsers( t, mainSDK, diff --git a/test/integration/pkg/client/common/selection/fabricselection_test.go b/test/integration/pkg/client/common/selection/fabricselection_test.go index 82cef7c34e..fa968aa372 100644 --- a/test/integration/pkg/client/common/selection/fabricselection_test.go +++ b/test/integration/pkg/client/common/selection/fabricselection_test.go @@ -27,6 +27,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/factory/defsvc" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/provider/chpvdr" "github.com/hyperledger/fabric-sdk-go/test/integration" + "github.com/hyperledger/fabric-sdk-go/test/metadata" "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/policydsl" grpcCodes "google.golang.org/grpc/codes" ) @@ -91,10 +92,15 @@ func TestFabricSelection(t *testing.T) { t.Run("Policy: Org1 Only", func(t *testing.T) { ccID := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, ccID) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member')") - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member')") + require.NoError(t, err) + } else { + err = integration.InstantiateExampleChaincodeLc(sdk, orgsContext, orgChannelID, ccID, "OR('Org1MSP.member')") + require.NoError(t, err) + } testEndorsers( t, selectionService, @@ -107,10 +113,15 @@ func TestFabricSelection(t *testing.T) { t.Run("Policy: Org2 Only", func(t *testing.T) { ccID := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, ccID) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org2MSP.member')") - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org2MSP.member')") + require.NoError(t, err) + } else { + err = integration.InstantiateExampleChaincodeLc(sdk, orgsContext, orgChannelID, ccID, "OR('Org2MSP.member')") + require.NoError(t, err) + } testEndorsers( t, selectionService, @@ -123,10 +134,15 @@ func TestFabricSelection(t *testing.T) { t.Run("Policy: Org1 or Org2", func(t *testing.T) { ccID := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, ccID) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')") - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')") + require.NoError(t, err) + } else { + err = integration.InstantiateExampleChaincodeLc(sdk, orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')") + require.NoError(t, err) + } testEndorsers( t, selectionService, @@ -141,10 +157,15 @@ func TestFabricSelection(t *testing.T) { t.Run("Policy: Org1 and Org2", func(t *testing.T) { ccID := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, ccID) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "AND('Org1MSP.member','Org2MSP.member')") - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "AND('Org1MSP.member','Org2MSP.member')") + require.NoError(t, err) + } else { + err = integration.InstantiateExampleChaincodeLc(sdk, orgsContext, orgChannelID, ccID, "AND('Org1MSP.member','Org2MSP.member')") + require.NoError(t, err) + } testEndorsers( t, selectionService, @@ -172,16 +193,26 @@ func TestFabricSelection(t *testing.T) { // Chaincode to Chaincode t.Run("Policy: CC1(Org1 Only) to CC2(Org2 Only)", func(t *testing.T) { ccID1 := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, ccID1) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID1, "OR('Org1MSP.member')") - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID1) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID1, "OR('Org1MSP.member')") + require.NoError(t, err) + } else { + err = integration.InstantiateExampleChaincodeLc(sdk, orgsContext, orgChannelID, ccID1, "OR('Org1MSP.member')") + require.NoError(t, err) + } ccID2 := integration.GenerateExampleID(true) - err = integration.InstallExampleChaincode(orgsContext, ccID2) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID2, "OR('Org2MSP.member')") - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID2) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID2, "OR('Org2MSP.member')") + require.NoError(t, err) + } else { + err = integration.InstantiateExampleChaincodeLc(sdk, orgsContext, orgChannelID, ccID2, "OR('Org2MSP.member')") + require.NoError(t, err) + } testEndorsers( t, selectionService, @@ -200,10 +231,15 @@ func TestFabricSelection(t *testing.T) { collConfig, err := newCollectionConfig(coll1, "OR('Org1MSP.member')", 0, 2, 1000) require.NoError(t, err) - err = integration.InstallExampleChaincode(orgsContext, ccID) - require.NoError(t, err) - err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')", collConfig) - require.NoError(t, err) + if metadata.CCMode == "lscc" { + err = integration.InstallExampleChaincode(orgsContext, ccID) + require.NoError(t, err) + err = integration.InstantiateExampleChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')", collConfig) + require.NoError(t, err) + } else { + err = integration.InstantiatePvtExampleChaincodeLc(sdk, orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')", collConfig) + require.NoError(t, err) + } testEndorsers( t, selectionService, diff --git a/test/integration/pkg/client/ledger/channel_ledger_test.go b/test/integration/pkg/client/ledger/channel_ledger_test.go index 25ab6d3c2d..236a4421b7 100644 --- a/test/integration/pkg/client/ledger/channel_ledger_test.go +++ b/test/integration/pkg/client/ledger/channel_ledger_test.go @@ -17,6 +17,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp" "github.com/hyperledger/fabric-sdk-go/test/integration" + "github.com/hyperledger/fabric-sdk-go/test/metadata" "github.com/hyperledger/fabric-sdk-go/pkg/client/channel" "github.com/hyperledger/fabric-sdk-go/pkg/client/ledger" @@ -81,8 +82,14 @@ func TestLedgerQueries(t *testing.T) { //defer client.Close() chaincodeID := integration.GenerateExampleID(false) - err := integration.PrepareExampleCC(sdk, fabsdk.WithUser("Admin"), testSetup.OrgID, chaincodeID) - require.Nil(t, err, "InstallAndInstantiateExampleCC return error") + + if metadata.CCMode == "lscc" { + err := integration.PrepareExampleCC(sdk, fabsdk.WithUser("Admin"), testSetup.OrgID, chaincodeID) + require.Nil(t, err, "InstallAndInstantiateExampleCC return error") + } else { + err := integration.PrepareExampleCCLc(sdk, fabsdk.WithUser("Admin"), testSetup.OrgID, chaincodeID) + require.Nil(t, err, "InstallAndInstantiateExampleCC return error") + } //prepare required contexts channelClientCtx := sdk.ChannelContext(channelID, fabsdk.WithUser("Admin"), fabsdk.WithOrg(orgName)) @@ -138,7 +145,9 @@ func TestLedgerQueries(t *testing.T) { require.Nil(t, err, "resmgmt new return error") - testInstantiatedChaincodes(t, chaincodeID, channelID, resmgmtClient, targets) + if metadata.CCMode == "lscc" { + testInstantiatedChaincodes(t, chaincodeID, channelID, resmgmtClient, targets) + } testQueryConfigBlock(t, ledgerClient, targets) } diff --git a/test/integration/pkg/client/resmgmt/resmgmt_queries_pvt_test.go b/test/integration/pkg/client/resmgmt/resmgmt_queries_pvt_test.go index 9ffef9b2e6..e7ca16fbf7 100644 --- a/test/integration/pkg/client/resmgmt/resmgmt_queries_pvt_test.go +++ b/test/integration/pkg/client/resmgmt/resmgmt_queries_pvt_test.go @@ -12,8 +12,10 @@ import ( pb "github.com/hyperledger/fabric-protos-go/peer" "github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt" + "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/test/integration" + "github.com/hyperledger/fabric-sdk-go/test/metadata" "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/policydsl" "github.com/stretchr/testify/require" ) @@ -27,6 +29,10 @@ const ( ) func TestQueryCollectionsConfig(t *testing.T) { + + if metadata.CCMode != "lscc" { + t.Skip("this test is only valid for legacy chaincode") + } sdk := mainSDK orgsContext := setupMultiOrgContext(t, sdk) @@ -36,7 +42,6 @@ func TestQueryCollectionsConfig(t *testing.T) { ccID := integration.GenerateExamplePvtID(true) collConfig, err := newCollectionConfig(collCfgName, collCfgPolicy, collCfgRequiredPeerCount, collCfgMaximumPeerCount, collCfgBlockToLive) require.NoError(t, err) - err = integration.InstallExamplePvtChaincode(orgsContext, ccID) require.NoError(t, err) err = integration.InstantiateExamplePvtChaincode(orgsContext, orgChannelID, ccID, "OR('Org1MSP.member','Org2MSP.member')", collConfig) @@ -48,7 +53,7 @@ func TestQueryCollectionsConfig(t *testing.T) { t.Fatalf("Failed to create new resource management client: %s", err) } - resp, err := client.QueryCollectionsConfig(orgChannelID, ccID) + resp, err := client.QueryCollectionsConfig(orgChannelID, ccID, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) if err != nil { t.Fatalf("QueryCollectionsConfig return error: %s", err) } @@ -63,6 +68,7 @@ func TestQueryCollectionsConfig(t *testing.T) { default: t.Fatalf("The CollectionConfig.Payload's type is incorrect, expected `CollectionConfig_StaticCollectionConfig`, got %+v", reflect.TypeOf(conf.Payload)) } + } func checkStaticCollectionConfig(t *testing.T, collConf *pb.StaticCollectionConfig) { diff --git a/test/integration/pkg/client/resmgmt/resmgmt_queries_test.go b/test/integration/pkg/client/resmgmt/resmgmt_queries_test.go index 77a7535bc1..c705e983f9 100644 --- a/test/integration/pkg/client/resmgmt/resmgmt_queries_test.go +++ b/test/integration/pkg/client/resmgmt/resmgmt_queries_test.go @@ -12,6 +12,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt" "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" + "github.com/hyperledger/fabric-sdk-go/test/metadata" ) func TestResMgmtClientQueries(t *testing.T) { @@ -43,55 +44,72 @@ func TestResMgmtClientQueries(t *testing.T) { // TODO java and node integration tests need to be fixed. /* - // test java chaincode installed and instantiated - javaCCID := integration.GenerateExampleJavaID(false) + // test java chaincode installed and instantiated + javaCCID := integration.GenerateExampleJavaID(false) - testInstalledChaincodes(t, javaCCID, target, client) + testInstalledChaincodes(t, javaCCID, target, client) - testInstantiatedChaincodes(t, orgChannelID, javaCCID, target, client) + testInstantiatedChaincodes(t, orgChannelID, javaCCID, target, client) - // test node chaincode installed and instantiated - nodeCCID := integration.GenerateExampleNodeID(false) + // test node chaincode installed and instantiated + nodeCCID := integration.GenerateExampleNodeID(false) - testInstalledChaincodes(t, nodeCCID, target, client) + testInstalledChaincodes(t, nodeCCID, target, client) - testInstantiatedChaincodes(t, orgChannelID, nodeCCID, target, client) + testInstantiatedChaincodes(t, orgChannelID, nodeCCID, target, client) */ } func testInstantiatedChaincodes(t *testing.T, channelID string, ccID string, target string, client *resmgmt.Client) { + if metadata.CCMode == "lscc" { + chaincodeQueryResponse, err := client.QueryInstantiatedChaincodes(channelID, resmgmt.WithTargetEndpoints(target), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatalf("QueryInstantiatedChaincodes return error: %s", err) + } - chaincodeQueryResponse, err := client.QueryInstantiatedChaincodes(channelID, resmgmt.WithTargetEndpoints(target), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) - if err != nil { - t.Fatalf("QueryInstantiatedChaincodes return error: %s", err) - } - - found := false - for _, chaincode := range chaincodeQueryResponse.Chaincodes { - t.Logf("**InstantiatedCC: %s", chaincode) - if chaincode.Name == ccID { - found = true + found := false + for _, chaincode := range chaincodeQueryResponse.Chaincodes { + t.Logf("**InstantiatedCC: %s", chaincode) + if chaincode.Name == ccID { + found = true + } } - } - if !found { - t.Fatalf("QueryInstantiatedChaincodes failed to find instantiated %s chaincode", ccID) + if !found { + t.Fatalf("QueryInstantiatedChaincodes failed to find instantiated %s chaincode", ccID) + } } } func testInstalledChaincodes(t *testing.T, ccID string, target string, client *resmgmt.Client) { + found := false + if metadata.CCMode == "lscc" { + chaincodeQueryResponse, err := client.QueryInstalledChaincodes(resmgmt.WithTargetEndpoints(target), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatalf("QueryInstalledChaincodes return error: %s", err) + } - chaincodeQueryResponse, err := client.QueryInstalledChaincodes(resmgmt.WithTargetEndpoints(target), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) - if err != nil { - t.Fatalf("QueryInstalledChaincodes return error: %s", err) - } + for _, chaincode := range chaincodeQueryResponse.Chaincodes { + t.Logf("**InstalledCC: %s", chaincode) + if chaincode.Name == ccID { + found = true + } + } + } else { + chaincodeQueryResponse, err := client.LifecycleQueryInstalledCC(resmgmt.WithTargetEndpoints(target), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatalf("QueryInstalledChaincodes return error: %s", err) + } - found := false - for _, chaincode := range chaincodeQueryResponse.Chaincodes { - t.Logf("**InstalledCC: %s", chaincode) - if chaincode.Name == ccID { - found = true + for _, re := range chaincodeQueryResponse { + for _, cc := range re.References { + for _, c := range cc { + if c.Name == ccID { + found = true + } + } + } } } diff --git a/test/integration/pkg/fab/install_chaincode_test.go b/test/integration/pkg/fab/install_chaincode_test.go index c2d793d5c4..f7e07de0b9 100644 --- a/test/integration/pkg/fab/install_chaincode_test.go +++ b/test/integration/pkg/fab/install_chaincode_test.go @@ -13,6 +13,8 @@ import ( "strings" "testing" + "github.com/hyperledger/fabric-protos-go/common" + "github.com/hyperledger/fabric-protos-go/peer" "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/hyperledger/fabric-sdk-go/pkg/context" @@ -20,8 +22,6 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fab/resource" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/test/integration" - "github.com/hyperledger/fabric-protos-go/common" - "github.com/hyperledger/fabric-protos-go/peer" "github.com/pkg/errors" "github.com/stretchr/testify/require" ) @@ -115,7 +115,7 @@ func testChaincodeInstallUsingChaincodePackage(t *testing.T, sdk *fabsdk.FabricS peers, err := getProposalProcessors(sdk, "Admin", testSetup.OrgID, testSetup.Targets) require.Nil(t, err, "creating peers failed") - err = installCC(t, reqCtx, "install", "github.com/example_cc_pkg", chainCodeVersion, ccPkg, peers) + err = installCC(t, reqCtx, "install", "github.com/example_cc", chainCodeVersion, ccPkg, peers) if err != nil { t.Fatalf("installCC return error: %s", err) diff --git a/test/integration/pkg/fab/resource_queries_test.go b/test/integration/pkg/fab/resource_queries_test.go index 9bc138c376..c0a86a3698 100644 --- a/test/integration/pkg/fab/resource_queries_test.go +++ b/test/integration/pkg/fab/resource_queries_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry" + "github.com/hyperledger/fabric-sdk-go/test/metadata" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/hyperledger/fabric-sdk-go/pkg/fab/resource" @@ -37,7 +38,11 @@ func TestChannelQueries(t *testing.T) { testQueryChannels(t, reqCtx, peers[0]) - testInstalledChaincodes(t, reqCtx, chaincodeID, peers[0]) + if metadata.CCMode == "lscc" { + testInstalledChaincodes(t, reqCtx, chaincodeID, peers[0]) + } else { + testInstalledChaincodesLc(t, reqCtx, peers[0]) + } } @@ -78,3 +83,18 @@ func testInstalledChaincodes(t *testing.T, reqCtx reqContext.Context, ccID strin t.Fatalf("QueryInstalledChaincodes failed to find installed %s chaincode", ccID) } } + +func testInstalledChaincodesLc(t *testing.T, reqCtx reqContext.Context, target fab.ProposalProcessor) { + lc := resource.NewLifecycle() + // Our target will be primary peer on this channel + t.Logf("****QueryInstalledChaincodes for %s", target) + + resp, err := lc.QueryInstalled(reqCtx, target, resource.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + for _, re := range resp.InstalledChaincodes { + t.Logf("**InstalledCC: %s", re.PackageID) + } + +} diff --git a/test/integration/pkg/fabsdk/provider/custom_cryptosuite_test.go b/test/integration/pkg/fabsdk/provider/custom_cryptosuite_test.go index 45b8daeb85..5ee1124cc1 100644 --- a/test/integration/pkg/fabsdk/provider/custom_cryptosuite_test.go +++ b/test/integration/pkg/fabsdk/provider/custom_cryptosuite_test.go @@ -21,6 +21,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/factory/defcore" "github.com/hyperledger/fabric-sdk-go/test/integration" + "github.com/hyperledger/fabric-sdk-go/test/metadata" "github.com/stretchr/testify/require" ) @@ -30,9 +31,15 @@ func customCryptoSuiteInit(t *testing.T) (*integration.BaseSetupImpl, string) { sdk := mainSDK testSetup := mainTestSetup - chaincodeID := integration.GenerateExampleID(false) - err := integration.PrepareExampleCC(sdk, fabsdk.WithUser("Admin"), testSetup.OrgID, chaincodeID) - require.Nil(t, err, "InstallAndInstantiateExampleCC return error") + chaincodeID := integration.GenerateExampleID(true) + + if metadata.CCMode == "lscc" { + err := integration.PrepareExampleCC(sdk, fabsdk.WithUser("Admin"), testSetup.OrgID, chaincodeID) + require.Nil(t, err, "InstallAndInstantiateExampleCC return error") + } else { + err := integration.PrepareExampleCCLc(sdk, fabsdk.WithUser("Admin"), testSetup.OrgID, chaincodeID) + require.Nil(t, err, "InstallAndInstantiateExampleCC return error") + } return testSetup, chaincodeID } diff --git a/test/integration/pkg/fabsdk/provider/sdk_provider_test.go b/test/integration/pkg/fabsdk/provider/sdk_provider_test.go index a6608773bb..faff6f1d18 100644 --- a/test/integration/pkg/fabsdk/provider/sdk_provider_test.go +++ b/test/integration/pkg/fabsdk/provider/sdk_provider_test.go @@ -23,11 +23,14 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/factory/defsvc" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/provider/chpvdr" "github.com/hyperledger/fabric-sdk-go/test/integration" + "github.com/hyperledger/fabric-sdk-go/test/metadata" "github.com/stretchr/testify/require" ) func TestDynamicSelection(t *testing.T) { - + if metadata.CCMode != "lscc" { + t.Skip("this test is only valid for legacy chaincode") + } // Using shared SDK instance to increase test speed. testSetup := mainTestSetup aKey := integration.GetKeyName(t) @@ -48,9 +51,15 @@ func TestDynamicSelection(t *testing.T) { t.Fatal(err) } - chaincodeID := integration.GenerateExampleID(false) - err = integration.PrepareExampleCC(sdk, fabsdk.WithUser("Admin"), testSetup.OrgID, chaincodeID) - require.NoError(t, err, "InstallAndInstantiateExampleCC returned error") + chaincodeID := integration.GenerateExampleID(true) + fmt.Printf("TestDynamicSelection cc = %v\n", chaincodeID) + if metadata.CCMode == "lscc" { + err = integration.PrepareExampleCC(sdk, fabsdk.WithUser("Admin"), testSetup.OrgID, chaincodeID) + require.NoError(t, err, "InstallAndInstantiateExampleCC returned error") + } else { + err = integration.PrepareExampleCCLc(sdk, fabsdk.WithUser("Admin"), testSetup.OrgID, chaincodeID) + require.NoError(t, err, "InstallAndInstantiateExampleCC returned error") + } //prepare contexts org1ChannelClientContext := sdk.ChannelContext(testSetup.ChannelID, fabsdk.WithUser(org1User), fabsdk.WithOrg(org1Name)) @@ -86,6 +95,7 @@ func TestDynamicSelection(t *testing.T) { valueInt, _ := strconv.Atoi(string(value)) verifyValue(t, chClient, queryArg, valueInt+1, chaincodeID) + } func verifyValue(t *testing.T, chClient *channel.Client, queryArg [][]byte, expectedValue int, ccID string) { diff --git a/test/integration/prepare.go b/test/integration/prepare.go index 483c7816e4..41296dc9c2 100644 --- a/test/integration/prepare.go +++ b/test/integration/prepare.go @@ -19,10 +19,12 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fab" packager "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/gopackager" javapackager "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/javapackager" + lcpackager "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/lifecycle" "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/nodepackager" "github.com/hyperledger/fabric-sdk-go/pkg/fab/comm" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/test/metadata" + "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/policydsl" "github.com/pkg/errors" ) @@ -139,6 +141,67 @@ func PrepareExampleCC(sdk *fabsdk.FabricSDK, user fabsdk.ContextOption, orgName return nil } +// PrepareExampleCCLc install and instantiate using resource management client +func PrepareExampleCCLc(sdk *fabsdk.FabricSDK, user fabsdk.ContextOption, orgName string, chaincodeID string) error { + const ( + channelID = defaultChannelID + ) + + fmt.Printf("Installing and instantiating example chaincode..., cc = %v\n", chaincodeID) + start := time.Now() + + ccPolicy, err := prepareOneOrgPolicy(sdk, orgName) + if err != nil { + return errors.WithMessage(err, "CC policy could not be prepared") + } + + orgContexts, err := prepareOrgContexts(sdk, user, []string{orgName}) + if err != nil { + return errors.WithMessage(err, "Org contexts could not be prepared") + } + + packageID, err := InstallExampleChaincodeLc(orgContexts, chaincodeID, exampleCCVersion) + if err != nil { + return errors.WithMessage(err, "Installing example chaincode failed") + } + + err = ApproveExampleChaincode(orgContexts, channelID, chaincodeID, exampleCCVersion, packageID, ccPolicy, 1) + if err != nil { + return errors.WithMessage(err, "Approve example chaincode failed") + } + + err = QueryApprovedCC(orgContexts, chaincodeID, 1, channelID) + if err != nil { + return errors.WithMessage(err, "QueryApprovedCC example chaincode failed") + } + + err = CheckCCCommitReadiness(orgContexts, packageID, chaincodeID, exampleCCVersion, 1, channelID, ccPolicy) + if err != nil { + return errors.WithMessage(err, "CheckCCCommitReadiness example chaincode failed") + } + + err = CommitExampleChaincode(orgContexts, channelID, chaincodeID, exampleCCVersion, ccPolicy, 1) + if err != nil { + return errors.WithMessage(err, "Commit example chaincode failed") + } + + err = QueryCommittedCC(orgContexts, chaincodeID, channelID, 1) + if err != nil { + return errors.WithMessage(err, "QueryCommittedCC example chaincode failed") + } + + err = InitExampleChaincode(sdk, channelID, chaincodeID, orgContexts[0].OrgID) + if err != nil { + return errors.WithMessage(err, "Init example chaincode failed") + } + + t := time.Now() + elapsed := t.Sub(start) + fmt.Printf("Done [%d ms]\n", elapsed/time.Millisecond) + + return nil +} + // InstallExampleChaincode installs the example chaincode to all peers in the given orgs func InstallExampleChaincode(orgs []*OrgContext, ccID string) error { ccPkg, err := packager.NewCCPackage(exampleCCPath, GetDeployPath()) @@ -154,6 +217,228 @@ func InstallExampleChaincode(orgs []*OrgContext, ccID string) error { return nil } +// InstallExampleChaincodeLc installs the example chaincode to all peers in the given orgs +func InstallExampleChaincodeLc(orgs []*OrgContext, ccID, ccVersion string) (string, error) { + label := ccID + "_" + ccVersion + desc := &lcpackager.Descriptor{ + Path: GetLcDeployPath(), + Type: pb.ChaincodeSpec_GOLANG, + Label: label, + } + + ccPkg, err := lcpackager.NewCCPackage(desc) + if err != nil { + return "", errors.WithMessage(err, "creating chaincode package failed") + } + + installCCReq := resmgmt.LifecycleInstallCCRequest{ + Label: label, + Package: ccPkg, + } + + packageID := lcpackager.ComputePackageID(installCCReq.Label, installCCReq.Package) + + for _, orgCtx := range orgs { + _, err := orgCtx.ResMgmt.LifecycleInstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + return "", errors.WithMessage(err, "installing example chaincode failed") + } + } + + return packageID, nil +} + +// ApproveExampleChaincode approve the example CC on the given channel +func ApproveExampleChaincode(orgs []*OrgContext, channelID, ccID, ccVersion, packageID, ccPolicyStr string, sequence int64, collConfigs ...*pb.CollectionConfig) error { + ccPolicy, err := policydsl.FromString(ccPolicyStr) + if err != nil { + return errors.Wrapf(err, "error creating CC policy [%s]", ccPolicyStr) + } + approveCCReq := resmgmt.LifecycleApproveCCRequest{ + Name: ccID, + Version: ccVersion, + PackageID: packageID, + Sequence: sequence, + EndorsementPlugin: "escc", + ValidationPlugin: "vscc", + SignaturePolicy: ccPolicy, + InitRequired: true, + CollectionConfig: collConfigs, + } + + for _, orgCtx := range orgs { + _, err := orgCtx.ResMgmt.LifecycleApproveCC(channelID, approveCCReq, resmgmt.WithTargets(orgCtx.Peers...), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + return errors.WithMessage(err, "approve example chaincode failed") + } + } + + return nil +} + +// QueryApprovedCC query approve of the example CC on the given channel +func QueryApprovedCC(mc []*OrgContext, ccName string, sequence int64, channelID string) error { + + // Query approve cc + queryApprovedCCReq := resmgmt.LifecycleQueryApprovedCCRequest{ + Name: ccName, + Sequence: sequence, + } + for _, orgCtx := range mc { + for _, p := range orgCtx.Peers { + _, err := retry.NewInvoker(retry.New(retry.TestRetryOpts)).Invoke( + func() (interface{}, error) { + resp1, err := orgCtx.ResMgmt.LifecycleQueryApprovedCC(channelID, queryApprovedCCReq, resmgmt.WithTargets(p), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleQueryApprovedCC returned error: %v", err), nil) + } + return resp1, err + }, + ) + if err != nil { + return errors.WithMessage(err, "QueryApprovedCC example chaincode failed") + } + } + } + return nil + +} + +// CheckCCCommitReadiness checkcommit the example CC on the given channel +func CheckCCCommitReadiness(mc []*OrgContext, packageID string, ccName, ccVersion string, sequence int64, channelID string, ccPolicyStr string) error { + ccPolicy, err := policydsl.FromString(ccPolicyStr) + if err != nil { + return errors.Wrapf(err, "error creating CC policy [%s]", ccPolicyStr) + } + req := resmgmt.LifecycleCheckCCCommitReadinessRequest{ + Name: ccName, + Version: ccVersion, + PackageID: packageID, + EndorsementPlugin: "escc", + ValidationPlugin: "vscc", + SignaturePolicy: ccPolicy, + Sequence: sequence, + InitRequired: true, + } + /*resp1, err := mc.org1ResMgmt.LifecycleCheckCCCommitReadiness(channelID, req, resmgmt.WithTargets([]fab.Peer{org1Peers[0]}...), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + require.NotNil(t, resp1)*/ + for _, orgCtx := range mc { + for _, p := range orgCtx.Peers { + _, err := retry.NewInvoker(retry.New(retry.TestRetryOpts)).Invoke( + func() (interface{}, error) { + resp1, err := orgCtx.ResMgmt.LifecycleCheckCCCommitReadiness(channelID, req, resmgmt.WithTargets(p), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + fmt.Printf("LifecycleCheckCCCommitReadiness cc = %v, = %v\n", ccName, resp1) + if err != nil { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleCheckCCCommitReadiness returned error: %v", err), nil) + } + flag := true + for _, r := range resp1.Approvals { + flag = flag && r + } + if !flag { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleCheckCCCommitReadiness returned : %v", resp1), nil) + } + return resp1, err + }, + ) + if err != nil { + errors.WithMessage(err, "LifecycleCheckCCCommitReadiness example chaincode failed") + } + } + } + return nil +} + +// CommitExampleChaincode approve the example CC on the given channel +func CommitExampleChaincode(orgs []*OrgContext, channelID, ccID, ccVersion, ccPolicyStr string, sequence int64, collConfigs ...*pb.CollectionConfig) error { + ccPolicy, err := policydsl.FromString(ccPolicyStr) + if err != nil { + return errors.Wrapf(err, "error creating CC policy [%s]", ccPolicyStr) + } + + req := resmgmt.LifecycleCommitCCRequest{ + Name: ccID, + Version: ccVersion, + Sequence: sequence, + EndorsementPlugin: "escc", + ValidationPlugin: "vscc", + SignaturePolicy: ccPolicy, + InitRequired: true, + CollectionConfig: collConfigs, + } + + _, err = orgs[0].ResMgmt.LifecycleCommitCC(channelID, req, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + return errors.WithMessage(err, "commit example chaincode failed") + } + + return nil + +} + +// InitExampleChaincode init the example CC on the given channel +func InitExampleChaincode(sdk *fabsdk.FabricSDK, channelID, ccID string, orgName string) error { + //prepare channel client context using client context + clientChannelContext := sdk.ChannelContext(channelID, fabsdk.WithUser("User1"), fabsdk.WithOrg(orgName)) + // Channel client is used to query and execute transactions (Org1 is default org) + client, err := channel.New(clientChannelContext) + if err != nil { + return errors.WithMessage(err, "init example chaincode failed") + } + + // init + _, err = client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "init", Args: ExampleCCInitArgsLc(), IsInit: true}, + channel.WithRetry(retry.DefaultChannelOpts)) + if err != nil { + return errors.WithMessage(err, "init example chaincode failed") + } + return nil + +} + +// QueryCommittedCC query commit of the example CC on the given channel +func QueryCommittedCC(mc []*OrgContext, ccName string, channelID string, sequence int64) error { + + req := resmgmt.LifecycleQueryCommittedCCRequest{ + Name: ccName, + } + /*resp1, err := mc.org1ResMgmt.LifecycleQueryCommittedCC(channelID, req, resmgmt.WithTargets(org1Peers[0]), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + }*/ + for _, orgCtx := range mc { + for _, p := range orgCtx.Peers { + _, err := retry.NewInvoker(retry.New(retry.TestRetryOpts)).Invoke( + func() (interface{}, error) { + resp1, err := orgCtx.ResMgmt.LifecycleQueryCommittedCC(channelID, req, resmgmt.WithTargets(p), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleQueryCommittedCC returned error: %v", err), nil) + } + flag := false + for _, r := range resp1 { + if r.Name == ccName && r.Sequence == sequence { + flag = true + break + } + } + if !flag { + return nil, status.New(status.TestStatus, status.GenericTransient.ToInt32(), fmt.Sprintf("LifecycleQueryCommittedCC returned : %v", resp1), nil) + } + return resp1, err + }, + ) + if err != nil { + errors.WithMessage(err, "queryCommittedCC example chaincode failed") + } + } + } + return nil + +} + // InstallExamplePvtChaincode installs the example pvt chaincode to all peers in the given orgs func InstallExamplePvtChaincode(orgs []*OrgContext, ccID string) error { ccPkg, err := packager.NewCCPackage(examplePvtCCPath, GetDeployPath()) @@ -169,6 +454,37 @@ func InstallExamplePvtChaincode(orgs []*OrgContext, ccID string) error { return nil } +// InstallExamplePvtChaincodeLc installs the example chaincode to all peers in the given orgs +func InstallExamplePvtChaincodeLc(orgs []*OrgContext, ccID, ccVersion string) (string, error) { + label := ccID + "_" + ccVersion + desc := &lcpackager.Descriptor{ + Path: GetLcPvtDeployPath(), + Type: pb.ChaincodeSpec_GOLANG, + Label: label, + } + + ccPkg, err := lcpackager.NewCCPackage(desc) + if err != nil { + return "", errors.WithMessage(err, "creating chaincode package failed") + } + + installCCReq := resmgmt.LifecycleInstallCCRequest{ + Label: label, + Package: ccPkg, + } + + packageID := lcpackager.ComputePackageID(installCCReq.Label, installCCReq.Package) + + for _, orgCtx := range orgs { + _, err := orgCtx.ResMgmt.LifecycleInstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + return "", errors.WithMessage(err, "installing example chaincode failed") + } + } + + return packageID, nil +} + // InstallExampleJavaChaincode installs the example java chaincode to all peers in the given orgs func InstallExampleJavaChaincode(orgs []*OrgContext, ccID string) error { ccPkg, err := javapackager.NewCCPackage(filepath.Join(GetJavaDeployPath(), exampleJavaCCPath)) @@ -199,6 +515,98 @@ func InstallExampleNodeChaincode(orgs []*OrgContext, ccID string) error { return nil } +// InstantiateExampleChaincodeLc install and instantiate using resource management client +func InstantiateExampleChaincodeLc(sdk *fabsdk.FabricSDK, orgs []*OrgContext, channelID, ccID, ccPolicy string, collConfigs ...*pb.CollectionConfig) error { + start := time.Now() + packageID, err := InstallExampleChaincodeLc(orgs, ccID, exampleCCVersion) + if err != nil { + return errors.WithMessage(err, "Installing example chaincode failed") + } + + err = instantiateExampleChaincodeLc(sdk, orgs, channelID, ccID, exampleCCVersion, ccPolicy, packageID, 1, collConfigs...) + if err != nil { + return errors.WithMessage(err, "init example chaincode failed") + } + t := time.Now() + elapsed := t.Sub(start) + fmt.Printf("Done [%d ms]\n", elapsed/time.Millisecond) + + return nil +} + +// InstantiatePvtExampleChaincodeLc install and instantiate using resource management client +func InstantiatePvtExampleChaincodeLc(sdk *fabsdk.FabricSDK, orgs []*OrgContext, channelID, ccID, ccPolicy string, collConfigs ...*pb.CollectionConfig) error { + start := time.Now() + packageID, err := InstallExamplePvtChaincodeLc(orgs, ccID, exampleCCVersion) + if err != nil { + return errors.WithMessage(err, "Installing example chaincode failed") + } + + err = instantiateExampleChaincodeLc(sdk, orgs, channelID, ccID, exampleCCVersion, ccPolicy, packageID, 1, collConfigs...) + if err != nil { + return errors.WithMessage(err, "init example chaincode failed") + } + t := time.Now() + elapsed := t.Sub(start) + fmt.Printf("Done [%d ms]\n", elapsed/time.Millisecond) + + return nil +} + +func instantiateExampleChaincodeLc(sdk *fabsdk.FabricSDK, orgs []*OrgContext, channelID, ccID, ccVersion, ccPolicy, packageID string, sequence int64, collConfigs ...*pb.CollectionConfig) error { + + err := ApproveExampleChaincode(orgs, channelID, ccID, ccVersion, packageID, ccPolicy, sequence, collConfigs...) + if err != nil { + return errors.WithMessage(err, "Approve example chaincode failed") + } + + err = QueryApprovedCC(orgs, ccID, sequence, channelID) + if err != nil { + return errors.WithMessage(err, "QueryApprovedCC example chaincode failed") + } + + err = CheckCCCommitReadiness(orgs, packageID, ccID, ccVersion, sequence, channelID, ccPolicy) + if err != nil { + return errors.WithMessage(err, "CheckCCCommitReadiness example chaincode failed") + } + + err = CommitExampleChaincode(orgs, channelID, ccID, ccVersion, ccPolicy, sequence, collConfigs...) + if err != nil { + return errors.WithMessage(err, "Commit example chaincode failed") + } + + err = QueryCommittedCC(orgs, ccID, channelID, sequence) + if err != nil { + return errors.WithMessage(err, "QueryCommittedCC example chaincode failed") + } + + err = InitExampleChaincode(sdk, channelID, ccID, orgs[0].OrgID) + if err != nil { + return errors.WithMessage(err, "Init example chaincode failed") + } + + return nil +} + +// UpgradeExamplePvtChaincodeLc upgrades the instantiated example pvt CC on the given channel +func UpgradeExamplePvtChaincodeLc(sdk *fabsdk.FabricSDK, orgs []*OrgContext, channelID, ccID, ccPolicy string, collConfigs ...*pb.CollectionConfig) error { + start := time.Now() + packageID, err := InstallExamplePvtChaincodeLc(orgs, ccID, exampleUpgdPvtCCVer) + if err != nil { + return errors.WithMessage(err, "Installing example chaincode failed") + } + + err = instantiateExampleChaincodeLc(sdk, orgs, channelID, ccID, exampleUpgdPvtCCVer, ccPolicy, packageID, 2, collConfigs...) + if err != nil { + return errors.WithMessage(err, "init example chaincode failed") + } + t := time.Now() + elapsed := t.Sub(start) + fmt.Printf("Done [%d ms]\n", elapsed/time.Millisecond) + + return nil +} + // InstantiateExampleChaincode instantiates the example CC on the given channel func InstantiateExampleChaincode(orgs []*OrgContext, channelID, ccID, ccPolicy string, collConfigs ...*pb.CollectionConfig) error { _, err := InstantiateChaincode(orgs[0].ResMgmt, channelID, ccID, exampleCCPath, exampleCCVersion, ccPolicy, ExampleCCInitArgs(), collConfigs...) diff --git a/test/integration/util/runner/runner.go b/test/integration/util/runner/runner.go index bfdf86668b..4531757dcc 100644 --- a/test/integration/util/runner/runner.go +++ b/test/integration/util/runner/runner.go @@ -13,6 +13,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/test/integration" + "github.com/hyperledger/fabric-sdk-go/test/metadata" ) const ( @@ -115,10 +116,17 @@ func (r *Runner) Initialize() { } if r.installExampleCC { - r.exampleChaincodeID = integration.GenerateExampleID(false) - if err := integration.PrepareExampleCC(sdk, fabsdk.WithUser("Admin"), r.testSetup.OrgID, r.exampleChaincodeID); err != nil { - panic(fmt.Sprintf("PrepareExampleCC return error: %s", err)) + r.exampleChaincodeID = integration.GenerateExampleID(true) + if metadata.CCMode == "lscc" { + if err := integration.PrepareExampleCC(sdk, fabsdk.WithUser("Admin"), r.testSetup.OrgID, r.exampleChaincodeID); err != nil { + panic(fmt.Sprintf("PrepareExampleCC return error: %s", err)) + } + } else { + if err := integration.PrepareExampleCCLc(sdk, fabsdk.WithUser("Admin"), r.testSetup.OrgID, r.exampleChaincodeID); err != nil { + panic(fmt.Sprintf("PrepareExampleCCLc return error: %s", err)) + } } + } } diff --git a/test/metadata/metadata.go b/test/metadata/metadata.go index a916da49b0..cd636df3e5 100644 --- a/test/metadata/metadata.go +++ b/test/metadata/metadata.go @@ -8,7 +8,7 @@ SPDX-License-Identifier: Apache-2.0 package metadata // ChannelConfigPath is the relative path to the generated channel artifacts directory -var ChannelConfigPath = "test/fixtures/fabric/v1.4/channel" +var ChannelConfigPath = "test/fixtures/fabric/v2.2/channel" // CryptoConfigPath is the relative path to the generated crypto config directory var CryptoConfigPath = "test/fixtures/fabric/v1/crypto-config" @@ -24,3 +24,6 @@ var ProjectPath = "" // TestRunID is an identifier for the current run of tests var TestRunID = "" + +// CCMode is an identifier for the cc mode: lifecycle or lscc +var CCMode = "lifecycle" diff --git a/test/scripts/integration-pkcs11.sh b/test/scripts/integration-pkcs11.sh index f35e6fd00c..8a75ab55ce 100755 --- a/test/scripts/integration-pkcs11.sh +++ b/test/scripts/integration-pkcs11.sh @@ -28,6 +28,7 @@ TEST_LOCAL="${TEST_LOCAL:-false}" TEST_CHANGED_ONLY="${TEST_CHANGED_ONLY:-false}" TEST_RACE_CONDITIONS="${TEST_RACE_CONDITIONS:-true}" SCRIPT_DIR="$(dirname "$0")" +CC_MODE="${CC_MODE:-lifecycle}" # TODO: better default handling for FABRIC_CRYPTOCONFIG_VERSION GOMOD_PATH=$(cd ${SCRIPT_DIR} && ${GO_CMD} env GOMOD) @@ -109,6 +110,7 @@ GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.ProjectPath=${PROJE GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.ChannelConfigPath=test/fixtures/fabric/${FABRIC_FIXTURE_VERSION}/channel" GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.CryptoConfigPath=test/fixtures/fabric/${FABRIC_CRYPTOCONFIG_VERSION}/crypto-config" GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.TestRunID=${FABRIC_SDKGO_TESTRUN_ID}" +GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.CCMode=${CC_MODE}" $GO_CMD test ${RACEFLAG} -tags "${GO_TAGS}" ${GO_TESTFLAGS} -ldflags="${GO_LDFLAGS}" ${PKGS[@]} -p 1 -timeout=40m configFile=${CONFIG_FILE} testLocal=${TEST_LOCAL} cd ${PWD_ORIG} diff --git a/test/scripts/integration.sh b/test/scripts/integration.sh index 01ff834050..394d921719 100755 --- a/test/scripts/integration.sh +++ b/test/scripts/integration.sh @@ -29,6 +29,7 @@ TEST_LOCAL="${TEST_LOCAL:-false}" TEST_CHANGED_ONLY="${TEST_CHANGED_ONLY:-false}" TEST_RACE_CONDITIONS="${TEST_RACE_CONDITIONS:-true}" SCRIPT_DIR="$(dirname "$0")" +CC_MODE="${CC_MODE:-lifecycle}" # TODO: better default handling for FABRIC_CRYPTOCONFIG_VERSION GOMOD_PATH=$(cd ${SCRIPT_DIR} && ${GO_CMD} env GOMOD) @@ -105,7 +106,8 @@ GO_TAGS="${GO_TAGS} ${FABRIC_SDKGO_CODELEVEL_TAG}" GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.ProjectPath=${PROJECT_DIR}" GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.ChannelConfigPath=test/fixtures/fabric/${FABRIC_FIXTURE_VERSION}/channel" GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.CryptoConfigPath=test/fixtures/fabric/${FABRIC_CRYPTOCONFIG_VERSION}/crypto-config" +GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.CCMode=${CC_MODE}" GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/fabric-sdk-go/test/metadata.TestRunID=${FABRIC_SDKGO_TESTRUN_ID}" -${GO_CMD} test ${RACEFLAG} -tags "${GO_TAGS}" ${GO_TESTFLAGS} -ldflags="${GO_LDFLAGS}" ${PKGS[@]} -p 1 -timeout=40m configFile=${CONFIG_FILE} testLocal=${TEST_LOCAL} +${GO_CMD} test ${RACEFLAG} -tags "${GO_TAGS}" ${GO_TESTFLAGS} -ldflags="${GO_LDFLAGS}" ${PKGS[@]} -p 1 -timeout=120m configFile=${CONFIG_FILE} testLocal=${TEST_LOCAL} cd ${PWD_ORIG} diff --git a/test/scripts/negative.sh b/test/scripts/negative.sh index 430fec3bcb..2e9a257b43 100755 --- a/test/scripts/negative.sh +++ b/test/scripts/negative.sh @@ -25,7 +25,7 @@ CONFIG_FILE="${CONFIG_FILE:-config_test.yaml}" TEST_CHANGED_ONLY="${TEST_CHANGED_ONLY:-false}" TEST_RACE_CONDITIONS="${TEST_RACE_CONDITIONS:-true}" SCRIPT_DIR="$(dirname "$0")" - +CC_MODE="${CC_MODE:-lifecycle}" # TODO: better default handling for FABRIC_CRYPTOCONFIG_VERSION GOMOD_PATH=$(cd ${SCRIPT_DIR} && ${GO_CMD} env GOMOD) @@ -94,6 +94,7 @@ GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.ProjectPath=${PROJE GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.ChannelConfigPath=test/fixtures/fabric/${FABRIC_SDKGO_CODELEVEL_VER}/channel" GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.CryptoConfigPath=test/fixtures/fabric/${FABRIC_CRYPTOCONFIG_VERSION}/crypto-config" GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.TestRunID=${FABRIC_SDKGO_TESTRUN_ID}" +GO_LDFLAGS="${GO_LDFLAGS} -X ${PROJECT_MODULE}/test/metadata.CCMode=${CC_MODE}" ${GO_CMD} test ${RACEFLAG} -tags "${GO_TAGS}" ${GO_TESTFLAGS} -ldflags="${GO_LDFLAGS}" ${PKGS[@]} -p 1 -timeout=40m configFile=${CONFIG_FILE} cd ${PWD_ORIG}