Merge "Chore: Updates to improve overall robustness of robot framework tooling"
diff --git a/jjb/integration/include-raw-integration-install-robotframework-py3.sh b/jjb/integration/include-raw-integration-install-robotframework-py3.sh
index 6d0b496..efeb0f7 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
-# Save the virtual environment in ROBOT_VENV
-ROBOT3_VENV="$(cat "${WORKSPACE}/.robot3_venv")"
-echo ROBOT3_VENV="${ROBOT3_VENV}" >> "${WORKSPACE}/env.properties"
+REQUIRED_PYTHON="3.7.0"
-set -exu
+### Common functions
-echo "Installing Python Requirements"
+# 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 ]]
+}
+
+### Main script entry point
+
+# 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
+
+# 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 @@
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 1052bff..0db140f 100644
--- a/jjb/integration/prepare-csit.sh
+++ b/jjb/integration/prepare-csit.sh
@@ -24,18 +24,48 @@
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 @@
# 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 bd35ac4..877cebb 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 @@
# 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 @@
# 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 @@
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 @@
# 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
+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 [ -z "$WORKSPACE" ]; then
- export WORKSPACE=$(git rev-parse --show-toplevel)
-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 @@
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 @@
# 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 @@
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
-