Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit b99774a

Browse files
committed
[FAB-10591] Discovery Client Endorser Tests
Added integration tests for Discovery Client endorser selection based on CC policy. Also, refactored and fixed some of the existing integration tests since they were failing intermittently. Change-Id: I9a35b5f9ab4037edcbcee8d1670b7d62e2fdcd59 Signed-off-by: Bob Stasyszyn <Bob.Stasyszyn@securekey.com>
1 parent aedc226 commit b99774a

File tree

6 files changed

+523
-113
lines changed

6 files changed

+523
-113
lines changed

test/integration/base_test_setup.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,23 @@ package integration
99
import (
1010
"os"
1111
"path"
12+
"time"
1213

1314
mspclient "github.com/hyperledger/fabric-sdk-go/pkg/client/msp"
1415
"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt"
1516
"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
17+
contextAPI "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context"
1618
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core"
19+
fabAPI "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
1720
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp"
21+
contextImpl "github.com/hyperledger/fabric-sdk-go/pkg/context"
1822
"github.com/hyperledger/fabric-sdk-go/pkg/fab"
1923
packager "github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/gopackager"
2024
"github.com/hyperledger/fabric-sdk-go/pkg/fab/comm"
25+
"github.com/hyperledger/fabric-sdk-go/pkg/fab/resource"
2126
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
2227
"github.com/hyperledger/fabric-sdk-go/pkg/util/test"
28+
"github.com/hyperledger/fabric-sdk-go/test/metadata"
2329
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/cauthdsl"
2430
"github.com/pkg/errors"
2531
)
@@ -39,6 +45,7 @@ const (
3945
ExampleCCInitB = "200"
4046
ExampleCCUpgradeB = "400"
4147
AdminUser = "Admin"
48+
OrdererOrgName = "ordererorg"
4249
)
4350

4451
// ExampleCC query and transaction arguments
@@ -69,6 +76,20 @@ func ExampleCCUpgradeArgs() [][]byte {
6976
return upgradeArgs
7077
}
7178

