diff options
author | Matthew Watkins <mwatkins@linuxfoundation.org> | 2023-01-04 11:29:33 +0000 |
---|---|---|
committer | Matthew Watkins <mwatkins@linuxfoundation.org> | 2023-02-14 10:51:50 +0000 |
commit | 795671a1f575b00012e1b5865cd338e45cc69b64 (patch) | |
tree | 3a07efab7eed5c4c95cf23fb2ea678a00d115b01 /jjb | |
parent | 381d669737e2f88b4c6800f00b21deb279e793b2 (diff) |
Chore: Updates to improve overall robustness of robot framework tooling
Improved scripts to better meet modern coding best practices. Improved
many script functions and behaviours to allow some code to run outside
Jenkins jobs. Addressed many warnings produced by linting tools.
Issue-ID: CCSDK-3820
Signed-off-by: Matthew Watkins <mwatkins@linuxfoundation.org>
Change-Id: I2e4f702a0b58cbace341c31669b4ffcb023d499c
Diffstat (limited to 'jjb')
-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 - |