Skip to content

Commit

Permalink
[FAB-7386] Enhance multi organisation test
Browse files Browse the repository at this point in the history
Change-Id: I151e92e86305429be8827de2cce3a78969dbad01
Signed-off-by: Sandra Vrtikapa <[email protected]>
  • Loading branch information
sandrask committed Dec 7, 2017
1 parent 7de1949 commit 83c4a87
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 9 deletions.
15 changes: 13 additions & 2 deletions test/integration/base_test_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,19 @@ type BaseSetupImpl struct {
AdminUser ca.User
}

// Initial B values for ExampleCC
const (
ExampleCCInitB = "200"
ExampleCCUpgradeB = "400"
)

// ExampleCC query and transaction arguments
var queryArgs = [][]byte{[]byte("query"), []byte("b")}
var txArgs = [][]byte{[]byte("move"), []byte("a"), []byte("b"), []byte("1")}

// ExampleCC init and upgrade args
var initArgs = [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}
var upgradeArgs = [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("400")}
var initArgs = [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte(ExampleCCInitB)}
var upgradeArgs = [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte(ExampleCCUpgradeB)}

var resMgmtClient resmgmt.ResourceMgmtClient

Expand All @@ -70,6 +76,11 @@ func ExampleCCInitArgs() [][]byte {
return initArgs
}

//ExampleCCUpgradeArgs returns example cc upgrade args
func ExampleCCUpgradeArgs() [][]byte {
return upgradeArgs
}

// Initialize reads configuration from file and sets up client, channel and event hub
func (setup *BaseSetupImpl) Initialize(t *testing.T) error {
// Create SDK setup for the integration tests
Expand Down
107 changes: 100 additions & 7 deletions test/integration/orgs/multiple_orgs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ import (
chmgmt "github.com/hyperledger/fabric-sdk-go/api/apitxn/chmgmtclient"
resmgmt "github.com/hyperledger/fabric-sdk-go/api/apitxn/resmgmtclient"
"github.com/hyperledger/fabric-sdk-go/def/fabapi"
"github.com/hyperledger/fabric-sdk-go/def/fabapi/context/defprovider"
"github.com/hyperledger/fabric-sdk-go/test/integration"

selection "github.com/hyperledger/fabric-sdk-go/pkg/fabric-txn/selection/dynamicselection"

"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/cauthdsl"
)

Expand Down Expand Up @@ -149,27 +152,106 @@ func TestOrgsEndToEnd(t *testing.T) {
}

// Assert that funds have changed value on org1 peer
initialInt, _ := strconv.Atoi(string(initialValue))
var finalInt int
initial, _ := strconv.Atoi(string(initialValue))
verifyValue(t, chClientOrg1User, initial+1)

// 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)
if err != nil {
t.Fatal(err)
}

// Install example cc version '1' to Org2 peers
_, err = org2ResMgmt.InstallCC(installCCReq)
if err != nil {
t.Fatal(err)
}

// 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'
err = org1ResMgmt.UpgradeCC("orgchannel", resmgmt.UpgradeCCRequest{Name: "exampleCC", Path: "github.com/example_cc", Version: "1", Args: integration.ExampleCCUpgradeArgs(), Policy: org1Andorg2Policy})
if err != nil {
t.Fatal(err)
}

// Org2 user moves funds on org2 peer (cc policy fails since both Org1 and Org2 peers should participate)
txOpts = apitxn.ExecuteTxOpts{ProposalProcessors: []apitxn.ProposalProcessor{orgTestPeer1}}
_, err = chClientOrg2User.ExecuteTxWithOpts(apitxn.ExecuteTxRequest{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCTxArgs()}, txOpts)
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)
txOpts = apitxn.ExecuteTxOpts{ProposalProcessors: []apitxn.ProposalProcessor{orgTestPeer0, orgTestPeer1}}
_, err = chClientOrg2User.ExecuteTxWithOpts(apitxn.ExecuteTxRequest{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCTxArgs()}, txOpts)
if err != nil {
t.Fatalf("Failed to move funds: %s", err)
}

