From 55c3eaf7fae4a4b44d549f26674b8a3704a18ac4 Mon Sep 17 00:00:00 2001 From: rennman Date: Wed, 28 Sep 2016 08:27:28 -0400 Subject: [PATCH] Updated Unit test script Change-Id: I0a4519a072a7b36dc9b5282943c1421c3367eea7 Signed-off-by: rennman --- sdk/node/bin/run-unit-tests.sh | 685 ++++++++++++++++++++++++++------- 1 file changed, 537 insertions(+), 148 deletions(-) diff --git a/sdk/node/bin/run-unit-tests.sh b/sdk/node/bin/run-unit-tests.sh index 9e6f332903c..5fba3c0cce2 100755 --- a/sdk/node/bin/run-unit-tests.sh +++ b/sdk/node/bin/run-unit-tests.sh @@ -1,93 +1,314 @@ +#!/bin/bash # +# run-unit-tests.sh # Run the unit tests associated with the node.js client sdk +# Any arguments supplied to this script will be interpreted +# as a *js test file existing in # +# ${GOPATH}//src/github.com/hyperledger/fabric/sdk/node/test/unit +# +# By default all tests are run. Note that run-unit-tests.sh will +# only run tests that it knows about, since there are unique +# environmental prerequisites to many of the tests (including copying +# the fabric code into the chaincode directory). The 'case' statement +# in runTests() will need to be updated with the specific actions +# to perform for any new test that is added to the test/unit directory. +# +# The tests can be run against a local fabric network, or remote (such +# as Bluemix, HSBN, vLaunch, softLayer, etc.). +# +# The test will run 4 permutations of each test: +# TLS-disabled - deployMode=Net +# TLS-disabled - deployMode=Dev +# TLS-enabled - deployMode=Net +# TLS-enabled - deployMode=Dev +# While both 'dev' and 'net' mode are exercised, only +# 'net' mode will be executed when the network nodes +# are remote w/r/t to the host running the tests. +# +# There are six conditions that are fatal and will +# cause the tests to abort: +# Local: +# membersrvc build fails +# membersrvc fails to initialize +# peer build fails +# peer fails to initialize +# Remote: +# membersrvc is unreachable +# peer is unreachable +# +# The following environment variables will determine the +# network resources to be tested +# SDK_KEYSTORE - local directory under which user +# authentication data is stored +# SDK_CA_CERT_FILE - CA certificate used to authenticate +# network nodes +# SDK_CA_CERT_HOST - Expected host identity in server certificate +# Default is 'tlsca' +# SDK_MEMBERSRVC_ADDRESS - ip address or hostname of membersrvc +# SDK_PEER_ADDRESS - ip address or hostname of peer node under test; +# it is assumed that only one peer will contacted +# SDK_TLS - Set to '1' (use TLS) or '0' (do not use TLS) +# Note that if TLS is requested, a CA cert must be used. +# The default certificate generated by membersrvc is the default: +# /var/hyperledger/production/.membersrvc/tlsca.cert +# The run-unit-tests.sh script will run all unit tests +# twice, one without TLS and one with TLS enabled +# +# Other environment variables that will be referenced by individual tests +# SDK_DEPLOYWAIT - time (in seconds) to wait after sending deploy request +# SDK_INVOKEWAIT - time (in seconds) to wait after sending invoke request +# GRPC_SSL_CIPHER_SUITES - quoted, colon-delimited list of specific cipher suites +# that node.js client sdk should propose. +# The default list is set in sdk/node/lib/hfc.js +# SDK_DEFAULT_USER - User defined with 'registrar' authority. Default is 'WebAppAdmin' +# SDK_DEFAULT_SECRET - Password for SDK_DEFAULT_USER. Defaults to 'DJY27pEnl16d' +# When running a local network, these are configured in the +# membersrvc.yaml file. In the IBM Bluemix starter and HSBN +# networks, this password is generated dynamically and returned +# in the network credentials file. +# SDK_KEYSTORE_PERSIST - Set to '0' will delete all previously generated auth +# enrollment data prior to running the tests +# Set to '1' keep the auth data from previous enrollments +# SDK_CHAINCODE_PATH - the directory (relative to ${GOPATH}/src/) which contains +# the chaincode (and CA cert) to be deployed +# SDK_CHAINCODE_ID - the chaincode ID from a previous deployment. e.g. can be used +# to invoke/query previously-deployed chaincode +# +export NODE_PATH=${GOPATH}/src/github.com/hyperledger/fabric/sdk/node:${GOPATH}/src/github.com/hyperledger/fabric/sdk/node/lib:/usr/local/lib/node_modules:/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript +#export NODE_PATH=${GOPATH}/src/github.com/hyperledger/fabric/sdk/node:/usr/local/lib/node_modules:/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript -# Variable to store error results -NODE_ERR_CODE=0 - -main() { - # Initialization - init - - # Start member services - startMemberServices +errorExit() { + printf "%s...exiting\n" "$1" + exit 1 +} - # Run tests in network mode - export DEPLOY_MODE='net' - runTests +resolvHost() { + # simple 'host' or 'nslookup' doesn't work for + # /etc/host entries...attempt to resolve via ping + local host="$1" + ping -w2 -c1 "$host" | head -n1 | awk -F'[()]' '{print $2}' +} - # Run tests in dev mode - export DEPLOY_MODE='dev' - runTests +isLocal() { + # determine if the ca/peer instance in question + # is running native/vagrant on this local machine, + # or on a remote network. echo 'true' or 'false' + # This permits constructions like + # $(isLocal ) + # to return 0 (true) or 1 (false) + + local addr="$1" + local port="$2" + + # assume remote + local result="false" + + # if localhost, return true + if test ${addr%%.*} = "127"; then + result="true" + else + # search this machine for address + ip addr list | + awk -v s="$addr" -v rc=1 ' + $1=="inet" { gsub(/\/.*/,"",$2); if ($2==s) rc=0 } + END { exit rc }' + if test $? -eq 0; then + # address is local but still peer might be running in container + # if docker-proxy is not running this instance, return true + sudo netstat -tlpn | grep "$port" | + awk -F '/' '{print $NF}'| grep -q proxy + test $? = 0 || result="true" + fi + fi + echo "$result" + return 0 +} - # Stop peer and member services - stopPeer - stopMemberServices +isReachable() { + # a test to see if there is a listener on + # specified host:port + # netcat would be *far* simpler: + # nc -nzvt host port + # but not guaranteed to be installed + # so use python, since it is ubiquitious + local host="$1" + local port="$2" + test -z "$host" -o -z "$port" && return 1 + + python - < /dev/null + cp -r $FABRIC . + cp -r fabric/vendor/github.com/op .. + cd ../../.. + + echo "Building chaincode..." + go build + rc+=$? + fi + + return $rc } # $1 is the name of the sample to start startExampleInDevMode() { - SRCDIR=$EXAMPLES/$1 - if [ ! -d $SRCDIR ]; then - echo "FATAL ERROR: directory does not exist: $SRCDIR" - NODE_ERR_CODE=1 - exit 1; - fi - EXE=$SRCDIR/$1 - cd $SRCDIR - go build + local chaincodeSrc="$1" + local rc=0 export CORE_CHAINCODE_ID_NAME=$2 - export CORE_PEER_ADDRESS=0.0.0.0:7051 - startProcess "$EXE" "${EXE}.log" "$1" + export CORE_PEER_ADDRESS=localhost:7051 + + SRCDIR=${EXAMPLES}/${chaincodeSrc} + + if test ! -d $SRC_DIR; then + echo "ERROR: directory does not exist: $SRCDIR" + rc=1 + else + EXE=${SRCDIR}/${chaincodeSrc} + if test ! -f $EXE; then + cd $SRCDIR + go build + rc=$? + fi + + test "$rc" = 0 && startProcess "$EXE" "${EXE}.log" "$chaincodeSrc" + let rc+=$? + fi + + return $rc } -# $1 is the name of the sample to start +# $1 is the name of the sample to stop stopExampleInDevMode() { + echo "killing $1" killProcess $1 } runRegistrarTests() { + local rc=0 echo "BEGIN running registrar tests ..." node $UNITTEST/registrar.js - if [ $? -ne 0 ]; then - echo "ERROR running registrar tests!" - NODE_ERR_CODE=1 - fi + rc=$? echo "END running registrar tests" + return $rc +} + +runMemberApi() { + local rc=0 + echo "BEGIN running member-api tests ..." + node $UNITTEST/member-api.js + rc=$? + echo "END running member-api tests" + return $rc } runChainTests() { + local rc=0 echo "BEGIN running chain-tests ..." preExample chaincode_example02 mycc1 - node $UNITTEST/chain-tests.js - if [ $? -ne 0 ]; then - echo "ERROR running chain-tests!" - NODE_ERR_CODE=1 + if test $? -eq 0; then + node $UNITTEST/chain-tests.js + rc=$? + postExample chaincode_example02 + else + echo "setup failed" + let rc+=1 fi - postExample chaincode_example02 echo "END running chain-tests" + return $rc } runAssetMgmtTests() { + local rc=0 echo "BEGIN running asset-mgmt tests ..." preExample asset_management mycc2 - node $UNITTEST/asset-mgmt.js - if [ $? -ne 0 ]; then - echo "ERROR running asset-mgmt tests!" - NODE_ERR_CODE=1 + if test $? -eq 0; then + node $UNITTEST/asset-mgmt.js + rc=$? + postExample asset_management + else + echo "setup failed" + let rc+=1 fi - postExample asset_management echo "END running asset-mgmt tests" + return $rc } runAssetMgmtWithRolesTests() { + local rc=0 echo "BEGIN running asset management with roles tests ..." preExample asset_management_with_roles mycc3 - node $UNITTEST/asset-mgmt-with-roles.js - if [ $? -ne 0 ]; then - echo "ERROR running asset management with roles tests!" - NODE_ERR_CODE=1 + if test $? -eq 0; then + node $UNITTEST/asset-mgmt-with-roles.js + rc=$? + postExample asset_management_with_roles + else + echo "setup failed" + let rc+=1 fi - postExample asset_management_with_roles echo "END running asset management with roles tests" + return $rc } runAssetMgmtWithDynamicRolesTests() { + local rc=0 echo "BEGIN running asset management with dynamic roles tests ..." preExample asset_management_with_roles mycc4 - node $UNITTEST/asset-mgmt-with-dynamic-roles.js - if [ $? -ne 0 ]; then - echo "ERROR running asset management with dynamic roles tests!" - NODE_ERR_CODE=1 + if test $? -eq 0; then + node $UNITTEST/asset-mgmt-with-dynamic-roles.js + rc=$? + echo "RC:" $rc + postExample asset_management_with_roles + else + echo "setup failed" + let rc+=1 fi - postExample asset_management_with_roles echo "END running asset management with dynamic roles tests" + return $rc } - -runEventTests() { - echo "BEGIN running event-tests ..." - preExample eventsender mycc5 - node $UNITTEST/event-tests.js - if [ $? -ne 0 ]; then - echo "ERROR running event-tests!" - NODE_ERR_CODE=1 - fi - postExample eventsender - echo "END running event-tests" -} - # start process # $1 is executable path with any args # $2 is the log file # $3 is string description of the process startProcess() { - $1 > $2 2>&1& + local cmd="$1" + local log="$2" + local proc="$3" + + $cmd >> $log 2>&1& PID=$! sleep 2 kill -0 $PID > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "$3 is started" + if test $? -eq 0; then + echo "$proc is started" else - echo "ERROR: $3 failed to start; see $2" - NODE_ERR_CODE=1 - exit 1 + echo "ERROR: $proc failed to start; see $log" + return 1 fi } # kill a process # $1 is the executable name killProcess() { - PID=`ps -ef | grep "$1" | grep -v "grep" | awk '{print $2}'` - if [ "$PID" != "" ]; then - echo "killing PID $PID running $1 ..." + local proc="$1" + PID=$(ps -ef | awk -v s="$proc" '$0~s && $8!="awk" {print $2}') + if test -n "$PID"; then + echo "killing PID $PID running $proc ..." kill -9 $PID fi } -main +# Run tests +runTests() { + local TestsToBeRun="$1" + local rc=0 -if [ "$NODE_ERR_CODE" != "0" ]; then - echo "ERROR: Error executing run-unit-tests.sh. Exiting with status code '1'." - exit 1 -fi + echo "Begin running tests in $SDK_DEPLOY_MODE mode ..." + # restart peer + if $($peerAddrIsLocal); then + stopPeer + startPeer || errorExit "Start peer failed." + fi + + for Test in $TestsToBeRun; do + # echo "HIT TO RUN NEXT TEST...." + # read x + case "${Test##*/}" in + "registrar.js") runRegistrarTests ;; + "chain-tests.js") runChainTests ;; + "asset-mgmt.js") runAssetMgmtTests ;; + "member-api.js") runMemberApi ;; +"asset-mgmt-with-dynamic-roles.js") if test "$SDK_TLS" = 0; then + runAssetMgmtWithDynamicRolesTests + else + echo "FAB-392; SKIPPING AssetMgmtWithDynamicRolesTests" + fi ;; + # bug...FAB-392 - ACA combined with TLS fails - re-enable this for all tests when closed + "asset-mgmt-with-roles.js") if test "$SDK_TLS" = 0; then + runAssetMgmtWithRolesTests + else + echo "FAB-392; SKIPPING AssetMgmtWithRolesTests" + fi ;; + *) echo "NO case statement for ${Test##*/}, skipping..." ;; + esac + if test $? -ne 0; then + echo "******* ${Test##*/} failed! *******" + let NODE_ERR_CODE=$((NODE_ERR_CODE+1)) + fi + echo "**************************************************************" + echo "" + echo "" + done + + echo "End running tests in $SDK_DEPLOY_MODE mode" + sleep 5 +} + +main() { + # Initialization + echo "Initilizing environment..." + init + { + printf "%s -----> Beginning nodejs SDK UT tests...\n" "$(date)" + for t in ${TEST_SUITE[*]}; do + echo ${t##*/} | sed 's/^/ /' + done + + # Start member services + for tlsEnabled in 0 1; do + export SDK_TLS=$tlsEnabled + test "$SDK_TLS" = 0 && echo "Running NON-TLS-enabled tests..." || echo "Running TLS-enabled tests..." + + if test "$SDK_TLS" = "1"; then + : ${SDK_CA_CERT_FILE:="/var/hyperledger/production/.membersrvc/tlsca.cert"} + : ${SDK_CA_KEY_FILE:="/var/hyperledger/production/.membersrvc/tlsca.priv"} + export SDK_CA_CERT_FILE + else + export MEMBERSRVC_CA_ACA_ENABLED=true + fi + + $($caAddrIsLocal) && startMemberServices + test $? -eq 0 || errorExit "Failed to start membersrvc" + + # Run tests in network mode + SDK_DEPLOYWAIT=40 + SDK_INVOKEWAIT=15 + export SDK_DEPLOY_MODE='net' + runTests "$TEST_SUITE" + + # Run tests in dev mode + SDK_DEPLOYWAIT=10 + SDK_INVOKEWAIT=5 + if $($peerAddrIsLocal); then + export SDK_DEPLOY_MODE='dev' + runTests "$TEST_SUITE" + fi + + # Stop peer and member services + $($peerAddrIsLocal) && stopPeer + $($caAddrIsLocal) && stopMemberServices + + # do not delete the authentication data if this is set + test "$SDK_KEYSTORE_PERSIST" != "1" && + rm -rf /var/hyperledger/production /tmp/*keyValStore* + + done + printf "\n%s\n" "${NODE_ERR_CODE}" + } 2>&1 | tee $LOGDIR/log +} + +TEST_SUITE="$@" +main +NODE_ERR_CODE=$(sed -n '$p' $LOGDIR/log | awk '{print $NF}') +echo "exit code: $NODE_ERR_CODE" +printf "%s " $(date) +test "$NODE_ERR_CODE" -eq 0 && echo "UT tests PASSED" || echo "UT tests FAILED" +exit $NODE_ERR_CODE