Skip to content

Commit

Permalink
[FABN-1149] NodeSDK: token e2e tests
Browse files Browse the repository at this point in the history
- Add e2e tests for the following token functions:
  issue, transfer, redeem, list
- Create tokenchanne.tx with v2_0 capability

Change-Id: If8486c2b176eeb457fef986ebac506e94dc347fe
Signed-off-by: Wenjian Qiao <[email protected]>
  • Loading branch information
wenjianqiao committed Feb 25, 2019
1 parent 55a4532 commit 2b14610
Show file tree
Hide file tree
Showing 7 changed files with 887 additions and 5 deletions.
296 changes: 296 additions & 0 deletions test/fixtures/channel/v2/configtx.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

---
################################################################################
#
# SECTION: Application
#
# - This section defines the values to encode into a config transaction or
# genesis block for application related parameters
#
################################################################################
Application: &ApplicationDefaults

# Organizations is the list of orgs which are defined as participants on
# the application side of the network
Organizations:

# Policies defines the set of policies at this level of the config tree
# For Application policies, their canonical path is
# /Channel/Application/<PolicyName>
Policies: &ApplicationDefaultPolicies
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
################################################################################
#
# SECTION: Capabilities
################################################################################
Capabilities:
Channel: &ChannelCapabilities
V2_0: true

Orderer: &OrdererCapabilities
V2_0: true

Application: &ApplicationCapabilities
V2_0: true

################################################################################
#
# CHANNEL
#
# This section defines the values to encode into a config transaction or
# genesis block for channel related parameters.
#
################################################################################
Channel: &ChannelDefaults
# Policies defines the set of policies at this level of the config tree
# For Channel policies, their canonical path is
# /Channel/<PolicyName>
Policies:
# Who may invoke the 'Deliver' API
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
# Who may invoke the 'Broadcast' API
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
# By default, who may modify elements at this config level
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"


# Capabilities describes the channel level capabilities, see the
# dedicated Capabilities section elsewhere in this file for a full
# description
Capabilities:
<<: *ChannelCapabilities


################################################################################
#
# SECTION: Orderer
#
# - This section defines the values to encode into a config transaction or
# genesis block for orderer related parameters
#
################################################################################
Orderer: &OrdererDefaults

# Orderer Type: The orderer implementation to start
# Available types are "solo" and "kafka"
OrdererType: solo

Addresses:
- orderer.example.com:7050

# Batch Timeout: The amount of time to wait before creating a batch
BatchTimeout: 0.5s

# Batch Size: Controls the number of messages batched into a block
BatchSize:

# Max Message Count: The maximum number of messages to permit in a batch
MaxMessageCount: 10

# Absolute Max Bytes: The absolute maximum number of bytes allowed for
# the serialized messages in a batch.
AbsoluteMaxBytes: 98 MB

# Preferred Max Bytes: The preferred maximum number of bytes allowed for
# the serialized messages in a batch. A message larger than the preferred
# max bytes will result in a batch larger than preferred max bytes.
PreferredMaxBytes: 512 KB

Kafka:
# Brokers: A list of Kafka brokers to which the orderer connects
# NOTE: Use IP:port notation
Brokers:
- 127.0.0.1:9092

# Organizations is the list of orgs which are defined as participants on
# the orderer side of the network
Organizations:

# Policies defines the set of policies at this level of the config tree
# For Orderer policies, their canonical path is
# /Channel/Orderer/<PolicyName>
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
# BlockValidation specifies what signatures must be included in the block
# from the orderer for the peer to validate it.
BlockValidation:
Type: ImplicitMeta
Rule: "ANY Writers"

################################################################################
#
# Section: Organizations
#
# - This section defines the different organizational identities which will
# be referenced later in the configuration.
#
################################################################################
Organizations:

# OrdererOrg defines an MSP using the sampleconfig. It should never be used
# in production but may be used as a template for other definitions
- &OrdererOrg
# DefaultOrg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
Name: OrdererMSP

# ID to load the MSP definition as
ID: OrdererMSP

# MSPDir is the filesystem path which contains the MSP configuration
MSPDir: ../crypto-config/ordererOrganizations/example.com/msp

# Policies defines the set of policies at this level of the config tree
# For organization policies, their canonical path is usually
# /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
Policies: &OrdererOrgPolicies
Readers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
# If your MSP is configured with the new NodeOUs, you might
# want to use a more specific rule like the following:
# Rule: "OR('OrdererMSP.admin', 'OrdererMSP.peer', 'OrdererMSP.client')"
Writers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
# If your MSP is configured with the new NodeOUs, you might
# want to use a more specific rule like the following:
# Rule: "OR('OrdererMSP.admin', 'OrdererMSP.client')"
Admins:
Type: Signature
Rule: "OR('OrdererMSP.admin')"

- &Org1
# DefaultOrg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
Name: Org1MSP

# ID to load the MSP definition as
ID: Org1MSP

MSPDir: ../crypto-config/peerOrganizations/org1.example.com/msp

AnchorPeers:
# AnchorPeers defines the location of peers which can be used
# for cross org gossip communication. Note, this value is only
# encoded in the genesis block in the Application section context
- Host: peer0.org1.example.com
Port: 7051

# Policies defines the set of policies at this level of the config tree
# For organization policies, their canonical path is usually
# /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
Policies: &Org1Policies
Readers:
Type: Signature
Rule: "OR('Org1MSP.member')"
# If your MSP is configured with the new NodeOUs, you might
# want to use a more specific rule like the following:
# Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org1MSP.member')"
# If your MSP is configured with the new NodeOUs, you might
# want to use a more specific rule like the following:
# Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org1MSP.admin')"