// Assert that funds have changed value on org1 peer
beforeTxValue, _ := strconv.Atoi(integration.ExampleCCUpgradeB)
expectedValue := beforeTxValue + 1
verifyValue(t, chClientOrg1User, expectedValue)

// Specify user that will be used by dynamic selection service (to retrieve chanincode policy information)
// This user has to have privileges to query lscc for chaincode data
mychannelUser := selection.ChannelUser{ChannelID: "orgchannel", UserName: "User1", OrgName: "Org1"}

// Create SDK setup for channel client with dynamic selection
sdkOptions.ProviderFactory = &DynamicSelectionProviderFactory{ChannelUsers: []selection.ChannelUser{mychannelUser}}
sdk, err = fabapi.NewSDK(sdkOptions)
if err != nil {
t.Fatalf("Failed to create new SDK: %s", err)
}

// Create new client that will use dynamic selection
chClientOrg2User, err = sdk.NewChannelClientWithOpts("orgchannel", "User1", &fabapi.ChannelClientOpts{OrgName: org2})
if err != nil {
t.Fatalf("Failed to create new channel client for Org2 user: %s", err)
}

// Org2 user moves funds (dynamic selection will inspect chaincode policy to determine endorsers)
_, err = chClientOrg2User.ExecuteTx(apitxn.ExecuteTxRequest{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCTxArgs()})
if err != nil {
t.Fatalf("Failed to move funds: %s", err)
}

expectedValue++
verifyValue(t, chClientOrg1User, expectedValue)

}

func verifyValue(t *testing.T, chClient apitxn.ChannelClient, expected int) {

// Assert that funds have changed value on org1 peer
var valueInt int
for i := 0; i < pollRetries; i++ {
// Query final value on org1 peer
queryOpts := apitxn.QueryOpts{ProposalProcessors: []apitxn.ProposalProcessor{orgTestPeer0}}
finalValue, err := chClientOrg1User.QueryWithOpts(apitxn.QueryRequest{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCQueryArgs()}, queryOpts)
value, err := chClient.QueryWithOpts(apitxn.QueryRequest{ChaincodeID: "exampleCC", Fcn: "invoke", Args: integration.ExampleCCQueryArgs()}, queryOpts)
if err != nil {
t.Fatalf("Failed to query funds after transaction: %s", err)
}
// If value has not propogated sleep with exponential backoff
finalInt, _ = strconv.Atoi(string(finalValue))
if initialInt+1 != finalInt {
valueInt, _ = strconv.Atoi(string(value))
if expected != valueInt {
backoffFactor := math.Pow(2, float64(i))
time.Sleep(time.Millisecond * 50 * time.Duration(backoffFactor))
} else {
break
}
}
if initialInt+1 != finalInt {
if expected != valueInt {
t.Fatalf("Org2 'move funds' transaction result was not propagated to Org1. Expected %d, got: %d",
(initialInt + 1), finalInt)
(expected), valueInt)
}

}
Expand Down Expand Up @@ -206,3 +288,14 @@ func loadOrgPeers(t *testing.T, sdk *fabapi.FabricSDK) {
t.Fatal(err)
}
}

// DynamicSelectionProviderFactory is configured with dynamic (endorser) selection provider
type DynamicSelectionProviderFactory struct {
defprovider.DefaultProviderFactory
ChannelUsers []selection.ChannelUser
}

// NewSelectionProvider returns a new implementation of dynamic selection provider
func (f *DynamicSelectionProviderFactory) NewSelectionProvider(config apiconfig.Config) (fab.SelectionProvider, error) {
return selection.NewSelectionProvider(config, f.ChannelUsers, nil)
}

0 comments on commit 83c4a87

Please sign in to comment.