Skip to content

Commit

Permalink
[FAB-7649] refactor unit test script
Browse files Browse the repository at this point in the history
Change-Id: Id179b886d958bac8338bc2ef2fc7bdcc6c4759af
Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
  • Loading branch information
sykesm committed Jan 8, 2018
1 parent 97fdf3d commit fd65c75
Showing 1 changed file with 113 additions and 88 deletions.
201 changes: 113 additions & 88 deletions unit-test/run.sh
@@ -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

0 comments on commit fd65c75

Please sign in to comment.