diff --git a/Makefile b/Makefile index 73565cdff4..b12a0d0f18 100644 --- a/Makefile +++ b/Makefile @@ -187,7 +187,7 @@ depend-install: @FABRIC_SDKGO_DEPEND_INSTALL="true" $(TEST_SCRIPTS_PATH)/dependencies.sh .PHONY: checks -checks: depend license lint spelling +checks: depend license lint .PHONY: license license: @@ -197,9 +197,6 @@ license: lint: populate @$(TEST_SCRIPTS_PATH)/check_lint.sh -.PHONY: spelling -spelling: - @$(TEST_SCRIPTS_PATH)/check_spelling.sh .PHONY: build-softhsm2-image build-softhsm2-image: diff --git a/gometalinter.json b/gometalinter.json index 16fa825712..80a98cfe21 100644 --- a/gometalinter.json +++ b/gometalinter.json @@ -3,7 +3,8 @@ "Exclude": [ ".*seekInfo can be .*proto.Message.*", "test/integration/msp/check_cert_attributes.go", - "test/integration/msp/check_cert_ser_attributes_prev.go" + "test/integration/msp/check_cert_ser_attributes_prev.go", + "test/fixtures/testdata/..." ], "EnableGC": true, "WarnUnmatchedDirective": true, diff --git a/test/integration/base_test_setup.go b/test/integration/base_test_setup.go index fc432d7966..67116ecd4a 100644 --- a/test/integration/base_test_setup.go +++ b/test/integration/base_test_setup.go @@ -10,6 +10,8 @@ import ( "os" "path" + "fmt" + "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/common/providers/core" @@ -94,7 +96,12 @@ func (setup *BaseSetupImpl) Initialize(sdk *fabsdk.FabricSDK) error { if err != nil { return errors.Wrapf(err, "opening channel config file failed") } - defer r.Close() + defer func() { + if err = r.Close(); err != nil { + fmt.Printf("close error %v\n", err) + } + + }() // Create channel for tests req := resmgmt.SaveChannelRequest{ChannelID: setup.ChannelID, ChannelConfig: r, SigningIdentities: []msp.SigningIdentity{adminIdentity}} diff --git a/test/integration/e2e/end_to_end_test.go b/test/integration/e2e/end_to_end_test.go index b337b1ab08..78b30695e9 100644 --- a/test/integration/e2e/end_to_end_test.go +++ b/test/integration/e2e/end_to_end_test.go @@ -19,5 +19,5 @@ func TestE2E(t *testing.T) { Run(t, config.FromFile("../../fixtures/config/config_test.yaml")) //Using setup done set above by end to end test, run below test with new config which has no orderer config inside - RunWithNoOrdererConfig(t, integration.ConfigNoOrdererBackend) + runWithNoOrdererConfig(t, integration.ConfigNoOrdererBackend) } diff --git a/test/integration/e2e/no_orderer_config.go b/test/integration/e2e/no_orderer_config_test.go similarity index 96% rename from test/integration/e2e/no_orderer_config.go rename to test/integration/e2e/no_orderer_config_test.go index 92fefe5e76..b6b2f0ece3 100644 --- a/test/integration/e2e/no_orderer_config.go +++ b/test/integration/e2e/no_orderer_config_test.go @@ -18,8 +18,8 @@ import ( "github.com/hyperledger/fabric-sdk-go/test/integration" ) -// RunWithNoOrdererConfig enables chclient scenarios using config and sdk options provided -func RunWithNoOrdererConfig(t *testing.T, configOpt core.ConfigProvider, sdkOpts ...fabsdk.Option) { +// runWithNoOrdererConfig enables chclient scenarios using config and sdk options provided +func runWithNoOrdererConfig(t *testing.T, configOpt core.ConfigProvider, sdkOpts ...fabsdk.Option) { sdk, err := fabsdk.New(configOpt, sdkOpts...) if err != nil { diff --git a/test/integration/env.go b/test/integration/env.go index 63ab9bf680..ac8a49e792 100644 --- a/test/integration/env.go +++ b/test/integration/env.go @@ -99,9 +99,12 @@ func addLocalEntityMappingToBackend(backend core.ConfigBackend) (core.ConfigBack networkConfig := fab.NetworkConfig{} configLookup := lookup.New(backend) - configLookup.UnmarshalKey("orderers", &networkConfig.Orderers) - configLookup.UnmarshalKey("peers", &networkConfig.Peers) - + if err = configLookup.UnmarshalKey("orderers", &networkConfig.Orderers); err != nil { + return nil, err + } + if err = configLookup.UnmarshalKey("peers", &networkConfig.Peers); err != nil { + return nil, err + } orderer, ok := networkConfig.Orderers["local.orderer.example.com"] if ok { orderer.URL = re.ReplaceAllString(orderer.URL, "localhost:") diff --git a/test/integration/orgs/multiple_orgs_test.go b/test/integration/orgs/multiple_orgs_test.go index c94892498a..7d9fcb19e4 100644 --- a/test/integration/orgs/multiple_orgs_test.go +++ b/test/integration/orgs/multiple_orgs_test.go @@ -34,6 +34,7 @@ import ( selection "github.com/hyperledger/fabric-sdk-go/pkg/client/common/selection/dynamicselection" "github.com/hyperledger/fabric-sdk-go/pkg/client/channel" + "github.com/hyperledger/fabric-sdk-go/pkg/fab/resource/api" "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/cauthdsl" ) @@ -105,12 +106,7 @@ func testWithOrg1(t *testing.T, sdk *fabsdk.FabricSDK) int { t.Fatalf("failed to get org2AdminUser, err : %v", err) } - req := resmgmt.SaveChannelRequest{ChannelID: "orgchannel", - ChannelConfigPath: path.Join("../../../", metadata.ChannelConfigPath, "orgchannel.tx"), - SigningIdentities: []msp.SigningIdentity{org1AdminUser, org2AdminUser}} - txID, err := chMgmtClient.SaveChannel(req, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) - require.Nil(t, err, "error should be nil") - require.NotEmpty(t, txID, "transaction ID should be populated") + createChannel(org1AdminUser, org2AdminUser, chMgmtClient, t) // Org1 resource management client (Org1 is default org) org1ResMgmt, err := resmgmt.New(org1AdminClientContext) @@ -134,100 +130,156 @@ func testWithOrg1(t *testing.T, sdk *fabsdk.FabricSDK) int { t.Fatalf("Org2 peers failed to JoinChannel: %s", err) } - // Create chaincode package for example cc ccPkg, err := packager.NewCCPackage("github.com/example_cc", "../../fixtures/testdata") if err != nil { t.Fatal(err) } - installCCReq := resmgmt.InstallCCRequest{Name: "exampleCC", Path: "github.com/example_cc", Version: "0", Package: ccPkg} + // Create chaincode package for example cc + createCC(t, org1ResMgmt, org2ResMgmt, ccPkg) - // Install example cc to Org1 peers - _, err = org1ResMgmt.InstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) - if err != nil { - t.Fatal(err) - } + chClientOrg1User, chClientOrg2User := connectUserToOrgChannel(org1ChannelClientContext, t, org2ChannelClientContext) - // Install example cc to Org2 peers - _, err = org2ResMgmt.InstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + // Call with a dummy function and expect a fail with multiple errors + verifyErrorFromCC(chClientOrg1User, t) + + // Org1 user queries initial value on both peers + value := queryCC(chClientOrg1User, t) + initial, _ := strconv.Atoi(string(value)) + + ledgerClient, err := ledger.New(org1AdminChannelContext) if err != nil { - t.Fatal(err) + t.Fatalf("Failed to create new ledger client: %s", err) } - // Set up chaincode policy to 'any of two msps' - ccPolicy := cauthdsl.SignedByAnyMember([]string{"Org1MSP", "Org2MSP"}) + // Ledger client will verify blockchain info + ledgerInfoBefore := getBlockchainInfo(ledgerClient, t) - // Org1 resource manager will instantiate 'example_cc' on 'orgchannel' - instantiateResp, err := org1ResMgmt.InstantiateCC("orgchannel", resmgmt.InstantiateCCRequest{Name: "exampleCC", Path: "github.com/example_cc", Version: "0", Args: integration.ExampleCCInitArgs(), Policy: ccPolicy}, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) - require.Nil(t, err, "error should be nil") - require.NotEmpty(t, instantiateResp, "transaction response should be populated") + // Org2 user moves funds on org2 peer + transactionID := moveFunds(chClientOrg2User, t) - // Verify that example CC is instantiated on Org1 peer - chaincodeQueryResponse, err := org1ResMgmt.QueryInstantiatedChaincodes("orgchannel", resmgmt.WithRetry(retry.DefaultResMgmtOpts)) - if err != nil { - t.Fatalf("QueryInstantiatedChaincodes return error: %v", err) - } + // Assert that funds have changed value on org1 peer + verifyValue(t, chClientOrg1User, initial+1) - found := false - for _, chaincode := range chaincodeQueryResponse.Chaincodes { - if chaincode.Name == "exampleCC" { - found = true - } - } + // Get latest block chain info + checkLedgerInfo(ledgerClient, t, ledgerInfoBefore, transactionID) - if !found { - t.Fatalf("QueryInstantiatedChaincodes failed to find instantiated exampleCC chaincode") - } + // Start chaincode upgrade process (install and instantiate new version of exampleCC) + upgradeCC(ccPkg, org1ResMgmt, t, org2ResMgmt) + + // Org2 user moves funds on org2 peer (cc policy fails since both Org1 and Org2 peers should participate) + testCCPolicy(chClientOrg2User, t) + // Assert that funds have changed value on org1 peer + beforeTxValue, _ := strconv.Atoi(integration.ExampleCCUpgradeB) + expectedValue := beforeTxValue + 1 + verifyValue(t, chClientOrg1User, expectedValue) + + return expectedValue +} + +func connectUserToOrgChannel(org1ChannelClientContext contextAPI.ChannelProvider, t *testing.T, org2ChannelClientContext contextAPI.ChannelProvider) (*channel.Client, *channel.Client) { // Org1 user connects to 'orgchannel' chClientOrg1User, err := channel.New(org1ChannelClientContext) if err != nil { t.Fatalf("Failed to create new channel client for Org1 user: %s", err) } - // Org2 user connects to 'orgchannel' chClientOrg2User, err := channel.New(org2ChannelClientContext) if err != nil { t.Fatalf("Failed to create new channel client for Org2 user: %s", err) } + return chClientOrg1User, chClientOrg2User +} - // Call with a dummy function and expect a fail with multiple errors - response, err := chClientOrg1User.Query(channel.Request{ChaincodeID: "exampleCC", Fcn: "DUMMY_FUNCTION", Args: integration.ExampleCCQueryArgs()}, - channel.WithRetry(retry.DefaultChClientOpts)) - require.Error(t, err, "Should have failed with dummy function") - s, ok := status.FromError(err) - require.True(t, ok, "expected status error") - require.Equal(t, s.Code, int32(status.MultipleErrors)) - for _, err := range err.(multi.Errors) { - s, ok := status.FromError(err) - require.True(t, ok, "expected status error") - require.EqualValues(t, int32(500), s.Code) - require.Equal(t, status.ChaincodeStatus, s.Group) +func checkLedgerInfo(ledgerClient *ledger.Client, t *testing.T, ledgerInfoBefore *fab.BlockchainInfoResponse, transactionID fab.TransactionID) { + ledgerInfoAfter, err := ledgerClient.QueryInfo(ledger.WithTargets(orgTestPeer0.(fab.Peer), orgTestPeer1.(fab.Peer)), ledger.WithMinTargets(2)) + if err != nil { + t.Fatalf("QueryInfo return error: %v", err) + } + if ledgerInfoAfter.BCI.Height-ledgerInfoBefore.BCI.Height <= 0 { + t.Fatalf("Block size did not increase after transaction") + } + // Test Query Block by Hash - retrieve current block by number + block, err := ledgerClient.QueryBlock(ledgerInfoAfter.BCI.Height-1, ledger.WithTargets(orgTestPeer0.(fab.Peer), orgTestPeer1.(fab.Peer)), ledger.WithMinTargets(2)) + if err != nil { + t.Fatalf("QueryBlock return error: %v", err) } + if block == nil { + t.Fatalf("Block info not available") + } + // Get transaction info + transactionInfo, err := ledgerClient.QueryTransaction(transactionID, ledger.WithTargets(orgTestPeer0.(fab.Peer), orgTestPeer1.(fab.Peer)), ledger.WithMinTargets(2)) + if err != nil { + t.Fatalf("QueryTransaction return error: %v", err) + } + if transactionInfo.TransactionEnvelope == nil { + t.Fatalf("Transaction info missing") + } +} - // Org1 user queries initial value on both peers - response, err = chClientOrg1User.Query(channel.Request{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCQueryArgs()}, +func createChannel(org1AdminUser msp.SigningIdentity, org2AdminUser msp.SigningIdentity, chMgmtClient *resmgmt.Client, t *testing.T) { + req := resmgmt.SaveChannelRequest{ChannelID: "orgchannel", + ChannelConfigPath: path.Join("../../../", metadata.ChannelConfigPath, "orgchannel.tx"), + SigningIdentities: []msp.SigningIdentity{org1AdminUser, org2AdminUser}} + txID, err := chMgmtClient.SaveChannel(req, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + require.Nil(t, err, "error should be nil") + require.NotEmpty(t, txID, "transaction ID should be populated") +} + +func testCCPolicy(chClientOrg2User *channel.Client, t *testing.T) { + _, err := chClientOrg2User.Execute(channel.Request{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCTxArgs()}, channel.WithTargets(orgTestPeer1), + channel.WithRetry(retry.DefaultChClientOpts)) + if err == nil { + t.Fatalf("Should have failed to move funds due to cc policy") + } + // Org2 user moves funds (cc policy ok since we have provided peers for both Orgs) + _, err = chClientOrg2User.Execute(channel.Request{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCTxArgs()}, channel.WithTargets(orgTestPeer0, orgTestPeer1), channel.WithRetry(retry.DefaultChClientOpts)) if err != nil { - t.Fatalf("Failed to query funds: %s", err) + t.Fatalf("Failed to move funds: %s", err) + } +} + +func upgradeCC(ccPkg *api.CCPackage, org1ResMgmt *resmgmt.Client, t *testing.T, org2ResMgmt *resmgmt.Client) { + installCCReq := resmgmt.InstallCCRequest{Name: "exampleCC", Path: "github.com/example_cc", Version: "1", Package: ccPkg} + // Install example cc version '1' to Org1 peers + _, err := org1ResMgmt.InstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) + } + // Install example cc version '1' to Org2 peers + _, err = org2ResMgmt.InstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + if err != nil { + t.Fatal(err) } - initial, _ := strconv.Atoi(string(response.Payload)) + // New chaincode policy (both orgs have to approve) + org1Andorg2Policy, err := cauthdsl.FromString("AND ('Org1MSP.member','Org2MSP.member')") + if err != nil { + t.Fatal(err) + } + // Org1 resource manager will instantiate 'example_cc' version 1 on 'orgchannel' + upgradeResp, err := org1ResMgmt.UpgradeCC("orgchannel", resmgmt.UpgradeCCRequest{Name: "exampleCC", Path: "github.com/example_cc", Version: "1", Args: integration.ExampleCCUpgradeArgs(), Policy: org1Andorg2Policy}) + require.Nil(t, err, "error should be nil") + require.NotEmpty(t, upgradeResp, "transaction response should be populated") +} +func moveFunds(chClientOrgUser *channel.Client, t *testing.T) fab.TransactionID { + response, err := chClientOrgUser.Execute(channel.Request{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCTxArgs()}, channel.WithTargets(orgTestPeer1), + channel.WithRetry(retry.DefaultChClientOpts)) + if err != nil { + t.Fatalf("Failed to move funds: %s", err) + } if response.ChaincodeStatus == 0 { t.Fatalf("Expected ChaincodeStatus") } - if response.Responses[0].ChaincodeStatus != response.ChaincodeStatus { t.Fatalf("Expected the chaincode status returned by successful Peer Endorsement to be same as Chaincode status for client response") } + return response.TransactionID +} - // Ledger client will verify blockchain info - ledgerClient, err := ledger.New(org1AdminChannelContext) - - if err != nil { - t.Fatalf("Failed to create new ledger client: %s", err) - } - +func getBlockchainInfo(ledgerClient *ledger.Client, t *testing.T) *fab.BlockchainInfoResponse { channelCfg, err := ledgerClient.QueryConfig(ledger.WithTargets(orgTestPeer0, orgTestPeer1), ledger.WithMinTargets(2)) if err != nil { t.Fatalf("QueryConfig return error: %v", err) @@ -239,12 +291,10 @@ func testWithOrg1(t *testing.T, sdk *fabsdk.FabricSDK) int { if !strings.Contains(channelCfg.Orderers()[0], expectedOrderer) { t.Fatalf("Expecting %s, got %s", expectedOrderer, channelCfg.Orderers()[0]) } - ledgerInfoBefore, err := ledgerClient.QueryInfo(ledger.WithTargets(orgTestPeer0, orgTestPeer1), ledger.WithMinTargets(2), ledger.WithMaxTargets(3)) if err != nil { t.Fatalf("QueryInfo return error: %v", err) } - // Test Query Block by Hash - retrieve current block by hash block, err := ledgerClient.QueryBlockByHash(ledgerInfoBefore.BCI.CurrentBlockHash, ledger.WithTargets(orgTestPeer0.(fab.Peer), orgTestPeer1.(fab.Peer)), ledger.WithMinTargets(2)) if err != nil { @@ -253,99 +303,72 @@ func testWithOrg1(t *testing.T, sdk *fabsdk.FabricSDK) int { if block == nil { t.Fatalf("Block info not available") } + return ledgerInfoBefore +} - // Org2 user moves funds on org2 peer - response, err = chClientOrg2User.Execute(channel.Request{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCTxArgs()}, channel.WithTargets(orgTestPeer1), +func queryCC(chClientOrg1User *channel.Client, t *testing.T) []byte { + response, err := chClientOrg1User.Query(channel.Request{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCQueryArgs()}, channel.WithRetry(retry.DefaultChClientOpts)) if err != nil { - t.Fatalf("Failed to move funds: %s", err) + t.Fatalf("Failed to query funds: %s", err) } - if response.ChaincodeStatus == 0 { t.Fatalf("Expected ChaincodeStatus") } - if response.Responses[0].ChaincodeStatus != response.ChaincodeStatus { t.Fatalf("Expected the chaincode status returned by successful Peer Endorsement to be same as Chaincode status for client response") } + return response.Payload +} - // Assert that funds have changed value on org1 peer - verifyValue(t, chClientOrg1User, initial+1) - - // Get latest block chain info - ledgerInfoAfter, err := ledgerClient.QueryInfo(ledger.WithTargets(orgTestPeer0.(fab.Peer), orgTestPeer1.(fab.Peer)), ledger.WithMinTargets(2)) - if err != nil { - t.Fatalf("QueryInfo return error: %v", err) - } - - if ledgerInfoAfter.BCI.Height-ledgerInfoBefore.BCI.Height <= 0 { - t.Fatalf("Block size did not increase after transaction") - } - - // Test Query Block by Hash - retrieve current block by number - block, err = ledgerClient.QueryBlock(ledgerInfoAfter.BCI.Height-1, ledger.WithTargets(orgTestPeer0.(fab.Peer), orgTestPeer1.(fab.Peer)), ledger.WithMinTargets(2)) - if err != nil { - t.Fatalf("QueryBlock return error: %v", err) - } - if block == nil { - t.Fatalf("Block info not available") - } - - // Get transaction info - transactionInfo, err := ledgerClient.QueryTransaction(response.TransactionID, ledger.WithTargets(orgTestPeer0.(fab.Peer), orgTestPeer1.(fab.Peer)), ledger.WithMinTargets(2)) - if err != nil { - t.Fatalf("QueryTransaction return error: %v", err) - } - if transactionInfo.TransactionEnvelope == nil { - t.Fatalf("Transaction info missing") +func verifyErrorFromCC(chClientOrg1User *channel.Client, t *testing.T) { + _, err := chClientOrg1User.Query(channel.Request{ChaincodeID: "exampleCC", Fcn: "DUMMY_FUNCTION", Args: integration.ExampleCCQueryArgs()}, + channel.WithRetry(retry.DefaultChClientOpts)) + require.Error(t, err, "Should have failed with dummy function") + s, ok := status.FromError(err) + require.True(t, ok, "expected status error") + require.Equal(t, s.Code, int32(status.MultipleErrors)) + for _, err := range err.(multi.Errors) { + s, ok := status.FromError(err) + require.True(t, ok, "expected status error") + require.EqualValues(t, int32(500), s.Code) + require.Equal(t, status.ChaincodeStatus, s.Group) } +} - // Start chaincode upgrade process (install and instantiate new version of exampleCC) - installCCReq = resmgmt.InstallCCRequest{Name: "exampleCC", Path: "github.com/example_cc", Version: "1", Package: ccPkg} - - // Install example cc version '1' to Org1 peers - _, err = org1ResMgmt.InstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) +func createCC(t *testing.T, org1ResMgmt *resmgmt.Client, org2ResMgmt *resmgmt.Client, ccPkg *api.CCPackage) { + installCCReq := resmgmt.InstallCCRequest{Name: "exampleCC", Path: "github.com/example_cc", Version: "0", Package: ccPkg} + // Install example cc to Org1 peers + _, err := org1ResMgmt.InstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) if err != nil { t.Fatal(err) } - - // Install example cc version '1' to Org2 peers + // Install example cc to Org2 peers _, err = org2ResMgmt.InstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) if err != nil { t.Fatal(err) } - - // New chaincode policy (both orgs have to approve) - org1Andorg2Policy, err := cauthdsl.FromString("AND ('Org1MSP.member','Org2MSP.member')") + // Set up chaincode policy to 'any of two msps' + ccPolicy := cauthdsl.SignedByAnyMember([]string{"Org1MSP", "Org2MSP"}) + // Org1 resource manager will instantiate 'example_cc' on 'orgchannel' + instantiateResp, err := org1ResMgmt.InstantiateCC("orgchannel", resmgmt.InstantiateCCRequest{Name: "exampleCC", Path: "github.com/example_cc", Version: "0", Args: integration.ExampleCCInitArgs(), Policy: ccPolicy}, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + require.Nil(t, err, "error should be nil") + require.NotEmpty(t, instantiateResp, "transaction response should be populated") + // Verify that example CC is instantiated on Org1 peer + chaincodeQueryResponse, err := org1ResMgmt.QueryInstantiatedChaincodes("orgchannel", resmgmt.WithRetry(retry.DefaultResMgmtOpts)) if err != nil { - t.Fatal(err) + t.Fatalf("QueryInstantiatedChaincodes return error: %v", err) } - - // Org1 resource manager will instantiate 'example_cc' version 1 on 'orgchannel' - upgradeResp, err := org1ResMgmt.UpgradeCC("orgchannel", resmgmt.UpgradeCCRequest{Name: "exampleCC", Path: "github.com/example_cc", Version: "1", Args: integration.ExampleCCUpgradeArgs(), Policy: org1Andorg2Policy}) - require.Nil(t, err, "error should be nil") - require.NotEmpty(t, upgradeResp, "transaction response should be populated") - - // Org2 user moves funds on org2 peer (cc policy fails since both Org1 and Org2 peers should participate) - response, err = chClientOrg2User.Execute(channel.Request{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCTxArgs()}, channel.WithTargets(orgTestPeer1), - channel.WithRetry(retry.DefaultChClientOpts)) - if err == nil { - t.Fatalf("Should have failed to move funds due to cc policy") + found := false + for _, chaincode := range chaincodeQueryResponse.Chaincodes { + if chaincode.Name == "exampleCC" { + found = true + } } - - // Org2 user moves funds (cc policy ok since we have provided peers for both Orgs) - response, err = chClientOrg2User.Execute(channel.Request{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCTxArgs()}, channel.WithTargets(orgTestPeer0, orgTestPeer1), - channel.WithRetry(retry.DefaultChClientOpts)) - if err != nil { - t.Fatalf("Failed to move funds: %s", err) + if !found { + t.Fatalf("QueryInstantiatedChaincodes failed to find instantiated exampleCC chaincode") } - // Assert that funds have changed value on org1 peer - beforeTxValue, _ := strconv.Atoi(integration.ExampleCCUpgradeB) - expectedValue := beforeTxValue + 1 - verifyValue(t, chClientOrg1User, expectedValue) - - return expectedValue } func testWithOrg2(t *testing.T, expectedValue int) int { diff --git a/test/integration/revoked/revoked_peer_test.go b/test/integration/revoked/revoked_peer_test.go index 8d44107e4e..735ab01b91 100644 --- a/test/integration/revoked/revoked_peer_test.go +++ b/test/integration/revoked/revoked_peer_test.go @@ -11,9 +11,7 @@ import ( "testing" "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry" - "github.com/hyperledger/fabric-sdk-go/pkg/common/logging" contextAPI "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context" - "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp" @@ -25,6 +23,7 @@ import ( "github.com/hyperledger/fabric-sdk-go/test/metadata" "github.com/hyperledger/fabric-sdk-go/pkg/client/channel" + "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core" "github.com/hyperledger/fabric-sdk-go/pkg/core/config" "github.com/hyperledger/fabric-sdk-go/pkg/core/config/lookup" "github.com/hyperledger/fabric-sdk-go/pkg/core/mocks" @@ -44,8 +43,6 @@ const ( configPath = "../../fixtures/config/config_test.yaml" ) -var logger = logging.NewLogger("fabsdk/test") - // Peers used for testing var orgTestPeer0 fab.Peer var orgTestPeer1 fab.Peer @@ -87,12 +84,7 @@ func TestRevokedPeer(t *testing.T) { t.Fatalf("failed to get org2AdminUser, err : %v", err) } - req := resmgmt.SaveChannelRequest{ChannelID: "orgchannel", - ChannelConfigPath: path.Join("../../../", metadata.ChannelConfigPath, "orgchannel.tx"), - SigningIdentities: []msp.SigningIdentity{org1AdminUser, org2AdminUser}} - txID, err := chMgmtClient.SaveChannel(req, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) - require.Nil(t, err, "error should be nil") - require.NotEmpty(t, txID, "transaction ID should be populated") + createChannel(org1AdminUser, org2AdminUser, chMgmtClient, t) // Org1 resource management client (Org1 is default org) org1ResMgmt, err := resmgmt.New(org1AdminClientContext) @@ -117,55 +109,66 @@ func TestRevokedPeer(t *testing.T) { } // Create chaincode package for example cc + createCC(t, org1ResMgmt, org2ResMgmt) + + // Load specific targets for move funds test - one of the + //targets has its certificate revoked + loadOrgPeers(t, org1AdminClientContext) + + queryCC(org1ChannelClientContext, t) + +} + +func queryCC(org1ChannelClientContext contextAPI.ChannelProvider, t *testing.T) { + // Org1 user connects to 'orgchannel' + chClientOrg1User, err := channel.New(org1ChannelClientContext) + if err != nil { + t.Fatalf("Failed to create new channel client for Org1 user: %s", err) + } + // Org1 user queries initial value on both peers + // Since one of the peers on channel has certificate revoked, eror is expected here + // Error in container is : + // .... identity 0 does not satisfy principal: + // Could not validate identity against certification chain, err The certificate has been revoked + _, err = chClientOrg1User.Query(channel.Request{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCQueryArgs()}) + if err == nil { + t.Fatalf("Expected error: '....Description: could not find chaincode with name 'exampleCC',,, ") + } +} + +func createCC(t *testing.T, org1ResMgmt *resmgmt.Client, org2ResMgmt *resmgmt.Client) { ccPkg, err := packager.NewCCPackage("github.com/example_cc", "../../fixtures/testdata") if err != nil { t.Fatal(err) } - installCCReq := resmgmt.InstallCCRequest{Name: "exampleCC", Path: "github.com/example_cc", Version: "0", 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 'any of two msps' ccPolicy := cauthdsl.SignedByAnyMember([]string{"Org1MSP", "Org2MSP"}) - // Org1 resource manager will instantiate 'example_cc' on 'orgchannel' resp, err := org1ResMgmt.InstantiateCC("orgchannel", resmgmt.InstantiateCCRequest{Name: "exampleCC", Path: "github.com/example_cc", Version: "0", Args: integration.ExampleCCInitArgs(), Policy: ccPolicy}, resmgmt.WithTargetURLs("peer0.org1.example.com")) require.Nil(t, err, "error should be nil") require.NotEmpty(t, resp, "transaction response should be populated") +} - // Load specific targets for move funds test - one of the - //targets has its certificate revoked - loadOrgPeers(t, org1AdminClientContext) - - // Org1 user connects to 'orgchannel' - chClientOrg1User, err := channel.New(org1ChannelClientContext) - if err != nil { - t.Fatalf("Failed to create new channel client for Org1 user: %s", err) - } - - // Org1 user queries initial value on both peers - // Since one of the peers on channel has certificate revoked, eror is expected here - // Error in container is : - // .... identity 0 does not satisfy principal: - // Could not validate identity against certification chain, err The certificate has been revoked - _, err = chClientOrg1User.Query(channel.Request{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCQueryArgs()}) - if err == nil { - t.Fatalf("Expected error: '....Description: could not find chaincode with name 'exampleCC',,, ") - } - +func createChannel(org1AdminUser msp.SigningIdentity, org2AdminUser msp.SigningIdentity, chMgmtClient *resmgmt.Client, t *testing.T) { + req := resmgmt.SaveChannelRequest{ChannelID: "orgchannel", + ChannelConfigPath: path.Join("../../../", metadata.ChannelConfigPath, "orgchannel.tx"), + SigningIdentities: []msp.SigningIdentity{org1AdminUser, org2AdminUser}} + txID, err := chMgmtClient.SaveChannel(req, resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + require.Nil(t, err, "error should be nil") + require.NotEmpty(t, txID, "transaction ID should be populated") } func loadOrgPeers(t *testing.T, ctxProvider contextAPI.ClientProvider) { diff --git a/test/integration/sdk/channel_config_test.go b/test/integration/sdk/channel_config_test.go index c0ab3784b2..250f5c17ce 100644 --- a/test/integration/sdk/channel_config_test.go +++ b/test/integration/sdk/channel_config_test.go @@ -105,7 +105,7 @@ func TestChannelConfigWithOrderer(t *testing.T) { } defer sdk.Close() - if err := testSetup.Initialize(sdk); err != nil { + if err = testSetup.Initialize(sdk); err != nil { t.Fatalf(err.Error()) } @@ -124,14 +124,17 @@ func TestChannelConfigWithOrderer(t *testing.T) { t.Fatalf("Failed to create new channel config: %s", err) } + queryChannelCfg(channelCtx, cfg, t) + +} + +func queryChannelCfg(channelCtx contextAPI.Channel, cfg fab.ChannelConfig, t *testing.T) { reqCtx, cancel := context.NewRequest(channelCtx, context.WithTimeoutType(fab.OrdererResponse)) defer cancel() - response, err := cfg.Query(reqCtx) if err != nil { t.Fatalf(err.Error()) } - expected := "orderer.example.com:7050" found := false for _, o := range response.Orderers() { @@ -140,11 +143,9 @@ func TestChannelConfigWithOrderer(t *testing.T) { break } } - if !found { t.Fatalf("Expected orderer %s, got %s", expected, response.Orderers()) } - } // ChannelConfigFromOrdererProviderFactory is configured to retrieve channel config from orderer diff --git a/test/integration/sdk/custom_cryptosuite_test.go b/test/integration/sdk/custom_cryptosuite_test.go index 40d15123de..980f1d2d19 100644 --- a/test/integration/sdk/custom_cryptosuite_test.go +++ b/test/integration/sdk/custom_cryptosuite_test.go @@ -23,8 +23,6 @@ import ( "github.com/stretchr/testify/require" ) -const samplekey = "sample-key" - func customCryptoSuiteInit(t *testing.T) (*integration.BaseSetupImpl, string) { // Using shared SDK instance to increase test speed. @@ -183,31 +181,3 @@ func TestCustomCryptoSuite(t *testing.T) { } } */ - -/* - BCCSP Wrapper for test -*/ - -func getBCCSPWrapper(bccsp bccsp.BCCSP) bccsp.BCCSP { - return &bccspWrapper{bccsp} -} - -func getBCCSPKeyWrapper(key bccsp.Key) bccsp.Key { - return &bccspKeyWrapper{key} -} - -type bccspWrapper struct { - bccsp.BCCSP -} - -func (mock *bccspWrapper) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) { - return getBCCSPKeyWrapper(nil), nil -} - -type bccspKeyWrapper struct { - bccsp.Key -} - -func (mock *bccspKeyWrapper) Bytes() ([]byte, error) { - return []byte("sample-key"), nil -} diff --git a/test/integration/sdk/events_client_test.go b/test/integration/sdk/events_client_test.go index 7ec7f79027..cc99d3c8bf 100644 --- a/test/integration/sdk/events_client_test.go +++ b/test/integration/sdk/events_client_test.go @@ -132,12 +132,12 @@ func testRegisterBlockEvent(ccID string, chClient *channel.Client, eventClient * } select { - case event, ok := <-beventch: + case e, ok := <-beventch: if !ok { t.Fatalf("unexpected closed channel while waiting for block event") } - t.Logf("Received block event: %#v", event) - if event.Block == nil { + t.Logf("Received block event: %#v", e) + if e.Block == nil { t.Fatalf("Expecting block in block event but got nil") } case <-time.After(time.Second * 20): diff --git a/test/integration/sdk/ledger_queries_test.go b/test/integration/sdk/ledger_queries_test.go index 1d81576bab..21eba7c83b 100644 --- a/test/integration/sdk/ledger_queries_test.go +++ b/test/integration/sdk/ledger_queries_test.go @@ -13,6 +13,7 @@ import ( "github.com/golang/protobuf/proto" "github.com/hyperledger/fabric-sdk-go/pkg/client/ledger" + providersFab "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab" "github.com/hyperledger/fabric-sdk-go/pkg/core/config" "github.com/hyperledger/fabric-sdk-go/pkg/fab" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" @@ -68,6 +69,13 @@ func TestLedgerClientQueries(t *testing.T) { t.Fatalf("Expecting same result from default peer and target peer") } + testQueryBlockNumberByHash(client, ledgerInfo, t) + + testQueryBlockNumber(client, t, 0) + +} + +func testQueryBlockNumberByHash(client *ledger.Client, ledgerInfo *providersFab.BlockchainInfoResponse, t *testing.T) { // Test Query Block by Hash - retrieve current block by hash block, err := client.QueryBlockByHash(ledgerInfo.BCI.CurrentBlockHash) if err != nil { @@ -76,28 +84,27 @@ func TestLedgerClientQueries(t *testing.T) { if block.Data == nil { t.Fatalf("QueryBlockByHash block data is nil") } - // Test Query Block by Hash - retrieve block by non-existent hash _, err = client.QueryBlockByHash([]byte("non-existent")) if err == nil { t.Fatalf("QueryBlockByHash non-existent didn't return an error") } +} +func testQueryBlockNumber(client *ledger.Client, t *testing.T, blockNumber uint64) { // Test Query Block by Number - block, err = client.QueryBlock(0) + block, err := client.QueryBlock(blockNumber) if err != nil { t.Fatalf("QueryBlockByHash return error: %v", err) } if block.Data == nil { t.Fatalf("QueryBlockByHash block data is nil") } - // Test Query Block by Number (non-existent) - block, err = client.QueryBlock(12345678) + _, err = client.QueryBlock(12345678) if err == nil { t.Fatalf("QueryBlock should have failed to query non-existent block") } - } func TestNoLedgerEndpoints(t *testing.T) { diff --git a/test/integration/sdk/resmgmt_queries_test.go b/test/integration/sdk/resmgmt_queries_test.go index fe05401c85..bb834cbc8c 100644 --- a/test/integration/sdk/resmgmt_queries_test.go +++ b/test/integration/sdk/resmgmt_queries_test.go @@ -147,7 +147,7 @@ func testQueryConfigFromOrderer(t *testing.T, channelID string, client *resmgmt. t.Fatalf("Expected orderer %s, got %s", expected, channelCfg.Orderers()) } - channelCfg, err = client.QueryConfigFromOrderer(channelID, resmgmt.WithOrdererURL("non-existent"), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) + _, err = client.QueryConfigFromOrderer(channelID, resmgmt.WithOrdererURL("non-existent"), resmgmt.WithRetry(retry.DefaultResMgmtOpts)) if err == nil { t.Fatalf("QueryConfig should have failed for invalid orderer") } diff --git a/test/integration/sdk/sdk_parent_context_test.go b/test/integration/sdk/sdk_parent_context_test.go index 7dc877406b..0f220de865 100644 --- a/test/integration/sdk/sdk_parent_context_test.go +++ b/test/integration/sdk/sdk_parent_context_test.go @@ -7,6 +7,8 @@ SPDX-License-Identifier: Apache-2.0 package sdk import ( + reqContext "context" + "strings" "testing" "time" @@ -15,6 +17,7 @@ import ( "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/errors/retry" + contextApi "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context" "github.com/hyperledger/fabric-sdk-go/pkg/context" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" "github.com/hyperledger/fabric-sdk-go/test/integration" @@ -67,14 +70,17 @@ func TestParentContext(t *testing.T) { } // ledger client + testLedgerClient(org1AdminChannelContext, t, parentContext) + +} + +func testLedgerClient(org1AdminChannelContext contextApi.ChannelProvider, t *testing.T, parentContext reqContext.Context) { legerClient, err := ledger.New(org1AdminChannelContext) if err != nil { t.Fatalf("Failed to create new resource management client: %s", err) } - _, err = legerClient.QueryInfo(ledger.WithParentContext(parentContext)) if err == nil && !strings.Contains(err.Error(), "context canceled") { t.Fatalf("expected context cancelled error but got: %v", err) } - } diff --git a/test/integration/sdk/sdk_provider_test.go b/test/integration/sdk/sdk_provider_test.go index 68f50e3773..15c16b76b7 100644 --- a/test/integration/sdk/sdk_provider_test.go +++ b/test/integration/sdk/sdk_provider_test.go @@ -26,7 +26,6 @@ import ( func TestDynamicSelection(t *testing.T) { // Using shared SDK instance to increase test speed. - sdk := mainSDK testSetup := mainTestSetup //testSetup := integration.BaseSetupImpl{ @@ -49,7 +48,7 @@ func TestDynamicSelection(t *testing.T) { } defer sdk.Close() - if err := testSetup.Initialize(sdk); err != nil { + if err = testSetup.Initialize(sdk); err != nil { t.Fatalf(err.Error()) } diff --git a/test/scripts/check_lint.sh b/test/scripts/check_lint.sh index 3d93fb6f13..5fb2320085 100755 --- a/test/scripts/check_lint.sh +++ b/test/scripts/check_lint.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright Greg Haskins, IBM Corp, SecureKey Technologies Inc. All Rights Reserved. +# Copyright SecureKey Technologies Inc. All Rights Reserved. # # SPDX-License-Identifier: Apache-2.0 # @@ -10,71 +10,19 @@ set -e -GO_CMD="${GO_CMD:-go}" -GOLINT_CMD=golint -GOFMT_CMD=gofmt -GOIMPORTS_CMD=goimports GOMETALINT_CMD=gometalinter - - PROJECT_PATH=$GOPATH/src/github.com/hyperledger/fabric-sdk-go declare -a arr=( -"./test" -) - -echo "Running linters..." -for i in "${arr[@]}" -do - echo "Checking $i" - OUTPUT="$($GOLINT_CMD $i/...)" - if [[ $OUTPUT ]]; then - echo "You should check the following golint suggestions:" - printf "$OUTPUT\n" - echo "end golint suggestions" - fi - - OUTPUT="$($GO_CMD vet $i/...)" - if [[ $OUTPUT ]]; then - echo "You should check the following govet suggestions:" - printf "$OUTPUT\n" - echo "end govet suggestions" - fi - - found=`$GOFMT_CMD -l \`find $i -name "*.go" |grep -v "./vendor"\` 2>&1` - if [ $? -ne 0 ]; then - echo "The following files need reformatting with '$GO_FMT -w ':" - printf "$badformat\n" - exit 1 - fi - - OUTPUT="$($GOIMPORTS_CMD -srcdir $PROJECT_PATH -l $i)" - - if [[ $OUTPUT ]]; then - echo "YOU MUST FIX THE FOLLOWING GOIMPORTS ERRORS:" - printf "$OUTPUT\n" - echo "END GOIMPORTS ERRORS" - exit 1 - fi -done - - - - -declare -a arr1=( "./pkg" -"./test/integration/e2e" -"./test/integration/expiredorderer" -"./test/integration/expiredpeer" -"./test/integration/fab" -"./test/integration/msp" +"./test" ) echo "Running metalinters..." -for i in "${arr1[@]}" +for i in "${arr[@]}" do echo "Checking $i" $GOMETALINT_CMD --config=./gometalinter.json $i/... diff --git a/test/scripts/check_spelling.sh b/test/scripts/check_spelling.sh deleted file mode 100755 index 114aa2a35d..0000000000 --- a/test/scripts/check_spelling.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -# -# Copyright IBM Corp. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -# - -CHECK=$(git diff --name-only HEAD * | grep -v .png$ | grep -v .git | grep -v ^CHANGELOG \ - | grep -v ^vendor/ | grep -v ^build/ | sort -u) - -if [[ -z "$CHECK" ]]; then - CHECK=$(git diff-tree --no-commit-id --name-only -r $(git log -2 \ - --pretty=format:"%h") | grep -v .png$ | grep -v .git | grep -v ^CHANGELOG \ - | grep -v ^vendor/ | grep -v ^build/ | sort -u) -fi - -echo "Checking changed go files for spelling errors ..." -errs=`echo $CHECK | xargs misspell -source=text` -if [ -z "$errs" ]; then - echo "spell checker passed" - exit 0 -fi -echo "The following files are have spelling errors:" -echo "$errs" -exit 0 diff --git a/test/scripts/dependencies.sh b/test/scripts/dependencies.sh index c9adb50f0a..2fa5533ec6 100755 --- a/test/scripts/dependencies.sh +++ b/test/scripts/dependencies.sh @@ -19,9 +19,6 @@ if [ "$FABRIC_SDKGO_DEPEND_INSTALL" = "true" ]; then TMP=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'` GOPATH=$TMP $GO_CMD get -u github.com/axw/gocov/... GOPATH=$TMP $GO_CMD get -u github.com/AlekSi/gocov-xml - GOPATH=$TMP $GO_CMD get -u github.com/client9/misspell/cmd/misspell - GOPATH=$TMP $GO_CMD get -u github.com/golang/lint/golint - GOPATH=$TMP $GO_CMD get -u golang.org/x/tools/cmd/goimports GOPATH=$TMP $GO_CMD get -u github.com/golang/mock/mockgen GOPATH=$TMP $GO_CMD get -u github.com/alecthomas/gometalinter mkdir -p $GOPATH/bin @@ -47,9 +44,6 @@ fi # Check that Go tools are installed and help the user if they are missing type gocov >/dev/null 2>&1 || { echo >& 2 "gocov is not installed (go get -u github.com/axw/gocov/...)"; ABORT=1; } type gocov-xml >/dev/null 2>&1 || { echo >& 2 "gocov-xml is not installed (go get -u github.com/AlekSi/gocov-xml)"; ABORT=1; } -type misspell >/dev/null 2>&1 || { echo >& 2 "misspell is not installed (go get -u github.com/client9/misspell/cmd/misspell)"; ABORT=1; } -type golint >/dev/null 2>&1 || { echo >& 2 "golint is not installed (go get -u github.com/golang/lint/golint)"; ABORT=1; } -type goimports >/dev/null 2>&1 || { echo >& 2 "goimports is not installed (go get -u golang.org/x/tools/cmd/goimports)"; ABORT=1; } type mockgen >/dev/null 2>&1 || { echo >& 2 "mockgen is not installed (go get -u github.com/golang/mock/mockgen)"; ABORT=1; } type $GO_DEP_CMD >/dev/null 2>&1 || { echo >& 2 "dep is not installed (go get -u github.com/golang/dep/cmd/dep)"; ABORT=1; } type gometalinter >/dev/null 2>&1 || { echo >& 2 "gometalinter is not installed (go get -u github.com/alecthomas/gometalinter)"; ABORT=1; }