Skip to content

Commit

Permalink
[FABG-708] No orderer e2e: verify from same peer
Browse files Browse the repository at this point in the history
This change updates the no orderer test to verify from the same
peer that delivered the CC event.

The tests are also refactored to allow reuse of code since
the original e2e test was already doing this.

Change-Id: I32e5cd309b57639a023d79f8d9743a3be2bc3c2b
Signed-off-by: Troy Ronda <[email protected]>
  • Loading branch information
troyronda committed Aug 10, 2018
1 parent cacc1a7 commit 779a8c1
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 102 deletions.
88 changes: 47 additions & 41 deletions test/integration/e2e/end_to_end.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,21 @@ var (

// Run enables testing an end-to-end scenario against the supplied SDK options
func Run(t *testing.T, configOpt core.ConfigProvider, sdkOpts ...fabsdk.Option) {
setupAndRun(t, true, configOpt, sdkOpts...)
setupAndRun(t, true, configOpt, e2eTest, sdkOpts...)
}

// RunWithoutSetup will execute the same way as Run but without creating a new channel and registering a new CC
func RunWithoutSetup(t *testing.T, configOpt core.ConfigProvider, sdkOpts ...fabsdk.Option) {
setupAndRun(t, false, configOpt, sdkOpts...)
setupAndRun(t, false, configOpt, e2eTest, sdkOpts...)
}

type testSDKFunc func(t *testing.T, sdk *fabsdk.FabricSDK)

// setupAndRun enables testing an end-to-end scenario against the supplied SDK options
// the doSetup flag will be used to either create a channel and the example CC or not(ie run the tests with existing ch and CC)
func setupAndRun(t *testing.T, doSetup bool, configOpt core.ConfigProvider, sdkOpts ...fabsdk.Option) {
// the createChannel flag will be used to either create a channel and the example CC or not(ie run the tests with existing ch and CC)
func setupAndRun(t *testing.T, createChannel bool, configOpt core.ConfigProvider, test testSDKFunc, sdkOpts ...fabsdk.Option) {

if integration.IsLocal() && doSetup {
if integration.IsLocal() {
//If it is a local test then add entity mapping to config backend to parse URLs
configOpt = integration.AddLocalEntityMapping(configOpt)
}
Expand All @@ -72,12 +74,14 @@ func setupAndRun(t *testing.T, doSetup bool, configOpt core.ConfigProvider, sdkO
integration.CleanupUserData(t, sdk)
defer integration.CleanupUserData(t, sdk)

if doSetup {
if createChannel {
createChannelAndCC(t, sdk)
}

// ************ Test setup complete ************** //
test(t, sdk)
}

func e2eTest(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)
Expand All @@ -86,31 +90,11 @@ func setupAndRun(t *testing.T, doSetup bool, configOpt core.ConfigProvider, sdkO
t.Fatalf("Failed to create new channel client: %s", err)
}

value := queryCC(client, t)

eventID := "test([a-zA-Z]+)"

// Register chaincode event (pass in channel which receives event details when the event is complete)
reg, notifier, err := client.RegisterChaincodeEvent(ccID, eventID)
if err != nil {
t.Fatalf("Failed to register cc event: %s", err)
}
defer client.UnregisterChaincodeEvent(reg)

// Move funds
executeCC(client, t)

var ccEvent *fab.CCEvent
select {
case ccEvent = <-notifier:
t.Logf("Received CC event: %#v\n", ccEvent)
case <-time.After(time.Second * 20):
t.Fatalf("Did NOT receive CC event for eventId(%s)\n", eventID)
}
existingValue := queryCC(t, client)
ccEvent := moveFunds(t, client)

// Verify move funds transaction result on the same peer where the event came from.
verifyFundsIsMoved(client, t, value, ccEvent)

verifyFundsIsMoved(t, client, existingValue, ccEvent)
}

func createChannelAndCC(t *testing.T, sdk *fabsdk.FabricSDK) {
Expand All @@ -125,10 +109,7 @@ func createChannelAndCC(t *testing.T, sdk *fabsdk.FabricSDK) {
}

// Create channel

// Org admin user is signing user for creating channel

createChannel(sdk, t, resMgmtClient)
createChannel(t, sdk, resMgmtClient)

//prepare context
adminContext := sdk.Context(fabsdk.WithUser(orgAdmin), fabsdk.WithOrg(orgName))
Expand All @@ -148,15 +129,40 @@ func createChannelAndCC(t *testing.T, sdk *fabsdk.FabricSDK) {
createCC(t, orgResMgmt)
}

func verifyFundsIsMoved(client *channel.Client, t *testing.T, value []byte, ccevent *fab.CCEvent) {
func moveFunds(t *testing.T, client *channel.Client) *fab.CCEvent {

eventID := "test([a-zA-Z]+)"

// Register chaincode event (pass in channel which receives event details when the event is complete)
reg, notifier, err := client.RegisterChaincodeEvent(ccID, eventID)
if err != nil {
t.Fatalf("Failed to register cc event: %s", err)
}
defer client.UnregisterChaincodeEvent(reg)

// Move funds
executeCC(t, client)

var ccEvent *fab.CCEvent
select {
case ccEvent = <-notifier:
t.Logf("Received CC event: %#v\n", ccEvent)
case <-time.After(time.Second * 20):
t.Fatalf("Did NOT receive CC event for eventId(%s)\n", eventID)
}

return ccEvent
}

func verifyFundsIsMoved(t *testing.T, client *channel.Client, value []byte, ccEvent *fab.CCEvent) {

//Fix for issue prev in release test, where 'ccEvent.SourceURL' has event URL
if !integration.IsLocal() {
portIndex := strings.Index(ccevent.SourceURL, ":")
ccevent.SourceURL = ccevent.SourceURL[0:portIndex]
portIndex := strings.Index(ccEvent.SourceURL, ":")
ccEvent.SourceURL = ccEvent.SourceURL[0:portIndex]
}

newValue := queryCC(client, t, ccevent.SourceURL)
newValue := queryCC(t, client, ccEvent.SourceURL)
valueInt, err := strconv.Atoi(string(value))
if err != nil {
t.Fatal(err.Error())
Expand All @@ -170,15 +176,15 @@ func verifyFundsIsMoved(client *channel.Client, t *testing.T, value []byte, ccev
}
}

func executeCC(client *channel.Client, t *testing.T) {
func executeCC(t *testing.T, client *channel.Client) {
_, err := client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "invoke", Args: integration.ExampleCCTxArgs()},
channel.WithRetry(retry.DefaultChannelOpts))
if err != nil {
t.Fatalf("Failed to move funds: %s", err)
}
}

func queryCC(client *channel.Client, t *testing.T, targetEndpoints ...string) []byte {
func queryCC(t *testing.T, client *channel.Client, targetEndpoints ...string) []byte {
response, err := client.Query(channel.Request{ChaincodeID: ccID, Fcn: "invoke", Args: integration.ExampleCCQueryArgs()},
channel.WithRetry(retry.DefaultChannelOpts),
channel.WithTargetEndpoints(targetEndpoints...),
Expand Down Expand Up @@ -212,7 +218,7 @@ func createCC(t *testing.T, orgResMgmt *resmgmt.Client) {
require.NotEmpty(t, resp, "transaction response should be populated")
}

func createChannel(sdk *fabsdk.FabricSDK, t *testing.T, resMgmtClient *resmgmt.Client) {
func createChannel(t *testing.T, sdk *fabsdk.FabricSDK, resMgmtClient *resmgmt.Client) {
mspClient, err := mspclient.New(sdk.Context(), mspclient.WithOrg(orgName))
if err != nil {
t.Fatal(err)
Expand Down
76 changes: 15 additions & 61 deletions test/integration/e2e/no_orderer_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ SPDX-License-Identifier: Apache-2.0
package e2e

import (
"strconv"
"testing"
"time"

"github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
Expand All @@ -21,88 +19,44 @@ import (

// runWithNoOrdererConfig enables chclient scenarios using config and client options provided
func runWithNoOrdererConfig(t *testing.T, configOpt core.ConfigProvider, sdkOpts ...fabsdk.Option) {
setupAndRun(t, false, configOpt, noOrdererE2ETest, sdkOpts...)
}

if integration.IsLocal() {
//If it is a local test then add entity mapping to config backend to parse URLs
configOpt = integration.AddLocalEntityMapping(configOpt)
}

sdk, err := fabsdk.New(configOpt, sdkOpts...)
if err != nil {
t.Fatalf("Failed to create new SDK: %s", err)
}
defer sdk.Close()

// Delete all private keys from the crypto suite store
// and users from the user store at the end
integration.CleanupUserData(t, sdk)
defer integration.CleanupUserData(t, sdk)

// ************ Test setup complete ************** //

//TODO : discovery filter should be fixed
discoveryFilter := &mockDiscoveryFilter{called: false}

func noOrdererE2ETest(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)
}

value := queryCCUsingTargetFilter(t, client)

// Move and verify funds
ccEvent := moveFunds(t, client)
verifyFundsIsMoved(t, client, value, ccEvent)
}

func queryCCUsingTargetFilter(t *testing.T, client *channel.Client) []byte {
//TODO : discovery filter should be fixed
discoveryFilter := &mockDiscoveryFilter{called: false}

response, err := client.Query(
channel.Request{ChaincodeID: ccID, Fcn: "invoke", Args: integration.ExampleCCQueryArgs()},
channel.WithTargetFilter(discoveryFilter),
channel.WithRetry(retry.DefaultChannelOpts))
if err != nil {
t.Fatalf("Failed to query funds: %s", err)
}
value := response.Payload

//Test if discovery filter is being called
if !discoveryFilter.called {
t.Fatal("discoveryFilter not called")
}

eventID := "test([a-zA-Z]+)"

// Register chaincode event (pass in channel which receives event details when the event is complete)
reg, notifier, err := client.RegisterChaincodeEvent(ccID, eventID)
if err != nil {
t.Fatalf("Failed to register cc event: %s", err)
}
defer client.UnregisterChaincodeEvent(reg)

// Move funds
moveFunds(response, client, t, notifier, eventID, value)
}

func moveFunds(response channel.Response, client *channel.Client, t *testing.T, notifier <-chan *fab.CCEvent, eventID string, value []byte) {
response, err := client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "invoke", Args: integration.ExampleCCTxArgs()},
channel.WithRetry(retry.DefaultChannelOpts))
if err != nil {
t.Fatalf("Failed to move funds: %s", err)
}
select {
case ccEvent := <-notifier:
t.Logf("Received CC event: %#v\n", ccEvent)
case <-time.After(time.Second * 20):
t.Fatalf("Did NOT receive CC event for eventId(%s)\n", eventID)
}
// Verify move funds transaction result
response, err = client.Query(channel.Request{ChaincodeID: ccID, Fcn: "invoke", Args: integration.ExampleCCQueryArgs()},
channel.WithRetry(retry.DefaultChannelOpts))
if err != nil {
t.Fatalf("Failed to query funds after transaction: %s", err)
}
valueInt, _ := strconv.Atoi(string(value))
valueAfterInvokeInt, _ := strconv.Atoi(string(response.Payload))
if valueInt+1 != valueAfterInvokeInt {
t.Fatalf("Execute failed. Before: %s, after: %s", value, response.Payload)
}
return response.Payload
}

type mockDiscoveryFilter struct {
Expand Down

0 comments on commit 779a8c1

Please sign in to comment.