.integration-test-helpers 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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. : "${TIMEOUT:=5m}"
  16. : "${TESTFLAGS:=}"
  17. : "${TESTDEBUG:=}"
  18. : "${TESTCOVERAGE:=}"
  19. : "${GOCACHE:=$(go env GOCACHE)}"
  20. setup_integration_test_filter() {
  21. if [ -z "${TEST_FILTER}" ]; then
  22. return
  23. fi
  24. local dirs
  25. local files
  26. if files=$(grep -rIlE --include '*_test.go' "func .*${TEST_FILTER}.*\(. \*testing\.T\)" ./integration*/); then
  27. dirs=$(echo "$files" | xargs -I file dirname file | uniq)
  28. fi
  29. if [ -z "${TEST_SKIP_INTEGRATION}" ]; then
  30. : "${TEST_INTEGRATION_DIR:=$(echo "$dirs" | grep -v '^\./integration-cli$')}"
  31. if [ -z "${TEST_INTEGRATION_DIR}" ]; then
  32. echo "Skipping integration tests since the supplied filter \"${TEST_FILTER}\" omits all integration tests"
  33. TEST_SKIP_INTEGRATION=1
  34. fi
  35. fi
  36. if [ -z "${TEST_SKIP_INTEGRATION_CLI}" ]; then
  37. if ! echo "$dirs" | grep -q '^./integration-cli$'; then
  38. TEST_SKIP_INTEGRATION_CLI=1
  39. echo "Skipping integration-cli tests since the supplied filter \"${TEST_FILTER}\" omits all integration-cli tests"
  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_repeat_timeout
  51. local failed=0
  52. if [ -z "${TEST_SKIP_INTEGRATION}" ]; then
  53. if ! run_test_integration_suites "${integration_api_dirs}"; then
  54. if [ -n "${TEST_INTEGRATION_FAIL_FAST}" ]; then
  55. return 1
  56. fi
  57. failed=1
  58. fi
  59. fi
  60. if [ -z "${TEST_SKIP_INTEGRATION_CLI}" ]; then
  61. if ! TIMEOUT=360m run_test_integration_suites integration-cli; then
  62. return 1
  63. fi
  64. fi
  65. if [ $failed -eq 1 ]; then
  66. return 1
  67. fi
  68. }
  69. run_test_integration_suites() {
  70. local dirs="$1"
  71. local flags="-test.v -test.timeout=${TIMEOUT} $TESTFLAGS "
  72. if [ -n "${TEST_FILTER}" ]; then
  73. if [ "$dirs" == "integration-cli" ]; then
  74. flags+=" -test.run /${TEST_FILTER}"
  75. else
  76. flags+=" -test.run ${TEST_FILTER}"
  77. fi
  78. fi
  79. local failed=0
  80. for dir in ${dirs}; do
  81. if ! (
  82. cd "$dir"
  83. # Create a useful package name based on the tests's $dir. We need to take
  84. # into account that "$dir" can be either an absolute (/go/src/github.com/docker/docker/integration/foo)
  85. # or relative (./integration/foo) path. To account for both, first we strip
  86. # the absolute path, then remove any leading periods and slashes.
  87. pkgname="${dir}"
  88. pkgname="${pkgname#*${GOPATH}/src/${DOCKER_PKG}}"
  89. pkgname="${pkgname#*.}"
  90. pkgname="${pkgname#*\/}"
  91. # Finally, we use periods as separator (instead of slashes) to be more
  92. # in line with Java package names (which is what junit.xml was designed for)
  93. pkgname="$(go env GOARCH).${pkgname//\//.}"
  94. pkgtestflags=$flags
  95. if [ -n "${TESTCOVERAGE}" ]; then
  96. pkgtestflags="$pkgtestflags -test.coverprofile=${ABS_DEST}/${pkgname//./-}-coverage.out"
  97. fi
  98. echo "Running $PWD (${pkgname}) flags=${pkgtestflags}"
  99. [ -n "$TESTDEBUG" ] && set -x
  100. if [ -n "$DELVE_PORT" ]; then
  101. delve_listen_port="${DELVE_PORT##*:}"
  102. test_env dlv --listen="0.0.0.0:${delve_listen_port}" \
  103. --headless=true \
  104. --log \
  105. --api-version=2 \
  106. --only-same-user=false \
  107. --check-go-version=false \
  108. --accept-multiclient \
  109. test ./ -- ${pkgtestflags}
  110. else
  111. # shellcheck disable=SC2086
  112. test_env gotestsum \
  113. --format=standard-verbose \
  114. --jsonfile="${ABS_DEST}/${pkgname//./-}-go-test-report.json" \
  115. --junitfile="${ABS_DEST}/${pkgname//./-}-junit-report.xml" \
  116. --raw-command \
  117. -- go tool test2json -p "${pkgname}" -t ./test.main ${pkgtestflags}
  118. fi
  119. ); then
  120. if [ -n "${TEST_INTEGRATION_FAIL_FAST}" ]; then
  121. return 1
  122. fi
  123. failed=1
  124. fi
  125. done
  126. if [ $failed -eq 1 ]; then
  127. return 1
  128. fi
  129. }
  130. build_test_suite_binaries() {
  131. if [ -n "${DOCKER_INTEGRATION_TESTS_VERIFIED}" ]; then
  132. echo "Skipping building test binaries; as DOCKER_INTEGRATION_TESTS_VERIFIED is set"
  133. return
  134. fi
  135. if [ -z "${TEST_SKIP_INTEGRATION_CLI}" ]; then
  136. build_test_suite_binary ./integration-cli "test.main"
  137. fi
  138. if [ -z "${TEST_SKIP_INTEGRATION}" ]; then
  139. for dir in ${integration_api_dirs}; do
  140. build_test_suite_binary "$dir" "test.main"
  141. done
  142. fi
  143. }
  144. # Build a binary for a test suite package
  145. build_test_suite_binary() {
  146. local dir="$1"
  147. local out="$2"
  148. local testflags
  149. echo Building test suite binary "$dir/$out"
  150. if [ -n "${TESTCOVERAGE}" ]; then
  151. testflags="-cover -covermode=atomic"
  152. fi
  153. go test ${testflags} -c -o "$dir/$out" -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}" "$dir"
  154. }
  155. cleanup_test_suite_binaries() {
  156. [ -n "$TESTDEBUG" ] && return
  157. echo "Removing test suite binaries"
  158. # shellcheck disable=SC2038
  159. find integration* -name test.main | xargs -r rm
  160. }
  161. repeat() {
  162. for i in $(seq 1 ${TEST_REPEAT}); do
  163. echo "Running integration-test (iteration $i)"
  164. $@
  165. done
  166. }
  167. # use "env -i" to tightly control the environment variables that bleed into the tests
  168. test_env() {
  169. (
  170. set -e
  171. [ -n "$TESTDEBUG" ] && set -x
  172. env -i \
  173. DEST="$ABS_DEST" \
  174. DOCKER_API_VERSION="$DOCKER_API_VERSION" \
  175. DOCKER_BUILDKIT="$DOCKER_BUILDKIT" \
  176. DOCKER_INTEGRATION_DAEMON_DEST="$DOCKER_INTEGRATION_DAEMON_DEST" \
  177. DOCKER_TLS_VERIFY="$DOCKER_TEST_TLS_VERIFY" \
  178. DOCKER_CERT_PATH="$DOCKER_TEST_CERT_PATH" \
  179. DOCKER_GRAPHDRIVER="$DOCKER_GRAPHDRIVER" \
  180. DOCKER_USERLANDPROXY="$DOCKER_USERLANDPROXY" \
  181. DOCKER_HOST="$DOCKER_HOST" \
  182. DOCKER_REMAP_ROOT="$DOCKER_REMAP_ROOT" \
  183. DOCKER_REMOTE_DAEMON="$DOCKER_REMOTE_DAEMON" \
  184. DOCKER_ROOTLESS="$DOCKER_ROOTLESS" \
  185. GITHUB_ACTIONS="$GITHUB_ACTIONS" \
  186. GO111MODULE="$GO111MODULE" \
  187. GOCACHE="$GOCACHE" \
  188. GOPATH="$GOPATH" \
  189. GOTRACEBACK=all \
  190. HOME="$ABS_DEST/fake-HOME" \
  191. PATH="$PATH" \
  192. TEMP="$TEMP" \
  193. TEST_CLIENT_BINARY="$TEST_CLIENT_BINARY" \
  194. TEST_INTEGRATION_USE_SNAPSHOTTER="$TEST_INTEGRATION_USE_SNAPSHOTTER" \
  195. OTEL_EXPORTER_OTLP_ENDPOINT="$OTEL_EXPORTER_OTLP_ENDPOINT" \
  196. OTEL_SERVICE_NAME="$OTEL_SERVICE_NAME" \
  197. "$@"
  198. )
  199. }
  200. set_repeat_timeout() {
  201. if [ "${TEST_REPEAT}" -gt 1 ]; then
  202. # TIMEOUT needs to take TEST_REPEAT into account, or a premature time out may happen.
  203. # The following ugliness will:
  204. # - remove last character (usually 'm' from '10m')
  205. # - multiply by testcount
  206. # - add last character back
  207. TIMEOUT=$((${TIMEOUT::-1} * ${TEST_REPEAT}))${TIMEOUT:$((${#TIMEOUT} - 1)):1}
  208. fi
  209. }