Skip to content

Commit

Permalink
run-tests.sh: Update to current CI procedures
Browse files Browse the repository at this point in the history
The objective of the 'run-tests.sh' script is to provide for a developer
a similar environment as the one used by the Azure CI to test the
modules and roles.

This patch updates the script to use the same tools as are being used
after the latest change in the Azure CI.
  • Loading branch information
rjeffman committed Oct 31, 2024
1 parent 33c1c00 commit 4e73675
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 356 deletions.
157 changes: 123 additions & 34 deletions utils/run-tests.sh → infra/image/run-tests.sh
Original file line number Diff line number Diff line change
@@ -1,20 +1,56 @@
#!/bin/bash -eu

SCRIPTDIR="$(readlink -f "$(dirname "$0")")"
TOPDIR="$(readlink -f "${SCRIPTDIR}/..")"
TOPDIR="$(readlink -f "${SCRIPTDIR}/../..")"
UTILSDIR="${SCRIPTDIR}"

# shellcheck source=utils/shfun
. "${SCRIPTDIR}/shfun"
# shellcheck source=utils/shcontainer
. "${SCRIPTDIR}/shcontainer"
# shellcheck source=utils/shansible
. "${SCRIPTDIR}/shansible"
# shellcheck source=infra/image/shfun
. "${UTILSDIR}/shfun"
# shellcheck source=infra/image/shcontainer
. "${UTILSDIR}/shcontainer"

set -o errexit -o errtrace

trap interrupt_exception SIGINT

interrupt_exception() {
trap - ERR SIGINT
log warn "User interrupted test execution."
# shellcheck disable=SC2119
cleanup "${scenario:+${scenario}}"
exit 1
}

trap cleanup ERR EXIT SIGABRT SIGTERM SIGQUIT

# shellcheck disable=SC2120
cleanup() {
trap - ERR EXIT SIGABRT SIGTERM SIGQUIT
local container
log info "Cleaning up environment"
container="${1:-${scenario:+${scenario}}}"
if [ "${STOP_CONTAINER:-"Y"}" == "Y" ] && [ -n "${container}" ]
then
run_if_exists container_stop "${container}"
[ -f "${inventory:-}" ] && rm "${inventory}"
else
if [ -n "${container}" ]
then
log info "Keeping container: $(podman ps --format "{{.Names}} - {{.ID}}" --filter "name=${container}")"
fi
fi
if [ "${STOP_VIRTUALENV:-"N"}" == "Y" ]
then
echo "Deactivating virtual environment"
run_if_exists deactivate
fi
}

usage() {
local prog="${0##*/}"
cat <<EOF
usage: ${prog} [-h] [-l] [-e] [-K] [-A|-a ANSIBLE] [-p INTERPRETER] [-c CONTAINER] [-s TESTS_SUITE] [-x] [-S SEED.GRP] [-i IMAGE] [-m MEMORY] [-v...] [TEST...]
${prog} runs playbook(s) TEST using an ansible-freeipa testing image.
usage: ${prog} [-h] [-l] [-e] [-K] [-A|-a ANSIBLE] [-p INTERPRETER] [-c CONTAINER] [-s TESTS_SUITE] [-x] [-S SEED.GRP] [-i IMAGE] [-v...] [TEST...]
${prog} runs test playbooks using an ansible-freeipa testing images.
EOF
}
Expand All @@ -33,10 +69,11 @@ optional arguments:
-A Do not install Ansible, use host's provided one.
-c CONTAINER use container CONTAINER to run tests
-K keep container, even if tests succeed
-l list available images
-L list available images
-l Try to use local image first, if not found download.
-e force recreation of the virtual environment
-i IMAGE select image to run the tests (default: fedora-latest)
-m MEMORY container memory, in GiB (default: 3)
-i IMAGE select image to run the tests
(default: fedora-latest-server)
-p INTERPRETER Python interpreter to use on target container
-s TEST_SUITE run all playbooks for test suite, which is a directory
under ${WHITE}tests${RST}
Expand All @@ -47,29 +84,54 @@ EOF
)"
}