- &Org2
# DefaultOrg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
Name: Org2MSP

# ID to load the MSP definition as
ID: Org2MSP

MSPDir: ../crypto-config/peerOrganizations/org2.example.com/msp

AnchorPeers:
# AnchorPeers defines the location of peers which can be used
# for cross org gossip communication. Note, this value is only
# encoded in the genesis block in the Application section context
- Host: peer0.org2.example.com
Port: 8051

# Policies defines the set of policies at this level of the config tree
# For organization policies, their canonical path is usually
# /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
Policies: &Org2Policies
Readers:
Type: Signature
Rule: "OR('Org2MSP.member')"
# If your MSP is configured with the new NodeOUs, you might
# want to use a more specific rule like the following:
# Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org2MSP.member')"
# If your MSP is configured with the new NodeOUs, you might
# want to use a more specific rule like the following:
# Rule: "OR('Org2MSP.admin', 'Org2MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org2MSP.admin')"

################################################################################
#
# Profile
#
# - Different configuration profiles may be encoded here to be specified
# as parameters to the configtxgen tool
#
################################################################################
Profiles:

TwoOrgsOrdererGenesis:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
<<: *ChannelDefaults
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Capabilities:
<<: *ApplicationCapabilities

Binary file added test/fixtures/channel/v2/tokenchannel.tx
Binary file not shown.
4 changes: 3 additions & 1 deletion test/integration/e2e/create-channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ test('\n\n***** SDK Built config update create flow *****\n\n', async (t) => {
client.setCryptoSuite(cryptoSuite);

// use the config update created by the configtx tool
const envelope_bytes = fs.readFileSync(path.join(__dirname, '../../fixtures/channel/mychannel.tx'));
const channeltx_basename = process.env.channeltx_subdir ? path.join(process.env.channeltx_subdir, channel_name) : channel_name;
const envelope_bytes = fs.readFileSync(path.join(__dirname, '../../fixtures/channel/' + channeltx_basename + '.tx'));
const config = client.extractChannelConfig(envelope_bytes);
t.pass('Successfully extracted the config update from the configtx envelope');

Expand Down Expand Up @@ -145,6 +146,7 @@ test('\n\n***** SDK Built config update create flow *****\n\n', async (t) => {
};

// send create request to orderer
logger.info('creating channel %s', channel_name);
const result = await client.createChannel(request);

logger.debug('\n***\n completed the create \n***\n', result);
Expand Down
77 changes: 77 additions & 0 deletions test/integration/e2e/e2eUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,83 @@ function queryChaincode(org, version, targets, fcn, args, value, chaincodeId, t,

module.exports.queryChaincode = queryChaincode;

// It sets up everything needed for a TokenClient:
// creates a client, enrolls a user, adds channel to client, and add orderers to the channel.
// The channel must be created and joined before this call.
// Returns an object including client, tokenClient, and user.
function createTokenClient(org, channel_name, targets, t) {
init();

Client.setConfigSetting('request-timeout', 60000);

// this is a transaction, will just use org's admin identity to
// submit the request. either org should work properly
const client = new Client();
const channel = client.newChannel(channel_name);
const tokenClient = client.newTokenClient(channel, targets);

const orgName = ORGS[org].name;
const cryptoSuite = Client.newCryptoSuite();
cryptoSuite.setCryptoKeyStore(Client.newCryptoKeyStore({path: testUtil.storePathForOrg(orgName)}));
client.setCryptoSuite(cryptoSuite);

const caRootsPath = ORGS.orderer.tls_cacerts;
const cadata = fs.readFileSync(path.join(__dirname, caRootsPath));
const caroots = Buffer.from(cadata).toString();
let tlsInfo = null;

return e2eUtils.tlsEnroll(org)
.then((enrollment) => {
t.pass('Successfully retrieved TLS certificate');
tlsInfo = enrollment;
client.setTlsClientCertAndKey(tlsInfo.certificate, tlsInfo.key);

return Client.newDefaultKeyValueStore({path: testUtil.storePathForOrg(orgName)});
}).then((store) => {

client.setStateStore(store);
return testUtil.getSubmitter(client, t, org);

}).then((admin) => {
the_user = admin;

t.pass('Successfully enrolled user \'admin\' (e2eUtil 4)');

channel.addOrderer(
client.newOrderer(
ORGS.orderer.url,
{
'pem': caroots,
'ssl-target-name-override': ORGS.orderer['server-hostname']
}
)
);

// set up the channel to use each org's 'peer1' for both requests and events
for (const key in ORGS) {
if (ORGS.hasOwnProperty(key) && typeof ORGS[key].peer1 !== 'undefined') {
const data = fs.readFileSync(path.join(__dirname, ORGS[key].peer1.tls_cacerts));
const peer = client.newPeer(
ORGS[key].peer1.requests,
{
pem: Buffer.from(data).toString(),
'ssl-target-name-override': ORGS[key].peer1['server-hostname']
});
channel.addPeer(peer);
}
}

return {client: client, tokenClient: tokenClient, user: the_user};
},
(err) => {
logger.error('createTokenClient got error: %s', err);
t.fail('Failed to get submitter \'admin\'. Error: ' + err.stack ? err.stack : err);
throw new Error('Failed to get submitter');
});
}

module.exports.createTokenClient = createTokenClient;

module.exports.sleep = testUtil.sleep;

function loadMSPConfig(name, mspdir) {
Expand Down
Loading

0 comments on commit 2b14610

Please sign in to comment.