Overview
Prerequisites
In following sections, we will test Fabric network base on test network.
For Caliper, we need
- networkConfig.yaml
- myAssetBenchmark.yaml
- readAsset.js
- connection.json
For Tape, we will use
- config.yaml
Define Test in Caliper and Tape
Network
General speaking,
- For Tape, you need put your node configuration in
config.yaml
with sample below with TLS file(location). - For Caliper, you need a general config file and a
connection.json
in Fabric SDK schema for nodes and defineconnectionProfile
innetworkConfig.yaml
withdiscover
on to use service discover.
Here is the network config for Tape:
# Definition of nodes
peer1: &peer1
addr: peer0.org1.example.com:7051
tls_ca_cert: /config/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/tlscacerts/tlsca.org1.example.com-cert.pem
peer2: &peer2
addr: peer0.org2.example.com:9051
tls_ca_cert: /config/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp/tlscacerts/tlsca.org2.example.com-cert.pem
orderer1: &orderer1
addr: orderer.example.com:7050
tls_ca_cert: /config/fabric-samples/test-network/organizations/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem
# Nodes to interact with
endorsers:
- *peer1
- *peer2
# we might support multi-committer in the future for more complex test scenario,
# i.e. consider tx committed only if it's done on >50% of nodes. But for now,
# it seems sufficient to support single committer.
committers:
- *peer2
commitThreshold: 1
orderer: *orderer1
Here is for Caliper:
{
"name": "test-network-org1",
"version": "1.0.0",
"client": {
"organization": "Org1",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
}
}
}
},
"organizations": {
"Org1": {
"mspid": "Org1MSP",
"peers": [
"peer0.org1.example.com"
],
"certificateAuthorities": [
"ca.org1.example.com"
]
}
},
"peers": {
"peer0.org1.example.com": {
"url": "grpcs://localhost:7051",
"tlsCACerts": {
"pem": "xxx"
},
"grpcOptions": {
"ssl-target-name-override": "peer0.org1.example.com",
"hostnameOverride": "peer0.org1.example.com"
}
}
},
"certificateAuthorities": {
"ca.org1.example.com": {
"url": "https://localhost:7054",
"caName": "ca-org1",
"tlsCACerts": {
"pem": ["xxx"]
},
"httpOptions": {
"verify": false
}
}
}
}
MSP
for MSP configuration, Tape and Caliper are similar.
Tape:
mspid: Org1MSP
private_key: /config/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp/keystore/priv_sk
sign_cert: /config/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp/signcerts/[email protected]
Caliper:
organizations:
- mspid: Org1MSP
identities:
certificates:
- name: 'User1'
clientPrivateKey:
path: '../fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp/keystore/priv_sk'
clientSignedCert:
path: '../fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp/signcerts/[email protected]'
Chain code Args
In general, To use Tape, we just need a random args list with limited chaincode functions.
Tape:
channel: mychannel
chaincode: basic
args:
- CreateAsset
- uuid
- randomString8
- randomNumber0_50
- randomString8
- randomNumber0_50
Caliper, we need define channels in networkConfig.yaml
channels:
- channelName: mychannel
contracts:
- id: basic
and make a random test config in readAsset.js
'use strict';
const { WorkloadModuleBase } = require('@hyperledger/caliper-core');
class MyWorkload extends WorkloadModuleBase {
constructor() {
super();
}
async initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext) {
await super.initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext);
for (let i=0; i<this.roundArguments.assets; i++) {
const assetID = `${this.workerIndex}_${i}`;
console.log(`Worker ${this.workerIndex}: Creating asset ${assetID}`);
const request = {
contractId: this.roundArguments.contractId,
contractFunction: 'CreateAsset',
invokerIdentity: 'User1',
contractArguments: [assetID,'blue','20','penguin','500'],
readOnly: false
};
await this.sutAdapter.sendRequests(request);
}
}
async submitTransaction() {
const randomId = Math.floor(Math.random()*this.roundArguments.assets);
const myArgs = {
contractId: this.roundArguments.contractId,
contractFunction: 'ReadAsset',
invokerIdentity: 'User1',
contractArguments: [`${this.workerIndex}_${randomId}`],
readOnly: true
};
await this.sutAdapter.sendRequests(myArgs);
}
async cleanupWorkloadModule() {
for (let i=0; i<this.roundArguments.assets; i++) {
const assetID = `${this.workerIndex}_${i}`;
console.log(`Worker ${this.workerIndex}: Deleting asset ${assetID}`);
const request = {
contractId: this.roundArguments.contractId,
contractFunction: 'DeleteAsset',
invokerIdentity: 'User1',
contractArguments: [assetID],
readOnly: false
};
await this.sutAdapter.sendRequests(request);
}
}
}
function createWorkloadModule() {
return new MyWorkload();
}
module.exports.createWorkloadModule = createWorkloadModule;
From Caliper to Tape
General speaking:
- Move network description from
connection.json
toconfig.yaml
(endorsers
,orderer
,committers
,commitThreshold
). - Move your manual script js logic to
config.yaml
. - Move MSP description from
networkConfig.yaml
(organizations
) toconfig.yaml
.(mspid
,private_key
,sign_cert
)
From Tape to Caliper
General speaking:
- Move network description from
config.yaml
(endorsers
,orderer
,committers
,commitThreshold
) toconnection.json
. - Move
config.yaml
random logic to your manual script js. - Move MSP description from
config.yaml
(mspid
,private_key
,sign_cert
) tonetworkConfig.yaml
(organizations
).
Summary
As Tape is A light-weight tool to test performance of Hyperledger Fabric, the maintainers want to make it easy use and quick start. On the other hands, Caliper supports more features as your can defined your test logic by manual script js file.