emqx/scripts/ct/run.sh
Kjell Winblad 96318bda1d build: run run.sh tests without being asked for sudo password
This commit makes it possible to run the scripts/ct/run.sh script
without being asked for sudo password if one instead wants to use the
run docker container with root user trick to reset owner of files.

One simply has to set the environment variable
EMQX_TEST_DO_NOT_RUN_SUDO.
2023-03-02 12:22:11 +01:00

255 lines
8.2 KiB
Bash
Executable File

#!/usr/bin/env bash
## This script runs CT (and necessary dependencies) in docker container(s)
set -euo pipefail
# ensure dir
cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")/../.."
help() {
echo
echo "-h|--help: To display this usage info"
echo "--app lib_dir/app_name: For which app to run start docker-compose, and run common tests"
echo "--console: Start EMQX in console mode but do not run test cases"
echo "--attach: Attach to the Erlang docker container without running any test case"
echo "--stop: Stop running containers for the given app"
echo "--only-up: Only start the testbed but do not run CT"
echo "--keep-up: Keep the testbed running after CT"
echo "--ci: Set this flag in GitHub action to enforce no tests are skipped"
echo "--: If any, all args after '--' are passed to rebar3 ct"
echo " otherwise it runs the entire app's CT"
}
if command -v docker-compose; then
DC='docker-compose'
else
DC='docker compose'
fi
WHICH_APP='novalue'
CONSOLE='no'
KEEP_UP='no'
ONLY_UP='no'
ATTACH='no'
STOP='no'
IS_CI='no'
while [ "$#" -gt 0 ]; do
case $1 in
-h|--help)
help
exit 0
;;
--app)
WHICH_APP="$2"
shift 2
;;
--only-up)
ONLY_UP='yes'
shift 1
;;
--keep-up)
KEEP_UP='yes'
shift 1
;;
--attach)
ATTACH='yes'
shift 1
;;
--stop)
STOP='yes'
shift 1
;;
--console)
CONSOLE='yes'
shift 1
;;
--ci)
IS_CI='yes'
shift 1
;;
--)
shift 1
REBAR3CT="$*"
shift $#
;;
*)
echo "unknown option $1"
exit 1
;;
esac
done
if [ "${WHICH_APP}" = 'novalue' ]; then
echo "must provide --app arg"
help
exit 1
fi
if [[ "${WHICH_APP}" == lib-ee* && (-z "${PROFILE+x}" || "${PROFILE}" != emqx-enterprise) ]]; then
echo 'You are trying to run an enterprise test case without the emqx-enterprise profile.'
echo 'This will most likely not work.'
echo ''
echo 'Run "export PROFILE=emqx-enterprise" and "make" to fix this'
exit 1
fi
ERLANG_CONTAINER='erlang'
DOCKER_CT_ENVS_FILE="${WHICH_APP}/docker-ct"
case "${WHICH_APP}" in
lib-ee*)
## ensure enterprise profile when testing lib-ee applications
export PROFILE='emqx-enterprise'
;;
*)
export PROFILE="${PROFILE:-emqx}"
;;
esac
if [ -f "$DOCKER_CT_ENVS_FILE" ]; then
# shellcheck disable=SC2002
CT_DEPS="$(cat "$DOCKER_CT_ENVS_FILE" | xargs)"
fi
CT_DEPS="${ERLANG_CONTAINER} ${CT_DEPS:-}"
FILES=( )
for dep in ${CT_DEPS}; do
case "${dep}" in
erlang)
FILES+=( '.ci/docker-compose-file/docker-compose.yaml' )
;;
toxiproxy)
FILES+=( '.ci/docker-compose-file/docker-compose-toxiproxy.yaml' )
;;
influxdb)
FILES+=( '.ci/docker-compose-file/docker-compose-influxdb-tcp.yaml'
'.ci/docker-compose-file/docker-compose-influxdb-tls.yaml' )
;;
mongo)
FILES+=( '.ci/docker-compose-file/docker-compose-mongo-single-tcp.yaml'
'.ci/docker-compose-file/docker-compose-mongo-single-tls.yaml' )
;;
mongo_rs_sharded)
FILES+=( '.ci/docker-compose-file/docker-compose-mongo-replicaset-tcp.yaml'
'.ci/docker-compose-file/docker-compose-mongo-sharded-tcp.yaml' )
;;
redis)
FILES+=( '.ci/docker-compose-file/docker-compose-redis-single-tcp.yaml'
'.ci/docker-compose-file/docker-compose-redis-single-tls.yaml'
'.ci/docker-compose-file/docker-compose-redis-sentinel-tcp.yaml'
'.ci/docker-compose-file/docker-compose-redis-sentinel-tls.yaml' )
;;
redis_cluster)
FILES+=( '.ci/docker-compose-file/docker-compose-redis-cluster-tcp.yaml'
'.ci/docker-compose-file/docker-compose-redis-cluster-tls.yaml' )
;;
mysql)
FILES+=( '.ci/docker-compose-file/docker-compose-mysql-tcp.yaml'
'.ci/docker-compose-file/docker-compose-mysql-tls.yaml' )
;;
pgsql)
FILES+=( '.ci/docker-compose-file/docker-compose-pgsql-tcp.yaml'
'.ci/docker-compose-file/docker-compose-pgsql-tls.yaml' )
;;
kafka)
# Kafka container generates root owned ssl files
# the files are shared with EMQX (with a docker volume)
NEED_ROOT=yes
FILES+=( '.ci/docker-compose-file/docker-compose-kafka.yaml' )
;;
tdengine)
FILES+=( '.ci/docker-compose-file/docker-compose-tdengine-restful.yaml' )
;;
clickhouse)
FILES+=( '.ci/docker-compose-file/docker-compose-clickhouse.yaml' )
;;
*)
echo "unknown_ct_dependency $dep"
exit 1
;;
esac
done
F_OPTIONS=""
for file in "${FILES[@]}"; do
F_OPTIONS="$F_OPTIONS -f $file"
done
ORIG_UID_GID="$UID:$UID"
if [[ "${NEED_ROOT:-}" == 'yes' ]]; then
export UID_GID='root:root'
else
# Passing $UID to docker-compose to be used in erlang container
# as owner of the main process to avoid git repo permissions issue.
# Permissions issue happens because we are mounting local filesystem
# where files are owned by $UID to docker container where it's using
# root (UID=0) by default, and git is not happy about it.
export UID_GID="$ORIG_UID_GID"
fi
# /emqx is where the source dir is mounted to the Erlang container
# in .ci/docker-compose-file/docker-compose.yaml
TTY=''
if [[ -t 1 ]]; then
TTY='-t'
fi
function restore_ownership {
if [[ -n ${EMQX_TEST_DO_NOT_RUN_SUDO+x} ]] || ! sudo chown -R "$ORIG_UID_GID" . >/dev/null 2>&1; then
docker exec -i $TTY -u root:root "$ERLANG_CONTAINER" bash -c "chown -R $ORIG_UID_GID /emqx" >/dev/null 2>&1 || true
fi
}
restore_ownership
trap restore_ownership EXIT
if [ "$STOP" = 'no' ]; then
# some left-over log file has to be deleted before a new docker-compose up
rm -f '.ci/docker-compose-file/redis/*.log'
# shellcheck disable=2086 # no quotes for F_OPTIONS
$DC $F_OPTIONS up -d --build --remove-orphans
fi
echo "Fixing file owners and permissions for $UID_GID"
# rebar and hex cache directory need to be writable by $UID
docker exec -i $TTY -u root:root "$ERLANG_CONTAINER" bash -c "mkdir -p /.cache && chown $UID_GID /.cache && chown -R $UID_GID /emqx/.git /emqx/.ci /emqx/_build/default/lib"
# need to initialize .erlang.cookie manually here because / is not writable by $UID
docker exec -i $TTY -u root:root "$ERLANG_CONTAINER" bash -c "openssl rand -base64 16 > /.erlang.cookie && chown $UID_GID /.erlang.cookie && chmod 0400 /.erlang.cookie"
if [ "$ONLY_UP" = 'yes' ]; then
exit 0
fi
set +e
if [ "$STOP" = 'yes' ]; then
# shellcheck disable=2086 # no quotes for F_OPTIONS
$DC $F_OPTIONS down --remove-orphans
elif [ "$ATTACH" = 'yes' ]; then
docker exec -it "$ERLANG_CONTAINER" bash
elif [ "$CONSOLE" = 'yes' ]; then
docker exec -e PROFILE="$PROFILE" -i $TTY "$ERLANG_CONTAINER" bash -c "make run"
else
if [ -z "${REBAR3CT:-}" ]; then
docker exec -e IS_CI="$IS_CI" -e PROFILE="$PROFILE" -i $TTY "$ERLANG_CONTAINER" bash -c "BUILD_WITHOUT_QUIC=1 make ${WHICH_APP}-ct"
else
docker exec -e IS_CI="$IS_CI" -e PROFILE="$PROFILE" -i $TTY "$ERLANG_CONTAINER" bash -c "./rebar3 ct $REBAR3CT"
fi
RESULT=$?
restore_ownership
if [ $RESULT -ne 0 ]; then
LOG='_build/test/logs/docker-compose.log'
echo "Dumping docker-compose log to $LOG"
# shellcheck disable=2086 # no quotes for F_OPTIONS
$DC $F_OPTIONS logs --no-color --timestamps > "$LOG"
fi
if [ "$KEEP_UP" != 'yes' ]; then
# shellcheck disable=2086 # no quotes for F_OPTIONS
$DC $F_OPTIONS down
fi
exit $RESULT
fi