install_ansible() {
ANSIBLE_VERSION="${1:-${ANSIBLE_VERSION:-"ansible-core"}}"
[ $# -gt 0 ] && shift
log info "Installing Ansible: ${ANSIBLE_VERSION}"
pip install --quiet "${ANSIBLE_VERSION}"
log debug "Ansible version: $(ansible --version | sed -n "1p")${RST}"

if [ -n "${ANSIBLE_COLLECTIONS}" ]
then
collections_path="$(mktemp -d)"
for collection in ${ANSIBLE_COLLECTIONS}
do
if ! quiet ansible-galaxy collection verify --offline "${collection}"
then
log info "Installing: Ansible Collection ${collection}"
# shellcheck disable=SC2086
quiet ansible-galaxy collection install \
-p "${collections_path}" \
"${collection}" || die "Failed to install Ansible collection: ${collection}"
fi
done
export ANSIBLE_COLLECTIONS_PATH="${collections_path}:${ANSIBLE_COLLECTIONS_PATH:-}"
fi
export ANSIBLE_VERSION
}


# Defaults
verbose=""
engine="${engine:-"podman"}"
CONTINUE_ON_ERROR=""
STOP_CONTAINER="Y"
STOP_VIRTUALENV="N"
FORCE_ENV="N"
declare -a ENABLED_MODULES
declare -a ENABLED_TESTS
read -r -a ENABLED_MODULES <<< "${IPA_ENABLED_MODULES:-""}"
read -r -a ENABLED_TESTS <<< "${IPA_ENABLED_MODULES:-""}"
IMAGE_TAG="fedora-latest"
scenario="freeipa-tests"
MEMORY=3
IMAGE_TAG="fedora-latest-server"
scenario="ansible-freeipa-tests"
IPA_HOSTNAME="ipaserver.test.local"
SEED="$(date "+%Y%m%d")"
GROUP=1
SPLITS=0
ANSIBLE_COLLECTIONS=${ANSIBLE_COLLECTIONS:-"${engine_collection}"}
ANSIBLE_COLLECTIONS=${ANSIBLE_COLLECTIONS:-"containers.podman"}
SKIP_ANSIBLE=""
ansible_interpreter="/usr/bin/python3"
EXTRA_OPTIONS=""
unset ANSIBLE_VERSION
unset ansible_interpreter

# Process command options

Expand All @@ -89,8 +151,7 @@ do
e) FORCE_ENV="Y" ;;
i) IMAGE_TAG="${OPTARG}" ;;
K) STOP_CONTAINER="N" ;;
l) "${SCRIPTDIR}"/setup_test_container.sh -l && exit 0 || exit 1 ;;
m) MEMORY="${OPTARG}" ;;
l) list_images && exit 0 || exit 1 ;;
p) ansible_interpreter="${OPTARG}" ;;
s)
[ ${SPLITS} -ne 0 ] && die -u "Can't use '-S' with '-s'"
Expand Down Expand Up @@ -131,16 +192,22 @@ done

[ ${SPLITS} -eq 0 ] && [ ${#ENABLED_MODULES[@]} -eq 0 ] && [ ${#ENABLED_TESTS[@]} -eq 0 ] && die -u "No test defined."

export STOP_CONTAINER FORCE_ENV STOP_VIRTUALENV ansible_interpreter
export STOP_CONTAINER STOP_VIRTUALENV

# Ensure $python is set
[ -z "${python}" ] && python="python3"
for py in "python3" "python"
do
python="$(command -v "${py}")"
[ -n "${python}" ] && break
done

log info "Controller Python executable: ${python}"
${python} --version

# Prepare virtual environment
start_virtual_environment
declare -a venv_opts=()
[ "${FORCE_ENV}" == "Y" ] && venv_opts+=("-f")
start_virtual_environment "${venv_opts[@]}"
log info "Installing dependencies from 'requirements-tests.txt'"
pip install --upgrade -r "${TOPDIR}/requirements-tests.txt"

Expand All @@ -151,17 +218,32 @@ export ANSIBLE_ROLES_PATH="${TOPDIR}/roles"
export ANSIBLE_LIBRARY="${TOPDIR}/plugins"
export ANSIBLE_MODULE_UTILS="${TOPDIR}/plugins/module_utils"

# Start container
"${SCRIPTDIR}/setup_test_container.sh" -e "${engine}" -m "${MEMORY}" -p "${ansible_interpreter}" -i "${IMAGE_TAG}" -n "${IPA_HOSTNAME}" -a "${scenario}" || die "Failed to setup test container"

# Ensure container is up and running
if [ "${FORCE_ENV:-"N"}" != "Y" ]
then
state="$(container_get_state "${scenario}")"
case "${state}" in
exited)
podman start "${scenario}"
container_wait_for_journald "${scenario}"
container_wait_up "${scenario}"
;;
running) ;; # container is running, nothing to do
*)
# assume container needs to be recreated
"${TOPDIR}/infra/image/start.sh" -l "${IMAGE_TAG}" -n "${IPA_HOSTNAME}"
;;
esac
else
"${TOPDIR}/infra/image/start.sh" -l "${IMAGE_TAG}" -n "${IPA_HOSTNAME}"
fi

