diff options
author | Jessica Wagantall <jwagantall@linuxfoundation.org> | 2023-02-14 19:00:18 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2023-02-14 19:00:18 +0000 |
commit | 2d22cdf18bde2cf868f986c19d16b679f1d3f24f (patch) | |
tree | aaa23ad4177aa158b9c4a75dacef5b655bda3d3e | |
parent | 77dd11b365ef34409fd7bbc17af117c1110df987 (diff) | |
parent | 795671a1f575b00012e1b5865cd338e45cc69b64 (diff) |
Merge "Chore: Updates to improve overall robustness of robot framework tooling"
-rw-r--r-- | jjb/integration/include-raw-integration-install-robotframework-py3.sh | 117 | ||||
-rw-r--r-- | jjb/integration/prepare-csit.sh | 62 | ||||
-rw-r--r-- | jjb/integration/run-csit.sh | 149 |
3 files changed, 233 insertions, 95 deletions
diff --git a/jjb/integration/include-raw-integration-install-robotframework-py3.sh b/jjb/integration/include-raw-integration-install-robotframework-py3.sh index 6d0b4968e..efeb0f78b 100644 --- a/jjb/integration/include-raw-integration-install-robotframework-py3.sh +++ b/jjb/integration/include-raw-integration-install-robotframework-py3.sh @@ -10,24 +10,70 @@ ############################################################################## # vim: sw=4 ts=4 sts=4 et ft=sh : -set -eu pipefail +set -euxo pipefail -# shellcheck disable=SC1090 -. ~/lf-env.sh +echo "---> install-robotframework-py3.sh" -# Create a virtual environment for robot tests and make sure setuptools & wheel -# are up-to-date in addition to pip -lf-activate-venv --python python3 --venv-file "${WORKSPACE}/.robot3_venv" \ - setuptools \ - wheel +### Common variables + +REQUIRED_PYTHON="3.7.0" + +### Common functions + +# Allows for the comparison of two Python version strings +ver_cmp() +{ + local IFS=. + # shellcheck disable=SC2206 + local V1=($1) V2=($2) I + for ((I=0 ; I<${#V1[*]} || I<${#V2[*]} ; I++)) ; do + [[ ${V1[$I]:-0} -lt ${V2[$I]:-0} ]] && echo -1 && return + [[ ${V1[$I]:-0} -gt ${V2[$I]:-0} ]] && echo 1 && return + done + echo 0 +} +# Checks if first version/string is greater than or equal to the second +ver_ge() +{ + [[ ! $(ver_cmp "$1" "$2") -eq -1 ]] +} -# Save the virtual environment in ROBOT_VENV -ROBOT3_VENV="$(cat "${WORKSPACE}/.robot3_venv")" -echo ROBOT3_VENV="${ROBOT3_VENV}" >> "${WORKSPACE}/env.properties" +### Main script entry point -set -exu +# Check for required Python versions and activate/warn appropriately +# Use PYENV for selecting the latest python version, if available +if [[ -d "/opt/pyenv" ]]; then + echo "Setup pyenv:" + export PYENV_ROOT="/opt/pyenv" + export PATH="$PYENV_ROOT/bin:$PATH" + pyenv versions + if command -v pyenv 1>/dev/null 2>&1; then + eval "$(pyenv init - --no-rehash)" + # Choose the latest numeric Python version from installed list + version=$(pyenv versions --bare | sed '/^[^0-9]/d' |\ + sort -V | tail -n 1) + pyenv local "${version}" + fi +fi -echo "Installing Python Requirements" +# Store the active/current Python3 version +PYTHON_VERSION=$(python3 --version | awk '{print $2}') + +# Check that the required minimum version has been met +if ! (ver_ge "${PYTHON_VERSION}" "${REQUIRED_PYTHON}"); then + echo "Warning: possible Python version problem" + echo "Python ${PYTHON_VERSION} does not meet requirement: ${REQUIRED_PYTHON}" +fi + +if (python3 -m robot.run --version > /dev/null 2>&1); then + echo "Working robot framework found; no installation necessary" + echo "Installed under Python version: ${PYTHON_VERSION}" + exit 0 +fi + + +# Create a requirements file; keep it around for potential later use +# Versions and dependencies below have been carefully tested for Python3 cat << 'EOF' > "requirements.txt" paramiko six @@ -79,6 +125,49 @@ PyVirtualDisplay odltools EOF -python3 -m pip install -r requirements.txt + +if [[ -f ~/lf-env.sh ]]; then + echo "Installing robot-framework using LF common tooling" + # shellcheck disable=SC1090 + source ~/lf-env.sh + + # Create a virtual environment for robot tests and make sure setuptools & wheel + # are up-to-date in addition to pip + lf-activate-venv --python python3 --venv-file "${WORKSPACE}/.robot3_venv" \ + setuptools \ + pip \ + wheel + + # Install the robot framework and other dependencies + python3 -m pip install -r requirements.txt + + # Save the virtual environment in ROBOT3_VENV + ROBOT3_VENV="$(cat "${WORKSPACE}/.robot3_venv")" + +else + echo "Installing robot-framework in a virtual environment" + if [[ -z "${WORKSPACE}" ]]; then + # Use a temporary folder location + WORKSPACE="/tmp" + ROBOT3_VENV=$(mktemp -d --suffix=-robot3_venv) + else + ROBOT3_VENV="${WORKSPACE}/.robot3_venv" + fi + + # The --system-site-packages parameter allows us to pick up system level + # installed packages. This allows us to bake matplotlib which takes very long + # to install into the image. + python3 -m venv --system-site-packages "${ROBOT3_VENV}" + source "${ROBOT3_VENV}/bin/activate" + + echo "Installing robot-framework using basic methods" + python3 -m pip install -r requirements.txt +fi + +# Store the virtual environment location +echo "ROBOT3_VENV=${ROBOT3_VENV}" >> "${WORKSPACE}/env.properties" + +# Display versioning/debugging output +python3 --version python3 -m pip freeze python3 -m robot.run --version || : diff --git a/jjb/integration/prepare-csit.sh b/jjb/integration/prepare-csit.sh index 1052bff86..0db140ff7 100644 --- a/jjb/integration/prepare-csit.sh +++ b/jjb/integration/prepare-csit.sh @@ -24,18 +24,48 @@ set -exo pipefail ROBOT_INSTALLER='include-raw-integration-install-robotframework-py3.sh' -if !(which git > /dev/null 2>&1); then - echo "GIT binary not found current PATH" - echo $PATH; exit 1 +# Allows testing for root permissions +REQ_USER=$(id -un) + +if ! (which git > /dev/null 2>&1); then + echo "GIT binary not found in current PATH" + # Add missing package to prevent script/job failures + if (grep Ubuntu /etc/os-release > /dev/null 2>&1) || \ + (grep Debian /etc/os-release > /dev/null 2>&1); then + echo "Installing package dependency for Ubuntu/Debian" + if [[ "${REQ_USER}" == 'root' ]]; then + apt-get update + apt-get install -y git + else + sudo apt-get update + sudo apt-get install -y git + fi + elif (grep RedHat /etc/os-release > /dev/null 2>&1) || \ + (grep CentOS /etc/os-release > /dev/null 2>&1); then + echo "Installing package dependency for CentOS/RedHat" + if [[ "${REQ_USER}" == 'root' ]]; then + yum install -y git + else + sudo yum install -y git + fi + else + echo "Warning: unmatched OS/distribution" + echo "Missing software will not be installed" + fi fi -if [ -z "$WORKSPACE" ]; then - # shellcheck disable=SC2155 - export WORKSPACE=`git rev-parse --show-toplevel` +if [[ -z "${WORKSPACE}" ]]; then + if (git rev-parse --show-toplevel > /dev/null 2>&1); then + WORKSPACE=$(git rev-parse --show-toplevel) + export WORKSPACE + else + WORKSPACE=$(pwd) + export WORKSPACE + fi fi # shellcheck disable=SC2034 -TESTPLANDIR=${WORKSPACE}/${TESTPLAN} +TESTPLANDIR="${WORKSPACE}/${TESTPLAN}" # Python version should match that used to setup # robot-framework in other jobs/stages @@ -56,22 +86,26 @@ fi # Assume that if ROBOT3_VENV is set, virtualenv # with system site packages can be activated -if [ -f ${WORKSPACE}/env.properties ]; then - source ${WORKSPACE}/env.properties +if [[ -f "${WORKSPACE}/env.properties" ]]; then + source "${WORKSPACE}/env.properties" +elif [[ -f /tmp/env.properties ]]; then + source /tmp/env.properties fi -if [ -f ${ROBOT3_VENV}/bin/activate ]; then - source ${ROBOT3_VENV}/bin/activate + +if [[ -f "${ROBOT3_VENV}/bin/activate" ]]; then + source "${ROBOT3_VENV}/bin/activate" else # Robot framework was not found # clone ci-management repository and use install script git clone "https://gerrit.onap.org/r/ci-management" \ /tmp/ci-management - source /tmp/ci-management/jjb/integration/${ROBOT_INSTALLER} + # shellcheck disable=SC1090 + source "/tmp/ci-management/jjb/integration/${ROBOT_INSTALLER}" fi # install eteutils -mkdir -p ${ROBOT3_VENV}/src/onap -rm -rf ${ROBOT3_VENV}/src/onap/testsuite +mkdir -p "${ROBOT3_VENV}/src/onap" +rm -rf "${ROBOT3_VENV}/src/onap/testsuite" # Source from the Nexus repository python3 -m pip install --upgrade \ --extra-index-url="https://nexus3.onap.org/repository/PyPi.staging/simple" \ diff --git a/jjb/integration/run-csit.sh b/jjb/integration/run-csit.sh index bd35ac438..877cebbba 100644 --- a/jjb/integration/run-csit.sh +++ b/jjb/integration/run-csit.sh @@ -15,13 +15,35 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# $1 project/functionality -# $2 robot options +# $1 project/functionality {TESTPLAN} +# $2 robot options {TESTOPTIONS} echo "---> run-csit.sh" WORKDIR=$(mktemp -d --suffix=-robot-workdir) +# Exit if no arguments are provided and required variables not set +if [[ $# -eq 0 ]] && [[ -z "${TESTPLAN}" ]] && [[ -z "${TESTOPTIONS}" ]]; then + echo + echo "Usage: $0 plans/<project>/<functionality> [<robot-options>]" + echo + echo " <project>, <functionality>, <robot-options>: " + echo " The same values as for the JJB job template:" + echo ' {project}-csit-{functionality}' + echo + exit 1 + +elif [[ $# -ne 2 ]] && [[ -z "${TESTPLAN}" ]] && [[ -z "${TESTOPTIONS}" ]]; then + echo + echo "Script called without arguments, but the following variables" + echo " must be set: {TESTPLAN} {TESTOPTIONS}" + echo + exit 1 + +elif [[ $# -eq 2 ]]; then + export TESTPLAN=$1; export TESTOPTIONS=$2 +fi + # Python version should match that used to setup # robot-framework in other jobs/stages # Use pyenv for selecting the python version @@ -43,12 +65,52 @@ fi # functions # +# load the saved set options +function load_set { + _setopts="$-" + + # bash shellopts + for i in $(echo "$SHELLOPTS" | tr ':' ' ') ; do + set +o "${i}" + done + for i in $(echo "$RUN_CSIT_SHELLOPTS" | tr ':' ' ') ; do + set -o "${i}" + done + + # other options + for i in $(echo "$_setopts" | sed 's/./& /g') ; do + set +"${i}" + done + set -"${RUN_CSIT_SAVE_SET}" +} + +# set options for quick bailout when error +function harden_set { + set -xeo pipefail + set +u # enabled it would probably fail too many often +} + +# relax set options so the sourced file will not fail +# the responsibility is shifted to the sourced file... +function relax_set { + set +e + set +o pipefail +} + +# save current set options +function save_set { + RUN_CSIT_SAVE_SET="$-" + RUN_CSIT_SHELLOPTS="$SHELLOPTS" +} + # wrapper for sourcing a file function source_safely { - [ -z "$1" ] && return 1 - relax_set - . "$1" - load_set + if [[ -z "$1" ]] && return 1; then + relax_set + # shellcheck disable=SC1090 + source "$1" + load_set + fi } function on_exit { @@ -66,11 +128,10 @@ function on_exit { # Run teardown script plan if it exists cd "${TESTPLANDIR}" TEARDOWN="${TESTPLANDIR}/teardown.sh" - if [ -f "${TEARDOWN}" ]; then + if [[ -f "${TEARDOWN}" ]]; then echo "Running teardown script ${TEARDOWN}" source_safely "${TEARDOWN}" fi - # TODO: do something with the output exit $rc } # ensure that teardown and other finalizing steps are always executed @@ -96,44 +157,6 @@ function docker_stats { echo } -# save current set options -function save_set { - RUN_CSIT_SAVE_SET="$-" - RUN_CSIT_SHELLOPTS="$SHELLOPTS" -} - -# load the saved set options -function load_set { - _setopts="$-" - - # bash shellopts - for i in $(echo "$SHELLOPTS" | tr ':' ' ') ; do - set +o ${i} - done - for i in $(echo "$RUN_CSIT_SHELLOPTS" | tr ':' ' ') ; do - set -o ${i} - done - - # other options - for i in $(echo "$_setopts" | sed 's/./& /g') ; do - set +${i} - done - set -${RUN_CSIT_SAVE_SET} -} - -# set options for quick bailout when error -function harden_set { - set -xeo pipefail - set +u # enabled it would probably fail too many often -} - -# relax set options so the sourced file will not fail -# the responsibility is shifted to the sourced file... -function relax_set { - set +e - set +o pipefail -} - # # main # @@ -141,29 +164,21 @@ function relax_set { # set and save options for quick failure harden_set && save_set -if [ $# -eq 0 ]; then - echo - echo "Usage: $0 plans/<project>/<functionality> [<robot-options>]" - echo - echo " <project>, <functionality>, <robot-options>: " - echo " The same values as for the '{project}-csit-{functionality}' JJB job template." - echo - exit 1 -fi - -if [ -z "$WORKSPACE" ]; then - export WORKSPACE=$(git rev-parse --show-toplevel) +if [[ -z "${WORKSPACE}" ]]; then + if (git rev-parse --show-toplevel > /dev/null 2>&1); then + WORKSPACE=$(git rev-parse --show-toplevel) + export WORKSPACE + else + WORKSPACE=$(pwd) + export WORKSPACE + fi fi -if [ -f "${WORKSPACE}/${1}/testplan.txt" ]; then - export TESTPLAN="${1}" -else +if [[ ! -f "${WORKSPACE}/${TESTPLAN}/testplan.txt" ]]; then echo "testplan not found: ${WORKSPACE}/${TESTPLAN}/testplan.txt" exit 2 fi -export TESTOPTIONS="${2}" - rm -rf "$WORKSPACE/archives/$TESTPLAN" mkdir -p "$WORKSPACE/archives/$TESTPLAN" @@ -178,7 +193,7 @@ source_safely "${ROBOT3_VENV}/bin/activate" cd "${WORKDIR}" # Add csit scripts to PATH -export PATH="${PATH}:${WORKSPACE}/docker/scripts:${WORKSPACE}/scripts:${ROBOT_VENV}/bin" +export PATH="${PATH}:${WORKSPACE}/docker/scripts:${WORKSPACE}/scripts:${ROBOT3_VENV}/bin" export SCRIPTS="${WORKSPACE}/scripts" export ROBOT_VARIABLES= @@ -199,7 +214,8 @@ docker_stats | tee "$WORKSPACE/archives/$TESTPLAN/_sysinfo-1-after-setup.txt" # Run test plan cd "$WORKDIR" echo "Reading the testplan:" -cat "${TESTPLANDIR}/testplan.txt" | egrep -v '(^[[:space:]]*#|^[[:space:]]*$)' | sed "s|^|${WORKSPACE}/tests/|" > testplan.txt +grep -E -v '(^[[:space:]]*#|^[[:space:]]*$)' "${TESTPLANDIR}/testplan.txt" |\ + sed "s|^|${WORKSPACE}/tests/|" > testplan.txt cat testplan.txt SUITES=$( xargs -a testplan.txt ) @@ -212,10 +228,9 @@ python3 --version pip freeze python3 -m robot.run --version || : -python -m robot.run -N ${TESTPLAN} -v WORKSPACE:/tmp ${ROBOT_VARIABLES} ${TESTOPTIONS} ${SUITES} +python -m robot.run -N "${TESTPLAN}" -v WORKSPACE:/tmp "${ROBOT_VARIABLES}" "${TESTOPTIONS}" "${SUITES}" RESULT=$? load_set echo "RESULT: $RESULT" # Note that the final steps are done in on_exit function after this exit! exit $RESULT - |