forked from hyperledger/fabric-chaincode-node
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch adds new e2e test for the chaincode gRPC server feature. The test performs as following: - Create a package which contains server and cc information - Build a container image of the chaincode - Install the package into peers - Obtain the installed package ID from the peers - Start the chaincode container with the package ID - Approve and commit the chaincode definition - Invoke and query the chaincode Signed-off-by: Taku Shimosawa <taku.shimosawa@hal.hitachi.com>
- Loading branch information
Showing
12 changed files
with
316 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
FROM hyperledger/fabric-ccenv:latest | ||
|
||
ADD . /opt/chaincode | ||
RUN cd /opt/chaincode; npm install | ||
|
||
WORKDIR /opt/chaincode | ||
ENTRYPOINT ["npm", "start"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
# Copyright Hitachi America, Ltd. All Rights Reserved. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
"use strict"; | ||
|
||
const shim = require('fabric-shim'); | ||
|
||
class ServerTest extends shim.ChaincodeInterface { | ||
async Init(stub) { | ||
} | ||
|
||
async Invoke(stub) { | ||
const { fcn, params } = stub.getFunctionAndParameters(); | ||
|
||
const response = { | ||
msg: "OK from ServerTest", | ||
func: fcn.toString(), | ||
params: params.map((p) => p.toString()) | ||
}; | ||
|
||
return shim.success(Buffer.from(JSON.stringify(response))); | ||
} | ||
} | ||
|
||
const server = shim.server(new ServerTest(), { | ||
ccid: process.env.CHAINCODE_ID, | ||
address: process.env.CHAINCODE_SERVER_ADDRESS | ||
}); | ||
|
||
server.start(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"name": "chaincode", | ||
"description": "Chaincode server", | ||
"engines": { | ||
"node": "^12.13.0", | ||
"npm": ">=5.3.0" | ||
}, | ||
"scripts": { | ||
"start": "node index.js" | ||
}, | ||
"main": "index.js", | ||
"engine-strict": true, | ||
"engineStrict": true, | ||
"version": "1.0.0", | ||
"author": "", | ||
"license": "Apache-2.0", | ||
"dependencies": { | ||
"fabric-shim": "3.0.0-unstable", | ||
"fabric-contract-api": "3.0.0-unstable" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"address": "cc-server:9999", | ||
"dial_timeout": "10s", | ||
"tls_requred": false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"path": "", | ||
"type": "external", | ||
"label": "server_v0" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
/* | ||
# Copyright Hitachi America, Ltd. All Rights Reserved. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
'use strict'; | ||
|
||
const {series} = require('gulp'); | ||
|
||
const util = require('util'); | ||
const path = require('path'); | ||
|
||
const { shell: runcmds , getTLSArgs, getPeerAddresses } = require('toolchain'); | ||
const ip = require('ip'); | ||
|
||
const CHANNEL_NAME = 'mychannel'; | ||
|
||
const chaincodeDir = path.join(__dirname, '..', '..', 'test', 'chaincodes', 'server'); | ||
|
||
async function packageChaincode() { | ||
await runcmds([ | ||
util.format( | ||
'tar -C %s/package -cvzf %s/package/code.tar.gz connection.json', | ||
chaincodeDir, chaincodeDir | ||
), | ||
util.format( | ||
'tar -C %s/package -cvzf %s/package/chaincode.tar.gz code.tar.gz metadata.json', | ||
chaincodeDir, chaincodeDir | ||
), | ||
]); | ||
} | ||
|
||
async function buildChaincode() { | ||
const npmrc = path.join(chaincodeDir, '.npmrc'); | ||
|
||
await runcmds([ | ||
`echo "registry=http://${ip.address()}:4873" > ${npmrc}`, | ||
util.format( | ||
'docker build --no-cache -t chaincode-e2e-server %s', | ||
chaincodeDir | ||
), | ||
`rm -f ${npmrc}` | ||
]); | ||
} | ||
|
||
async function installChaincode() { | ||
const peerInstall = 'peer lifecycle chaincode install /opt/gopath/src/github.com/chaincode/server/package/chaincode.tar.gz'; | ||
|
||
await runcmds([ | ||
util.format( | ||
'docker exec %s %s', | ||
'org1_cli', | ||
peerInstall | ||
), | ||
util.format( | ||
'docker exec %s %s', | ||
'org2_cli', | ||
peerInstall | ||
) | ||
]); | ||
}; | ||
|
||
function findPackageId(queryOutput, label) { | ||
const output = JSON.parse(queryOutput); | ||
|
||
const cc = output.installed_chaincodes.filter((chaincode) => chaincode.label === label); | ||
if (cc.length !== 1) { | ||
throw new Error('Failed to find installed chaincode'); | ||
} | ||
|
||
return cc[0].package_id; | ||
} | ||
|
||
async function instantiateChaincode() { | ||
const endorsementPolicy = '"OR (\'Org1MSP.member\', \'Org2MSP.member\')"'; | ||
const queryInstalled = util.format( | ||
'peer lifecycle chaincode queryinstalled --output json' | ||
); | ||
const sequence = 1; | ||
|
||
const approveChaincode = util.format( | ||
'peer lifecycle chaincode approveformyorg -o %s %s -C %s -n %s -v %s --package-id %s --sequence %d --signature-policy %s', | ||
'orderer.example.com:7050', | ||
getTLSArgs(), | ||
CHANNEL_NAME, | ||
'server', | ||
'v0', | ||
'%s', // To be filled in for each org | ||
sequence, | ||
endorsementPolicy | ||
); | ||
|
||
const outputs = await runcmds([ | ||
util.format( | ||
'docker exec %s %s', | ||
'org1_cli', | ||
queryInstalled | ||
), | ||
util.format( | ||
'docker exec %s %s', | ||
'org2_cli', | ||
queryInstalled | ||
), | ||
]); | ||
|
||
const packageIdOrg1 = findPackageId(outputs[0], 'server_v0'); | ||
const packageIdOrg2 = findPackageId(outputs[1], 'server_v0'); | ||
|
||
// TODO: Assuming the two package IDs are the same | ||
await runcmds([ | ||
// Start the CC Server container | ||
`docker run -e CHAINCODE_ID=${packageIdOrg1} -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999 -h cc-server --name cc-server -d --network node_default chaincode-e2e-server`, | ||
// Approve the chaincode definition by each org | ||
util.format('docker exec %s %s', | ||
'org1_cli', | ||
util.format(approveChaincode, packageIdOrg1) | ||
), | ||
util.format('docker exec %s %s', | ||
'org2_cli', | ||
util.format(approveChaincode, packageIdOrg2) | ||
), | ||
// Commit the chaincode definition | ||
util.format('docker exec org1_cli peer lifecycle chaincode commit -o %s %s -C %s -n %s -v %s --sequence %d --signature-policy %s %s', | ||
'orderer.example.com:7050', | ||
getTLSArgs(), | ||
CHANNEL_NAME, | ||
'server', | ||
'v0', | ||
sequence, | ||
endorsementPolicy, | ||
getPeerAddresses() | ||
) | ||
]); | ||
} | ||
|
||
const invokeFunctions = async () => { | ||
const args = util.format('docker exec org1_cli peer chaincode invoke %s -C %s -n %s -c %s --waitForEvent', | ||
getTLSArgs(), | ||
CHANNEL_NAME, | ||
'server', | ||
'\'{"Args":["anyFunction","\'42\'"]}\''); | ||
|
||
await runcmds([args]); | ||
}; | ||
|
||
const queryFunctions = async () => { | ||
const args = util.format('docker exec org1_cli peer chaincode query %s -C %s -n %s -c %s', | ||
getTLSArgs(), | ||
CHANNEL_NAME, | ||
'server', | ||
'\'{"Args":["someFunction", "life", "universe", "everything"]}\''); | ||
|
||
const ret = await runcmds([args]); | ||
|
||
const response = JSON.parse(ret[0]); | ||
|
||
if (response.func !== 'someFunction' || response.params.length !== 3 || response.params[1] !== 'universe') { | ||
throw new Error("Unexpected result from chaincode"); | ||
} | ||
} | ||
|
||
exports.default = series( | ||
packageChaincode, buildChaincode, installChaincode, instantiateChaincode, | ||
invokeFunctions, queryFunctions | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#!/bin/sh | ||
# | ||
# Copyright Hitachi America, Ltd. All Rights Reserved. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
set -e | ||
|
||
SOURCE="$1" | ||
OUTPUT="$3" | ||
|
||
if [ ! -f "${SOURCE}/connection.json" ]; then | ||
echo "Error: ${SOURCE}/connection.json not found" 1>&2 | ||
exit 1 | ||
fi | ||
|
||
cp "${SOURCE}/connection.json" "${OUTPUT}/connection.json" | ||
|
||
if [ -d "${SOURCE}/metadata" ]; then | ||
cp -a ${SOURCE}/metadata ${OUTPUT}/metadata | ||
fi | ||
|
||
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#!/bin/sh | ||
# | ||
# Copyright Hitachi America, Ltd. All Rights Reserved. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
set -e | ||
|
||
METADIR="$2" | ||
|
||
if [ `jq -r .type "${METADIR}/metadata.json"` = "external" ]; then | ||
exit 0 | ||
fi | ||
|
||
exit 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#!/bin/sh | ||
# | ||
# Copyright Hitachi America, Ltd. All Rights Reserved. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
set -e | ||
|
||
BUILD="$1" | ||
RELEASE="$2" | ||
|
||
if [ -d "${BUILD}/metadata" ]; then | ||
cp -a "${BUILD}/metadata/*" "${RELEASE}/" | ||
fi | ||
|
||
if [ -f "${BUILD}/connection.json" ]; then | ||
mkdir -p "${RELEASE}/chaincode/server" | ||
cp "${BUILD}/connection.json" "${RELEASE}/chaincode/server" | ||
|
||
# TODO: TLS | ||
|
||
exit 0 | ||
fi |