79+
// IsJoinedChannel returns true if the given peer has joined the given channel
80+
func IsJoinedChannel(channelID string, resMgmtClient *resmgmt.Client, peer fabAPI.Peer) (bool, error) {
81+
resp, err := resMgmtClient.QueryChannels(resmgmt.WithTargets(peer))
82+
if err != nil {
83+
return false, err
84+
}
85+
for _, chInfo := range resp.Channels {
86+
if chInfo.ChannelId == channelID {
87+
return true, nil
88+
}
89+
}
90+
return false, nil
91+
}
92+
7293
// Initialize reads configuration from file and sets up client, channel and event hub
7394
func (setup *BaseSetupImpl) Initialize(sdk *fabsdk.FabricSDK) error {
7495

@@ -168,3 +189,132 @@ func InstallAndInstantiateCC(sdk *fabsdk.FabricSDK, user fabsdk.ContextOption, o
168189
ccPolicy := cauthdsl.SignedByMspMember(mspID)
169190
return resMgmtClient.InstantiateCC("mychannel", resmgmt.InstantiateCCRequest{Name: ccName, Path: ccPath, Version: ccVersion, Args: ccArgs, Policy: ccPolicy}, resmgmt.WithRetry(retry.DefaultResMgmtOpts))
170191
}
192+
193+
// OrgContext provides SDK client context for a given org
194+
type OrgContext struct {
195+
OrgID string
196+
CtxProvider contextAPI.ClientProvider
197+
SigningIdentity msp.SigningIdentity
198+
ResMgmt *resmgmt.Client
199+
Peers []fabAPI.Peer
200+
AnchorPeerConfigFile string
201+
}
202+
203+
// CreateChannelAndUpdateAnchorPeers creates the channel and updates all of the anchor peers for all orgs
204+
func CreateChannelAndUpdateAnchorPeers(sdk *fabsdk.FabricSDK, channelID string, channelConfigFile string, orgsContext []*OrgContext) error {
205+
ordererCtx := sdk.Context(fabsdk.WithUser(AdminUser), fabsdk.WithOrg(OrdererOrgName))
206+
207+
// Channel management client is responsible for managing channels (create/update channel)
208+
chMgmtClient, err := resmgmt.New(ordererCtx)
209+
if err != nil {
210+
return errors.New("failed to get a new resmgmt client for orderer")
211+
}
212+
213+
var signingIdentities []msp.SigningIdentity
214+
for _, orgCtx := range orgsContext {
215+
signingIdentities = append(signingIdentities, orgCtx.SigningIdentity)
216+
}
217+
218+
req := resmgmt.SaveChannelRequest{
219+
ChannelID: channelID,
220+
ChannelConfigPath: path.Join("../../../", metadata.ChannelConfigPath, channelConfigFile),
221+
SigningIdentities: signingIdentities,
222+
}
223+
_, err = chMgmtClient.SaveChannel(req, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint("orderer.example.com"))
224+
if err != nil {
225+
return err
226+
}
227+
228+
for _, orgCtx := range orgsContext {
229+
req := resmgmt.SaveChannelRequest{
230+
ChannelID: channelID,
231+
ChannelConfigPath: path.Join("../../../", metadata.ChannelConfigPath, orgCtx.AnchorPeerConfigFile),
232+
SigningIdentities: []msp.SigningIdentity{orgCtx.SigningIdentity},
233+
}
234+
if _, err := orgCtx.ResMgmt.SaveChannel(req, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint("orderer.example.com")); err != nil {
235+
return err
236+
}
237+
}
238+
239+
return nil
240+
}
241+
242+
// JoinPeersToChannel joins all peers in all of the given orgs to the given channel
243+
func JoinPeersToChannel(channelID string, orgsContext []*OrgContext) error {
244+
for _, orgCtx := range orgsContext {
245+
err := orgCtx.ResMgmt.JoinChannel(
246+
channelID,
247+
resmgmt.WithRetry(retry.DefaultResMgmtOpts),
248+
resmgmt.WithOrdererEndpoint("orderer.example.com"),
249+
resmgmt.WithTargets(orgCtx.Peers...),
250+
)
251+
if err != nil {
252+
return errors.Wrapf(err, "failed to join peers in org [%s] to channel [%s]", orgCtx.OrgID, channelID)
253+
}
254+
}
255+
return nil
256+
}
257+
258+
// InstallAndInstantiateChaincode installs the given chaincode to all peers in the given orgs and instantiates it on the given channel
259+
func InstallAndInstantiateChaincode(channelID string, ccPkg *resource.CCPackage, ccID, ccVersion, ccPolicy string, orgs []*OrgContext) error {
260+
for _, orgCtx := range orgs {
261+
if err := InstallChaincode(orgCtx.ResMgmt, orgCtx.CtxProvider, ccPkg, ccID, ccVersion, orgCtx.Peers); err != nil {
262+
return errors.Wrapf(err, "failed to install chaincode to peers in org [%s]", orgCtx.OrgID)
263+
}
264+
}
265+
_, err := InstantiateChaincode(orgs[0].ResMgmt, channelID, ccID, ccVersion, ccPolicy)
266+
return err
267+
}
268+
269+
// InstallChaincode installs the given chaincode to the given peers
270+
func InstallChaincode(resMgmt *resmgmt.Client, ctxProvider contextAPI.ClientProvider, ccPkg *resource.CCPackage, ccName, ccVersion string, localPeers []fabAPI.Peer) error {
271+
installCCReq := resmgmt.InstallCCRequest{Name: ccName, Path: "github.com/example_cc", Version: ccVersion, Package: ccPkg}
272+
_, err := resMgmt.InstallCC(installCCReq, resmgmt.WithRetry(retry.DefaultResMgmtOpts))
273+
return err
274+
}
275+
276+
// InstantiateChaincode instantiates the given chaincode to the given channel
277+
func InstantiateChaincode(resMgmt *resmgmt.Client, channelID, ccName, ccVersion string, ccPolicyStr string) (resmgmt.InstantiateCCResponse, error) {
278+
ccPolicy, err := cauthdsl.FromString(ccPolicyStr)
279+
if err != nil {
280+
return resmgmt.InstantiateCCResponse{}, errors.Wrapf(err, "error creating CC policy [%s]", ccPolicyStr)
281+
}
282+
283+
return resMgmt.InstantiateCC(
284+
channelID,
285+
resmgmt.InstantiateCCRequest{
286+
Name: ccName,
287+
Path: "github.com/example_cc",
288+
Version: ccVersion,
289+
Args: ExampleCCInitArgs(),
290+
Policy: ccPolicy,
291+
},
292+
resmgmt.WithRetry(retry.DefaultResMgmtOpts),
293+
)
294+
}
295+
296+
// DiscoverLocalPeers queries the local peers for the given MSP context and returns all of the peers. If
297+
// the number of peers does not match the expected number then an error is returned.
298+
func DiscoverLocalPeers(ctxProvider contextAPI.ClientProvider, expectedPeers int) ([]fabAPI.Peer, error) {
299+
ctx, err := contextImpl.NewLocal(ctxProvider)
300+
if err != nil {
301+
return nil, errors.Wrap(err, "error creating local context")
302+
}
303+
304+
var peers []fabAPI.Peer
305+
for i := 0; i < 10; i++ {
306+
peers, err = ctx.LocalDiscoveryService().GetPeers()
307+
if err != nil {
308+
return nil, errors.Wrapf(err, "error getting peers for MSP [%s]", ctx.Identifier().MSPID)
309+
}
310+
if len(peers) >= expectedPeers {
311+
break
312+
}
313+
// wait some time to allow the gossip to propagate the peers discovery
314+
time.Sleep(3 * time.Second)
315+
}
316+
if expectedPeers != len(peers) {
317+
return nil, errors.Errorf("Expecting %d peers but got %d", expectedPeers, len(peers))
318+
}
319+
return peers, nil
320+
}

test/integration/e2e/end_to_end.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ package e2e
99
import (
1010
"path"
1111
"strconv"
12+
"strings"
1213
"testing"
1314
"time"
1415

1516
"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
17+
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
1618
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp"
1719
"github.com/stretchr/testify/require"
1820

@@ -96,15 +98,18 @@ func setupAndRun(t *testing.T, doSetup bool, configOpt core.ConfigProvider, sdkO
9698
// Move funds
9799
executeCC(client, t)
98100

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

106-
// Verify move funds transaction result
107-
verifyFundsIsMoved(client, t, value)
109+
i := strings.Index(ccEvent.SourceURL, ":")
110+
111+
// Verify move funds transaction result on the same peer where the event came from.
112+
verifyFundsIsMoved(client, t, value, ccEvent.SourceURL[0:i])
108113

109114
}
110115

@@ -143,8 +148,8 @@ func createChannelAndCC(t *testing.T, sdk *fabsdk.FabricSDK) {
143148
createCC(t, orgResMgmt)
144149
}
145150

146-
func verifyFundsIsMoved(client *channel.Client, t *testing.T, value []byte) {
147-
newValue := queryCC(client, t)
151+
func verifyFundsIsMoved(client *channel.Client, t *testing.T, value []byte, targetEndpoints ...string) {
152+
newValue := queryCC(client, t, targetEndpoints...)
148153
valueInt, err := strconv.Atoi(string(value))
149154
if err != nil {
150155
t.Fatal(err.Error())
@@ -166,9 +171,11 @@ func executeCC(client *channel.Client, t *testing.T) {
166171
}
167172
}
168173

169-
func queryCC(client *channel.Client, t *testing.T) []byte {
174+
func queryCC(client *channel.Client, t *testing.T, targetEndpoints ...string) []byte {
170175
response, err := client.Query(channel.Request{ChaincodeID: ccID, Fcn: "invoke", Args: integration.ExampleCCQueryArgs()},
171-
channel.WithRetry(retry.DefaultChannelOpts))
176+
channel.WithRetry(retry.DefaultChannelOpts),
177+
channel.WithTargetEndpoints(targetEndpoints...),
178+
)
172179
if err != nil {
173180
t.Fatalf("Failed to query funds: %s", err)
174181
}

0 commit comments

Comments
 (0)