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