Merge pull request #34000 from dnephin/test-integration-api
Introduce `test-integration` target
This commit is contained in:
commit
f34e4d295d
32 changed files with 344 additions and 238 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -4,7 +4,7 @@
|
|||
*.exe
|
||||
*.exe~
|
||||
*.orig
|
||||
*.test
|
||||
test.main
|
||||
.*.swp
|
||||
.DS_Store
|
||||
# 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
|
||||
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
|
||||
documentation changes for clarity, concision, and correctness, as well as a
|
||||
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
|
||||
#
|
||||
# # 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:
|
||||
# docker run --privileged \
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
|
||||
#
|
||||
# # 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
|
||||
# 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
|
||||
#
|
||||
# # 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
|
||||
# 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
|
||||
#
|
||||
# # 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
|
||||
# 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
|
||||
#
|
||||
# # 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
|
||||
# the case. Therefore, you don't have to disable it anymore.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# docker build -t docker:simple -f Dockerfile.simple .
|
||||
# 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 -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.
|
||||
|
||||
|
|
10
Makefile
10
Makefile
|
@ -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
|
||||
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
|
||||
|
||||
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
|
||||
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary test-docker-py
|
||||
|
||||
test-integration-cli: build ## run the integration tests
|
||||
$(DOCKER_RUN_DOCKER) hack/make.sh build-integration-test-binary dynbinary test-integration-cli
|
||||
test-integration-cli: test-integration ## (DEPRECATED) use test-integration
|
||||
|
||||
test-integration: build ## run the integration tests
|
||||
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary test-integration
|
||||
|
||||
test-unit: build ## run the unit tests
|
||||
$(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,
|
||||
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
|
||||
`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
|
||||
(`${TIMEOUT:=60m}`), since it currently takes up to an hour to run
|
||||
all of the tests.
|
||||
- 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
|
||||
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,
|
||||
refer to
|
||||
[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 -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/integration-cli"
|
||||
$pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/integration"
|
||||
$pkgList = $pkgList -replace "`r`n", " "
|
||||
$goTestCommand = "go test" + $raceParm + " -cover -ldflags -w -tags """ + "autogen daemon" + """ -a """ + "-test.timeout=10m" + """ $pkgList"
|
||||
Invoke-Expression $goTestCommand
|
||||
|
|
|
@ -60,7 +60,7 @@ DEFAULT_BUNDLES=(
|
|||
dynbinary
|
||||
|
||||
test-unit
|
||||
test-integration-cli
|
||||
test-integration
|
||||
test-docker-py
|
||||
|
||||
cross
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if ! docker inspect -t image emptyfs &> /dev/null; then
|
||||
# let's build a "docker save" tarball for "emptyfs"
|
||||
if ! docker image inspect emptyfs > /dev/null; then
|
||||
# build a "docker save" tarball for "emptyfs"
|
||||
# see https://github.com/docker/docker/pull/5262
|
||||
# and also https://github.com/docker/docker/issues/4242
|
||||
dir="$DEST/emptyfs"
|
||||
mkdir -p "$dir"
|
||||
uuid=511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
|
||||
mkdir -p "$dir/$uuid"
|
||||
(
|
||||
cd "$dir"
|
||||
echo '{"emptyfs":{"latest":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158"}}' > repositories
|
||||
mkdir -p 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
|
||||
(
|
||||
cd 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
|
||||
tar -cf layer.tar --files-from /dev/null
|
||||
)
|
||||
echo '{"emptyfs":{"latest":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158"}}' > "$dir/repositories"
|
||||
cd "$dir/$uuid"
|
||||
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"
|
||||
fi
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
bundle .detect-daemon-osarch
|
||||
source "$MAKEDIR/.detect-daemon-osarch"
|
||||
if [ "$DOCKER_ENGINE_GOOS" != "windows" ]; then
|
||||
bundle .ensure-emptyfs
|
||||
fi
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/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/.."
|
||||
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
|
||||
export container=""
|
||||
(
|
||||
set -x
|
||||
[ -n "$TESTDEBUG" ] && set -x
|
||||
/etc/init.d/apparmor start
|
||||
)
|
||||
fi
|
||||
|
||||
export DOCKER_HOST="unix://$(cd "$DEST" && pwd)/docker.sock" # "pwd" tricks to make sure $DEST is an absolute path, not a relative one
|
||||
( set -x; exec \
|
||||
dockerd --debug \
|
||||
--host "$DOCKER_HOST" \
|
||||
--storage-driver "$DOCKER_GRAPHDRIVER" \
|
||||
--pidfile "$DEST/docker.pid" \
|
||||
--userland-proxy="$DOCKER_USERLANDPROXY" \
|
||||
$storage_params \
|
||||
$extra_params \
|
||||
&> "$DEST/docker.log"
|
||||
# "pwd" tricks to make sure $DEST is an absolute path, not a relative one
|
||||
export DOCKER_HOST="unix://$(cd "$DEST" && pwd)/docker.sock"
|
||||
(
|
||||
echo "Starting dockerd"
|
||||
[ -n "$TESTDEBUG" ] && set -x
|
||||
exec \
|
||||
dockerd --debug \
|
||||
--host "$DOCKER_HOST" \
|
||||
--storage-driver "$DOCKER_GRAPHDRIVER" \
|
||||
--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
|
||||
export DOCKER_HOST="$DOCKER_TEST_HOST"
|
||||
fi
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
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
|
||||
pid=$(set -x; cat "$pidFile")
|
||||
( set -x; kill "$pid" )
|
||||
pid=$([ -n "$TESTDEBUG" ] && set -x; cat "$pidFile")
|
||||
(
|
||||
[ -n "$TESTDEBUG" ] && set -x
|
||||
kill "$pid"
|
||||
)
|
||||
if ! wait "$pid"; then
|
||||
echo >&2 "warning: PID $pid from $pidFile had a nonzero exit code"
|
||||
fi
|
||||
|
@ -15,7 +16,7 @@ if [ ! "$(go env GOOS)" = 'windows' ]; then
|
|||
# Stop apparmor if it is enabled
|
||||
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
|
||||
)
|
||||
fi
|
||||
|
|
|
@ -1,65 +1,72 @@
|
|||
#!/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
|
||||
# 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
|
||||
precompiled=$2
|
||||
testbinary="$ABS_DEST/test.main"
|
||||
testcover=()
|
||||
testcoverprofile=()
|
||||
|
||||
source "$SCRIPTDIR/make/.go-autogen"
|
||||
|
||||
: ${TEST_REPEAT:=1}
|
||||
|
||||
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
|
||||
mkdir -p "$DEST/coverprofiles"
|
||||
export DEST="$ABS_DEST" # in a subshell this is safe -- our integration-cli tests need DEST, and "cd" screws it up
|
||||
if [ -z $precompiled ]; then
|
||||
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
|
||||
flags="-check.v -check.timeout=${TIMEOUT} -test.timeout=360m $TESTFLAGS"
|
||||
cd integration-cli
|
||||
echo "Running $PWD"
|
||||
test_env ./test.main $flags
|
||||
)
|
||||
}
|
||||
|
||||
ensure_test_dir() {
|
||||
(
|
||||
# make sure a test dir will compile
|
||||
dir="$1"
|
||||
out="$2"
|
||||
echo Building test dir: "$dir"
|
||||
set -xe
|
||||
cd "$dir"
|
||||
go test -c -o "$out" -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}"
|
||||
)
|
||||
build_test_suite_binaries() {
|
||||
build_test_suite_binary ./integration-cli "test.main"
|
||||
for dir in $integration_api_dirs; do
|
||||
build_test_suite_binary "$dir" "test.main"
|
||||
done
|
||||
}
|
||||
|
||||
# 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() {
|
||||
(
|
||||
set -xe
|
||||
# use "env -i" to tightly control the environment variables that bleed into the tests
|
||||
set -e
|
||||
[ -n "$TESTDEBUG" ] && set -x
|
||||
env -i \
|
||||
DEST="$DEST" \
|
||||
DEST="$ABS_DEST" \
|
||||
DOCKER_CLI_VERSION="$DOCKER_CLI_VERSION" \
|
||||
DOCKER_API_VERSION="$DOCKER_API_VERSION" \
|
||||
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
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
|
||||
set -e
|
||||
echo "WARNING: test-integration-cli is DEREPCATED. Use test-integration." >&2
|
||||
|
||||
source "${MAKEDIR}/.go-autogen"
|
||||
source hack/make/.integration-test-helpers
|
||||
|
||||
# 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"
|
||||
# TODO: remove this and exit 1 once CI has changed to use test-integration
|
||||
bundle test-integration
|
||||
|
|
|
@ -5,3 +5,5 @@ bundle .integration-daemon-setup
|
|||
|
||||
export ABS_DEST
|
||||
bash +e
|
||||
|
||||
bundle .integration-daemon-stop
|
||||
|
|
|
@ -57,7 +57,7 @@ if [ "$1" != '--release-regardless-of-test-failure' ]; then
|
|||
RELEASE_BUNDLES=(
|
||||
test-unit
|
||||
"${RELEASE_BUNDLES[@]}"
|
||||
test-integration-cli
|
||||
test-integration
|
||||
)
|
||||
fi
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ TESTFLAGS+=" -test.timeout=${TIMEOUT:-5m}"
|
|||
BUILDFLAGS=( -tags "netgo seccomp libdm_no_deferred_remove" )
|
||||
TESTDIRS="${TESTDIRS:-"./..."}"
|
||||
|
||||
exclude_paths="/vendor/|/integration-cli"
|
||||
exclude_paths="/vendor/|/integration"
|
||||
if [ "$(go env GOHOSTOS)" = 'solaris' ]; then
|
||||
exclude_paths="$exclude_paths|/daemon/graphdriver"
|
||||
fi
|
||||
|
|
|
@ -4,10 +4,8 @@ import (
|
|||
"fmt"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
@ -72,17 +70,7 @@ func TestMain(m *testing.M) {
|
|||
func Test(t *testing.T) {
|
||||
cli.EnsureTestEnvIsLoaded(t)
|
||||
fakestorage.EnsureTestEnvIsLoaded(t)
|
||||
cmd := exec.Command(dockerBinary, "images", "-f", "dangling=false", "--format", "{{.Repository}}:{{.Tag}}")
|
||||
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)
|
||||
}
|
||||
environment.ProtectImages(t, testEnv)
|
||||
check.TestingT(t)
|
||||
}
|
||||
|
||||
|
|
|
@ -11,82 +11,6 @@ import (
|
|||
"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) {
|
||||
// test invalid Interval in Healthcheck: less than 0s
|
||||
name := "test1"
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
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
|
||||
func (e *Execution) ProtectImage(t testingT, images ...string) {
|
||||
for _, image := range images {
|
||||
|
@ -7,6 +18,31 @@ func (e *Execution) ProtectImage(t testingT, images ...string) {
|
|||
}
|
||||
}
|
||||
|
||||
type protectedElements struct {
|
||||
images map[string]struct{}
|
||||
// ProtectImages protects existing images and on linux frozen images from being
|
||||
// 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{})
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
func ensureSyscallTest(c *check.C) {
|
||||
|
|
93
integration/container/create_test.go
Normal file
93
integration/container/create_test.go
Normal file
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
37
integration/container/main_test.go
Normal file
37
integration/container/main_test.go
Normal file
|
@ -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
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
|
15
integration/util/request/client.go
Normal file
15
integration/util/request/client.go
Normal file
|
@ -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 shell
|
||||
- make test-unit
|
||||
- make test-integration-cli
|
||||
- make test-integration
|
||||
- make
|
||||
|
||||
The Makefile does include logic to determine on which OS and architecture the Docker Development Image is built.
|
||||
|
|
Loading…
Reference in a new issue