github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/scripts/run-unit-tests.sh (about) 1 #!/bin/bash 2 3 # Copyright IBM Corp. All Rights Reserved. 4 # 5 # SPDX-License-Identifier: Apache-2.0 6 7 set -e 8 set -o pipefail 9 10 base_dir="$(cd "$(dirname "$0")/.." && pwd)" 11 12 # regexes for packages to exclude from unit test 13 excluded_packages=( 14 "/integration(/|$)" 15 ) 16 17 # packages that must be run serially 18 serial_packages=( 19 "github.com/hyperledger/fabric/gossip/..." 20 ) 21 22 # packages which need to be tested with build tag pluginsenabled 23 plugin_packages=() 24 25 # packages which need to be tested with build tag pkcs11 26 pkcs11_packages=( 27 "github.com/hyperledger/fabric/bccsp/..." 28 ) 29 30 # packages that are only tested when they (or their deps) change 31 conditional_packages=( 32 "github.com/hyperledger/fabric/gossip/..." 33 ) 34 35 # join array elements by the specified string 36 join_by() { 37 local IFS="$1"; shift 38 [ "$#" -ne 0 ] && echo "$*" 39 } 40 41 contains_element() { 42 local key="$1"; shift 43 44 for e in "$@"; do [ "$e" == "$key" ] && return 0; done 45 return 1 46 } 47 48 # create a grep regex from the provide package spec 49 package_filter() { 50 local -a filter 51 if [ "${#@}" -ne 0 ]; then 52 while IFS= read -r pkg; do [ -n "$pkg" ] && filter+=("$pkg"); done < <(go list -f '^{{ .ImportPath }}$' "${@}") 53 fi 54 55 join_by '|' "${filter[@]}" 56 } 57 58 # obtain packages changed since some git refspec 59 packages_diff() { 60 git -C "${base_dir}" diff --no-commit-id --name-only -r "${1:-HEAD}" | 61 (grep '.go$' || true) | \ 62 sed 's%/[^/]*$%%' | sort -u | \ 63 awk '{print "github.com/hyperledger/fabric/"$1}' 64 } 65 66 # obtain list of changed packages for verification 67 changed_packages() { 68 local -a changed 69 70 # first check for uncommitted changes 71 while IFS= read -r pkg; do changed+=("$pkg"); done < <(packages_diff HEAD | grep -Ev '/vendor(/|$)' || true) 72 if [ "${#changed[@]}" -eq 0 ]; then 73 # next check for changes in the latest commit 74 while IFS= read -r pkg; do changed+=("$pkg"); done < <(packages_diff HEAD^ | grep -Ev '/vendor(/|$)' || true) 75 fi 76 77 join_by $'\n' "${changed[@]}" 78 } 79 80 # "go list" packages and filter out excluded packages 81 list_and_filter() { 82 local excluded conditional filter 83 84 excluded=("${excluded_packages[@]}") 85 conditional=$(package_filter "${conditional_packages[@]}") 86 if [ -n "$conditional" ]; then 87 excluded+=("$conditional") 88 fi 89 90 filter=$(join_by '|' "${excluded[@]}") 91 if [ -n "$filter" ]; then 92 go list "$@" 2>/dev/null | grep -Ev "${filter}" || true 93 else 94 go list "$@" 2>/dev/null 95 fi 96 } 97 98 # list conditional packages that have been changed 99 list_changed_conditional() { 100 [ "${#conditional_packages[@]}" -eq 0 ] && return 0 101 102 local changed 103 changed=$(changed_packages) 104 105 local -a additional_packages 106 for pkg in $(go list "${conditional_packages[@]}"); do 107 local dep_regexp 108 dep_regexp=$(go list -f '{{ join .Deps "$|" }}' "$pkg") 109 echo "${changed}" | grep -qE "$dep_regexp" && additional_packages+=("$pkg") 110 echo "${changed}" | grep -qE "$pkg\$" && additional_packages+=("$pkg") 111 done 112 113 join_by $'\n' "${additional_packages[@]}" 114 } 115 116 # remove packages that must be tested serially 117 parallel_test_packages() { 118 local filter 119 filter=$(package_filter "${serial_packages[@]}") 120 if [ -n "$filter" ]; then 121 join_by $'\n' "$@" | grep -Ev "$filter" || true 122 else 123 join_by $'\n' "$@" 124 fi 125 } 126 127 # get packages that must be tested serially 128 serial_test_packages() { 129 local filter 130 filter=$(package_filter "${serial_packages[@]}") 131 if [ -n "$filter" ]; then 132 join_by $'\n' "$@" | grep -E "$filter" || true 133 else 134 join_by $'\n' "$@" 135 fi 136 } 137 138 # "go test" the provided packages. Packages that are not present in the serial package list 139 # will be tested in parallel 140 run_tests() { 141 local -a flags=("-cover") 142 if [ -n "${VERBOSE}" ]; then 143 flags+=("-v") 144 fi 145 146 local -a race_flags=() 147 if [ "$(uname -m)" == "x86_64" ]; then 148 export GORACE=atexit_sleep_ms=0 # reduce overhead of race 149 race_flags+=("-race") 150 fi 151 152 GO_TAGS=${GO_TAGS## } 153 [ -n "$GO_TAGS" ] && echo "Testing with $GO_TAGS..." 154 155 time { 156 local -a serial 157 while IFS= read -r pkg; do serial+=("$pkg"); done < <(serial_test_packages "$@") 158 if [ "${#serial[@]}" -ne 0 ]; then 159 go test "${flags[@]}" -tags "$GO_TAGS" "${serial[@]}" -short -p 1 -timeout=20m 160 fi 161 162 local -a parallel 163 while IFS= read -r pkg; do parallel+=("$pkg"); done < <(parallel_test_packages "$@") 164 if [ "${#parallel[@]}" -ne 0 ]; then 165 go test "${flags[@]}" "${race_flags[@]}" -tags "$GO_TAGS" "${parallel[@]}" -short -timeout=20m 166 fi 167 } 168 } 169 170 # "go test" the provided packages and generate code coverage reports. 171 run_tests_with_coverage() { 172 # run the tests serially 173 time go test -p 1 -cover -coverprofile=profile_tmp.cov -tags "$GO_TAGS" "$@" -timeout=20m 174 tail -n +2 profile_tmp.cov >> profile.cov && rm profile_tmp.cov 175 } 176 177 main() { 178 # explicit exclusions for ppc and s390x 179 if [ "$(uname -m)" == "ppc64le" ] || [ "$(uname -m)" == "s390x" ]; then 180 excluded_packages+=("github.com/hyperledger/fabric/core/chaincode/platforms/java") 181 fi 182 183 # default behavior is to run all tests 184 local -a package_spec=("${TEST_PKGS:-github.com/hyperledger/fabric/...}") 185 186 # when running a "verify" job, only test packages that have changed 187 if [ "${JOB_TYPE}" = "VERIFY" ]; then 188 package_spec=() 189 while IFS= read -r pkg; do package_spec+=("$pkg"); done < <(changed_packages) 190 fi 191 192 # run everything when profiling 193 if [ "${JOB_TYPE}" = "PROFILE" ]; then 194 conditional_packages=() 195 fi 196 197 # expand the package specs into arrays of packages 198 local -a candidates packages packages_with_plugins packages_with_pkcs11 199 while IFS= read -r pkg; do candidates+=("$pkg"); done < <(go list "${package_spec[@]}") 200 while IFS= read -r pkg; do packages+=("$pkg"); done < <(list_and_filter "${package_spec[@]}") 201 while IFS= read -r pkg; do contains_element "$pkg" "${candidates[@]}" && packages+=("$pkg"); done < <(list_changed_conditional) 202 while IFS= read -r pkg; do contains_element "$pkg" "${packages[@]}" && packages_with_plugins+=("$pkg"); done < <(list_and_filter "${plugin_packages[@]}") 203 while IFS= read -r pkg; do contains_element "$pkg" "${packages[@]}" && packages_with_pkcs11+=("$pkg"); done < <(list_and_filter "${pkcs11_packages[@]}") 204 205 local all_packages=( "${packages[@]}" "${packages_with_pkcs11[@]}" "${packages_with_pkcs11[@]}" ) 206 if [ "${#all_packages[@]}" -eq 0 ]; then 207 echo "Nothing to test!!!" 208 elif [ "${JOB_TYPE}" = "PROFILE" ]; then 209 echo "mode: set" > profile.cov 210 [ "${#packages}" -eq 0 ] || run_tests_with_coverage "${packages[@]}" 211 [ "${#packages_with_plugins}" -eq 0 ] || GO_TAGS="${GO_TAGS} pluginsenabled" run_tests_with_coverage "${packages_with_plugins[@]}" 212 [ "${#packages_with_pkcs11}" -eq 0 ] || GO_TAGS="${GO_TAGS} pkcs11" run_tests_with_coverage "${packages_with_pkcs11[@]}" 213 gocov convert profile.cov | gocov-xml > report.xml 214 else 215 [ "${#packages}" -eq 0 ] || run_tests "${packages[@]}" 216 [ "${#packages_with_plugins}" -eq 0 ] || GO_TAGS="${GO_TAGS} pluginsenabled" run_tests "${packages_with_plugins[@]}" 217 [ "${#packages_with_pkcs11}" -eq 0 ] || GO_TAGS="${GO_TAGS} pkcs11" run_tests "${packages_with_pkcs11[@]}" 218 fi 219 } 220 221 main