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