test 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #!/bin/bash
  2. set -e
  3. DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  4. SLOW=
  5. NO_GO_GET=true
  6. TAGS=
  7. PARALLEL=
  8. RACE="-race -covermode=atomic"
  9. TIMEOUT=1m
  10. VERBOSE=
  11. usage() {
  12. echo "$0 [-slow] [-in-container foo] [-netgo] [-(no-)go-get] [-timeout 1m]"
  13. }
  14. while [ $# -gt 0 ]; do
  15. case "$1" in
  16. "-v")
  17. VERBOSE="-v"
  18. shift 1
  19. ;;
  20. "-slow")
  21. SLOW=true
  22. shift 1
  23. ;;
  24. "-no-race")
  25. RACE=
  26. shift 1
  27. ;;
  28. "-no-go-get")
  29. NO_GO_GET=true
  30. shift 1
  31. ;;
  32. "-go-get")
  33. NO_GO_GET=
  34. shift 1
  35. ;;
  36. "-netgo")
  37. TAGS="netgo"
  38. shift 1
  39. ;;
  40. "-tags")
  41. TAGS="$2"
  42. shift 2
  43. ;;
  44. "-p")
  45. PARALLEL=true
  46. shift 1
  47. ;;
  48. "-timeout")
  49. TIMEOUT=$2
  50. shift 2
  51. ;;
  52. *)
  53. usage
  54. exit 2
  55. ;;
  56. esac
  57. done
  58. GO_TEST_ARGS=(-tags "${TAGS[@]}" -cpu 4 -timeout "$TIMEOUT" $VERBOSE)
  59. if [ -n "$SLOW" ] || [ -n "$CIRCLECI" ]; then
  60. SLOW=true
  61. fi
  62. if [ -n "$SLOW" ]; then
  63. GO_TEST_ARGS=("${GO_TEST_ARGS[@]}" ${RACE})
  64. # shellcheck disable=SC2153
  65. if [ -n "$COVERDIR" ]; then
  66. coverdir="$COVERDIR"
  67. else
  68. coverdir=$(mktemp -d coverage.XXXXXXXXXX)
  69. fi
  70. mkdir -p "$coverdir"
  71. fi
  72. fail=0
  73. if [ -z "$TESTDIRS" ]; then
  74. # NB: Relies on paths being prefixed with './'.
  75. TESTDIRS=($(git ls-files -- '*_test.go' | grep -vE '^(vendor|experimental)/' | xargs -n1 dirname | sort -u | sed -e 's|^|./|'))
  76. else
  77. # TESTDIRS on the right side is not really an array variable, it
  78. # is just a string with spaces, but it is written like that to
  79. # shut up the shellcheck tool.
  80. TESTDIRS=($(for d in ${TESTDIRS[*]}; do echo "$d"; done))
  81. fi
  82. # If running on circle, use the scheduler to work out what tests to run on what shard
  83. if [ -n "$CIRCLECI" ] && [ -z "$NO_SCHEDULER" ] && [ -x "$DIR/sched" ]; then
  84. PREFIX=$(go list -e ./ | sed -e 's/\//-/g')
  85. TESTDIRS=($(echo "${TESTDIRS[@]}" | "$DIR/sched" sched "$PREFIX-$CIRCLE_PROJECT_USERNAME-$CIRCLE_PROJECT_REPONAME-$CIRCLE_BUILD_NUM" "$CIRCLE_NODE_TOTAL" "$CIRCLE_NODE_INDEX"))
  86. echo "${TESTDIRS[@]}"
  87. fi
  88. PACKAGE_BASE=$(go list -e ./)
  89. run_test() {
  90. local dir=$1
  91. if [ -z "$NO_GO_GET" ]; then
  92. go get -t -tags "${TAGS[@]}" "$dir"
  93. fi
  94. local GO_TEST_ARGS_RUN=("${GO_TEST_ARGS[@]}")
  95. if [ -n "$SLOW" ]; then
  96. local COVERPKGS
  97. COVERPKGS=$( (
  98. go list "$dir"
  99. go list -f '{{join .Deps "\n"}}' "$dir" | grep -v "vendor" | grep "^$PACKAGE_BASE/"
  100. ) | paste -s -d, -)
  101. local output
  102. output=$(mktemp "$coverdir/unit.XXXXXXXXXX")
  103. local GO_TEST_ARGS_RUN=("${GO_TEST_ARGS[@]}" "-coverprofile=$output" "-coverpkg=$COVERPKGS")
  104. fi
  105. local START
  106. START=$(date +%s)
  107. if ! go test "${GO_TEST_ARGS_RUN[@]}" "$dir"; then
  108. fail=1
  109. fi
  110. local END
  111. END=$(date +%s)
  112. local RUNTIME=$((END - START))
  113. # Report test runtime when running on circle, to help scheduler
  114. if [ -n "$CIRCLECI" ] && [ -z "$NO_SCHEDULER" ] && [ -x "$DIR/sched" ]; then
  115. "$DIR/sched" time "$dir" "$RUNTIME"
  116. fi
  117. }
  118. for dir in "${TESTDIRS[@]}"; do
  119. if [ -n "$PARALLEL" ]; then
  120. run_test "$dir" &
  121. else
  122. run_test "$dir"
  123. fi
  124. done
  125. if [ -n "$PARALLEL" ]; then
  126. wait
  127. fi
  128. if [ -n "$SLOW" ] && [ -z "$COVERDIR" ]; then
  129. go get github.com/weaveworks/tools/cover
  130. cover "$coverdir"/* >profile.cov
  131. rm -rf "$coverdir"
  132. go tool cover -html=profile.cov -o=coverage.html
  133. go tool cover -func=profile.cov | tail -n1
  134. fi
  135. exit $fail