# run tests
RESULT=0

export RUN_TESTS_IN_DOCKER=${engine}
export RUN_TESTS_IN_DOCKER=podman
export IPA_SERVER_HOST="${scenario}"
# Ensure proper ansible_python_interpreter is used by pytest.
export IPA_PYTHON_PATH="${ansible_interpreter}"
[ -z "${ansible_interpreter:-}" ] || export IPA_PYTHON_PATH="${ansible_interpreter}"

if [ ${SPLITS} -ne 0 ]
then
Expand All @@ -184,13 +266,20 @@ IPA_VERBOSITY="${verbose}"
[ -n "${IPA_VERBOSITY}" ] && export IPA_VERBOSITY

# shellcheck disable=SC2086
if ! pytest -m "playbook" --verbose --color=yes --suppress-no-test-exit-code --junit-xml=TEST-results-group-${GROUP:-1}.xml ${EXTRA_OPTIONS}
if ! pytest -m "playbook" \
--verbose \
--color=yes \
--suppress-no-test-exit-code \
--junit-xml=TEST-results-group-${GROUP:-1}.xml \
${EXTRA_OPTIONS}
then
RESULT=2
export STOP_CONTAINER="N"
log error "Container not stopped for verification: ${scenario}"
log info "Container: $(${engine} ps -f "name=${scenario}" --format "{{.Names}} - {{.ID}}")"
log info "Container: $(podman ps -f "name=${scenario}" --format "{{.Names}} - {{.ID}}")"
fi
[ -z "${CONTINUE_ON_ERROR}" ] && [ $RESULT -ne 0 ] && die "Stopping on test failure."

# cleanup environment
cleanup "${scenario}" "${engine}"
if [ -z "${CONTINUE_ON_ERROR}" ] && [ $RESULT -ne 0 ]
then
die "Stopping on test failure."
fi
15 changes: 13 additions & 2 deletions infra/image/shcontainer
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@
# This file is meant to be source'd by other scripts

SCRIPTDIR="$(dirname -- "$(readlink -f "${BASH_SOURCE[0]}")")"
TOPDIR="$(readlink -f "${SCRIPTDIR}/../..")"

. "${TOPDIR}/utils/shfun"
# shellcheck source=infra/image/shfun
. "${SCRIPTDIR}/shfun"

list_images() {
local quay_api="https://quay.io/api/v1/repository/ansible-freeipa/upstream-tests/tag"
log info "Available images on quay:"
curl --silent -L "${quay_api}" | jq '.tags[]|.name' | tr -d '"'| sort | uniq | sed "s/.*/ &/"
echo
log info "Local images (use -l):"
local_image=$(container_image_list "${repo:-"quay.io/ansible-freeipa/upstream-tests"}:")
echo "${local_image}" | sed -e "s/.*://" | sed "s/.*/ &/"
echo
}

