Add trigger fro DPDK tests
[csit.git] / resources / libraries / bash / function / common.sh
index a8ce456..f2931b3 100644 (file)
@@ -21,6 +21,71 @@ set -exuo pipefail
 #   the code might become more readable (but longer).
 
 
+function activate_docker_topology () {
+    # Create virtual vpp-device topology. Output of the function is topology
+    # file describing created environment saved to a file.
+    #
+    # Variables read:
+    # - BASH_FUNCTION_DIR - Path to existing directory this file is located in.
+    # - TOPOLOGIES - Available topologies.
+    # - NODENESS - Node multiplicity of desired testbed.
+    # - FLAVOR - Node flavor string, usually describing the processor.
+    # Variables set:
+    # - WORKING_TOPOLOGY - Path to topology file.
+
+    set -exuo pipefail
+
+    source "${BASH_FUNCTION_DIR}/device.sh" || {
+        die "Source failed!"
+    }
+
+    device_image="$(< ${CSIT_DIR}/VPP_DEVICE_IMAGE)"
+    case_text="${NODENESS}_${FLAVOR}"
+    case "${case_text}" in
+        "1n_skx")
+            # We execute reservation over csit-shim-dcr (ssh) which runs sourced
+            # script's functions. Env variables are read from ssh output
+            # back to localhost for further processing.
+            hostname=$(grep search /etc/resolv.conf | cut -d' ' -f3)
+            ssh="ssh root@${hostname} -p 6022"
+            run="activate_wrapper ${NODENESS} ${FLAVOR} ${device_image}"
+            env_vars=$(${ssh} "$(declare -f); ${run}") || {
+                die "Topology reservation via shim-dcr failed!"
+            }
+            set -a
+            source <(echo "$env_vars" | grep -v /usr/bin/docker) || {
+                die "Source failed!"
+            }
+            set +a
+            ;;
+        "1n_vbox")
+            # We execute reservation on localhost. Sourced script automatially
+            # sets environment variables for further processing.
+            activate_wrapper "${NODENESS}" "${FLAVOR}" "${device_image}" || die
+            ;;
+        *)
+            die "Unknown specification: ${case_text}!"
+    esac
+
+    trap 'deactivate_docker_topology' EXIT || {
+         die "Trap attempt failed, please cleanup manually. Aborting!"
+    }
+
+    # Replace all variables in template with those in environment.
+    source <(echo 'cat <<EOF >topo.yml'; cat ${TOPOLOGIES[0]}; echo EOF;) || {
+        die "Topology file create failed!"
+    }
+
+    WORKING_TOPOLOGY="/tmp/topology.yaml"
+    mv topo.yml "${WORKING_TOPOLOGY}" || {
+        die "Topology move failed!"
+    }
+    cat ${WORKING_TOPOLOGY} | grep -v password || {
+        die "Topology read failed!"
+    }
+}
+
+
 function activate_virtualenv () {
 
     set -exuo pipefail
@@ -82,6 +147,20 @@ function check_download_dir () {
 }
 
 
+function cleanup_topo () {
+
+    set -exuo pipefail
+
+    # Variables read:
+    # - WORKING_TOPOLOGY - Path to topology yaml file of the reserved testbed.
+    # - PYTHON_SCRIPTS_DIR - Path to directory holding the reservation script.
+
+    python "${PYTHON_SCRIPTS_DIR}/topo_cleanup.py" -t "${WORKING_TOPOLOGY}"
+    # Not using "|| die" as some callers might want to ignore errors,
+    # e.g. in teardowns, such as unreserve.
+}
+
+
 function common_dirs () {
 
     set -exuo pipefail
@@ -140,13 +219,28 @@ function compose_pybot_arguments () {
     # - DUT - CSIT test/ subdirectory, set while processing tags.
     # - TAGS - Array variable holding selected tag boolean expressions.
     # - TOPOLOGIES_TAGS - Tag boolean expression filtering tests for topology.
+    # - TEST_CODE - The test selection string from environment or argument.
     # Variables set:
     # - PYBOT_ARGS - String holding part of all arguments for pybot.
     # - EXPANDED_TAGS - Array of strings pybot arguments compiled from tags.
 
     # No explicit check needed with "set -u".
-    PYBOT_ARGS=("--loglevel" "TRACE" "--variable" "TOPOLOGY_PATH:${WORKING_TOPOLOGY}")
-    PYBOT_ARGS+=("--suite" "tests.${DUT}.perf")
+    PYBOT_ARGS=("--loglevel" "TRACE")
+    PYBOT_ARGS+=("--variable" "TOPOLOGY_PATH:${WORKING_TOPOLOGY}")
+
+    case "${TEST_CODE}" in
+        *"device"*)
+            PYBOT_ARGS+=("--suite" "tests.${DUT}.device")
+            ;;
+        *"func"*)
+            PYBOT_ARGS+=("--suite" "tests.${DUT}.func")
+            ;;
+        *"perf"*)
+            PYBOT_ARGS+=("--suite" "tests.${DUT}.perf")
+            ;;
+        *)
+            die "Unknown specification: ${TEST_CODE}"
+    esac
 
     EXPANDED_TAGS=()
     for tag in "${TAGS[@]}"; do
