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 Dec 4, 2024
1 parent 227c95e commit cd3a75c
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 365 deletions.
139 changes: 92 additions & 47 deletions utils/run-tests.sh → infra/image/run-tests.sh
Original file line number Diff line number Diff line change
@@ -1,20 +1,44 @@
#!/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
exit 1
}

trap cleanup ERR EXIT SIGABRT SIGTERM SIGQUIT

# shellcheck disable=SC2120
cleanup() {
trap - ERR EXIT SIGABRT SIGTERM SIGQUIT
log info "Cleaning up environment"
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] [-A|-a ANSIBLE] [-s TESTS_SUITE] [-x] [-S SEED.GRP] [-l] [-i IMAGE] [-v...] [TEST...]
${prog} runs test playbooks using an ansible-freeipa testing images.
EOF
}
Expand All @@ -31,13 +55,11 @@ optional arguments:
-a ANSIBLE Ansible version to use, e.g. "ansible-core==2.16.0"
(default: latest ansible-core for the python version)
-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)
-p INTERPRETER Python interpreter to use on target container
-i IMAGE select image to run the tests
(default: fedora-latest-server)
-s TEST_SUITE run all playbooks for test suite, which is a directory
under ${WHITE}tests${RST}
-S SEED.GROUP Replicate Azure's test group and seed (seed is YYYYMMDD)
Expand All @@ -47,51 +69,72 @@ 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="/tmp/ansible-freeipa-tests-collections"
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
default_collections_path="$(ansible-config init | grep "collections_path=" | cut -d= -f2-)"
export ANSIBLE_COLLECTIONS_PATH="${collections_path}:${ANSIBLE_COLLECTIONS_PATH:-${default_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"
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 LOCAL_IMAGES
unset ANSIBLE_VERSION

# Process command options

while getopts ":ha:Ac:ei:Klm:p:s:S:vx" option
while getopts ":ha:Aei:lLs:S:vx" option
do
case "$option" in
h) help && exit 0 ;;
A)
[ -n "${ANSIBLE_VERSION:-""}" ] && die "Can't use -A with '-a'"
SKIP_ANSIBLE="YES"
;;
a)
a)
[ "${SKIP_ANSIBLE:-"no"}" == "YES" ] && die "Can't use -A with '-a'"
ANSIBLE_VERSION="${OPTARG}"
;;
c) scenario="${OPTARG}" ;;
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}" ;;
p) ansible_interpreter="${OPTARG}" ;;
L) list_images && exit 0 || exit 1 ;;
l) LOCAL_IMAGES="-l" ;;
s)
[ ${SPLITS} -ne 0 ] && die -u "Can't use '-S' with '-s'"
if [ -d "${TOPDIR}/tests/${OPTARG}" ]
Expand Down Expand Up @@ -131,16 +174,18 @@ 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 IPA_SERVER_HOST="ansible-freeipa-tests"
export STOP_VIRTUALENV

# Ensure $python is set
[ -z "${python}" ] && python="python3"
python="$(get_python_executable)"

log info "Controller Python executable: ${python}"
log info "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 +196,13 @@ 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"

# Start test container
"${TOPDIR}/infra/image/start.sh" ${LOCAL_IMAGES:-} "${IMAGE_TAG}" -n "${IPA_HOSTNAME}"

# run tests
RESULT=0

export RUN_TESTS_IN_DOCKER=${engine}
export IPA_SERVER_HOST="${scenario}"
# Ensure proper ansible_python_interpreter is used by pytest.
export IPA_PYTHON_PATH="${ansible_interpreter}"
export RUN_TESTS_IN_DOCKER=podman

if [ ${SPLITS} -ne 0 ]
then
Expand All @@ -184,13 +225,17 @@ 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
log error "Container not stopped for verification: ${scenario}"
log info "Container: $(${engine} 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: 17 additions & 34 deletions utils/shfun → infra/image/shfun
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,32 @@

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() {
trap - ERR
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}" ]
get_python_executable() {
trap - ERR
for py in "/usr/libexec/platform-python" "python3" "python2" "python"
do
python_cmd="$(command -v "${py}")"
if [ -n "${python_cmd}" ]
then
log info "Keeping container: $(${container_engine} ps --format "{{.Names}} - {{.ID}}" --filter "name=${container}")"
echo "${python_cmd}"
return 0
fi
fi
if [ "${STOP_VIRTUALENV:-"N"}" == "Y" ]
then
echo "Deactivating virtual environment"
run_if_exists deactivate
fi
done
die "Could not find python executable."
}

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

python="$(get_python_executable)"

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

Expand All @@ -77,7 +61,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 +84,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 cd3a75c

Please sign in to comment.