.integration-test-helpers 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #!/usr/bin/env bash
  2. #
  3. # For integration-cli test, we use [gocheck](https://labix.org/gocheck), if you want
  4. # to run certain tests on your local host, you should run with command:
  5. #
  6. # TESTFLAGS='-test.run TestDockerCLIBuildSuite' ./hack/make.sh binary test-integration
  7. #
  8. if [ -z "${MAKEDIR}" ]; then
  9. MAKEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  10. export MAKEDIR
  11. fi
  12. source "${MAKEDIR}/.go-autogen"
  13. # Set defaults
  14. : "${TEST_REPEAT:=1}"
  15. : "${TESTFLAGS:=}"
  16. : "${TESTDEBUG:=}"
  17. : "${TESTCOVERAGE:=}"
  18. : "${GOCACHE:=$(go env GOCACHE)}"
  19. setup_integration_test_filter() {
  20. if [ -z "${TEST_FILTER}" ]; then
  21. return
  22. fi
  23. local dirs
  24. dirs=$(grep -rIlE --include '*_test.go' "func .*${TEST_FILTER}.*\(. \*testing\.T\)" ./integration*/ | xargs -I file dirname file | uniq)
  25. if [ -z "${TEST_SKIP_INTEGRATION}" ]; then
  26. : "${TEST_INTEGRATION_DIR:=$(echo "$dirs" | grep -v '^\./integration-cli$')}"
  27. if [ -z "${TEST_INTEGRATION_DIR}" ]; then
  28. echo "Skipping integration tests since the supplied filter \"${TEST_FILTER}\" omits all integration tests"
  29. TEST_SKIP_INTEGRATION=1
  30. else
  31. TESTFLAGS+=" -test.run ${TEST_FILTER}"
  32. fi
  33. fi
  34. if [ -z "${TEST_SKIP_INTEGRATION_CLI}" ]; then
  35. if echo "$dirs" | grep -vq '^./integration-cli$'; then
  36. TEST_SKIP_INTEGRATION_CLI=1
  37. echo "Skipping integration-cli tests since the supplied filter \"${TEST_FILTER}\" omits all integration-cli tests"
  38. else
  39. TESTFLAGS+=" -test.run /${TEST_FILTER}"
  40. fi
  41. fi
  42. }
  43. setup_integration_test_filter
  44. if [ -z "${TEST_SKIP_INTEGRATION}" ] && [ -z "${TEST_INTEGRATION_DIR}" ]; then
  45. integration_api_dirs="$(go list -test -f '{{- if ne .ForTest "" -}}{{- .Dir -}}{{- end -}}' ./integration/...)"
  46. else
  47. integration_api_dirs="${TEST_INTEGRATION_DIR}"
  48. fi
  49. run_test_integration() {
  50. set_platform_timeout
  51. if [ -z "${TEST_SKIP_INTEGRATION}" ]; then
  52. run_test_integration_suites "${integration_api_dirs}"
  53. fi
  54. if [ -z "${TEST_SKIP_INTEGRATION_CLI}" ]; then
  55. TIMEOUT=360m run_test_integration_suites integration-cli
  56. fi
  57. }
  58. run_test_integration_suites() {
  59. local flags="-test.v -test.timeout=${TIMEOUT} $TESTFLAGS"
  60. local dirs="$1"
  61. local failed=0
  62. for dir in ${dirs}; do
  63. if ! (
  64. cd "$dir"
  65. # Create a useful package name based on the tests's $dir. We need to take
  66. # into account that "$dir" can be either an absolute (/go/src/github.com/docker/docker/integration/foo)
  67. # or relative (./integration/foo) path. To account for both, first we strip
  68. # the absolute path, then remove any leading periods and slashes.
  69. pkgname="${dir}"
  70. pkgname="${pkgname#*${GOPATH}/src/${DOCKER_PKG}}"
  71. pkgname="${pkgname#*.}"
  72. pkgname="${pkgname#*\/}"
  73. # Finally, we use periods as separator (instead of slashes) to be more
  74. # in line with Java package names (which is what junit.xml was designed for)
  75. pkgname="$(go env GOARCH).${pkgname//\//.}"
  76. pkgtestflags=$flags
  77. if [ -n "${TESTCOVERAGE}" ]; then
  78. pkgtestflags="$pkgtestflags -test.coverprofile=${ABS_DEST}/${pkgname//./-}-coverage.out"
  79. fi
  80. echo "Running $PWD (${pkgname}) flags=${pkgtestflags}"
  81. [ -n "$TESTDEBUG" ] && set -x
  82. # shellcheck disable=SC2086
  83. test_env gotestsum \
  84. --format=standard-verbose \
  85. --jsonfile="${ABS_DEST}/${pkgname//./-}-go-test-report.json" \
  86. --junitfile="${ABS_DEST}/${pkgname//./-}-junit-report.xml" \
  87. --raw-command \
  88. -- go tool test2json -p "${pkgname}" -t ./test.main ${pkgtestflags}
  89. ); then
  90. if [ -n "${TEST_INTEGRATION_FAIL_FAST}" ]; then
  91. exit 1
  92. fi
  93. failed=1
  94. fi
  95. done
  96. if [ $failed -eq 1 ]; then
  97. exit 1
  98. fi
  99. }
  100. build_test_suite_binaries() {
  101. if [ -n "${DOCKER_INTEGRATION_TESTS_VERIFIED}" ]; then
  102. echo "Skipping building test binaries; as DOCKER_INTEGRATION_TESTS_VERIFIED is set"
  103. return
  104. fi
  105. if [ -z "${TEST_SKIP_INTEGRATION_CLI}" ]; then
  106. build_test_suite_binary ./integration-cli "test.main"
  107. fi
  108. if [ -z "${TEST_SKIP_INTEGRATION}" ]; then
  109. for dir in ${integration_api_dirs}; do
  110. build_test_suite_binary "$dir" "test.main"
  111. done
  112. fi
  113. }
  114. # Build a binary for a test suite package
  115. build_test_suite_binary() {
  116. local dir="$1"
  117. local out="$2"
  118. local testflags
  119. echo Building test suite binary "$dir/$out"
  120. if [ -n "${TESTCOVERAGE}" ]; then
  121. testflags="-cover -covermode=atomic"
  122. fi
  123. go test ${testflags} -c -o "$dir/$out" -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}" "$dir"
  124. }
  125. cleanup_test_suite_binaries() {
  126. [ -n "$TESTDEBUG" ] && return
  127. echo "Removing test suite binaries"
  128. # shellcheck disable=SC2038
  129. find integration* -name test.main | xargs -r rm
  130. }
  131. repeat() {
  132. for i in $(seq 1 ${TEST_REPEAT}); do
  133. echo "Running integration-test (iteration $i)"
  134. $@
  135. done
  136. }
  137. # use "env -i" to tightly control the environment variables that bleed into the tests
  138. test_env() {
  139. (
  140. set -e
  141. [ -n "$TESTDEBUG" ] && set -x
  142. env -i \
  143. DEST="$ABS_DEST" \
  144. DOCKER_API_VERSION="$DOCKER_API_VERSION" \
  145. DOCKER_BUILDKIT="$DOCKER_BUILDKIT" \
  146. DOCKER_INTEGRATION_DAEMON_DEST="$DOCKER_INTEGRATION_DAEMON_DEST" \
  147. DOCKER_TLS_VERIFY="$DOCKER_TEST_TLS_VERIFY" \
  148. DOCKER_CERT_PATH="$DOCKER_TEST_CERT_PATH" \
  149. DOCKER_ENGINE_GOARCH="$DOCKER_ENGINE_GOARCH" \
  150. DOCKER_GRAPHDRIVER="$DOCKER_GRAPHDRIVER" \
  151. DOCKER_USERLANDPROXY="$DOCKER_USERLANDPROXY" \
  152. DOCKER_HOST="$DOCKER_HOST" \
  153. DOCKER_REMAP_ROOT="$DOCKER_REMAP_ROOT" \
  154. DOCKER_REMOTE_DAEMON="$DOCKER_REMOTE_DAEMON" \
  155. DOCKER_ROOTLESS="$DOCKER_ROOTLESS" \
  156. GITHUB_ACTIONS="$GITHUB_ACTIONS" \
  157. GOCACHE="$GOCACHE" \
  158. GOPATH="$GOPATH" \
  159. GOTRACEBACK=all \
  160. HOME="$ABS_DEST/fake-HOME" \
  161. PATH="$PATH" \
  162. TEMP="$TEMP" \
  163. TEST_CLIENT_BINARY="$TEST_CLIENT_BINARY" \
  164. TEST_INTEGRATION_USE_SNAPSHOTTER="$TEST_INTEGRATION_USE_SNAPSHOTTER" \
  165. "$@"
  166. )
  167. }
  168. set_platform_timeout() {
  169. # Test timeout.
  170. if [ "${DOCKER_ENGINE_GOARCH}" = "arm64" ] || [ "${DOCKER_ENGINE_GOARCH}" = "arm" ]; then
  171. : "${TIMEOUT:=10m}"
  172. elif [ "${DOCKER_ENGINE_GOARCH}" = "windows" ]; then
  173. : "${TIMEOUT:=8m}"
  174. else
  175. : "${TIMEOUT:=5m}"
  176. fi
  177. if [ "${TEST_REPEAT}" -gt 1 ]; then
  178. # TIMEOUT needs to take TEST_REPEAT into account, or a premature time out may happen.
  179. # The following ugliness will:
  180. # - remove last character (usually 'm' from '10m')
  181. # - multiply by testcount
  182. # - add last character back
  183. TIMEOUT=$((${TIMEOUT::-1} * ${TEST_REPEAT}))${TIMEOUT:$((${#TIMEOUT} - 1)):1}
  184. fi
  185. }