github.com/status-im/status-go@v1.1.0/_assets/scripts/run_unit_tests.sh (about)

     1  #!/usr/bin/env bash
     2  set -o pipefail
     3  
     4  GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
     5  
     6  source "${GIT_ROOT}/_assets/scripts/colors.sh"
     7  
     8  if [[ $UNIT_TEST_RERUN_FAILS == 'true' ]]; then
     9    GOTESTSUM_EXTRAFLAGS="${GOTESTSUM_EXTRAFLAGS} --rerun-fails"
    10  elif [[ $UNIT_TEST_FAILFAST == 'true' ]]; then
    11    GOTEST_EXTRAFLAGS="${GOTEST_EXTRAFLAGS} -failfast"
    12  fi
    13  
    14  if [[ $UNIT_TEST_USE_DEVELOPMENT_LOGGER == 'false' ]]; then
    15    if [[ -z $BUILD_TAGS ]]; then
    16      BUILD_TAGS="test_silent"
    17    else
    18      BUILD_TAGS="${BUILD_TAGS},test_silent"
    19    fi
    20  fi
    21  
    22  if [[ -z "${UNIT_TEST_COUNT}" ]]; then
    23    UNIT_TEST_COUNT=1
    24  fi
    25  
    26  redirect_stdout() {
    27    output_file=$1
    28  
    29    if [[ "${CI}" == 'true' ]]; then
    30      cat > "${output_file}";
    31    else
    32      tee "${output_file}";
    33    fi
    34  }
    35  
    36  run_test_for_packages() {
    37    local packages="$1"
    38    local iteration="$2"
    39    local count="$3"
    40    local single_timeout="$4"
    41    local log_message="$5"
    42  
    43    local output_file="test_${iteration}.log"
    44    local coverage_file="test_${iteration}.coverage.out"
    45    local report_file="report_${iteration}.xml"
    46    local rerun_report_file="report_rerun_fails_${iteration}.txt"
    47    local exit_code_file="exit_code_${iteration}.txt"
    48    local timeout="$(( single_timeout * count))m"
    49  
    50    if [[ "${UNIT_TEST_DRY_RUN}" == 'true' ]]; then
    51      echo -e "${GRN}Dry run ${iteration}. message:${RST} ${log_message}\n"\
    52      "${YLW}Dry run ${iteration}. packages:${RST} ${packages}\n"\
    53      "${YLW}Dry run ${iteration}. count:${RST} ${count}\n"\
    54      "${YLW}Dry run ${iteration}. timeout:${RST} ${timeout}"
    55      return 0
    56    fi
    57  
    58    echo -e "${GRN}Testing:${RST} ${log_message}. Iteration ${iteration}. -test.count=${count}. Timeout: ${timeout}"
    59  
    60    gotestsum_flags="${GOTESTSUM_EXTRAFLAGS}"
    61    if [[ "${CI}" == 'true' ]]; then
    62      gotestsum_flags="${gotestsum_flags} --junitfile=${report_file} --rerun-fails-report=${rerun_report_file}"
    63    fi
    64  
    65    # Prepare env variables for `test-with-coverage.sh`
    66    export TEST_WITH_COVERAGE_PACKAGES="${packages}"
    67    export TEST_WITH_COVERAGE_COUNT="${count}"
    68    export TEST_WITH_COVERAGE_REPORTS_DIR="$(mktemp -d)"
    69  
    70    # Cleanup previous coverage reports
    71    rm -f "${TEST_WITH_COVERAGE_REPORTS_DIR}/coverage.out.rerun.*"
    72  
    73    # Run tests
    74    gotestsum --packages="${packages}" ${gotestsum_flags} --raw-command -- \
    75      ./_assets/scripts/test-with-coverage.sh \
    76      ${GOTEST_EXTRAFLAGS} \
    77      -timeout "${timeout}" \
    78      -tags "${BUILD_TAGS}" | \
    79      redirect_stdout "${output_file}"
    80  
    81    local go_test_exit=$?
    82  
    83    # Merge package coverage results
    84    go run ./cmd/test-coverage-utils/gocovmerge.go ${TEST_WITH_COVERAGE_REPORTS_DIR}/coverage.out.rerun.* > ${coverage_file}
    85    rm -f "${COVERAGE_REPORTS_DIR}/coverage.out.rerun.*"
    86  
    87    echo "${go_test_exit}" > "${exit_code_file}"
    88    if [[ "${go_test_exit}" -ne 0 ]]; then
    89      if [[ "${CI}" == 'true' ]]; then
    90        echo -e "${YLW}Failed, see the log:${RST} ${BLD}${output_file}${RST}"
    91      fi
    92    fi
    93  
    94    return ${go_test_exit}
    95  }
    96  
    97  if [[ $UNIT_TEST_REPORT_CODECLIMATE == 'true' ]]; then
    98  	cc-test-reporter before-build
    99  fi
   100  
   101  rm -rf ./**/*.coverage.out
   102  
   103  echo -e "${GRN}Testing HEAD:${RST} $(git rev-parse HEAD)"
   104  
   105  DEFAULT_TIMEOUT_MINUTES=5
   106  PROTOCOL_TIMEOUT_MINUTES=45
   107  
   108  HAS_PROTOCOL_PACKAGE=true
   109  if [[ $(echo "${UNIT_TEST_PACKAGES}" | grep -E '\s?\S+protocol\s+') == "" ]]; then
   110    HAS_PROTOCOL_PACKAGE=false
   111  fi
   112  
   113  if [[ $HAS_PROTOCOL_PACKAGE == 'false' ]]; then
   114    # This is the default single-line flow for testing all packages
   115    # The `else` branch is temporary and will be removed once the `protocol` package runtime is optimized.
   116    run_test_for_packages "${UNIT_TEST_PACKAGES}" "0" "${UNIT_TEST_COUNT}" "${DEFAULT_TIMEOUT_MINUTES}" "All packages"
   117  else
   118    # Spawn a process to test all packages except `protocol`
   119    UNIT_TEST_PACKAGES_FILTERED=$(echo "${UNIT_TEST_PACKAGES}" | tr ' ' '\n' | grep -v '/protocol$' | tr '\n' ' ')
   120    run_test_for_packages "${UNIT_TEST_PACKAGES_FILTERED}" "0" "${UNIT_TEST_COUNT}" "${DEFAULT_TIMEOUT_MINUTES}" "All packages except 'protocol'" &
   121  
   122    # Spawn separate processes to run `protocol` package
   123    for ((i=1; i<=UNIT_TEST_COUNT; i++)); do
   124      run_test_for_packages github.com/status-im/status-go/protocol "${i}" 1 "${PROTOCOL_TIMEOUT_MINUTES}" "Only 'protocol' package" &
   125    done
   126  
   127    wait
   128  fi
   129  
   130  # When running in PRs (count=1), early exit if any test failed.
   131  # When running nightly (count>1), generate test stats ant coverage reports anyway.
   132  if [[ $UNIT_TEST_COUNT -eq 1 ]]; then
   133    for exit_code_file in "${GIT_ROOT}"/exit_code_*.txt; do
   134      read exit_code < "${exit_code_file}"
   135      if [[ "${exit_code}" -ne 0 ]]; then
   136        echo -e "${RED}Testing failed${RST}, exit code: ${exit_code}"
   137        exit ${exit_code}
   138      fi
   139    done
   140  fi
   141  
   142  # Gather test coverage results
   143  merged_coverage_report="coverage_merged.out"
   144  final_coverage_report="c.out" # Name expected by cc-test-reporter
   145  coverage_reports=$(find . -iname "*.coverage.out")
   146  rm -f ${final_coverage_report} ${merged_coverage_report}
   147  
   148  echo -e "${GRN}Gathering test coverage results: ${RST} output: ${merged_coverage_report}, input: ${coverage_reports}"
   149  echo $coverage_reports | xargs go run ./cmd/test-coverage-utils/gocovmerge.go > ${merged_coverage_report}
   150  
   151  # Filter out test coverage for packages in ./cmd
   152  echo -e "${GRN}Filtering test coverage packages:${RST} ./cmd"
   153  grep -v '^github.com/status-im/status-go/cmd/' ${merged_coverage_report} > ${final_coverage_report}
   154  
   155  # Generate HTML coverage report
   156  echo -e "${GRN}Generating HTML coverage report${RST}"
   157  go tool cover -html ${final_coverage_report} -o test-coverage.html
   158  
   159  # Upload coverage report to CodeClimate
   160  if [[ $UNIT_TEST_REPORT_CODECLIMATE == 'true' ]]; then
   161    echo -e "${GRN}Uploading coverage report to CodeClimate${RST}"
   162    # https://docs.codeclimate.com/docs/jenkins#jenkins-ci-builds
   163    GIT_COMMIT=$(git log | grep -m1 -oE '[^ ]+$')
   164    cc-test-reporter format-coverage --prefix=github.com/status-im/status-go # To generate 'coverage/codeclimate.json'
   165    cc-test-reporter after-build --prefix=github.com/status-im/status-go
   166  fi
   167  
   168  if [[ $UNIT_TEST_REPORT_CODECOV == 'true' ]]; then
   169    echo -e "${GRN}Uploading coverage report to Codecov${RST}"
   170    # https://docs.codeclimate.com/docs/jenkins#jenkins-ci-builds
   171    codecov_report_files_args=""
   172    for file in report_*.xml; do
   173      codecov_report_files_args+="--file ${file} "
   174    done
   175    codecov do-upload --token "${CODECOV_TOKEN}" --report-type test_results ${codecov_report_files_args}
   176    codecov --token "${CODECOV_TOKEN}" -f ${final_coverage_report} -F "unit"
   177  fi
   178  
   179  # Generate report with test stats
   180  shopt -s globstar nullglob # Enable recursive globbing
   181  if [[ "${UNIT_TEST_COUNT}" -gt 1 ]]; then
   182    for exit_code_file in "${GIT_ROOT}"/**/exit_code_*.txt; do
   183      read exit_code < "${exit_code_file}"
   184      if [[ "${exit_code}" -ne 0 ]]; then
   185        echo -e "${GRN}Generating test stats${RST}, exit code: ${exit_code}"
   186        mkdir -p "${GIT_ROOT}/reports"
   187        "${GIT_ROOT}/_assets/scripts/test_stats.py" | tee "${GIT_ROOT}/reports/test_stats.txt"
   188        exit ${exit_code}
   189      fi
   190    done
   191  fi
   192  
   193  echo -e "${GRN}Testing finished${RST}"