.integration-test-helpers 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. for dir in ${dirs}; do
  62. if ! (
  63. cd "$dir"
  64. # Create a useful package name based on the tests's $dir. We need to take
  65. # into account that "$dir" can be either an absolute (/go/src/github.com/docker/docker/integration/foo)
  66. # or relative (./integration/foo) path. To account for both, first we strip
  67. # the absolute path, then remove any leading periods and slashes.
  68. pkgname="${dir}"
  69. pkgname="${pkgname#*${GOPATH}/src/${DOCKER_PKG}}"
  70. pkgname="${pkgname#*.}"
  71. pkgname="${pkgname#*\/}"
  72. # Finally, we use periods as separator (instead of slashes) to be more
  73. # in line with Java package names (which is what junit.xml was designed for)
  74. pkgname="$(go env GOARCH).${pkgname//\//.}"
  75. pkgtestflags=$flags
  76. if [ -n "${TESTCOVERAGE}" ]; then
  77. pkgtestflags="$pkgtestflags -test.coverprofile=${ABS_DEST}/${pkgname//./-}-coverage.out"
  78. fi
  79. echo "Running $PWD (${pkgname}) flags=${pkgtestflags}"
  80. [ -n "$TESTDEBUG" ] && set -x
  81. # shellcheck disable=SC2086
  82. test_env gotestsum \
  83. --format=standard-verbose \
  84. --jsonfile="${ABS_DEST}/${pkgname//./-}-go-test-report.json" \
  85. --junitfile="${ABS_DEST}/${pkgname//./-}-junit-report.xml" \
  86. --raw-command \
  87. -- go tool test2json -p "${pkgname}" -t ./test.main ${pkgtestflags}
  88. ); then exit 1; fi
  89. done
  90. }
  91. build_test_suite_binaries() {
  92. if [ -n "${DOCKER_INTEGRATION_TESTS_VERIFIED}" ]; then
  93. echo "Skipping building test binaries; as DOCKER_INTEGRATION_TESTS_VERIFIED is set"
  94. return
  95. fi
  96. if [ -z "${TEST_SKIP_INTEGRATION_CLI}" ]; then
  97. build_test_suite_binary ./integration-cli "test.main"
  98. fi
  99. if [ -z "${TEST_SKIP_INTEGRATION}" ]; then
  100. for dir in ${integration_api_dirs}; do
  101. build_test_suite_binary "$dir" "test.main"
  102. done
  103. fi
  104. }
  105. # Build a binary for a test suite package
  106. build_test_suite_binary() {
  107. local dir="$1"
  108. local out="$2"
  109. local testflags
  110. echo Building test suite binary "$dir/$out"
  111. if [ -n "${TESTCOVERAGE}" ]; then
  112. testflags="-cover -covermode=atomic"
  113. fi
  114. go test ${testflags} -c -o "$dir/$out" -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}" "$dir"
  115. }
  116. cleanup_test_suite_binaries() {
  117. [ -n "$TESTDEBUG" ] && return
  118. echo "Removing test suite binaries"
  119. # shellcheck disable=SC2038
  120. find integration* -name test.main | xargs -r rm
  121. }
  122. repeat() {
  123. for i in $(seq 1 ${TEST_REPEAT}); do
  124. echo "Running integration-test (iteration $i)"
  125. $@
  126. done
  127. }
  128. # use "env -i" to tightly control the environment variables that bleed into the tests
  129. test_env() {
  130. (
  131. set -e
  132. [ -n "$TESTDEBUG" ] && set -x
  133. env -i \
  134. DEST="$ABS_DEST" \
  135. DOCKER_API_VERSION="$DOCKER_API_VERSION" \
  136. DOCKER_BUILDKIT="$DOCKER_BUILDKIT" \
  137. DOCKER_INTEGRATION_DAEMON_DEST="$DOCKER_INTEGRATION_DAEMON_DEST" \
  138. DOCKER_TLS_VERIFY="$DOCKER_TEST_TLS_VERIFY" \
  139. DOCKER_CERT_PATH="$DOCKER_TEST_CERT_PATH" \
  140. DOCKER_ENGINE_GOARCH="$DOCKER_ENGINE_GOARCH" \
  141. DOCKER_GRAPHDRIVER="$DOCKER_GRAPHDRIVER" \
  142. DOCKER_USERLANDPROXY="$DOCKER_USERLANDPROXY" \
  143. DOCKER_HOST="$DOCKER_HOST" \
  144. DOCKER_REMAP_ROOT="$DOCKER_REMAP_ROOT" \
  145. DOCKER_REMOTE_DAEMON="$DOCKER_REMOTE_DAEMON" \
  146. DOCKER_ROOTLESS="$DOCKER_ROOTLESS" \
  147. GITHUB_ACTIONS="$GITHUB_ACTIONS" \
  148. GOCACHE="$GOCACHE" \
  149. GOPATH="$GOPATH" \
  150. GOTRACEBACK=all \
  151. HOME="$ABS_DEST/fake-HOME" \
  152. PATH="$PATH" \
  153. TEMP="$TEMP" \
  154. TEST_CLIENT_BINARY="$TEST_CLIENT_BINARY" \
  155. TEST_INTEGRATION_USE_SNAPSHOTTER="$TEST_INTEGRATION_USE_SNAPSHOTTER" \
  156. "$@"
  157. )
  158. }
  159. set_platform_timeout() {
  160. # Test timeout.
  161. if [ "${DOCKER_ENGINE_GOARCH}" = "arm64" ] || [ "${DOCKER_ENGINE_GOARCH}" = "arm" ]; then
  162. : "${TIMEOUT:=10m}"
  163. elif [ "${DOCKER_ENGINE_GOARCH}" = "windows" ]; then
  164. : "${TIMEOUT:=8m}"
  165. else
  166. : "${TIMEOUT:=5m}"
  167. fi
  168. if [ "${TEST_REPEAT}" -gt 1 ]; then
  169. # TIMEOUT needs to take TEST_REPEAT into account, or a premature time out may happen.
  170. # The following ugliness will:
  171. # - remove last character (usually 'm' from '10m')
  172. # - multiply by testcount
  173. # - add last character back
  174. TIMEOUT=$((${TIMEOUT::-1} * ${TEST_REPEAT}))${TIMEOUT:$((${#TIMEOUT} - 1)):1}
  175. fi
  176. }