Merge pull request #34000 from dnephin/test-integration-api

Introduce `test-integration` target
This commit is contained in:
Tibor Vass 2017-08-11 10:39:27 -07:00 коммит произвёл GitHub
Родитель aaee3ca6c1 e593b72cc9
Коммит f34e4d295d
32 изменённых файлов: 344 добавлений и 238 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -4,7 +4,7 @@
*.exe *.exe
*.exe~ *.exe~
*.orig *.orig
*.test test.main
.*.swp .*.swp
.DS_Store .DS_Store
# a .bashrc may be added to customize the build environment # a .bashrc may be added to customize the build environment

Просмотреть файл

@ -160,6 +160,10 @@ it! Take a look at existing tests for inspiration. [Run the full test
suite](https://docs.docker.com/opensource/project/test-and-docs/) on your branch before suite](https://docs.docker.com/opensource/project/test-and-docs/) on your branch before
submitting a pull request. submitting a pull request.
If your changes need integration tests, write them against the API. The `cli`
integration tests are slowly either migrated to API tests or moved away as unit
tests in `docker/cli` and end-to-end tests for docker.
Update the documentation when creating or modifying features. Test your Update the documentation when creating or modifying features. Test your
documentation changes for clarity, concision, and correctness, as well as a documentation changes for clarity, concision, and correctness, as well as a
clean documentation build. See our contributors guide for [our style clean documentation build. See our contributors guide for [our style

Просмотреть файл

@ -9,7 +9,7 @@
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash # docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
# #
# # Run the test suite: # # Run the test suite:
# docker run -e DOCKER_GITCOMMIT=foo --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py # docker run -e DOCKER_GITCOMMIT=foo --privileged docker hack/make.sh test-unit test-integration test-docker-py
# #
# # Publish a release: # # Publish a release:
# docker run --privileged \ # docker run --privileged \

Просмотреть файл

@ -9,7 +9,7 @@
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash # docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
# #
# # Run the test suite: # # Run the test suite:
# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py # docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
# #
# Note: AppArmor used to mess with privileged mode, but this is no longer # Note: AppArmor used to mess with privileged mode, but this is no longer
# the case. Therefore, you don't have to disable it anymore. # the case. Therefore, you don't have to disable it anymore.

Просмотреть файл

@ -9,7 +9,7 @@
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash # docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
# #
# # Run the test suite: # # Run the test suite:
# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py # docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
# #
# Note: AppArmor used to mess with privileged mode, but this is no longer # Note: AppArmor used to mess with privileged mode, but this is no longer
# the case. Therefore, you don't have to disable it anymore. # the case. Therefore, you don't have to disable it anymore.

Просмотреть файл

@ -9,7 +9,7 @@
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash # docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
# #
# # Run the test suite: # # Run the test suite:
# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py # docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
# #
# Note: AppArmor used to mess with privileged mode, but this is no longer # Note: AppArmor used to mess with privileged mode, but this is no longer
# the case. Therefore, you don't have to disable it anymore. # the case. Therefore, you don't have to disable it anymore.

Просмотреть файл

@ -9,7 +9,7 @@
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash # docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
# #
# # Run the test suite: # # Run the test suite:
# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py # docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
# #
# Note: AppArmor used to mess with privileged mode, but this is no longer # Note: AppArmor used to mess with privileged mode, but this is no longer
# the case. Therefore, you don't have to disable it anymore. # the case. Therefore, you don't have to disable it anymore.

Просмотреть файл

@ -1,7 +1,7 @@
# docker build -t docker:simple -f Dockerfile.simple . # docker build -t docker:simple -f Dockerfile.simple .
# docker run --rm docker:simple hack/make.sh dynbinary # docker run --rm docker:simple hack/make.sh dynbinary
# docker run --rm --privileged docker:simple hack/dind hack/make.sh test-unit # docker run --rm --privileged docker:simple hack/dind hack/make.sh test-unit
# docker run --rm --privileged -v /var/lib/docker docker:simple hack/dind hack/make.sh dynbinary test-integration-cli # docker run --rm --privileged -v /var/lib/docker docker:simple hack/dind hack/make.sh dynbinary test-integration
# This represents the bare minimum required to build and test Docker. # This represents the bare minimum required to build and test Docker.

Просмотреть файл

@ -1,4 +1,4 @@
.PHONY: all binary dynbinary build cross deb help init-go-pkg-cache install manpages rpm run shell test test-docker-py test-integration-cli test-unit tgz validate win .PHONY: all binary dynbinary build cross deb help init-go-pkg-cache install manpages rpm run shell test test-docker-py test-integration test-unit tgz validate win
# set the graph driver as the current graphdriver if not set # set the graph driver as the current graphdriver if not set
DOCKER_GRAPHDRIVER := $(if $(DOCKER_GRAPHDRIVER),$(DOCKER_GRAPHDRIVER),$(shell docker info 2>&1 | grep "Storage Driver" | sed 's/.*: //')) DOCKER_GRAPHDRIVER := $(if $(DOCKER_GRAPHDRIVER),$(DOCKER_GRAPHDRIVER),$(shell docker info 2>&1 | grep "Storage Driver" | sed 's/.*: //'))
@ -149,13 +149,15 @@ shell: build ## start a shell inside the build env
$(DOCKER_RUN_DOCKER) bash $(DOCKER_RUN_DOCKER) bash
test: build ## run the unit, integration and docker-py tests test: build ## run the unit, integration and docker-py tests
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary cross test-unit test-integration-cli test-docker-py $(DOCKER_RUN_DOCKER) hack/make.sh dynbinary cross test-unit test-integration test-docker-py
test-docker-py: build ## run the docker-py tests test-docker-py: build ## run the docker-py tests
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary test-docker-py $(DOCKER_RUN_DOCKER) hack/make.sh dynbinary test-docker-py
test-integration-cli: build ## run the integration tests test-integration-cli: test-integration ## (DEPRECATED) use test-integration
$(DOCKER_RUN_DOCKER) hack/make.sh build-integration-test-binary dynbinary test-integration-cli
test-integration: build ## run the integration tests
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary test-integration
test-unit: build ## run the unit tests test-unit: build ## run the unit tests
$(DOCKER_RUN_DOCKER) hack/make.sh test-unit $(DOCKER_RUN_DOCKER) hack/make.sh test-unit

Просмотреть файл

@ -37,14 +37,14 @@ More information is found within `make.ps1` by the author, @jhowardmsft
- Referenced via `make test` when running tests on a local machine, - Referenced via `make test` when running tests on a local machine,
or directly referenced when running tests inside a Docker development container. or directly referenced when running tests inside a Docker development container.
- When running on a local machine, `make test` to run all tests found in - When running on a local machine, `make test` to run all tests found in
`test`, `test-unit`, `test-integration-cli`, and `test-docker-py` on `test`, `test-unit`, `test-integration`, and `test-docker-py` on
your local machine. The default timeout is set in `make.sh` to 60 minutes your local machine. The default timeout is set in `make.sh` to 60 minutes
(`${TIMEOUT:=60m}`), since it currently takes up to an hour to run (`${TIMEOUT:=60m}`), since it currently takes up to an hour to run
all of the tests. all of the tests.
- When running inside a Docker development container, `hack/make.sh` does - When running inside a Docker development container, `hack/make.sh` does
not have a single target that runs all the tests. You need to provide a not have a single target that runs all the tests. You need to provide a
single command line with multiple targets that performs the same thing. single command line with multiple targets that performs the same thing.
An example referenced from [Run targets inside a development container](https://docs.docker.com/opensource/project/test-and-docs/#run-targets-inside-a-development-container): `root@5f8630b873fe:/go/src/github.com/moby/moby# hack/make.sh dynbinary binary cross test-unit test-integration-cli test-docker-py` An example referenced from [Run targets inside a development container](https://docs.docker.com/opensource/project/test-and-docs/#run-targets-inside-a-development-container): `root@5f8630b873fe:/go/src/github.com/moby/moby# hack/make.sh dynbinary binary cross test-unit test-integration test-docker-py`
- For more information related to testing outside the scope of this README, - For more information related to testing outside the scope of this README,
refer to refer to
[Run tests and test documentation](https://docs.docker.com/opensource/project/test-and-docs/) [Run tests and test documentation](https://docs.docker.com/opensource/project/test-and-docs/)

Просмотреть файл

@ -318,7 +318,7 @@ Function Run-UnitTests() {
$pkgList = $pkgList | Select-String -Pattern "github.com/docker/docker" $pkgList = $pkgList | Select-String -Pattern "github.com/docker/docker"
$pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/vendor" $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/vendor"
$pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/man" $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/man"
$pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/integration-cli" $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/integration"
$pkgList = $pkgList -replace "`r`n", " " $pkgList = $pkgList -replace "`r`n", " "
$goTestCommand = "go test" + $raceParm + " -cover -ldflags -w -tags """ + "autogen daemon" + """ -a """ + "-test.timeout=10m" + """ $pkgList" $goTestCommand = "go test" + $raceParm + " -cover -ldflags -w -tags """ + "autogen daemon" + """ -a """ + "-test.timeout=10m" + """ $pkgList"
Invoke-Expression $goTestCommand Invoke-Expression $goTestCommand

Просмотреть файл

@ -60,7 +60,7 @@ DEFAULT_BUNDLES=(
dynbinary dynbinary
test-unit test-unit
test-integration-cli test-integration
test-docker-py test-docker-py
cross cross

Просмотреть файл

@ -1,23 +1,23 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
if ! docker inspect -t image emptyfs &> /dev/null; then if ! docker image inspect emptyfs > /dev/null; then
# let's build a "docker save" tarball for "emptyfs" # build a "docker save" tarball for "emptyfs"
# see https://github.com/docker/docker/pull/5262 # see https://github.com/docker/docker/pull/5262
# and also https://github.com/docker/docker/issues/4242 # and also https://github.com/docker/docker/issues/4242
dir="$DEST/emptyfs" dir="$DEST/emptyfs"
mkdir -p "$dir" uuid=511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
mkdir -p "$dir/$uuid"
( (
cd "$dir" echo '{"emptyfs":{"latest":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158"}}' > "$dir/repositories"
echo '{"emptyfs":{"latest":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158"}}' > repositories cd "$dir/$uuid"
mkdir -p 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158 echo '{"id":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158","comment":"Imported from -","created":"2013-06-13T14:03:50.821769-07:00","container_config":{"Hostname":"","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"NetworkDisabled":false,"OnBuild":null},"docker_version":"0.4.0","architecture":"x86_64","Size":0}' > json
( echo '1.0' > VERSION
cd 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158 tar -cf layer.tar --files-from /dev/null
echo '{"id":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158","comment":"Imported from -","created":"2013-06-13T14:03:50.821769-07:00","container_config":{"Hostname":"","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"NetworkDisabled":false,"OnBuild":null},"docker_version":"0.4.0","architecture":"x86_64","Size":0}' > json )
echo '1.0' > VERSION (
tar -cf layer.tar --files-from /dev/null [ -n "$TESTDEBUG" ] && set -x
) tar -cC "$dir" . | docker load
) )
( set -x; tar -cC "$dir" . | docker load )
rm -rf "$dir" rm -rf "$dir"
fi fi

Просмотреть файл

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
bundle .detect-daemon-osarch source "$MAKEDIR/.detect-daemon-osarch"
if [ "$DOCKER_ENGINE_GOOS" != "windows" ]; then if [ "$DOCKER_ENGINE_GOOS" != "windows" ]; then
bundle .ensure-emptyfs bundle .ensure-emptyfs
fi fi

Просмотреть файл

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# see test-integration-cli for example usage of this script # see test-integration for example usage of this script
base="$ABS_DEST/.." base="$ABS_DEST/.."
export PATH="$base/binary-daemon:$base/dynbinary-daemon:$PATH" export PATH="$base/binary-daemon:$base/dynbinary-daemon:$PATH"
@ -76,24 +76,26 @@ if [ -z "$DOCKER_TEST_HOST" ]; then
# see https://github.com/docker/libcontainer/blob/master/apparmor/apparmor.go#L16 # see https://github.com/docker/libcontainer/blob/master/apparmor/apparmor.go#L16
export container="" export container=""
( (
set -x [ -n "$TESTDEBUG" ] && set -x
/etc/init.d/apparmor start /etc/init.d/apparmor start
) )
fi fi
export DOCKER_HOST="unix://$(cd "$DEST" && pwd)/docker.sock" # "pwd" tricks to make sure $DEST is an absolute path, not a relative one # "pwd" tricks to make sure $DEST is an absolute path, not a relative one
( set -x; exec \ export DOCKER_HOST="unix://$(cd "$DEST" && pwd)/docker.sock"
dockerd --debug \ (
--host "$DOCKER_HOST" \ echo "Starting dockerd"
--storage-driver "$DOCKER_GRAPHDRIVER" \ [ -n "$TESTDEBUG" ] && set -x
--pidfile "$DEST/docker.pid" \ exec \
--userland-proxy="$DOCKER_USERLANDPROXY" \ dockerd --debug \
$storage_params \ --host "$DOCKER_HOST" \
$extra_params \ --storage-driver "$DOCKER_GRAPHDRIVER" \
&> "$DEST/docker.log" --pidfile "$DEST/docker.pid" \
--userland-proxy="$DOCKER_USERLANDPROXY" \
$storage_params \
$extra_params \
&> "$DEST/docker.log"
) & ) &
# make sure that if the script exits unexpectedly, we stop this daemon we just started
trap 'bundle .integration-daemon-stop' EXIT
else else
export DOCKER_HOST="$DOCKER_TEST_HOST" export DOCKER_HOST="$DOCKER_TEST_HOST"
fi fi

Просмотреть файл

@ -1,11 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
if [ ! "$(go env GOOS)" = 'windows' ]; then if [ ! "$(go env GOOS)" = 'windows' ]; then
trap - EXIT # reset EXIT trap applied in .integration-daemon-start
for pidFile in $(find "$DEST" -name docker.pid); do for pidFile in $(find "$DEST" -name docker.pid); do
pid=$(set -x; cat "$pidFile") pid=$([ -n "$TESTDEBUG" ] && set -x; cat "$pidFile")
( set -x; kill "$pid" ) (
[ -n "$TESTDEBUG" ] && set -x
kill "$pid"
)
if ! wait "$pid"; then if ! wait "$pid"; then
echo >&2 "warning: PID $pid from $pidFile had a nonzero exit code" echo >&2 "warning: PID $pid from $pidFile had a nonzero exit code"
fi fi
@ -15,7 +16,7 @@ if [ ! "$(go env GOOS)" = 'windows' ]; then
# Stop apparmor if it is enabled # Stop apparmor if it is enabled
if [ -e "/sys/module/apparmor/parameters/enabled" ] && [ "$(cat /sys/module/apparmor/parameters/enabled)" == "Y" ]; then if [ -e "/sys/module/apparmor/parameters/enabled" ] && [ "$(cat /sys/module/apparmor/parameters/enabled)" == "Y" ]; then
( (
set -x [ -n "$TESTDEBUG" ] && set -x
/etc/init.d/apparmor stop /etc/init.d/apparmor stop
) )
fi fi

Просмотреть файл

@ -1,65 +1,72 @@
#!/usr/bin/env bash #!/usr/bin/env bash
: ${TEST_REPEAT:=0}
bundle_test_integration_cli() {
TESTFLAGS="$TESTFLAGS -check.v -check.timeout=${TIMEOUT} -test.timeout=360m"
go_test_dir integration-cli $DOCKER_INTEGRATION_TESTS_VERIFIED
}
# If $TESTFLAGS is set in the environment, it is passed as extra arguments to 'go test'.
# You can use this to select certain tests to run, e.g.
#
# TESTFLAGS='-test.run ^TestBuild$' ./hack/make.sh test-unit
# #
# For integration-cli test, we use [gocheck](https://labix.org/gocheck), if you want # For integration-cli test, we use [gocheck](https://labix.org/gocheck), if you want
# to run certain tests on your local host, you should run with command: # to run certain tests on your local host, you should run with command:
# #
# TESTFLAGS='-check.f DockerSuite.TestBuild*' ./hack/make.sh binary test-integration-cli # TESTFLAGS='-check.f DockerSuite.TestBuild*' ./hack/make.sh binary test-integration
# #
go_test_dir() {
dir=$1 source "$SCRIPTDIR/make/.go-autogen"
precompiled=$2
testbinary="$ABS_DEST/test.main" : ${TEST_REPEAT:=1}
testcover=()
testcoverprofile=() integration_api_dirs=("$(
find ./integration -type d |
grep -vE '^(./integration$|./integration/util)')")
run_test_integration() {
local flags="-test.v -test.timeout=${TIMEOUT} $TESTFLAGS"
for dir in $integration_api_dirs; do
(
cd $dir
echo "Running $PWD"
test_env ./test.main $flags
)
done
( (
set -e flags="-check.v -check.timeout=${TIMEOUT} -test.timeout=360m $TESTFLAGS"
mkdir -p "$DEST/coverprofiles" cd integration-cli
export DEST="$ABS_DEST" # in a subshell this is safe -- our integration-cli tests need DEST, and "cd" screws it up echo "Running $PWD"
if [ -z $precompiled ]; then test_env ./test.main $flags
ensure_test_dir $1 $testbinary
fi
cd "$dir"
i=0
while ((++i)); do
test_env "$testbinary" $TESTFLAGS
if [ $i -gt "$TEST_REPEAT" ]; then
break
fi
echo "Repeating test ($i)"
done
) )
} }
ensure_test_dir() { build_test_suite_binaries() {
( build_test_suite_binary ./integration-cli "test.main"
# make sure a test dir will compile for dir in $integration_api_dirs; do
dir="$1" build_test_suite_binary "$dir" "test.main"
out="$2" done
echo Building test dir: "$dir"
set -xe
cd "$dir"
go test -c -o "$out" -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}"
)
} }
# Build a binary for a test suite package
build_test_suite_binary() {
local dir="$1"
local out="$2"
echo Building test suite binary "$dir/$out"
go test -c -o "$dir/$out" -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}" "$dir"
}
cleanup_test_suite_binaries() {
[ -n "$TESTDEBUG" ] && return
echo "Removing test suite binaries"
find integration* -name test.main | xargs -r rm
}
repeat() {
for i in $(seq 1 $TEST_REPEAT); do
echo "Running integration-test (iteration $i)"
$@
done
}
# use "env -i" to tightly control the environment variables that bleed into the tests
test_env() { test_env() {
( (
set -xe set -e
# use "env -i" to tightly control the environment variables that bleed into the tests [ -n "$TESTDEBUG" ] && set -x
env -i \ env -i \
DEST="$DEST" \ DEST="$ABS_DEST" \
DOCKER_CLI_VERSION="$DOCKER_CLI_VERSION" \ DOCKER_CLI_VERSION="$DOCKER_CLI_VERSION" \
DOCKER_API_VERSION="$DOCKER_API_VERSION" \ DOCKER_API_VERSION="$DOCKER_API_VERSION" \
DOCKER_INTEGRATION_DAEMON_DEST="$DOCKER_INTEGRATION_DAEMON_DEST" \ DOCKER_INTEGRATION_DAEMON_DEST="$DOCKER_INTEGRATION_DAEMON_DEST" \
@ -82,3 +89,19 @@ test_env() {
"$@" "$@"
) )
} }
error_on_leaked_containerd_shims() {
if [ "$(go env GOOS)" == 'windows' ]; then
return
fi
leftovers=$(ps -ax -o pid,cmd |
awk '$2 == "docker-containerd-shim" && $4 ~ /.*\/bundles\/.*\/test-integration/ { print $1 }')
if [ -n "$leftovers" ]; then
ps aux
kill -9 $leftovers 2> /dev/null
echo "!!!! WARNING you have left over shim(s), Cleanup your test !!!!"
exit 1
fi
}

Просмотреть файл

@ -1,13 +0,0 @@
#!/usr/bin/env bash
set -e
rm -rf "$DEST"
DEST="$ABS_DEST/../test-integration-cli"
source "$SCRIPTDIR/make/.go-autogen"
if [ -z $DOCKER_INTEGRATION_TESTS_VERIFIED ]; then
source ${MAKEDIR}/.integration-test-helpers
ensure_test_dir integration-cli "$DEST/test.main"
export DOCKER_INTEGRATION_TESTS_VERIFIED=1
fi

22
hack/make/test-integration Executable file
Просмотреть файл

@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -e
source "${MAKEDIR}/.go-autogen"
source hack/make/.integration-test-helpers
(
build_test_suite_binaries
bundle .integration-daemon-start
bundle .integration-daemon-setup
local testexit=0
( repeat run_test_integration ) || testexit=$?
# Always run cleanup, even if the subshell fails
bundle .integration-daemon-stop
cleanup_test_suite_binaries
error_on_leaked_containerd_shims
exit $testexit
) 2>&1 | tee -a "$DEST/test.log"

Просмотреть файл

@ -1,29 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
echo "WARNING: test-integration-cli is DEREPCATED. Use test-integration." >&2
source "${MAKEDIR}/.go-autogen" # TODO: remove this and exit 1 once CI has changed to use test-integration
source hack/make/.integration-test-helpers bundle test-integration
# subshell so that we can export PATH without breaking other things
(
bundle .integration-daemon-start
bundle .integration-daemon-setup
bundle_test_integration_cli
bundle .integration-daemon-stop
if [ "$(go env GOOS)" != 'windows' ]
then
leftovers=$(ps -ax -o pid,cmd | awk '$2 == "docker-containerd-shim" && $4 ~ /.*\/bundles\/.*\/test-integration-cli/ { print $1 }')
if [ -n "$leftovers" ]
then
ps aux
kill -9 $leftovers 2> /dev/null
echo "!!!! WARNING you have left over shim(s), Cleanup your test !!!!"
exit 1
fi
fi
) 2>&1 | tee -a "$DEST/test.log"

Просмотреть файл

@ -5,3 +5,5 @@ bundle .integration-daemon-setup
export ABS_DEST export ABS_DEST
bash +e bash +e
bundle .integration-daemon-stop

Просмотреть файл

@ -57,7 +57,7 @@ if [ "$1" != '--release-regardless-of-test-failure' ]; then
RELEASE_BUNDLES=( RELEASE_BUNDLES=(
test-unit test-unit
"${RELEASE_BUNDLES[@]}" "${RELEASE_BUNDLES[@]}"
test-integration-cli test-integration
) )
fi fi

Просмотреть файл

@ -16,7 +16,7 @@ TESTFLAGS+=" -test.timeout=${TIMEOUT:-5m}"
BUILDFLAGS=( -tags "netgo seccomp libdm_no_deferred_remove" ) BUILDFLAGS=( -tags "netgo seccomp libdm_no_deferred_remove" )
TESTDIRS="${TESTDIRS:-"./..."}" TESTDIRS="${TESTDIRS:-"./..."}"
exclude_paths="/vendor/|/integration-cli" exclude_paths="/vendor/|/integration"
if [ "$(go env GOHOSTOS)" = 'solaris' ]; then if [ "$(go env GOHOSTOS)" = 'solaris' ]; then
exclude_paths="$exclude_paths|/daemon/graphdriver" exclude_paths="$exclude_paths|/daemon/graphdriver"
fi fi

Просмотреть файл

@ -4,10 +4,8 @@ import (
"fmt" "fmt"
"net/http/httptest" "net/http/httptest"
"os" "os"
"os/exec"
"path" "path"
"path/filepath" "path/filepath"
"strings"
"sync" "sync"
"syscall" "syscall"
"testing" "testing"
@ -72,17 +70,7 @@ func TestMain(m *testing.M) {
func Test(t *testing.T) { func Test(t *testing.T) {
cli.EnsureTestEnvIsLoaded(t) cli.EnsureTestEnvIsLoaded(t)
fakestorage.EnsureTestEnvIsLoaded(t) fakestorage.EnsureTestEnvIsLoaded(t)
cmd := exec.Command(dockerBinary, "images", "-f", "dangling=false", "--format", "{{.Repository}}:{{.Tag}}") environment.ProtectImages(t, testEnv)
cmd.Env = appendBaseEnv(true)
out, err := cmd.CombinedOutput()
if err != nil {
panic(fmt.Errorf("err=%v\nout=%s\n", err, out))
}
images := strings.Split(strings.TrimSpace(string(out)), "\n")
testEnv.ProtectImage(t, images...)
if testEnv.DaemonPlatform() == "linux" {
ensureFrozenImagesLinux(t)
}
check.TestingT(t) check.TestingT(t)
} }

Просмотреть файл

@ -11,82 +11,6 @@ import (
"github.com/go-check/check" "github.com/go-check/check"
) )
func (s *DockerSuite) TestAPICreateWithNotExistImage(c *check.C) {
name := "test"
config := map[string]interface{}{
"Image": "test456:v1",
"Volumes": map[string]struct{}{"/tmp": {}},
}
status, body, err := request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusNotFound)
expected := "No such image: test456:v1"
c.Assert(getErrorMessage(c, body), checker.Contains, expected)
config2 := map[string]interface{}{
"Image": "test456",
"Volumes": map[string]struct{}{"/tmp": {}},
}
status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config2, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusNotFound)
expected = "No such image: test456:latest"
c.Assert(getErrorMessage(c, body), checker.Equals, expected)
config3 := map[string]interface{}{
"Image": "sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efeaaaa",
}
status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config3, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusNotFound)
expected = "No such image: sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efeaaaa"
c.Assert(getErrorMessage(c, body), checker.Equals, expected)
}
// Test for #25099
func (s *DockerSuite) TestAPICreateEmptyEnv(c *check.C) {
name := "test1"
config := map[string]interface{}{
"Image": "busybox",
"Env": []string{"", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
"Cmd": []string{"true"},
}
status, body, err := request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
expected := "invalid environment variable:"
c.Assert(getErrorMessage(c, body), checker.Contains, expected)
name = "test2"
config = map[string]interface{}{
"Image": "busybox",
"Env": []string{"=", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
"Cmd": []string{"true"},
}
status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
expected = "invalid environment variable: ="
c.Assert(getErrorMessage(c, body), checker.Contains, expected)
name = "test3"
config = map[string]interface{}{
"Image": "busybox",
"Env": []string{"=foo", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
"Cmd": []string{"true"},
}
status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
expected = "invalid environment variable: =foo"
c.Assert(getErrorMessage(c, body), checker.Contains, expected)
}
func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) { func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) {
// test invalid Interval in Healthcheck: less than 0s // test invalid Interval in Healthcheck: less than 0s
name := "test1" name := "test1"

Просмотреть файл

@ -1,5 +1,16 @@
package environment package environment
import (
"strings"
"github.com/docker/docker/integration-cli/fixtures/load"
icmd "github.com/docker/docker/pkg/testutil/cmd"
)
type protectedElements struct {
images map[string]struct{}
}
// ProtectImage adds the specified image(s) to be protected in case of clean // ProtectImage adds the specified image(s) to be protected in case of clean
func (e *Execution) ProtectImage(t testingT, images ...string) { func (e *Execution) ProtectImage(t testingT, images ...string) {
for _, image := range images { for _, image := range images {
@ -7,6 +18,31 @@ func (e *Execution) ProtectImage(t testingT, images ...string) {
} }
} }
type protectedElements struct { // ProtectImages protects existing images and on linux frozen images from being
images map[string]struct{} // cleaned up at the end of test runs
func ProtectImages(t testingT, testEnv *Execution) {
images := getExistingImages(t, testEnv)
if testEnv.DaemonPlatform() == "linux" {
images = append(images, ensureFrozenImagesLinux(t, testEnv)...)
}
testEnv.ProtectImage(t, images...)
}
func getExistingImages(t testingT, testEnv *Execution) []string {
// TODO: use API instead of cli
result := icmd.RunCommand(testEnv.dockerBinary, "images", "-f", "dangling=false", "--format", "{{.Repository}}:{{.Tag}}")
result.Assert(t, icmd.Success)
return strings.Split(strings.TrimSpace(result.Stdout()), "\n")
}
func ensureFrozenImagesLinux(t testingT, testEnv *Execution) []string {
images := []string{"busybox:latest", "hello-world:frozen", "debian:jessie"}
err := load.FrozenImagesLinux(testEnv.DockerBinary(), images...)
if err != nil {
result := icmd.RunCommand(testEnv.DockerBinary(), "image", "ls")
t.Logf(result.String())
t.Fatalf("%+v", err)
}
return images
} }

Просмотреть файл

@ -24,16 +24,6 @@ type logT interface {
Logf(string, ...interface{}) Logf(string, ...interface{})
} }
func ensureFrozenImagesLinux(t testingT) {
images := []string{"busybox:latest", "hello-world:frozen", "debian:jessie"}
err := load.FrozenImagesLinux(dockerBinary, images...)
if err != nil {
t.Logf(dockerCmdWithError("images"))
t.Fatalf("%+v", err)
}
defer testEnv.ProtectImage(t, images...)
}
var ensureSyscallTestOnce sync.Once var ensureSyscallTestOnce sync.Once
func ensureSyscallTest(c *check.C) { func ensureSyscallTest(c *check.C) {

Просмотреть файл

@ -0,0 +1,93 @@
package container
import (
"context"
"strconv"
"testing"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/integration/util/request"
"github.com/docker/docker/pkg/testutil"
)
func TestCreateFailsWhenIdentifierDoesNotExist(t *testing.T) {
defer setupTest(t)()
client := request.NewAPIClient(t)
testCases := []struct {
doc string
image string
expectedError string
}{
{
doc: "image and tag",
image: "test456:v1",
expectedError: "No such image: test456:v1",
},
{
doc: "image no tag",
image: "test456",
expectedError: "No such image: test456",
},
{
doc: "digest",
image: "sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efeaaaa",
expectedError: "No such image: sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efeaaaa",
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.doc, func(t *testing.T) {
t.Parallel()
_, err := client.ContainerCreate(context.Background(),
&container.Config{Image: tc.image},
&container.HostConfig{},
&network.NetworkingConfig{},
"foo",
)
testutil.ErrorContains(t, err, tc.expectedError)
})
}
}
func TestCreateWithInvalidEnv(t *testing.T) {
defer setupTest(t)()
client := request.NewAPIClient(t)
testCases := []struct {
env string
expectedError string
}{
{
env: "",
expectedError: "invalid environment variable:",
},
{
env: "=",
expectedError: "invalid environment variable: =",
},
{
env: "=foo",
expectedError: "invalid environment variable: =foo",
},
}
for index, tc := range testCases {
tc := tc
t.Run(strconv.Itoa(index), func(t *testing.T) {
t.Parallel()
_, err := client.ContainerCreate(context.Background(),
&container.Config{
Image: "busybox",
Env: []string{tc.env},
},
&container.HostConfig{},
&network.NetworkingConfig{},
"foo",
)
testutil.ErrorContains(t, err, tc.expectedError)
})
}
}

Просмотреть файл

@ -0,0 +1,37 @@
package container
import (
"fmt"
"os"
"testing"
"github.com/docker/docker/integration-cli/environment"
)
var (
testEnv *environment.Execution
)
func TestMain(m *testing.M) {
var err error
testEnv, err = environment.New()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// TODO: replace this with `testEnv.Print()` to print the full env
if testEnv.LocalDaemon() {
fmt.Println("INFO: Testing against a local daemon")
} else {
fmt.Println("INFO: Testing against a remote daemon")
}
res := m.Run()
os.Exit(res)
}
func setupTest(t *testing.T) func() {
environment.ProtectImages(t, testEnv)
return func() { testEnv.Clean(t, testEnv.DockerBinary()) }
}

3
integration/doc.go Normal file
Просмотреть файл

@ -0,0 +1,3 @@
// Package integration provides integrations tests for Moby (API).
// These tests require a daemon (dockerd for now) to run.
package integration

Просмотреть файл

@ -0,0 +1,15 @@
package request
import (
"testing"
"github.com/docker/docker/client"
"github.com/stretchr/testify/require"
)
// NewAPIClient returns a docker API client configured from environment variables
func NewAPIClient(t *testing.T) client.APIClient {
clt, err := client.NewEnvClient()
require.NoError(t, err)
return clt
}

Просмотреть файл

@ -17,7 +17,7 @@ From the root of the Docker/Docker repo one can use make to execute the followin
- make default - make default
- make shell - make shell
- make test-unit - make test-unit
- make test-integration-cli - make test-integration
- make - make
The Makefile does include logic to determine on which OS and architecture the Docker Development Image is built. The Makefile does include logic to determine on which OS and architecture the Docker Development Image is built.