SHA256
1
0
forked from pool/docker
docker/tests.sh

220 lines
5.8 KiB
Bash
Raw Normal View History

#!/bin/bash
#
# Script for launching the Docker integration tests
# XXX: We currently only support running integration-cli.
#
set -Eeuxo pipefail
DOCKER_DIR=/usr/src/docker
SCRIPTS_DIR=$DOCKER_DIR/hack
TESTS_EXE=$DOCKER_DIR/integration-cli/tests.main
VERSION=$(cat $DOCKER_DIR/VERSION)
# working dirs
TESTS_DIR=/tmp/docker-int-tests
BUNDLES_DIR=$TESTS_DIR/run/bundles
FAKE_GOPATH=$TESTS_DIR/go
CHECK_TIMEOUT="${CHECK_TIMEOUT:-5m}"
TEST_TIMEOUT="${TEST_TIMEOUT:-60m}"
TEST_ARGS="-check.vv -check.timeout=${CHECK_TIMEOUT} -test.timeout=${TEST_TIMEOUT}"
TEST_SELECT=
TEST_LOG=/tmp/docker-tests.log
ENABLE_XUNIT="${ENABLE_XUNIT:=yes}"
# the config file for Docker
CFG_DOCKER=/etc/docker/daemon.json
################################################################################
log() { echo ">>> $@" ; }
warn() { log "WARNING: $@" ; }
error() { log "ERROR: $@" ; }
abort() { log "FATAL: $@" ; exit 1 ; }
usage() { echo "$USAGE" ; }
abort_usage() { usage ; abort $@ ; }
bundle() {
local bundle="$1"; shift
log "Making bundle: $(basename "$bundle") (in $DEST)"
source "$SCRIPTS_DIR/make/$bundle" "$@"
}
set_opts() {
OPT="$1"
VALUE="$2"
FILE=$3
perl -pi -e "s/^$OPT=.*$//g" $FILE
echo "$OPT=\"$VALUE\"" >> $FILE
}
set_docker_opts() { set_opts "DOCKER_OPTS" "$DOCKER_OPTS" /etc/sysconfig/docker ; }
fix_expected() {
EXPECTED=$1
EXISTING=$2
exp_base=$(basename $EXPECTED)
exp_dir=$(dirname $EXPECTED)
[ -d $exp_dir ] || mkdir -p $exp_dir
rm -f $exp_dir/$exp_base
(cd $exp_dir && ln -sf $EXISTING $exp_base)
}
save_backup() {
for x in $@ ; do
if [ ! -f $x ] ; then
touch $x.nbak
elif [ -f $x.bak ] ; then
warn "$x.bak already exists: no backup will be done"
else
cp -f $x $x.bak
fi
done
}
restore_backup() {
for x in $@ ; do
if [ -f $x.nbak ] ; then
rm -f $x.nbak
else
if [ -f $x.bak ] ; then
mv -f $x.bak $x
fi
fi
done
}
require_go() { go version >/dev/null 2>&1 ; }
require_git() { git version >/dev/null 2>&1 ; }
################################################################################
[ -x $TESTS_EXE ] || abort "integration tests executable not found at $TESTS_EXE"
[ $EUID -eq 0 ] || abort "this script must be run as root"
[ -n "$VERSION" ] || abort "could not obtain version"
if [ $# -gt 0 ] ; then
# run only some specific tests
TEST_SELECT="-check.f=$(echo $@ | tr ' ' '|')"
fi
# We want this to fail if the bundles already exist and cannot be removed.
# This is to avoid mixing bundles from different versions of the code.
mkdir -p $BUNDLES_DIR
if [ -e "$BUNDLES_DIR/$VERSION" ] && [ -z "$KEEPBUNDLE" ]; then
log "$BUNDLES_DIR/$VERSION already exists. Removing."
rm -fr "$BUNDLES_DIR/$VERSION" && mkdir "$BUNDLES_DIR/$VERSION" || exit 1
echo
fi
DEST="$BUNDLES_DIR/$VERSION/"
mkdir -p "$DEST"
export DEST=$(realpath $DEST)
if [ -n "$ENABLE_XUNIT" ] ; then
if [ ! -x /usr/local/bin/go2xunit ] ; then
echo >&2 "Installing go2xunit."
require_go || abort "the Go compiler is not installed"
export GOPATH="$(mktemp -d)"
go get -d github.com/tebeka/go2xunit
cd $GOPATH/src/github.com/tebeka/go2xunit && go build -o /usr/local/bin/go2xunit .
chmod 755 /usr/local/bin/go2xunit
[ -x /usr/local/bin/go2xunit ] || abort "go2xunit could not be built"
rm -rf "$GOPATH"
export -n GOPATH
fi
fi
# tests require this user and group
/usr/sbin/groupadd -r docker >/dev/null 2>&1 || /bin/true
/usr/sbin/useradd --create-home --gid docker unprivilegeduser >/dev/null 2>&1 || /bin/true
# prepare some expected dirs, files, etc...
fix_expected $TESTS_DIR/contrib $DOCKER_DIR/contrib
fix_expected $DEST/fixtures $DOCKER_DIR/integration-cli/fixtures
export DOCKER_TEST_HOST="tcp://127.0.0.1:2375"
export PATH=/usr/local/bin:$PATH
export TZ=utc
export GOPATH="$FAKE_GOPATH"
export DOCKER_GRAPHDRIVER="${DOCKER_GRAPHDRIVER:-vfs}"
export DOCKER_USERLANDPROXY="${DOCKER_USERLANDPROXY:-true}"
#export DOCKER_REMAP_ROOT=default
# example usage: DOCKER_STORAGE_OPTS="dm.basesize=20G,dm.loopdatasize=200G"
storage_params=""
if [ -n "$DOCKER_STORAGE_OPTS" ]; then
IFS=','
for i in ${DOCKER_STORAGE_OPTS}; do
storage_params="--storage-opt $i $storage_params"
done
unset IFS
fi
# example usage: DOCKER_STORAGE_OPTS="dm.basesize=20G,dm.loopdatasize=200G"
extra_params=""
# deal with remapping
save_backup /etc/subuid /etc/subgid
echo "dockremap:500000:65536" > /etc/subuid
echo "dockremap:500000:65536" > /etc/subgid
groupadd dockremap >/dev/null 2>&1 || /bin/true
useradd -g dockremap dockremap >/dev/null 2>&1 || /bin/true
# make sure Docker is stopped, set our config file and then start again
save_backup $CFG_DOCKER
cat <<CFG_DOCKER_EOF > $CFG_DOCKER
{
"log-level": "debug",
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "5"
},
"pidfile": "$DEST/docker.pid",
"host": [
"tcp://127.0.0.1:2375"
],
"storage-driver": "$DOCKER_GRAPHDRIVER",
"userland-proxy": $DOCKER_USERLANDPROXY
}
CFG_DOCKER_EOF
systemctl restart docker.service
cleanup() {
log "Restoring the Docker service..."
restore_backup $CFG_DOCKER
systemctl restart docker.service
log "Removing extra files and restoring backups..."
restore_backup /etc/subuid /etc/subgid
rm -f $TESTS_DIR/contrib \
$DEST/fixtures
}
trap cleanup EXIT
cd $DOCKER_DIR
log "Preparing the environment..."
bundle .integration-daemon-start
bundle .integration-daemon-setup
log "Running integration tests..."
export DOCKER_HOST=$DOCKER_TEST_HOST
cd $DEST && $TESTS_EXE $TEST_ARGS $TEST_SELECT | tee $TEST_LOG || /bin/true
if [ -n "$ENABLE_XUNIT" ] ; then
log "Generating xunit logs..."
go2xunit -fail -gocheck -input $TEST_LOG -output $TEST_LOG.xml
fi
export -n DOCKER_HOST
bundle .integration-daemon-stop