Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FAB-7649] refactor unit test script
Change-Id: Id179b886d958bac8338bc2ef2fc7bdcc6c4759af Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
- Loading branch information
Showing
1 changed file
with
113 additions
and
88 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 |
---|---|---|
@@ -1,98 +1,123 @@ | ||
#!/bin/bash | ||
#!/bin/bash -e | ||
# | ||
# Copyright IBM Corp. All Rights Reserved. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
|
||
# regexes for packages to exclude from unit test | ||
excluded_packages=( | ||
"github.com/hyperledger/fabric/bccsp/factory" # this package's tests need to be mocked | ||
"github.com/hyperledger/fabric/bccsp/mocks" | ||
"github.com/hyperledger/fabric/bddtests" | ||
"github.com/hyperledger/fabric/build/" | ||
"github.com/hyperledger/fabric/common/ledger/testutil" | ||
"github.com/hyperledger/fabric/common/mocks" | ||
"github.com/hyperledger/fabric/core/chaincode/platforms/car/test" # until FAB-7629 is resolved | ||
"github.com/hyperledger/fabric/core/deliverservice/mocks" | ||
"github.com/hyperledger/fabric/core/ledger/kvledger/example" | ||
"github.com/hyperledger/fabric/core/ledger/kvledger/marble_example" | ||
"github.com/hyperledger/fabric/core/ledger/testutil" | ||
"github.com/hyperledger/fabric/core/mocks" | ||
"github.com/hyperledger/fabric/core/testutil" | ||
"github.com/hyperledger/fabric/examples" | ||
"github.com/hyperledger/fabric/orderer/mocks" | ||
"github.com/hyperledger/fabric/orderer/sample_clients" | ||
"github.com/hyperledger/fabric/test" | ||
"github.com/hyperledger/fabric/vendor/" | ||
) | ||
|
||
set -e | ||
ARCH=`uname -m` | ||
|
||
#check job type, do patch set specific unit test when job is verify | ||
if [ "$JOB_TYPE" = "VERIFY" ]; then | ||
|
||
cd $GOPATH/src/github.com/hyperledger/fabric/ | ||
|
||
#figure out what packages should be tested for uncommitted changes | ||
# first check for uncommitted changes | ||
TEST_PKGS=$(git diff --name-only HEAD * | grep .go$ | grep -v ^vendor/ \ | ||
| grep -v ^build/ | sed 's%/[^/]*$%/%'| sort -u \ | ||
| awk '{print "github.com/hyperledger/fabric/"$1"..."}') | ||
|
||
if [ -z "$TEST_PKGS" ]; then | ||
# next check for changes in the latest commit - typically this will | ||
# be for CI only, but could also handle a committed change before | ||
# pushing to Gerrit | ||
TEST_PKGS=$(git diff-tree --no-commit-id --name-only -r $(git log -2 \ | ||
--pretty=format:"%h") | grep .go$ | grep -v ^vendor/ | grep -v ^build/ \ | ||
| sed 's%/[^/]*$%/%'| sort -u | \ | ||
awk '{print "github.com/hyperledger/fabric/"$1"..."}') | ||
fi | ||
|
||
#only run the test when test pkgs is not empty | ||
if [[ ! -z "$TEST_PKGS" ]]; then | ||
echo "Testing packages:" | ||
echo $TEST_PKGS | ||
echo " with tags " $GO_TAGS | ||
# use go test -cover as this is much more efficient than gocov | ||
time go test -cover -tags "$GO_TAGS" -ldflags "$GO_LDFLAGS" $TEST_PKGS -short -timeout=20m | ||
else | ||
echo "Nothing changed in unit test!!!" | ||
fi | ||
|
||
else | ||
|
||
#check to see if TEST_PKGS is set else use default (all packages) | ||
TEST_PKGS=${TEST_PKGS:-github.com/hyperledger/fabric/...} | ||
echo -n "Obtaining list of tests to run for the following packages: ${TEST_PKGS}" | ||
|
||
# Some examples and packages don't play nice with `go test` | ||
PKGS=`go list ${TEST_PKGS} 2> /dev/null | \ | ||
grep -v /vendor/ | \ | ||
grep -v /build/ | \ | ||
grep -v /bccsp/mocks | \ | ||
grep -v /bddtests | \ | ||
grep -v /orderer/mocks | \ | ||
grep -v /orderer/sample_clients | \ | ||
grep -v /common/mocks | \ | ||
grep -v /common/ledger/testutil | \ | ||
grep -v /core/mocks | \ | ||
grep -v /core/testutil | \ | ||
grep -v /core/ledger/testutil | \ | ||
grep -v /core/ledger/kvledger/example | \ | ||
grep -v /core/ledger/kvledger/marble_example | \ | ||
grep -v /core/deliverservice/mocks | \ | ||
# this package's tests need to be mocked | ||
grep -v /bccsp/factory | \ | ||
grep -v github.com/hyperledger/fabric/gossip | \ | ||
grep -v /test | \ | ||
grep -v /examples` | ||
|
||
if [ x$ARCH == xppc64le -o x$ARCH == xs390x ]; then | ||
PKGS=`echo $PKGS | sed 's@'github.com/hyperledger/fabric/core/chaincode/platforms/java/test'@@g'` | ||
PKGS=`echo $PKGS | sed 's@'github.com/hyperledger/fabric/core/chaincode/platforms/java'@@g'` | ||
fi | ||
|
||
echo -e "\nDONE!" | ||
echo -e "Running tests with tags ${GO_TAGS} ..." | ||
|
||
if [ "$JOB_TYPE" = "PROFILE" ]; then | ||
# regexes for packages that must be run serially | ||
serial_packages=( | ||
"github.com/hyperledger/fabric/gossip" | ||
) | ||
|
||
# obtain packages changed since some git refspec | ||
packages_diff() { | ||
local ref="${1:-HEAD}" | ||
|
||
git -C "${GOPATH}/src/github.com/hyperledger/fabric" diff --no-commit-id --name-only -r "${1:-HEAD}" | | ||
grep -Ev '.go$|^vendor/|^build/' | \ | ||
sed 's%/[^/]*$%/%' | sort -u | \ | ||
awk '{print "github.com/hyperledger/fabric/"$1"..."}' | ||
} | ||
|
||
# "go list" packages and filter out excluded packages | ||
list_and_filter() { | ||
go list $@ 2>/dev/null | grep -Ev $(local IFS='|' ; echo "${excluded_packages[*]}") || true | ||
} | ||
|
||
# remove packages that must be tested serially | ||
parallel_test_packages() { | ||
echo "$@" | grep -Ev $(local IFS='|' ; echo "${serial_packages[*]}") || true | ||
} | ||
|
||
# get packages that must be tested serially | ||
serial_test_packages() { | ||
echo "$@" | grep -E $(local IFS='|' ; echo "${serial_packages[*]}") || true | ||
} | ||
|
||
# "go test" the provided packages. Packages that are not prsent in the serial package list | ||
# will be tested in parallel | ||
run_tests() { | ||
local parallel=$(parallel_test_packages "$@") | ||
if [ -n "${parallel}" ]; then | ||
time go test -cover -tags "$GO_TAGS" -ldflags "$GO_LDFLAGS" ${parallel[@]} -short -timeout=20m | ||
fi | ||
|
||
local serial=$(serial_test_packages "$@") | ||
if [ -n "${serial}" ]; then | ||
time go test -cover -tags "$GO_TAGS" -ldflags "$GO_LDFLAGS" ${serial[@]} -short -p 1 -timeout=20m | ||
fi | ||
} | ||
|
||
# "go test" the provided packages and generate code coverage reports. Until go 1.10 is released, | ||
# profile reports can only be generated one package at a time. | ||
run_tests_with_coverage() { | ||
# Initialize profile.cov | ||
date | ||
echo "mode: set" > profile.cov | ||
for pkg in $PKGS | ||
do | ||
:> profile_tmp.cov | ||
go test -cover -coverprofile=profile_tmp.cov -tags "$GO_TAGS" -ldflags "$GO_LDFLAGS" $pkg -timeout=20m | ||
tail -n +2 profile_tmp.cov >> profile.cov || echo "Unable to append coverage for $pkg" | ||
for pkg in "$@"; do | ||
:> profile_tmp.cov | ||
go test -cover -coverprofile=profile_tmp.cov -tags "$GO_TAGS" -ldflags "$GO_LDFLAGS" $pkg -timeout=20m | ||
tail -n +2 profile_tmp.cov >> profile.cov || echo "Unable to append coverage for $pkg" | ||
done | ||
#convert to cobertura format | ||
gocov convert profile.cov |gocov-xml > report.xml | ||
date | ||
else | ||
time go test -cover -tags "$GO_TAGS" -ldflags "$GO_LDFLAGS" $PKGS -short -timeout=20m | ||
# gossip packages need to be serialized | ||
time go test -cover -tags "$GO_TAGS" -ldflags "$GO_LDFLAGS" ./gossip/... -short -p 1 -timeout=20m | ||
fi | ||
fi | ||
|
||
# convert to cobertura format | ||
gocov convert profile.cov | gocov-xml > report.xml | ||
} | ||
|
||
main() { | ||
# default behavior is to run all tests | ||
local package_spec=${TEST_PKGS:-github.com/hyperledger/fabric/...} | ||
|
||
# extra exclusions for ppc and s390x | ||
local arch=`uname -m` | ||
if [ x${arch} == xppc64le -o x${arch} == xs390x ]; then | ||
excluded_packages+=("github.com/hyperledger/fabric/core/chaincode/platforms/java") | ||
fi | ||
|
||
# when running a "verify" job, only test packages that have changed | ||
if [ "${JOB_TYPE}" = "VERIFY" ]; then | ||
# first check for uncommitted changes | ||
package_spec=$(packages_diff HEAD) | ||
if [ -z "${package_spec}" ]; then | ||
# next check for changes in the latest commit - typically this will | ||
# be for CI only, but could also handle a committed change before | ||
# pushing to Gerrit | ||
package_spec=$(packages_diff HEAD^) | ||
fi | ||
fi | ||
|
||
# expand the package spec into an array of packages | ||
local -a packages=$(list_and_filter ${package_spec}) | ||
|
||
if [ -z "${packages}" ]; then | ||
echo "Nothing to test!!!" | ||
elif [ "${JOB_TYPE}" = "PROFILE" ]; then | ||
run_tests_with_coverage "${packages[@]}" | ||
else | ||
run_tests "${packages[@]}" | ||
fi | ||
} | ||
|
||
main |