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