container_create() {
local name=${1}
Expand Down
51 changes: 13 additions & 38 deletions utils/shfun → infra/image/shfun
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,15 @@

SCRIPTDIR="$(dirname -- "$(readlink -f "${BASH_SOURCE[0]}")")"

# shellcheck source=infra/image/shlog
. "${SCRIPTDIR}/shlog"

[ -n "$(command -v python3)" ] && python="$(command -v python3)" || python="$(command -v python2)"
export python

trap interrupt_exception SIGINT

interrupt_exception() {
trap - SIGINT
log warn "User interrupted test execution."
# shellcheck disable=SC2119
cleanup "${scenario:+${scenario}}"
exit 1
}

run_if_exists() {
cmd="${1}"
shift
[ -n "$(command -v "${cmd}")" ] && "${cmd}" "${@}"
}

# shellcheck disable=SC2120
cleanup() {
local container container_engine
container="${1:-${scenario:+${scenario}}}"
container_engine="${2:-${engine:-"podman"}}"
if [ "${STOP_CONTAINER:-"Y"}" == "Y" ] && [ -n "${container}" ]
then
run_if_exists stop_container "${container}" "${container_engine}"
[ -f "${inventory:-}" ] && rm "${inventory}"
else
if [ -n "${container}" ]
then
log info "Keeping container: $(${container_engine} ps --format "{{.Names}} - {{.ID}}" --filter "name=${container}")"
fi
fi
if [ "${STOP_VIRTUALENV:-"N"}" == "Y" ]
then
echo "Deactivating virtual environment"
run_if_exists deactivate
fi
}

start_virtual_environment() {
# options -f
local FORCE_ENV VENV envdirectory
Expand All @@ -59,6 +25,16 @@ start_virtual_environment() {
done
envdirectory="${test_env:-/tmp/ansible-freeipa-tests}"

for py in python3 python2
do
if quiet command -v "${py}"
then
python="$(command -v ${py})"
export python
break
fi
done

# Prepare virtual environment
VENV=$(in_python_virtualenv && echo Y || echo N)

Expand All @@ -77,7 +53,7 @@ start_virtual_environment() {
then
log info "Creating virtual environment: ${envdirectory}..."
log warn "RUN: ${python} -m venv ${envdirectory}"
${python} -m venv "${envdirectory}" || die "Cannot create virtual environment."
"${python}" -m venv "${envdirectory}" || die "Cannot create virtual environment."
fi
log info "Starting virtual environment: ${envdirectory}"
[ -f "${envdirectory}/bin/activate" ] || die "Failed to create virtual environment."
Expand All @@ -100,8 +76,7 @@ die() {
shift 1
fi
log error "${*}"
STOP_CONTAINER="N"
cleanup "${scenario:+${scenario}}"
export STOP_CONTAINER="N"
[ "${usg}" == "Y" ] && run_if_exists usage
exit 1
}
Expand Down
2 changes: 1 addition & 1 deletion utils/shlog → infra/image/shlog
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@ log() {
}

quiet() {
"$@" >/dev/null 2>&1
"$@" >/dev/null 2>/dev/null
}

14 changes: 1 addition & 13 deletions infra/image/start.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#!/bin/bash -eu

BASEDIR="$(readlink -f "$(dirname "$0")")"
TOPDIR="$(readlink -f "${BASEDIR}/../..")"

# shellcheck disable=SC1091
. "${BASEDIR}/shcontainer"
# shellcheck disable=SC1091
. "${TOPDIR}/utils/shfun"
. "${BASEDIR}/shfun"

usage() {
local prog="${0##*/}"
Expand Down Expand Up @@ -36,17 +35,6 @@ NOTE:
EOF
}

list_images() {
local quay_api="https://quay.io/api/v1/repository/ansible-freeipa/upstream-tests/tag"
log info "Available images on quay:"
curl --silent -L "${quay_api}" | jq '.tags[]|.name' | tr -d '"'| sort | uniq | sed "s/.*/ &/"
echo
log info "Local images (use -l):"
local_image=$(container_image_list "${repo}:")
echo "${local_image}" | sed -e "s/.*://" | sed "s/.*/ &/"
echo
}

repo="quay.io/ansible-freeipa/upstream-tests"
name="ansible-freeipa-tests"
hostname="ipaserver.test.local"
Expand Down
Loading

0 comments on commit 4e73675

Please sign in to comment.