@@ -178,11 +272,43 @@ function copy_archives () {
     # automatically archived to logs.fd.io.
     if [[ -n "${WORKSPACE-}" ]]; then
         mkdir -p "${WORKSPACE}/archives/" || die "Archives dir create failed."
-        cp -r "${ARCHIVE_DIR}"/* "${WORKSPACE}/archives" || die "Copy failed."
+        cp -rf "${ARCHIVE_DIR}"/* "${WORKSPACE}/archives" || die "Copy failed."
     fi
 }
 
 
+function deactivate_docker_topology () {
+    # Deactivate virtual vpp-device topology by removing containers.
+    #
+    # Variables read:
+    # - NODENESS - Node multiplicity of desired testbed.
+    # - FLAVOR - Node flavor string, usually describing the processor.
+
+    set -exuo pipefail
+
+    case_text="${NODENESS}_${FLAVOR}"
+    case "${case_text}" in
+        "1n_skx")
+            hostname=$(grep search /etc/resolv.conf | cut -d' ' -f3)
+            ssh="ssh root@${hostname} -p 6022"
+            env_vars="$(env | grep CSIT_ | tr '\n' ' ' )"
+            ${ssh} "$(declare -f); deactivate_wrapper ${env_vars}" || {
+                die "Topology cleanup via shim-dcr failed!"
+            }
+            ;;
+        "1n_vbox")
+            enter_mutex || die
+            clean_environment || {
+                die "Topology cleanup locally failed!"
+            }
+            exit_mutex || die
+            ;;
+        *)
+            die "Unknown specification: ${case_text}!"
+    esac
+}
+
+
 function die () {
     # Print the message to standard error end exit with error code specified
     # by the second argument.
@@ -237,6 +363,14 @@ function get_test_code () {
     fi
 
     case "${TEST_CODE}" in
+        *"1n-vbox"*)
+            NODENESS="1n"
+            FLAVOR="vbox"
+            ;;
+        *"1n-skx"*)
+            NODENESS="1n"
+            FLAVOR="skx"
+            ;;
         *"2n-skx"*)
             NODENESS="2n"
             FLAVOR="skx"
@@ -261,6 +395,7 @@ function get_test_tag_string () {
     # Variables read:
     # - GERRIT_EVENT_TYPE - Event type set by gerrit, can be unset.
     # - GERRIT_EVENT_COMMENT_TEXT - Comment text, read for "comment-added" type.
+    # - TEST_CODE - The test selection string from environment or argument.
     # Variables set:
     # - TEST_TAG_STRING - The string following "perftest" in gerrit comment,
     #   or empty.
@@ -269,12 +404,27 @@ function get_test_tag_string () {
 
     trigger=""
     if [[ "${GERRIT_EVENT_TYPE-}" == "comment-added" ]]; then
-        # On parsing error, ${trigger} stays empty.
-        trigger="$(echo "${GERRIT_EVENT_COMMENT_TEXT}" \
-            | grep -oE '(perftest$|perftest[[:space:]].+$)')" || true
+        case "${TEST_CODE}" in
+            *"device"*)
+                # On parsing error, ${trigger} stays empty.
+                trigger="$(echo "${GERRIT_EVENT_COMMENT_TEXT}" \
+                    | grep -oE '(devicetest$|devicetest[[:space:]].+$)')" \
+                    || true
+                # Set test tags as string.
+                TEST_TAG_STRING="${trigger#$"devicetest"}"
+                ;;
+            *"perf"*)
+                # On parsing error, ${trigger} stays empty.
+                trigger="$(echo "${GERRIT_EVENT_COMMENT_TEXT}" \
+                    | grep -oE '(perftest$|perftest[[:space:]].+$)')" \
+                    || true
+                # Set test tags as string.
+                TEST_TAG_STRING="${trigger#$"perftest"}"
+                ;;
+            *)
+                die "Unknown specification: ${TEST_CODE}"
+        esac
     fi
-    # Set test tags as string.
-    TEST_TAG_STRING="${trigger#$"perftest"}"
 }
 
 
@@ -310,7 +460,7 @@ function reserve_testbed () {
                     }
                     die "Trap attempt failed, unreserve succeeded. Aborting."
                 }
-                python "${PYTHON_SCRIPTS_DIR}/topo_cleanup.py" -t "${topo}" || {
+                cleanup_topo || {
                     die "Testbed cleanup failed."
                 }
                 break
@@ -410,8 +560,8 @@ function select_tags () {
                             "mrrANDnic_cisco-vic-1227AND64b"
                             "mrrANDnic_cisco-vic-1385AND64b"
                             # memif
-                            "mrrANDmemifAND64b"
-                            "mrrANDmemifANDimix"
+                            "mrrANDmemifANDethAND64b"
+                            "mrrANDmemifANDethANDimix"
                             # crypto
                             "mrrANDipsecAND64b"
                             # ip4 base
@@ -430,6 +580,10 @@ function select_tags () {
                             "mrrANDip4fwdANDnat44ANDsrc_user_4000AND64b"
                             # ip4 features
                             "mrrANDip4fwdANDfeatureANDnic_intel-*710AND64b"
+                            # TODO: Remove when tags in
+                            # tests/vpp/perf/ip4/*-ipolicemarkbase-*.robot
+                            # are fixed
+                            "mrrANDip4fwdANDpolice_markANDnic_intel-*710AND64b"
                             # ip4 tunnels
                             "mrrANDip4fwdANDencapANDip6unrlayANDip4ovrlayANDnic_intel-x520-da2AND64b"
                             "mrrANDip4fwdANDencapANDnic_intel-*710AND64b"
@@ -463,11 +617,11 @@ function select_tags () {
                             "mrrANDl2bdmaclrnANDacl1AND10k_flowsAND64b"
                             "mrrANDl2bdmaclrnANDacl50AND10k_flowsAND64b"
                             # l2bd scale FIB 2M
-                            "mrrANDl2bdmaclrnANDfib_2mAND64b"
+                            "mrrANDl2bdmaclrnANDfib_1mAND64b"
                             # l2bd scale FIB 200k
-                            "mrrANDl2bdmaclrnANDfib_200kANDnic_intel-*710AND64b"
+                            "mrrANDl2bdmaclrnANDfib_100kANDnic_intel-*710AND64b"
                             # l2bd scale FIB 20k
-                            "mrrANDl2bdmaclrnANDfib_20kANDnic_intel-*710AND64b"
+                            "mrrANDl2bdmaclrnANDfib_10kANDnic_intel-*710AND64b"
                             # l2 patch base
                             "mrrANDl2patchAND64b"
                             # srv6
@@ -481,9 +635,12 @@ function select_tags () {
                             "mrrANDvhostANDl2bdmaclrnANDbaseAND64b"
                             "mrrANDvhostANDl2bdmaclrnANDbaseANDimix"
                             # vm vhost ip4 base
-                            "mrrANDvhostANDip4baseAND64b"
-                            "mrrANDvhostANDip4baseANDimix"
+                            "mrrANDvhostANDip4fwdANDbaseAND64b"
+                            "mrrANDvhostANDip4fwdANDbaseANDimix"
+                            # DPDK
+                            "mrrANDdpdkAND64b"
                             # Exclude
+                            "!mrrANDip6baseANDdot1qAND78b"
                             "!vhost_256ANDnic_intel-x520-da2"
                             "!vhostANDnic_intel-xl710"
                             "!cfs_opt"
@@ -546,6 +703,52 @@ function select_tags () {
 }
 
 
+function select_vpp_device_tags () {
+
+    set -exuo pipefail
+
+    # Variables read:
+    # - TEST_CODE - String affecting test selection, usually jenkins job name.
+    # - TEST_TAG_STRING - String selecting tags, from gerrit comment.
+    #   Can be unset.
+    # Variables set:
+    # - TAGS - Array of processed tag boolean expressions.
+
+    case "${TEST_CODE}" in
+        # Select specific performance tests based on jenkins job type variable.
+        * )
+            if [[ -z "${TEST_TAG_STRING-}" ]]; then
+                # If nothing is specified, we will run pre-selected tests by
+                # following tags. Items of array will be concatenated by OR
+                # in Robot Framework.
+                test_tag_array=()
+            else
+                # If trigger contains tags, split them into array.
+                test_tag_array=(${TEST_TAG_STRING//:/ })
+            fi
+            ;;
+    esac
+
+    TAGS=()
+
+    # We will prefix with perftest to prevent running other tests
+    # (e.g. Functional).
+    prefix="devicetestAND"
+    if [[ "${TEST_CODE}" == "vpp-"* ]]; then
+        # Automatic prefixing for VPP jobs to limit testing.
+        prefix="${prefix}"
+    fi
+    for tag in "${test_tag_array[@]}"; do
+        if [[ ${tag} == "!"* ]]; then
+            # Exclude tags are not prefixed.
+            TAGS+=("${tag}")
+        else
+            TAGS+=("${prefix}${tag}")
+        fi
+    done
+}
+
+
 function select_topology () {
 
     set -exuo pipefail
@@ -554,7 +757,7 @@ function select_topology () {
     # - NODENESS - Node multiplicity of testbed, either "2n" or "3n".
     # - FLAVOR - Node flavor string, currently either "hsw" or "skx".
     # - CSIT_DIR - Path to existing root of local CSIT git repository.
-    # - TOPOLOGIES_DIR - Path to existing directory with available tpologies.
+    # - TOPOLOGIES_DIR - Path to existing directory with available topologies.
     # Variables set:
     # - TOPOLOGIES - Array of paths to suitable topology yaml files.
     # - TOPOLOGIES_TAGS - Tag expression selecting tests for the topology.
@@ -563,13 +766,17 @@ function select_topology () {
 
     case_text="${NODENESS}_${FLAVOR}"
     case "${case_text}" in
-        "3n_hsw")
+        "1n_vbox")
             TOPOLOGIES=(
-                        "${TOPOLOGIES_DIR}/lf_3n_hsw_testbed1.yaml"
-                        "${TOPOLOGIES_DIR}/lf_3n_hsw_testbed2.yaml"
-                        "${TOPOLOGIES_DIR}/lf_3n_hsw_testbed3.yaml"
+                        "${TOPOLOGIES_DIR}/vpp_device.template"
                        )
-            TOPOLOGIES_TAGS="3_node_single_link_topo"
+            TOPOLOGIES_TAGS="2_node_single_link_topo"
+            ;;
+        "1n_skx")
+            TOPOLOGIES=(
+                        "${TOPOLOGIES_DIR}/vpp_device.template"
+                       )
+            TOPOLOGIES_TAGS="2_node_single_link_topo"
             ;;
         "2n_skx")
             TOPOLOGIES=(
@@ -587,6 +794,14 @@ function select_topology () {
                        )
             TOPOLOGIES_TAGS="3_node_*_link_topo"
             ;;
+        "3n_hsw")
+            TOPOLOGIES=(
+                        "${TOPOLOGIES_DIR}/lf_3n_hsw_testbed1.yaml"
+                        "${TOPOLOGIES_DIR}/lf_3n_hsw_testbed2.yaml"
+                        "${TOPOLOGIES_DIR}/lf_3n_hsw_testbed3.yaml"
+                       )
+            TOPOLOGIES_TAGS="3_node_single_link_topo"
+            ;;
         *)
             # No falling back to 3n_hsw default, that should have been done
             # by the function which has set NODENESS and FLAVOR.
@@ -625,9 +840,9 @@ function untrap_and_unreserve_testbed () {
     wt="${WORKING_TOPOLOGY}"  # Just to avoid too long lines.
     if [[ -z "${wt-}" ]]; then
         set -eu
-        echo "Testbed looks unreserved already. Trap removal failed before?"
+        warn "Testbed looks unreserved already. Trap removal failed before?"
     else
-        python "${PYTHON_SCRIPTS_DIR}/topo_cleanup.py" -t "${wt}" || true
+        cleanup_topo || true
         python "${PYTHON_SCRIPTS_DIR}/topo_reservation.py" -c -t "${wt}" || {
             die "${1:-FAILED TO UNRESERVE, FIX MANUALLY.}" 2
         }