The Performance Traffic Engine (PTE) uses SDKs to interact with Hyperledger Fabric networks by sending requests to and receiving responses from one or more networks. Currently, PTE only uses Hyperledger Fabric Client (HFC) Node SDK and will include other SDKs in the future.
PTE is designed to meet two-fold requirements:
- to handle the complexity of the Hyperledger Fabric network, e.g., locations and number of network, number of channels, organizations, peers, orderers etc.
- to support various test cases, e.g., various chaincodes, transaction number, duration, mode, type, and payload size etc,
In order to meet the two-fold requirements above, flexibility and modularity are the primary design concepts of PTE regarding implementation and usage. Moreover, PTE provides users many options for their test cases, see below for available options. The design of PTE is demonstrated in the diagram below:
In brief, PTE has the following features:
- channel: to create and join channel
- chaincode: to install, instantiate and upgrade user specified chaincode
- transactions: to deliver transactions to the targeted peers with specified transaction mode, type, and frequency
- network: to interact with local and/or remote networks simultaneously
- scaling: easy to work with any number of networks, orderers, peers, organizations, channels, chaincodes etc.
- events: to open and listen to event port and maintain the record of events received and un-received
- blockchain height: to query blockchain height and number of transactions
- results: to provide number of transactions sent versus the events received, and validates blockchain contents after last transaction
- multiple PTEs: easy to manage multiple PTEs, see the diagram below:
To build and test the following prerequisites must be installed first:
- node and npm
node
: >=v8.9
AND <=v10.0
npm
: >=v5.6.0
- gulp command
npm install -g gulp
- go (v1.11 or later)
- refer to Go - Getting Started
- others:
- in Ubuntu:
apt install -y build-essential libltdl-dev
- or refer to your distribution's repository
- in Ubuntu:
If planning to run your Fabric network locally, you'll need docker and a bit more. See Hyperledger Fabric - Getting Started for details.
You need to install a gnu-compatible version of the awk
, date
utility. Install Brew (http://brew.sh) and run the following commands:
Install coreutils will install gdate
brew install gawk --with-default-names
brew install coreutils
PTE can be used with either the stable fabric-sdk-node
libraries obtained from the npm
package manager, or the latest unstable libraries
-
Download fabric-test sources:
go get -d github.com/hyperledger/fabric-test
-
Download or update fabric, and fabric-ca sources, see Hyperledger fabric-test for details:
cd $GOPATH/src/github.com/hyperledger/fabric-test
- if first time:
git submodule update --init --recursive
git submodule foreach git pull origin master
- else:
git submodule foreach git pull origin master
cd $GOPATH/src/github.com/hyperledger/fabric-test/scripts and run ./update_go_modules.sh
to update all the go modules for the chaincodes in the fabric-test
-
Obtain appropriate docker images:
Optionally, you may choose to skip this step of obtaining fabric
and fabric-ca
images if plan to run PTE against a remote Fabric network. See Creating a local Fabric network for additional information on this.
- fabric
- download from dockerhub:
* `cd $GOPATH/src/github.com/hyperledger/fabric-test/fabric/scripts`
* If testing v1.0.0: `./bootstrap-1.0.0.sh`
- build images yourself (v1.0.0 shown here):
* `cd $GOPATH/src/github.com/hyperledger/fabric-test/fabric/`
* `git checkout v1.0.0`
* `make docker`
- fabric-ca
* `cd $GOPATH/src/github.com/hyperledger/fabric-test/fabric-ca`
* `git checkout v1.0.0`
* `make docker`
- Install SDK-Node
- Stable (with latest fabric sdk-node)
cd $GOPATH/src/github.com/hyperledger/fabric-test/tools/PTE
rm package-lock.json
rm -rf node_modules
npm install fabric-client
npm install fabric-ca-client
- Stable (with specific version of fabric sdk-node)
cd $GOPATH/src/github.com/hyperledger/fabric-test/tools/PTE
rm package-lock.json
rm -rf node_modules
npm install fabric-client@version
, for example to install version1.0.2
,npm install [email protected]
npm install fabric-ca-client@version
, for example to install version1.0.2
,npm install [email protected]
- Unstable (with development version of fabric sdk-node)
cd $GOPATH/src/github.com/hyperledger/fabric-test/tools/PTE
rm package-lock.json
rm -rf node_modules
npm install
- Stable (with latest fabric sdk-node)
Once installed, the following steps are required.
-
Create Connection profile(s) for your Fabric network:
- Create your own version of connection profile, see the example in PTE/ConnProfiles/test-network/config.yaml and change the address to your own Fabric addresses and credentials. The connection profile can be in either yaml or json format. Add a block for each channel, organization, orderer, peer, and certificateAuthorities, ensuring correctness.
Note that the service credential file is supported in fabric-test commit level
f923d548c00ee1f7336bbc8812ee0d2058489785
and older. -
Specify run scenarios:
- Create your own version of PTEMgr.txt (if use pte_mgr.sh), runCases.txt and User Input json files, according to the test requirements. Use the desired chaincode name, channel name, organizations, etc. Using the information in your own network profiles, remember to "create" all channels, "join" channel, and "install" and "instantiate"/"upgrade" chaincode for each org, to ensure all peers are set up correctly. Additional information can be found below.
Before attempting to run PTE please ensure
- your network is running!
- you are in the correct directory
$GOPATH/src/github.com/hyperledger/fabric-test/tools/PTE
If you do not have access to a Fabric network, please see the section on Creating a local Fabric network.
There are two ways to execute PTE: pte_mgr.sh and pte_driver.sh. pte_mgr.sh can be used to manage multiple PTEs while pte_driver.sh can only manage one PTE.
-
`./pte_mgr.sh <PTE mgr input file>`
-
Example
./pte_mgr.sh sampleccInputs/PTEMgr.txt
sampleccInputs/PTEMgr.txt
contains the list of user specified run cases to be executed. Each line is a PTE run case and includes two parameters: driver type and run case file.For instance, a PTE mgr file containing two run cases files would be:
driver=pte sampleccInputs/runCases-constant-i-TLS.txt driver=pte sampleccInputs/runCases-constant-q-TLS.txt
Note: Available driver type is pte only.
-
-
./pte_driver.sh <run cases file>
-
Example
./pte_driver.sh sampleccInputs/runCases.txt
sampleccInputs/runCases.txt
contains the list of test cases to be executed. Each line is a test case and includes two parameters: SDK type and user input file.For instance, a run cases file containing three test cases using the node SDK would be:
sdk=node sampleccInputs/samplecc-chan1-i-TLS.json sdk=node sampleccInputs/samplecc-chan2-i-TLS.json sdk=node sampleccInputs/samplecc-chan3-i-TLS.json
Note: Available SDK types are node, go, python and java; however, only the node SDK is currently supported.
See User Input file in the Reference section below for more information about these files.
-
A single test case is described by a user input file. User input files define all the parameters for executing a test; including transaction type, number of processes, number of transactions, duration, etc. All processes in one test case will concurrently execute the specified transaction. Different transactions may be used in different test cases and then combined into a single run cases file, making it possible to create more complicated scenarios. For example, in a single run of PTE, a user could send a specific number of invokes to all peers and then query each peer separately.
-
The transaction can be executed with either transaction number or run time duration. They are controlled by two user input parameters nRequest and runDur. See User Input file in the Reference section below on how to control transaction execution using these two parameters.
-
To execute invoke (move) transactions, set the transType to Invoke and invokeType to Move, and specify the network parameters and desired execution parameters(Please make sure to update the path with your gopath in all the following snippets):
"invokeCheck": "TRUE", "transMode": "Constant", "transType": "Invoke", "invokeType": "Move", "targetPeers": "OrgAnchor", "nProcPerOrg": "4", "nRequest": "1000", "runDur": "600", "TLS": "serverauth",
And set the channel name in channelOpt:
"channelOpt": { "name": "testchannel1", "channelTX": "/root/gopath/src/github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/ordererOrganizations/testorgschannel1.tx", "action": "create", "orgName": [ "testOrg1" ] },
-
To execute invoke (move) transactions, set the transType to Invoke and invokeType to Query, and specify the network parameters and desired execution parameters:
"invokeCheck": "TRUE", "transMode": "Constant", "transType": "Invoke", "invokeType": "Query", "targetPeers": "OrgAnchor", "nProcPerOrg": "4", "nRequest": "1000", "runDur": "600", "TLS": "clientauth",
And set the channel name in channelOpt:
"channelOpt": { "name": "testchannel1", "channelTX": "/root/gopath/src/github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/ordererOrganizations/testorgschannel1.tx", "action": "create", "orgName": [ "testOrg1" ] },
If you started a network using Network Launcher and specified an organization map JSON (using the -M
parameter) to create organizations with custom names and MSPs with custom IDs, you will need to create connection profile and test case files with the appropriate organization names.
You can use PTE/ConnProfiles/test-network/config.yaml
as an example to create your own connection profile. See Connection Profile for detail of the connection profile.
You can refer to PTE/sampleccInputs
as an example to create your testcase. See User Input File for detail of the testcase
-
Example:
sampleccInputs/samplecc-chan1-latency-i.json
Performs 1000 invokes (Move) with 1 process on 1 network using the sample_cc chaincode. The average of the execution result (execution time (ms)/1000 transactions) represents the latency of 1 invoke (Move). -
Example:
sampleccInputs/samplecc-chan1-longrun-i.json
Performs invokes (Move) of various payload size of 1kb with 1 process on one network using sample_cc chaincode for 36 hours at 1 transaction per second. -
Example:
sampleccInputs/samplecc-chan1-complex-i.json
Performs invokes (Move) of various payload size ranging from 10kb-500kb with 10 processes on one 4-peer network using sample_cc chaincode for 10 minutes. Each invoke (Move) is followed by an invoke (Query). -
- For multiple chaincodes deployments and transactions, configure each user input file to install and instantiate chaincodes and drive the transactions appropriately.
- For a stress test on a single network, set all SCFiles to same network. Then concurrent execution of the test is performed against the network but with the workload specified in each user input file.
- For a density test, configure config json in SCFiles, create run cases files, and user input files for each network. Then execute pte_mgr.sh against these run cases files.
Although PTE's primary use case is to drive transactions into a Fabric network, it can be used for creating and joining channels, and chaincode installation, instantiation and upgrade. This gives the ability for more complete end-to-end scenarios.
-
For any channel activities (create or join), set transType to
Channel
:"transMode": "Constant", "transType": "Channel", "invokeType": "Move",
-
To create a channel, set the action in channelOpt to
create
, and set the name to the channel name. Note that orgName is ignored in this operation:"channelOpt": { "name": "testchannel1", "channelTX": "/root/gopath/src/github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/ordererOrganizations/testorgschannel1.tx", "action": "create", "orgName": [ "testOrg1" ] },
-
To join all peers in an org to a channel, set the action in channelOpt to
join
, set name to channel name, and set orgName to the list of orgs to join:"channelOpt": { "name": "testchannel1", "channelTX": "/root/gopath/src/github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/ordererOrganizations/testorgschannel1.tx", "action": "join", "orgName": [ "testOrg1" ] },
-
-
For chaincode setup (install or instantiate) set
deploy
according to the test. For example:"deploy": { "chaincodePath": "github.com/hyperledger/fabric-test/fabric-sdk-node/test/fixtures/src/github.com/sample_cc", "fcn": "init", "args": [] },
If installing chaincode on CouchDB with indexing, then inside the
deploy
section we should also addmetadataPath
for the location of the index definition files. Note: ifgopath
is defined in the service credential json, then specify the relative path from$GOPATH/src/
(as is done in this example); otherwise use a fully specified absolute path."deploy": { "chaincodePath": "github.com/hyperledger/fabric-test/chaincodes/marbles02/go", "metadataPath": "github.com/hyperledger/fabric-test/chaincodes/marbles02/go/META-INF", "fcn": "init", "args": [] },
In above example, a default endorsement policy of "a signature by any member from any of the organizations corresponding to the array of member service providers" is used. If the test need a specific endorsement policy when chaincode instantiate, the 'endorsement' section need be configured like below format:
"deploy": { "chaincodePath": "github.com/hyperledger/fabric-sdk-node/test/fixtures/src/github.com/sample_cc", "fcn": "init", "endorsement": { "identities": [ { "role": { "name": "member", "mspId": "Org1MSP" }}, { "role": { "name": "member", "mspId": "Org2MSP" }} ], "policy": { "2-of": [{ "signed-by": 0 }, { "signed-by": 1 }] } }, "args": [] },
The policy syntax definition in : Polciy Specification
-
To install a chaincode, set the transType to
install
:"transMode": "Constant", "transType": "install", "invokeType": "Move",
PTE can install a chaincode on all peers within an orgnization or on specified peers.
In
channelOpt
, set channel name inname
and list all orgs inorgName
, such as:"channelOpt": "name": "testchannel1", "channelTX": "/root/gopath/src/github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/ordererOrganizations/testorgschannel1.tx", "action": "create", "orgName": [ "testOrg1", "testOrg2" ] },
Note that action is ignored.
-
Set the
targetPeers
toLIST
"targetPeers": "LIST",
-
List all individual orgs and peers in
listOpt
, such as"listOpt": { "org1": ["peer1", "peer2"], "org2": ["peer1"] },
-
-
To instantiate a chaincode, set the transType to
instantiate
:"transMode": "Constant", "transType": "instantiate", "invokeType": "Move",
and set channelOpt name to the channel name and specify the list of organizations that the chaincode will be instantiated:
"channelOpt": { "name": "testchannel1", "channelTX": "/root/gopath/src/github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/ordererOrganizations/testorgschannel1.tx", "action": "create", "orgName": [ "testOrg1", "testOrg2" ] },
Note that action is ignored. PTE instantiates chaincode on all peers of each organization listed in channelOpt.orgName.
Recommendation: instantiate a chaincode on the organization before sending a transaction to any peer of that organization.
-
To Upgrade a chaincode, set the transType to
upgrade
:"transMode": "Constant", "transType": "upgrade", "invokeType": "Move",
and rest of the steps are same as for instantiating a chaincode (see above).
-
-
For any query blockchain height activities (query block), set transType to
QueryBlock
:"transMode": "Constant", "transType": "QueryBlock", "invokeType": "Move",
-
To query the length (number of transactions) in blocks, set org, peer, startBlock, and endBlock in queryBlockOpt:
"queryBlockOpt": { "org1": ["peer0org1examplecom"], "startBlock": "195", "endBlock": "200" },
The following is the output with startBlock=195 and endBlock=200. The output includes the block height and the number of transactions from startBlock to endBlock.
info: [PTE 0 main]: [queryBlockchainInfo] Channel queryInfo() returned block height=202 info: [PTE 0 main]: [queryBlockchainInfo] block:Length:accu length= 195:10:10 info: [PTE 0 main]: [queryBlockchainInfo] block:Length:accu length= 196:10:20 info: [PTE 0 main]: [queryBlockchainInfo] block:Length:accu length= 197:10:30 info: [PTE 0 main]: [queryBlockchainInfo] block:Length:accu length= 198:10:40 info: [PTE 0 main]: [queryBlockchainInfo] block:Length:accu length= 199:10:50 info: [PTE 0 main]: [queryBlockchainInfo] block:Length:accu length= 200:10:60 info: [PTE 0 main]: [queryBlockchainInfo] blocks= 195:200, totalLength= 60
-
The following chaincodes are tested and supported:
-
example02: This is a simple chaincode with limited capability. This chaincode is NOT suitable for performance benchmark.
-
sample_cc: This chaincode supports variable (randomized) payload sizes and performs encryption and decryption on the payload. Specify
ccType
asccchecker
when using this chaincode. See directorysampleccInputs
for examples related to this chaincode. This chaincode is available in$GOPATH/src/github.com/hyperledger/fabric-test/chaincodes/samplecc/go
. Set the deploy.chaincodePath to this directory in the user input file."deploy": { "chaincodePath": "github.com/hyperledger/fabric-test/chaincodes/samplecc/go", "fcn": "init", "args": [] },
-
marbles_cc: Marbles02 chaincode. PTE alters the marble name (the first argument) and the marble size (the third argument) for each
initMarble
transaction. SpecifyccType
asmarblescc
when using this chaincode. This chaincode ignores payload size, such as payLoadMin and payLoadMax. See directorymarblesccInputs
for examples related to this chaincode. This chaincode is available in$GOPATH/src/github.com/hyperledger/fabric-test/chaincodes/marbles02/go
. Set the deploy.chaincodePath to this directory in the user input file."deploy": { "chaincodePath": "github.com/hyperledger/fabric-test/chaincodes/marbles02/go", "fcn": "init", "args": [] },
-
marblescc_priv: Marbles02 private chaincode. PTE alters the marble name (the first argument) and the marble size (the third argument) for each
initMarble
transaction. SpecifyccType
asmarblescc_priv
when using this chaincode. This chaincode ignores payload size, such as payLoadMin and payLoadMax. See directorymarblescc_privInputs
for examples related to this chaincode. This chaincode is available in$GOPATH/src/github.com/hyperledger/fabric-test/chaincodes/marbles02_private/go
. Set the deploy.chaincodePath to this directory in the user input file. This chaincode can be used for side DB if user specifies collection configuration json in thecollectionsConfigPath
when instantiate the chaincode."deploy": { "chaincodePath": "github.com/hyperledger/fabric-test/chaincodes/marbles02_private/go", "collectionsConfigPath": "github.com/hyperledger/fabric-test/tools/PTE/marblescc_privInputs/collections_config-chan1.json", "fcn": "init", "args": [] },
This chaincode passes private data as base64 encoded bytes in transient map. User can define transient MAP in the move
subsection under invoke
section. PTE will create a unique name for each marble. See below for an example of transientMap.
"invoke": {
"query": {
"fcn": "readMarblePrivateDetails",
"args": ["marble"]
},
"move": {
"fcn": "initMarble",
"transientMap": {"marble": {"name":"marble", "color":"blue", "size":35, "owner":"tom", "price":99}},
"args": []
}
},
-
sample_js: This is the Node JS chaincode of sample_cc. See directory
samplejsInputs
for examples related to this chaincode. This chaincode is available in$GOPATH/src/github.com/hyperledger/fabric-test/chaincodes/samplecc/node
. Set the deploy.chaincodePath to this directory in the user input file."deploy": { "chaincodePath": "github.com/hyperledger/fabric-test/chaincodes/samplecc/node", "fcn": "init", "language": "node", "args": [] },
-
sample_java: This is the java chaincode of sample_cc. See directory
samplejavaInputs
for examples related to this chaincode. This chaincode is available in$GOPATH/src/github.com/hyperledger/fabric-test/chaincodes/samplecc/java
. Set the deploy.chaincodePath to this directory in the user input file."deploy": { "chaincodePath": "github.com/hyperledger/fabric-test/chaincodes/samplecc/java", "fcn": "init", "language": "java", "args": [] },
-
sbecc: This is the golang chaincode of state-based endorsement. See directory
sbeccInputs
for examples related to this chaincode. This chaincode is available in$GOPATH/src/github.com/hyperledger/fabric-test/chaincodes/sbe
. This chaincode ignores payload size, such as payLoadMin and payLoadMax. Set the deploy.chaincodePath to this directory in the user input file."deploy": { "chaincodePath": "github.com/hyperledger/fabric-test/chaincodes/sbe", "fcn": "init", "language": "golang", "args": [] },
This chaincode requires packages not provided by the Go standard library, you will need to include those packages with this chaincode for managing or vendoring these dependencies by executing the following commands:
- cd $GOPATH/src/github.com/hyperledger/fabric-test
- make pre-setup
- cd chaincodes/sbe
- govendor init
- govendor add +external
You can write logic to generate transaction (invoke or query) arguments that is specific to a chaincode type (or ccType
in your chaincode definition JSON file.)
In addition, you can also write per-chaincode logic to specify the organization to which the submitter of a particular transaction must belong. Such an access control policy can be specified at the chaincode function level; i.e., the function name determines the list of organizations.
(This feature is useful when a chaincode function implements access control by checking the organization name of the transaction submitter using the GetCreator()
method in the shim API. If PTE does not assign the right signing identity to the fabric client instance, transaction endorsements attempted during a test run will fail.)
The logic for <ccType>
should be specified in ccArgumentsGenerators/<ccType>/ccFunctions.js
, in a class named ccFunctions
that inherits the ccFunctionsBase
class defined in ccArgumentsGenerators/ccFunctionsBase.js
.
(The following ccType
values are supported by default: {ccchecker
, marblescc
, marblescc_priv
, sbecc
}. If you want to run PTE on a custom ccType
, create an appropriate folder and JS file.)
The ccFunctions
interface that should be implemented is described below. (Note: The functions in these interface will be called by pte-execRequest.js
, so please ensure that they are defined and return a value of an appropriate type.)
class ccFunctions extends ccFunctionsBase {
constructor(ccDfnPtr, logger, Nid, channelName, org, pid) {
super(ccDfnPtr, logger, Nid, channelName, org, pid);
// ADD INITIALIZATION LOGIC HERE
}
getInvokeArgs(txIDVar) {
// ADD LOGIC TO COMPUTE CHAINCODE INVOCATION ARGUMENTS (EXCLUDING THE FUNCTION NAME)
// POPULATE THE 'this.testInvokeArgs[]' ARRAY WITH THE COMPUTED ARGUMENTS' LIST
// THIS ARRAY WILL BE READ IN 'pte-execRequest.js:getMoveRequest()'
}
getQueryArgs(txIDVar) {
// ADD LOGIC TO COMPUTE CHAINCODE QUERY ARGUMENTS (EXCLUDING THE FUNCTION NAME)
// POPULATE THE 'this.testQueryArgs[]' ARRAY WITH THE COMPUTED ARGUMENTS' LIST
// THIS ARRAY WILL BE READ IN 'pte-execRequest.js:getQueryRequest()'
}
getExecModeLatencyFreq() {
'return 0; // RETURN APPROPRIATE INTEGER VALUE
// THIS VALUE WILL BE USED IN 'pte-execRequest.js:execModeLatency()'
}
getAccessControlPolicyMap() {
return {}; // RETURN JSON key-value mappings: <function-name> --> <array of org-names>
// THIS VALUE WILL BE USED IN 'pte-execRequest.js:getMoveRequest()' and 'pte-execRequest.js:getQueryRequest()'
}
}
For examples, see:
- ccArgumentsGenerators/ccchecker/ccFunctions.js
- ccArgumentsGenerators/marblescc/ccFunctions.js
- ccArgumentsGenerators/marblescc_priv/ccFunctions.js
- ccArgumentsGenerators/sbecc/ccFunctions.js
-
Statistical Output Message
The statistical output message includes PTE id, network id, channel name, org name, process id, transaction type, total transactions received and sent, elapsed time, starting time, ending time, and number of un-received events.
For example, the following is the statistical output message for a test case with 4 processes.
info: [PTE 0 main]: stdout: info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org2:0 eventRegister] completed Rcvd(sent)=1000(1000) Invoke(Move) in 46199 ms, timestamp: start 1508185534030 end 1508185580229, #event timeout: 0 info: [PTE 0 main]: stdout: info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org2:1 eventRegister] completed Rcvd(sent)=1000(1000) Invoke(Move) in 46266 ms, timestamp: start 1508185533969 end 1508185580235, #event timeout: 0 info: [PTE 0 main]: stdout: info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org1:0 eventRegister] completed Rcvd(sent)=1000(1000) Invoke(Move) in 54232 ms, timestamp: start 1508185533962 end 1508185588194, #event timeout: 0 info: [PTE 0 main]: stdout: info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org1:1 eventRegister] completed Rcvd(sent)=1000(1000) Invoke(Move) in 54613 ms, timestamp: start 1508185533985 end 1508185588598, #event timeout: 0
-
Completed Message
For each process, One message of
pte-exec:completed
is logged in PTE output upon the status of completion of each process. For each pte_driver.sh (each line in runCase.txt) execution, one message ofpte-main:completed
is logged in the PTE output upon completion of all associated pte_driver.sh.-
pte-main:completed For each runCases.txt, a
pte-main:completed
message is logged in PTE output. -
pte-exec:completed If PTE completed normally, then the message
pte-exec:completed
is logged. -
pte-exec:completed:timeout If PTE completed but with any event timeout, then the message
pte-exec:completed:timeout
is logged. -
pte-exec:completed:error If PTE exits due to any error, then the message
pte-exec:completed:error
is logged.
For example, if pte_mgr.sh is executed with a mgr.txt contains:
driver=pte CITest/FAB-3832-4i/samplecc/runCases-FAB-3832-4i1-TLS.txt
and runCases-FAB-3832-4i1-TLS.txt contains
sdk=node CITest/FAB-3832-4i/samplecc/samplecc-chan1-FAB-3832-4i-TLS.json
and
samplecc-chan1-FAB-3832-4i-TLS.json
contains... "nProcPerOrg": "2", ... "channelOpt": { ... "orgName": [ "org1", "org2" ] },
Then there will be 4
pte-exec:completed
messages since there are 4 processes, 2 org and 2 processes per org. And there will be 1pte-main:completed
since 1 pte_driver.sh is executed (only one line of sdk=node in runCases.txt). The completed message will be as follow:info: [PTE 0 main]: stdout: info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org2:0 eventRegister] pte-exec:completed info: [PTE 0 main]: stdout: info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org2:1 eventRegister] pte-exec:completed info: [PTE 0 main]: stdout: info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org1:0 eventRegister] pte-exec:completed info: [PTE 0 main]: stdout: info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org1:1 eventRegister] pte-exec:completed info: [PTE 0 main]: [performance_main] pte-main:completed
When the transmode is
CONSTANT
, the latency metrics forproposal
,transaction
andevent
of each process are provided. Where* **proposal**: the time between the prosoal is sent to peers and the response is received. * **transaction**: the time between the transaction is sent to orderer and response is received. * **event**: the time between the event is registered, the transaction is sent to orderer, and the event is received.
The output of the latency metrics include average, minimum, and maximum of all transactions for that process. The following is an example of the output with two processes, one targets org1 and one targets org2 with 1000 transactions each:
info: [PTE 0 main]: stdout: info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org1:0 latency_output] peer latency stats: tx num= 1000, total time: 10240 ms, avg= 10.24 ms, min= 5 ms, max= 92 ms info: [PTE 0 main]: stdout: info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org1:0 latency_output] orderer latency stats: tx num= 1000, total time: 8735 ms, avg= 8.73 ms, min= 4 ms, max= 79 ms info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org1:0 latency_output] event latency stats: tx num= 1000, total time: 837918 ms, avg= 837.92 ms, min= 307 ms, max= 2130 ms info: [PTE 0 main]: stdout: info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org2:0 latency_output] peer latency stats: tx num= 1000, total time: 9991 ms, avg= 9.99 ms, min= 5 ms, max= 111 ms info: [PTE 0 main]: stdout: info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org2:0 latency_output] orderer latency stats: tx num= 1000, total time: 9128 ms, avg= 9.13 ms, min= 4 ms, max= 126 ms info: [PTE 0 exec]: [Nid:chan:org:id=0:testorgschannel1:org2:0 latency_output] event latency stats: tx num= 1000, total time: 828433 ms, avg= 828.43 ms, min= 284 ms, max= 2195 ms
-
-
Test Summary Report
A test summary report file, namely pteReport.txt, is generated at the PTE directory after PTE execution. The report contains overall tranasction TPS and latency statistics (min, max, avg) for endorsement, transaction acknowledgment, and end-to-end transaction events for each PTE execution, i.e., each runCases.txt. Below is an example of the report of executing PTE with 3 runCases.txt, involving chaincode sample_cc_ch1 on channel testorgschannel1, sample_cc_ch2, on channel testorgschannel2 and sample_cc_ch3 on channel testorgschannel2 respectively. The report will be appended to the report file if it exists.
======= PTE 0 main Test Summary: executed at Wed May 02 2018 13:10:19 GMT-0400 (EDT) ======= (testorgschannel1:sample_cc_ch1): INVOKE transaction stats (testorgschannel1:sample_cc_ch1): Total transactions 200 timeout transactions 0 (testorgschannel1:sample_cc_ch1): start 1525281040506 end 1525281049585 duration 9079 ms (testorgschannel1:sample_cc_ch1): TPS 22.03 (testorgschannel1:sample_cc_ch1): peer latency stats (endorsement) (testorgschannel1:sample_cc_ch1): total transactions: 200 total time: 4998 ms (testorgschannel1:sample_cc_ch1): min: 8 ms max: 98 ms avg: 24.99 ms (testorgschannel1:sample_cc_ch1): orderer latency stats (transaction ack) (testorgschannel1:sample_cc_ch1): total transactions: 200 total time: 12527 ms (testorgschannel1:sample_cc_ch1): min: 14 ms max: 174 ms avg: 62.635 ms (testorgschannel1:sample_cc_ch1): event latency stats (end-to-end) (testorgschannel1:sample_cc_ch1): total transactions: 200 total time: 66070 ms (testorgschannel1:sample_cc_ch1): min: 76 ms max: 674 ms avg: 330.35 ms ======= PTE 1 main Test Summary: executed at Wed May 02 2018 13:10:19 GMT-0400 (EDT) ======= (testorgschannel2:sample_cc_ch2): INVOKE transaction stats (testorgschannel2:sample_cc_ch2): Total transactions 200 timeout transactions 0 (testorgschannel2:sample_cc_ch2): start 1525281040579 end 1525281049680 duration 9101 ms (testorgschannel2:sample_cc_ch2): TPS 21.98 (testorgschannel2:sample_cc_ch2): peer latency stats (endorsement) (testorgschannel2:sample_cc_ch2): total transactions: 200 total time: 4905 ms (testorgschannel2:sample_cc_ch2): min: 9 ms max: 92 ms avg: 24.525 ms (testorgschannel2:sample_cc_ch2): orderer latency stats (transaction ack) (testorgschannel2:sample_cc_ch2): total transactions: 200 total time: 12534 ms (testorgschannel2:sample_cc_ch2): min: 20 ms max: 173 ms avg: 62.67 ms (testorgschannel2:sample_cc_ch2): event latency stats (end-to-end) (testorgschannel2:sample_cc_ch2): total transactions: 200 total time: 68286 ms (testorgschannel2:sample_cc_ch2): min: 113 ms max: 716 ms avg: 341.43 ms ======= PTE 2 main Test Summary: executed at Wed May 02 2018 13:10:19 GMT-0400 (EDT) ======= (testorgschannel3:sample_cc_ch3): INVOKE transaction stats (testorgschannel3:sample_cc_ch3): Total transactions 200 timeout transactions 0 (testorgschannel3:sample_cc_ch3): start 1525281040539 end 1525281049696 duration 9157 ms (testorgschannel3:sample_cc_ch3): TPS 21.84 (testorgschannel3:sample_cc_ch3): peer latency stats (endorsement) (testorgschannel3:sample_cc_ch3): total transactions: 200 total time: 5222 ms (testorgschannel3:sample_cc_ch3): min: 8 ms max: 102 ms avg: 26.11 ms (testorgschannel3:sample_cc_ch3): orderer latency stats (transaction ack) (testorgschannel3:sample_cc_ch3): total transactions: 200 total time: 12424 ms (testorgschannel3:sample_cc_ch3): min: 13 ms max: 175 ms avg: 62.12 ms (testorgschannel3:sample_cc_ch3): event latency stats (end-to-end) (testorgschannel3:sample_cc_ch3): total transactions: 200 total time: 72844 ms (testorgschannel3:sample_cc_ch3): min: 92 ms max: 736 ms avg: 364.22 ms
The user input file contains configuration parameters including chaincode definition, transaction configuration, and channel information. Two structure options are provided:
- contain all configuration parameters in one file as identified in the testcase runCases.txt files
- split into three files: main input file, transaction configuration file, and chaincode definition file.
{
"channelID": "_ch1",
"chaincodeID": "sample_cc",
"chaincodeVer": "v0",
"logLevel": "ERROR",
"invokeCheck": "TRUE",
"transMode": "Constant",
"transType": "Invoke",
"invokeType": "Move",
"targetPeers": "RoundRobin",
"peerFailover": "TRUE",
"ordererFailover": "TRUE",
"nProcPerOrg": "4",
"nRequest": "0",
"runDur": "600",
"TLS": "clientauth",
"queryBlockOpt": {
"org1": ["peer0org1examplecom"],
"startBlock": "6590",
"endBlock": "6800"
},
"channelOpt": {
"name": "testchannel1",
"channelTX": "github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/ordererOrganizations/testorgschannel1.tx",
"action": "create",
"orgName": [
"org1"
]
},
"constantOpt": {
"constFreq": "1000",
"devFreq": "300"
},
"listOpt": {
"org1": ["peer1"],
"org2": ["peer1"]
},
"discoveryOpt": {
"localHost": "true",
"collection": ["myCollectionName"],
"initFreq": "300000"
},
"eventOpt": {
"type": "FilteredBlock",
"timeout": "240000"
},
"failoverOpt": {
"method": "RoundRobin",
"list": "targetPeers"
},
"invokeCheckOpt": {
"peers": "OrgAnchor",
"transactions": "LAST",
"txNum": "10"
},
"ordererOpt": {
"method": "UserDefined",
"nOrderers": "3",
},
"timeoutOpt": {
"preConfig": "200000",
"request": "45000",
"grpcTimeout": "3000"
},
"ccType": "general",
"ccOpt": {
"keyIdx": [1],
"keyPayLoad": [2, 3, 4, 6],
"keyPayLoadType": ["Random", "FixedInt", "Fixed", "RandomInt"],
"keyPayLoadMin": [128, 32, 256, 0],
"keyPayLoadMax": [512, 64, 512, 12],
"keyStart": "5000",
"payLoadType": "Random",
"payLoadMin": "1024",
"payLoadMax": "2048"
},
"deploy": {
"chaincodePath": "github.com/hyperledger/fabric-test/fabric-sdk-node/test/fixtures/src/github.com/sample_cc",
"fcn": "init",
"language": "golang"
"args": []
},
"invoke": {
"query": {
"fcn": "invoke",
"args": ["get", "a"]
},
"move": {
"fcn": "invoke",
"args": ["put", "a", "string-msg"]
}
},
"ConnProfilePath": "ConnProfiles/test-network"
}
####### Main Input File
{
"txCfgPtr": "sampleccInputs/txCfgOpt.json",
"ccDfnPtr": "sampleccInputs/ccDfnOpt.json",
"channelID": "_ch1",
"chaincodeID": "sample_cc",
"chaincodeVer": "v0",
"channelOpt": {
"name": "testchannel1",
"channelTX": "github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/ordererOrganizations/testorgschannel1.tx",
"action": "create",
"orgName": [
"org1"
]
},
"ConnProfilePath": "ConnProfiles/test-network"
}
where
- txCfgPtr: the transaction configuration input file, supported file type: json and yaml, see PTE/sampleccInputs for example of both file types
- ccDfnPtr: the chaincode definition input file, supported file type: json and yaml, see PTE/sampleccInputs for example of both file types
- The supported file type of this Main Input File: json and yaml.
####### Transaction configuration File
{
"logLevel": "ERROR",
"invokeCheck": "TRUE",
"transMode": "Constant",
"transType": "Invoke",
"invokeType": "Move",
"targetPeers": "OrgAnchor",
"peerFailover": "TRUE",
"ordererFailover": "TRUE",
"nProcPerOrg": "4",
"nRequest": "0",
"runDur": "600",
"TLS": "serverauth",
"queryBlockOpt": {
"org1": ["peer0org1examplecom"],
"startBlock": "6590",
"endBlock": "6800"
},
"constantOpt": {
"constFreq": "1000",
"devFreq": "300"
},
"listOpt": {
"org1": ["peer1"],
"org2": ["peer1"]
},
"eventOpt": {
"type": "FilteredBlock",
"timeout": "240000"
},
"failoverOpt": {
"method": "RoundRobin",
"list": "targetPeers"
},
"invokeCheckOpt": {
"peers": "OrgAnchor",
"transactions": "LAST",
"txNum": "10"
},
"ordererOpt": {
"method": "RoundRobin",
"nOrderers": "0"
},
"timeoutOpt": {
"preConfig": "200000",
"request": "45000",
"grpcTimeout": "3000"
}
}
####### Chaincode Definition File
{
"ccType": "general",
"ccOpt": {
"keyIdx": [1],
"keyPayLoad": [2],
"keyPayLoadType": ["Random"],
"keyPayLoadMin": [128],
"keyPayLoadMax": [512],
"keyStart": "5000",
"payLoadType": "Random",
"payLoadMin": "1024",
"payLoadMax": "2048"
},
"deploy": {
"chaincodePath": "github.com/hyperledger/fabric-test/fabric-sdk-node/test/fixtures/src/github.com/sample_cc",
"fcn": "init",
"language": "golang"
"args": []
},
"invoke": {
"query": {
"fcn": "invoke",
"args": ["get", "a"]
},
"move": {
"fcn": "invoke",
"args": ["put", "a", "string-msg"]
}
}
}
where:
-
channelID: channel ID for the run.
-
chaincodeID: chaincode ID for the run.
-
chaincodeVer: chaincode version.
-
logLevel: logging level for the run. Options are ERROR, DEBUG, or INFO. Set to ERROR for performance test. The default value is ERROR.
-
invokeCheck: if this is
TRUE
, then queries will be executed for validation based on the setting ofinvokeCheckOpt
once the event of all invokes are received. This value is ignored for query test. Default:FALSE
-
transMode: transaction mode (applicable for each thread). Note: the per-thread transaction send rates for all modes have an upper bound. For example, if it typically takes 5 ms to get ack responses for sending transactions to peers in your network, then that limits your max effective rate to be 200 tps - such as when you use transMode = Constant with constantOpt.constFreq = any value between 1 - 5 ms. The host hardware cpu and memory resources may also impose limitations, especially when your test uses higher numbers of simultaneous connections and threads competing for those resources. (See Notes on Statistical Distributions for more info.)
- Constant: the transactions are sent by the specified rate, see constantOpt for details
- Poisson: the transactions are sent according to a Poisson distribution, see poissonOpt for details
- Latency: one transaction type and rate only, the subsequent transaction is sent when the event message (ledger update is completed) of the previous transaction is received
-
transType: transaction type
- Channel: channel activities specified in channelOpt.action
- Install: install chaincode
- Instantiate: instantiate chaincode
- Upgrade: upgrade chaincode
- QueryBlock: query blockchain information
- Invoke: invokes transaction
- Discovery: service discovery initialization
-
peerFailover: if this parameter is set to
TRUE
and if the transaction cannot be delivered to the targeted peer, then PTE will send the transaction to the next peer in the peer list, and so on. The peer list consists of all peers in the configuration json. -
ordererFailover: if this parameter is set to
TRUE
and if the transaction cannot be delivered to the targeted orderer, then PTE will send the transaction to the next orderer in the orderer list, and so on. The orderer list consists of all orderers in the configuration json. -
invokeType: invoke transaction type. This parameter is valid only if the transType is set to invoke
- Move: move transaction
- Query: query transaction
-
targetPeers: the target peers that transactions will sent to
- OrgAnchor: send to the anchor peer (peer1) of the organization being executed in the current process
- AllAnchors: send to the anchor peers of all organizations
- OrgPeers: send to all peers in the organization being executed in the current process
- AllPeers: send to all peers in all organizations from all connection profiles
- List: only send to the peers given in listOpt, see listOpt below for details
- Disovery: use service discovery to determine the target peers, see discoveryOpt below for details
- RoundRobin: a peer from the org section of Service Credentials File is assigned to each thread in the round robin fashion
-
nProcPerOrg: number of processes for the test
-
nRequest: number of transactions to be executed for each process
-
runDur: run duration in seconds to be executed for each process.
- if nRequest is non-zero the nRequest is executed.
- if nRequest is zero and runDur is non-zero, then runDur is executed.
- if both nRequest and runDur are zero, then PTE runs forever.
-
TLS: TLS setting for the test
- disabled: TLS is disabled
- serverauth: server authentication, TLS
- clientauth: client authentication, mutual TLS
-
queryBlock: query blockchain information options
- org: the org to be queried and the peer in the org
- startBlock: the starting block
- endBlock: the ending block. If the the ending block is greater than the chain height in the peer, eBlock will be set to the chain height.
-
channelOpt: transType channel options
- name: channel name
- channelTX: channel transaction file. If the
gopath
is defined in the service credential json, then the path is relative togopath/src
. Otherwise, absolute path is required. - action: channel action: create or join
- orgName: name of organization for the test
-
constantOpt: the transactions are sent at the specified rate. This parameter is valid only if the transMode is set to Constant.
- constFreq: frequency in ms for the transaction rate.
- devFreq: deviation of frequency in ms for the transaction rate. A random frequency is calculated between
constFrq-devFreq
andconstFrq+devFreq
for the next transaction. The value is set to default value, 0, if this value is not set in the user input json file. All transactions are sent at constant rate if this number is set to 0.
-
poissonOpt: the transactions are sent according to a Poisson distribution. This parameter is valid only if the transMode is set to Poisson.
- lambda: average transaction rate in an interval, in seconds. This can be an integer or a fraction.
-
listOpt: targetPeers list of the peers that the transactions are sent. These parameters are valid only when the targetPeers is set to List. Each line includes two parameters: org name and peer array within the org, for example:
"listOpt": { "org1": ["peer1","peer2"], "org3": ["peer1"], "org6": ["peer3"] }
-
discoveryOpt: service discovery option. The option is valid only when targetPeer is set to
Discovery
.- localHost: set to
true
when fabric is running in containers and executing PTE from not in a container, else set tofalse
. For CI automation tests or other tests on single host using docker, when sending invokes or queries, setlocalHost=true
and settargetPeers=discovery
. Default value is false. - collection: an array of collection names for the discovery service to calculate the plan layout for invokes. This should match the name that is specified in the private-data collection file during the instantiation. If this attribute is missing, then only chaincode is used for plan layout calculation. This is useful for sending private-data queries or invokes to only the peers included in a private-data collection; without it, for example, a service-discovery query for private-data might be sent by SDK to a peer that is not in the collection but is still in the channel, and thus the query would fail. (This field is irrelevant for orderers.)
- initFreq: service discovery re-initialization frequency in ms. PTE will not re-initialize service discovery if this parameter is set to 0. Default: 0.
- localHost: set to
-
eventOpt: event options
- type: event service type, default: FilteredBlock
- FilteredBlock: efficient option, delivers filtered events per channel for each block or transaction
- Channel: basic option, delivers full events per channel for each block or transaction
- timeout: event timeout, unit ms, default: 120000 ms
- type: event service type, default: FilteredBlock
-
failoverOpt: peer failover options
- method: peer failover selection method, default is
RoundRobin
- random: a peer is selected randomly from the list for failover
- RoundRobin: the peer listed next to the current peer is selected for failover
- list: peer failover candidate list, default is
targetPeers
- targetPeers: the peer candidate list is the same as the peers specified in the
targetPeers
- all: the peer candidate list is made of all peers listed in the associated service confidential file
- targetPeers: the peer candidate list is the same as the peers specified in the
- method: peer failover selection method, default is
-
invokeCheckOpt: invokeCheck configuration, valid only if invokeCheck is
TRUE
. Note that the validation queries results are written in the PTE log which may take a large amount of space with large requested validation queries.- peers: The peers that the validation queries to be sent. Available options are the same as those of
targetPeers
listed above. Default: same astargetPeers
. - transactions: The transactions for invokes validation. Default: LAST.
- ALL: all transactions.
- LAST: last
txNum
transactions.
- txNum: last txNum transactions to be validated. Valid only if transactions is
LAST
. Defailt: 1.
- peers: The peers that the validation queries to be sent. Available options are the same as those of
-
ordererOpt: transaction orderer options
- method: orderer selection method, default:
UserDefined
. Note a Service Credentials File must contain exact orderers to be used for a channel.- UserDefined: the orderer defined in the
ordererID
in the Service Credentials File for each org is used for invoke transactions. Note this is the same orderer used for all admin transactions. - RoundRobin: an orderer from the orderer section of Service Credentials File is assigned to each thread in the round robin fashion
- UserDefined: the orderer defined in the
- nOrderers: the number of orderers to participate in the transactions, if this number is greater than the number of orderers listed in the service credential json, then all orderers will participate in the transactions. If this number is set to 0, then all orderers participate in the transactions. Default: 0.
- method: orderer selection method, default:
-
timeoutOpt: timeout configuration
- preConfig: The timeout for channel creation and join and chaincode installation and instantiation. Unit: ms. Default:200,000.
- request: The timeout for proposal and transaction. Unit: ms. Default:45,000.
- grpcTimeout: The timeout for grpc that to be used for any transactions using grpc connection. Unit: ms. Default:3,000.
-
ccType: chaincode type
- ccchecker: The first argument (key) in the query and invoke request is incremented by 1 for every transaction. The prefix of the key is made of process ID, ex, all keys issued from process 4 will have prefix of key3_. And, the second argument (payload) in an invoke (Move) is a random string of size ranging between payLoadMin and payLoadMax defined in ccOpt.
- general: The arguments from user input file will be modified for each transaction according to the parameters keyPayLoadType, keyPayLoadMin, and keyPayLoadMax.
-
ccOpt: chaincode options, see
ccOpt
andinvoke.query
andinvoke.move
inmarblesccInputs/marblescc-chan1-constant-i-TLS.json
as an example on how to keyIdx and keyPayLoad below.- keyIdx: a list of indexes of transaction argument used as keys
- keyPayLoad: a list of indexes of transaction argument used as payload
- keyPayLoadType: a list of payload type for each entry of the arguments given in keyPayLoad, corresponding to each entry of keyPayLoad, used with ccType general
- Fixed: a fixed string with a random length between keyPayLoadMin and kayPayLoadMax
- Random: a random string with a random length between kayPayLoadMin and kayPayLoadMax
- FixedInt: a fixed random integer between kayPayLoadMin and kayPayLoadMax
- RandomInt: a random integer between kayPayLoadMin and kayPayLoadMax
- keyPayLoadMin: a list of minimum size in bytes or integer of the payload, corresponding to each entry of keyPayLoad defined above, used with ccType general
- keyPayLoadMax: a list of maximum size in bytes or integer of the payload, corresponding to each entry of keyPayLoad defined above, used with ccType general
- keyStart: the starting transaction key index, this is used when the ccType is non general which requires a unique key for each invoke.
- payLoadType: payload type of the transactions that ccType is not general
- Fixed: fixed payload with the size of payLoadMin for every trandsaction
- Random: random payload with a random size between payLoadMin and payLoadMax for every transaction
- payLoadMin: minimum size in bytes of the payload
- payLoadMax: maximum size in bytes of the payload
-
deploy: deploy transaction contents
- chaincodePath: this path is relative to
gopath/src
if thegopath
is defined in the service credential json. Otherwise, absolute path is required. - language: the chaincode language including:
- golang: golang chaincode, this is the default language
- node: Node JS chaincode
- java: java chaincode
- chaincodePath: this path is relative to
-
invoke invoke transaction contents
- query: query content
- move: move content
-
ConnProfilePath: path to the connection profiles, all connection profiles listed in this directory will be used by PTE. supported file type: json and yaml, see PTE/ConnProfiles/test-network/config.yaml for example
PTE can be extended to support transaction generation according to a particular statistical distribution, or even a custom schedule. Two distributions have currently been implemented:
- Uniform Distribution: see
transMode
Constant - Poisson Distribution: see
transMode
Poisson
To generate and configure transaction events according to a different distribution, you need to update pte-execRequest.js
as follows:
-
Define a new
transMode
(e.g., Poisson for a Poisson distribution) -
Define a JSON structure for parameters (e.g.,
poissonOpt
for Poisson; see previous section) -
Add code to the function
execTransMode()
to handle this new distribution (example for Poisson below):} else if (transMode == 'POISSON') { distOpt = txCfgPtr.poissonOpt; execModePoisson(); } ...
-
Create a function to call
execModeDistribution(backoffCalculator, delayCalculator)
with the right parameter values (e.g.,execModePoisson
for Poisson below):function execModePoisson() { execModeDistribution(backoffCalculatorPoisson); }
-
Create a function to dynamically calculate the backoff (in milliseconds) to the next transaction. The parameter
backoffCalculator
above represents the handle to this function. (e.g.,backoffCalculatorPoisson()
for Poisson as below):function backoffCalculatorPoisson() { var lambda = parseFloat(txCfgPtr.poissonOpt.lambda); return -1000 * Math.log(1 - Math.random()) / lambda; }
-
Optionally, create a separate function to support secondary deviations from the main event distribution. The Constant (or uniform) distribution supports this using the
devFreq
parameter.-
Example: for Constant distribution, we have two functions,
backoffCalculatorConstantFreq()
to compute uniform-value backoffs, andbackoffCalculatorConstant()
to compute uniform-value backoffs with small random deviations in every iteration. -
Here, the parameters supplied to
execModeDistribution
are as follows:execModeDistribution(backoffCalculatorConstant, backoffCalculatorConstantFreq);
In the function
execModeDistribution
, thebackoffCalculator
parameter represents the backoff calculator with secondary deviations, whereas thedelayCalculator
parameter represents the backoff calculator according to the base statistical distribution.
-
For example input files to run Poisson-based traffic, see:
sampleccInputs/runCases-poisson-i1-TLS.txt
sampleccInputs/runCases-poisson-q1-TLS.txt
sampleccInputs/samplecc-chan1-poisson-i-TLS.json
sampleccInputs/samplecc-chan1-poisson-q-TLS.json
sampleccInputs/txCfgOpt-poisson.json
The connection profile contains the information of the network and are stored in subdirectories of PTE/ConnProfiles
. The following is a sample of the connection profile yaml file:
---
version: 1.0
name: My network
description: Connection Profile for a Blockchain Network
gopath: GOPATH
# client
client:
organization: org1
connection:
timeout:
peer:
endorser: 300
eventHub: 600
eventReg: 300
orderer: 300
# channels
channels:
testorgschannel1:
orderers:
orderer0
orderer1
orderer2
peers:
peer0org1examplecom:
peer1org1examplecom:
peer0org2examplecom:
peer1org2examplecom:
chaincodes: []
# organizations
organizations:
org1:
name: PeerOrg1
mspid: PeerOrg1
peers:
- peer0org1examplecom
- peer1org1examplecom
certificateAuthorities:
- ca0
adminPrivateKey:
path: src/github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/peerOrganizations/org1.example.com/users/[email protected]/msp
signedCert:
path: src/github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/peerOrganizations/org1.example.com/users/[email protected]/msp
ordererID: orderer0
# orderers
orderers:
orderer0:
mspid: OrdererOrg
url: grpcs://localhost:5005
grpcOptions:
ssl-target-name-override: orderer0.example.com
tlsCACerts:
path: src/github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
adminPath: src/github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/ordererOrganizations/example.com/users/[email protected]/msp
# peers
peers:
peer0org1examplecom:
url: grpcs://localhost:7061
grpcOptions:
ssl-target-name-override: peer0.org1.example.com
tlsCACerts:
path: src/github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem
peer1org1examplecom:
url: grpcs://localhost:7062
grpcOptions:
ssl-target-name-override: peer1.org1.example.com
tlsCACerts:
path: src/github.com/hyperledger/fabric-test/fabric/internal/cryptogen/crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem
# certificateAuthorities
certificateAuthorities:
ca0:
url: https://localhost:7054
caName: ca0
tlsCACerts:
path: ../../fabric/internal/cryptogen/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem
httpOptions:
verify: false
registrar:
enrollId: admin
enrollSecret: adminpw
Note that
-
Key gopath is the GOPATH used by PTE. Set to
GOPATH
to use the environment variableGOPATH
. -
Key ordererID is the orderer that the org will communicate. This orderer will be used for transactions only if the ordererOpt method is UserDefined, see ordererOpt in the User Input file for detail usage. If this key is absent, then the first orderer in the orderer group is used.
-
User can opt to use the same
tls_cert
for all orderers and peers by settingtls_cert
at the same level as the orderer. If thetls_cert
is set, then the file defined intls_cacerts
is ignored. This can simplify the setting of tls_cert for a network with large number of peers and orderers. -
User can opt to include
admin_cert
in the json by settingadmin_cert
within each org section. If theadmin_cert
is set, then the files specified inadminPath
are ignored. This allows the certificate to be included in the config json file rather than copy it in multiple locations. -
Keys adminPrivateKey, signedCert, and tls_cacerts for orderer or org can be either the path to the key by using subkey
path
or the pem content of the key by using subkeypem
:- path:
<path>
- pem:
-----BEGIN PRIVATE KEY----- <etc>
- path:
Prerequisite: If you do not yet have the Fabric docker images in your local docker registry, please either build them from Fabric source or download them from dockerhub.
Create a local netork using the NetworkLauncher tool:
- cd $GOPATH/src/github.com/hyperledger/
- git clone https://github.com/hyperledger/fabric-test
- cd tools/NL
- ./networkLauncher.sh -?
A set of predefined tests are designed for CI daily or weekly execution and are available in the directory, CITest, under PTE.
This feature allows user to execute PTE (PTE manager and/or driver) to send transactions from remote hosts to Blockchain networks, see diagram below.
In order to execute PTE remotely, the PTE controller host will need to have access to the remote PTE hosts. In the setup below, ssh auto login without password is illustrated. However, users should choose any preferred remote access method between PTE controller host and remote PTE hosts for their environment.
-
./pte_ctlr.sh <PTE controller file>
-
Example
./pte_ctlr.sh ctlrInputs/PTECtlr.txt
ctlrInputs/PTECtlr.txt
contains the list of testcases to be executed on the remote hosts. Each line is a PTE controller case and inlcude three parameters: driver type, user/host, and a script. The available driver type isctlr
only.For instance, this sample PTE controller file conatins two control testcases:
driver=ctlr [email protected] ctlrInputs/remotePTEhost-samplecc-q.sh driver=ctlr [email protected] ctlrInputs/remotePTEhost-samplecc-i.sh
-
-
- On the local host where the PTE controller resides
- setup ssh auto login to remote systems without password. Note that users may choose a preferred method for remote access.
- a PTECtlr.txt file containing the controller testcases, e.g.,
PTE/ctlrInputs/PTECtlr.txt
- all controller testcases files, e.g.,
PTE/ctlrInputs/pteHost11-samplecc-q.sh
- On the remote host where the PTE manager/driver resides
- setup PTE
- contains crypto keys of the Blockchain network
- a script to execute PTE, e.g.,
PTE/CITest/scripts/test_driver_remote.sh
, Users can create scripts for their testcases.
- Blockchain network
- can be a single host or multi hosts network
- On the local host where the PTE controller resides
-
Note that ssh is just one method for the PTE controller host to access remote PTE. Users should choose a method suitable for their environment.
- On PTE controller host (assuming the remote access is [email protected]):
-
ssh-keygen -t rsa
(You can just hit return for each question.) -
ssh [email protected] mkdir -p .ssh
[email protected]'s password:
-
cat .ssh/id_rsa.pub | ssh [email protected] 'cat >> .ssh/authorized_keys'
[email protected]'s password:
-
- On PTE controller host (assuming the remote access is [email protected]):
This work is licensed under a Creative Commons Attribution 4.0 International License.