Introduce CPS integration testing (CSIT)
Issue-ID: CPS-188
Change-Id: I4a225da73587d5276f302b05a0729d1127caddd9
Signed-off-by: Ruslan Kashapov <ruslan.kashapov@pantheon.tech>
diff --git a/csit/.gitignore b/csit/.gitignore
new file mode 100644
index 0000000..c8865c2
--- /dev/null
+++ b/csit/.gitignore
@@ -0,0 +1,2 @@
+env.properties
+archives/
diff --git a/csit/README.md b/csit/README.md
new file mode 100644
index 0000000..31a59e3
--- /dev/null
+++ b/csit/README.md
@@ -0,0 +1,34 @@
+## Continuous System and Integration Testing (CSIT) for CPS
+
+The directory structure:
+
+- **plans/** contains testing plans, each sub-folder represents a separate test plan, contains processed subsequently:
+ _startup.sh_ (serves docker containers startup), _testplan.txt_ (lists test-suits), _teardown.sh_ (serves docker containers stopping and images removal)
+- **scripts/** contains shell scripts used on tests executions
+- **tests/** contains test suits which are processed by folder name (relative to _tests_ folder) taken from _testplan.txt_
+
+Test suits are executed using Robots framework.
+
+### Running on local environment
+
+Prerequisites:
+- docker
+- python + pip
+
+```bash
+sudo apt install python3-pip
+```
+
+The Robot framework and required python packages will be installed on first execution.
+
+Build a docker image (see also [docker-compose readme](../docker-compose/README.md) ):
+
+```bash
+mvn clean package -Dmaven.test.skip=true -Dnexus.repository= -Pcps-xnf-docker
+```
+
+Execute test from current folder:
+```bash
+./run-project-csit.sh
+```
+
\ No newline at end of file
diff --git a/csit/plans/default/setup.sh b/csit/plans/default/setup.sh
new file mode 100755
index 0000000..e7e8f4b
--- /dev/null
+++ b/csit/plans/default/setup.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+#
+# Copyright 2016-2017 Huawei Technologies Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Modifications copyright (c) 2017 AT&T Intellectual Property
+# Modifications copyright (c) 2020-2021 Samsung Electronics Co., Ltd.
+# Modifications Copyright (C) 2021 Pantheon.tech
+#
+
+# Copy docker-compose.yml and application.yml to archives
+mkdir -p $WORKSPACE/archives/docker-compose
+cp $WORKSPACE/../docker-compose/*.yml $WORKSPACE/archives/docker-compose
+cd $WORKSPACE/archives/docker-compose
+
+# Set env variables for docker compose
+export DB_HOST=dbpostgresql
+export DB_USERNAME=cps
+export DB_PASSWORD=cps
+# Use latest image version
+export VERSION=latest
+
+# start CPS and PostgreSQL containers with docker compose
+docker-compose up -d
+
+# Validate CPS service initialization completed via periodic log checking for line like below:
+# org.onap.cps.Application ... Started Application in X.XXX seconds
+
+TIME_OUT=300
+INTERVAL=10
+TIME=0
+
+while [ "$TIME" -le "$TIME_OUT" ]; do
+ LOG_FOUND=$( docker-compose logs --tail="all" | grep "org.onap.cps.Application" | egrep -c "Started Application in" )
+
+ if [ "$LOG_FOUND" -gt 0 ]; then
+ echo "CPS Service started"
+ break;
+ fi
+
+ echo "Sleep $INTERVAL seconds before next check for CPS initialization (waiting $TIME seconds; timeout is $TIME_OUT seconds)"
+ sleep $INTERVAL
+ TIME=$((TIME + INTERVAL))
+done
+
+if [ "$TIME" -gt "$TIME_OUT" ]; then
+ echo "TIME OUT: CPS Service wasn't able to start in $TIME_OUT seconds, setup failed."
+ exit 1;
+fi
+
+# TODO localhost works on a local environment, check if it's ok on jenkins
+CPS_HOST="http://localhost:8883"
+
+# Pass variables required for Robot test suites in ROBOT_VARIABLES
+ROBOT_VARIABLES="-v SCRIPTS:$SCRIPTS -v CPS_HOST:$CPS_HOST"
+
diff --git a/csit/plans/default/teardown.sh b/csit/plans/default/teardown.sh
new file mode 100755
index 0000000..9028025
--- /dev/null
+++ b/csit/plans/default/teardown.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+#
+# Copyright 2016-2017 Huawei Technologies Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Modifications copyright (c) 2017 AT&T Intellectual Property
+# Modifications copyright (c) 2020 Samsung Electronics Co., Ltd.
+# Modifications Copyright (C) 2021 Pantheon.tech
+#
+
+cd $WORKSPACE/archives/docker-compose
+docker-compose down -v
diff --git a/csit/plans/default/testplan.txt b/csit/plans/default/testplan.txt
new file mode 100644
index 0000000..edcad0d
--- /dev/null
+++ b/csit/plans/default/testplan.txt
@@ -0,0 +1,4 @@
+# Test suites are relative paths under csit/tests/.
+# Place the suites in run order.
+actuator
+
diff --git a/csit/prepare-csit.sh b/csit/prepare-csit.sh
new file mode 100755
index 0000000..05d99a7
--- /dev/null
+++ b/csit/prepare-csit.sh
@@ -0,0 +1,52 @@
+#!/bin/bash -x
+#
+# Copyright 2019-2021 © Samsung Electronics Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This script installs common libraries required by CSIT tests
+#
+
+# Branched from integration/csit to this repository 18.2.2021
+#
+
+if [ -z "$WORKSPACE" ]; then
+ export WORKSPACE=`git rev-parse --show-toplevel`
+fi
+
+TESTPLANDIR=${WORKSPACE}/${TESTPLAN}
+
+# Assume that if ROBOT_VENV is set and virtualenv with system site packages can be activated,
+# ci-management/jjb/integration/include-raw-integration-install-robotframework.sh has already
+# been executed
+
+if [ -f ${WORKSPACE}/env.properties ]; then
+ source ${WORKSPACE}/env.properties
+fi
+if [ -f ${ROBOT_VENV}/bin/activate ]; then
+ source ${ROBOT_VENV}/bin/activate
+else
+ rm -rf /tmp/ci-management
+ rm -f ${WORKSPACE}/env.properties
+ cd /tmp
+ git clone "https://gerrit.onap.org/r/ci-management"
+ source /tmp/ci-management/jjb/integration/include-raw-integration-install-robotframework.sh
+fi
+
+# install eteutils
+mkdir -p ${ROBOT_VENV}/src/onap
+rm -rf ${ROBOT_VENV}/src/onap/testsuite
+#pip install --upgrade --extra-index-url="https://nexus3.onap.org/repository/PyPi.staging/simple" 'robotframework-onap==0.5.1.*' --pre
+
+pip freeze
+
diff --git a/csit/run-csit.sh b/csit/run-csit.sh
new file mode 100755
index 0000000..e23e84a
--- /dev/null
+++ b/csit/run-csit.sh
@@ -0,0 +1,198 @@
+#!/bin/bash -x
+#
+# Copyright 2016-2017 Huawei Technologies Co., Ltd.
+# Modification Copyright 2019-2021 © Samsung Electronics Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# $1 project/functionality
+# $2 robot options
+
+# Branched from integration/csit to this repository 18.2.2021
+#
+
+#
+# functions
+#
+
+function on_exit(){
+ rc=$?
+ if [[ ${WORKSPACE} ]]; then
+ if [[ ${WORKDIR} ]]; then
+ rsync -av "$WORKDIR/" "$WORKSPACE/archives/$TESTPLAN"
+ fi
+ # Record list of active docker containers
+ docker ps --format "{{.Image}}" > "$WORKSPACE/archives/$TESTPLAN/_docker-images.log"
+
+ # show memory consumption after all docker instances initialized
+ docker_stats | tee "$WORKSPACE/archives/$TESTPLAN/_sysinfo-2-after-robot.txt"
+ fi
+ # Run teardown script plan if it exists
+ cd "${TESTPLANDIR}"
+ TEARDOWN="${TESTPLANDIR}/teardown.sh"
+ 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
+trap on_exit EXIT
+
+function docker_stats(){
+ #General memory details
+ echo "> top -bn1 | head -3"
+ top -bn1 | head -3
+ echo
+
+ echo "> free -h"
+ free -h
+ echo
+
+ #Memory details per Docker
+ echo "> docker ps"
+ docker ps
+ echo
+
+ echo "> docker stats --no-stream"
+ docker stats --no-stream
+ 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
+}
+
+# wrapper for sourcing a file
+function source_safely() {
+ [ -z "$1" ] && return 1
+ relax_set
+ . "$1"
+ load_set
+}
+
+#
+# main
+#
+
+# 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)
+fi
+
+if [ -f "${WORKSPACE}/${1}/testplan.txt" ]; then
+ export TESTPLAN="${1}"
+else
+ echo "testplan not found: ${WORKSPACE}/${TESTPLAN}/testplan.txt"
+ exit 2
+fi
+
+export TESTOPTIONS="${2}"
+
+rm -rf "$WORKSPACE/archives/$TESTPLAN"
+mkdir -p "$WORKSPACE/archives/$TESTPLAN"
+
+TESTPLANDIR="${WORKSPACE}/${TESTPLAN}"
+
+# Run installation of prerequired libraries
+source_safely "${WORKSPACE}/prepare-csit.sh"
+
+# Activate the virtualenv containing all the required libraries installed by prepare-csit.sh
+source_safely "${ROBOT_VENV}/bin/activate"
+
+WORKDIR=$(mktemp -d --suffix=-robot-workdir)
+cd "${WORKDIR}"
+
+# Add csit scripts to PATH
+export PATH="${PATH}:${WORKSPACE}/docker/scripts:${WORKSPACE}/scripts:${ROBOT_VENV}/bin"
+export SCRIPTS="${WORKSPACE}/scripts"
+export ROBOT_VARIABLES=
+
+# Sign in to nexus3 docker repo
+docker login -u docker -p docker nexus3.onap.org:10001
+
+# Run setup script plan if it exists
+cd "${TESTPLANDIR}"
+SETUP="${TESTPLANDIR}/setup.sh"
+if [ -f "${SETUP}" ]; then
+ echo "Running setup script ${SETUP}"
+ source_safely "${SETUP}"
+fi
+
+# show memory consumption after all docker instances initialized
+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
+cat testplan.txt
+SUITES=$( xargs -a testplan.txt )
+
+echo ROBOT_VARIABLES="${ROBOT_VARIABLES}"
+echo "Starting Robot test suites ${SUITES} ..."
+relax_set
+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
diff --git a/csit/run-project-csit.sh b/csit/run-project-csit.sh
new file mode 100755
index 0000000..1df8267
--- /dev/null
+++ b/csit/run-project-csit.sh
@@ -0,0 +1,34 @@
+#!/bin/bash -x
+#
+# Copyright 2020-2021 © Samsung Electronics Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Modifications Copyright (C) 2021 Pantheon.tech
+#
+
+# $1 test options (passed on to run-csit.sh as such)
+
+export TESTOPTIONS=${1}
+export WORKSPACE=$(git rev-parse --show-toplevel)/csit
+
+rm -rf ${WORKSPACE}/archives
+mkdir -p ${WORKSPACE}/archives
+cd ${WORKSPACE}
+
+# Execute all test-suites defined under plans subdirectory
+for dir in plans/*/
+do
+ dir=${dir%*/} # remove the trailing /
+ ./run-csit.sh ${dir} ${TESTOPTIONS}
+done
diff --git a/csit/scripts/actuator/check_endpoint.sh b/csit/scripts/actuator/check_endpoint.sh
new file mode 100755
index 0000000..7a8cac7
--- /dev/null
+++ b/csit/scripts/actuator/check_endpoint.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+#
+# ============LICENSE_START=======================================================
+# Copyright (C) 2021 Pantheon.tech
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+#
+
+# $1 is endpoint for GET request
+
+echo "Testing CPS actuator endpoint $1"
+
+response=$(curl -o /dev/null -s -w "%{http_code}\n" -H "Accept: application/json" -H "Content-Type: application/json" -X GET $1)
+
+if [ "$response" == "200" ]; then
+ echo "CPS Actuator endpoint check successful."
+ exit 0;
+fi
+
+echo "CPS Actuator endpoint check failed with response code ${response}."
+exit 1
diff --git a/csit/tests/actuator/__init__.robot b/csit/tests/actuator/__init__.robot
new file mode 100644
index 0000000..714f3c3
--- /dev/null
+++ b/csit/tests/actuator/__init__.robot
@@ -0,0 +1,2 @@
+*** Settings ***
+Documentation CPS - Actuator endpoints
diff --git a/csit/tests/actuator/actuator.robot b/csit/tests/actuator/actuator.robot
new file mode 100644
index 0000000..59c7607
--- /dev/null
+++ b/csit/tests/actuator/actuator.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Library OperatingSystem
+Library Process
+
+*** Variables ***
+
+${check} ${SCRIPTS}/actuator/check_endpoint.sh
+
+*** Test Cases ***
+Liveness Probe for CPS
+ [Documentation] Liveness Probe
+ ${result}= Run Process bash ${check} ${CPS_HOST}/manage/health/liveness >> actuator-test.log shell=yes
+ Should Be Equal As Integers ${result.rc} 0
+
+Readiness Probe for CPS
+ [Documentation] Readiness Probe
+ ${result}= Run Process bash ${check} ${CPS_HOST}/manage/health/readiness >> actuator-test.log shell=yes
+ Should Be Equal As Integers ${result.rc} 0