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