Run tests in stricter environment

Use `env -i` to very explicitly control exactly which environment variables leak into our tests.  This enforces a clean separation of "build environment knobs" versus "test suite knobs".

This also includes a minor tweak to how we handle starting our integration daemon, especially to catch failure to start sooner than failing tests.

Signed-off-by: Andrew "Tianon" Page <admwiggin@gmail.com>
This commit is contained in:
Tianon Gravi 2015-02-14 03:27:31 -07:00
parent 2243e32cbb
commit ed345fb18e
7 changed files with 47 additions and 10 deletions

View File

@ -122,7 +122,7 @@ RUN set -x \
go build -o /go/bin/registry-v2 github.com/docker/distribution/cmd/registry
# Get the "docker-py" source so we can run their integration tests
ENV DOCKER_PY_COMMIT aa19d7b6609c6676e8258f6b900dea2eda1dbe95
ENV DOCKER_PY_COMMIT d39da1167975aaeb6c423b99621ecda1223477b8
RUN git clone https://github.com/docker/docker-py.git /docker-py \
&& cd /docker-py \
&& git checkout -q $DOCKER_PY_COMMIT

View File

@ -20,6 +20,8 @@ import (
"strings"
"testing"
"time"
"github.com/docker/docker/api"
)
// Daemon represents a Docker daemon for the testing framework.
@ -266,8 +268,8 @@ func (d *Daemon) Cmd(name string, arg ...string) (string, error) {
}
func daemonHost() string {
daemonUrlStr := "unix:///var/run/docker.sock"
if daemonHostVar := os.Getenv("DOCKER_TEST_HOST"); daemonHostVar != "" {
daemonUrlStr := "unix://" + api.DEFAULTUNIXSOCKET
if daemonHostVar := os.Getenv("DOCKER_HOST"); daemonHostVar != "" {
daemonUrlStr = daemonHostVar
}
return daemonUrlStr
@ -772,6 +774,12 @@ func fakeGIT(name string, files map[string]string) (*FakeGIT, error) {
if err != nil {
return nil, err
}
if output, err := exec.Command("git", "config", "user.name", "Fake User").CombinedOutput(); err != nil {
return nil, fmt.Errorf("error trying to set 'user.name': %s (%s)", err, output)
}
if output, err := exec.Command("git", "config", "user.email", "fake.user@example.com").CombinedOutput(); err != nil {
return nil, fmt.Errorf("error trying to set 'user.email': %s (%s)", err, output)
}
if output, err := exec.Command("git", "add", "*").CombinedOutput(); err != nil {
return nil, fmt.Errorf("error trying to add files to repo: %s (%s)", err, output)
}

View File

@ -178,9 +178,22 @@ go_test_dir() {
export DEST
echo '+ go test' $TESTFLAGS "${DOCKER_PKG}${dir#.}"
cd "$dir"
go test ${testcover[@]} -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}" $TESTFLAGS
test_env go test ${testcover[@]} -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}" $TESTFLAGS
)
}
test_env() {
# use "env -i" to tightly control the environment variables that bleed into the tests
env -i \
DEST="$DEST" \
DOCKER_EXECDRIVER="$DOCKER_EXECDRIVER" \
DOCKER_GRAPHDRIVER="$DOCKER_GRAPHDRIVER" \
DOCKER_HOST="$DOCKER_HOST" \
GOPATH="$GOPATH" \
HOME="$DEST/fake-HOME" \
PATH="$PATH" \
TEST_DOCKERINIT_PATH="$TEST_DOCKERINIT_PATH" \
"$@"
}
# a helper to provide ".exe" when it's appropriate
binary_extension() {

View File

@ -16,8 +16,10 @@ export DOCKER_GRAPHDRIVER=${DOCKER_GRAPHDRIVER:-vfs}
export DOCKER_EXECDRIVER=${DOCKER_EXECDRIVER:-native}
if [ -z "$DOCKER_TEST_HOST" ]; then
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 \
docker --daemon --debug \
--host "$DOCKER_HOST" \
--storage-driver "$DOCKER_GRAPHDRIVER" \
--exec-driver "$DOCKER_EXECDRIVER" \
--pidfile "$DEST/docker.pid" \
@ -26,3 +28,20 @@ if [ -z "$DOCKER_TEST_HOST" ]; then
else
export DOCKER_HOST="$DOCKER_TEST_HOST"
fi
# give it a second to come up so it's "ready"
tries=10
while ! docker version &> /dev/null; do
(( tries-- ))
if [ $tries -le 0 ]; then
if [ -z "$DOCKER_HOST" ]; then
echo >&2 "error: daemon failed to start"
echo >&2 " check $DEST/docker.log for details"
else
echo >&2 "error: daemon at $DOCKER_HOST fails to 'docker version':"
docker version >&2 || true
fi
false
fi
sleep 2
done

View File

@ -18,8 +18,8 @@ DEST=$1
git clone https://github.com/docker/docker-py.git "$dockerPy"
}
export PYTHONPATH="$dockerPy" # import "docker" from our local docker-py
python "$dockerPy/tests/integration_test.py"
# exporting PYTHONPATH to import "docker" from our local docker-py
test_env PYTHONPATH="$dockerPy" python "$dockerPy/tests/integration_test.py"
}; then
didFail=1
fi

View File

@ -16,9 +16,6 @@ bundle_test_integration_cli() {
# even and especially on test failures
didFail=
if ! {
# pull the busybox image before running the tests
sleep 2
source "$(dirname "$BASH_SOURCE")/.ensure-busybox"
source "$(dirname "$BASH_SOURCE")/.ensure-emptyfs"

View File

@ -58,7 +58,7 @@ go_run_test_dir() {
echo
echo '+ go test' $TESTFLAGS "${DOCKER_PKG}${dir#.}"
precompiled="$DEST/precompiled/$dir.test$(binary_extension)"
if ! ( cd "$dir" && "$precompiled" $TESTFLAGS ); then
if ! ( cd "$dir" && test_env "$precompiled" $TESTFLAGS ); then
TESTS_FAILED+=("$dir")
echo
echo "${RED}Tests failed: $dir${TEXTRESET}"