diff options
Diffstat (limited to 'tests')
33 files changed, 959 insertions, 535 deletions
diff --git a/tests/ci/cover.awk b/tests/ci/cover.awk deleted file mode 100644 index e4bb816dc..000000000 --- a/tests/ci/cover.awk +++ /dev/null @@ -1,25 +0,0 @@ -BEGIN{ - template = "%6s %-75s\n" - printf template, "Delta", "Module Path" -} - -/^-/{ - s = substr($1, 2) - x[s] = $3; -}; - -/^+/{ - s = substr($1, 2) - d = $3 - if (s in x) - d = d - x[s] - y[s" "d] = d -} - -END{ - asorti(y, z1, "@val_num_asc") - for (i=1; i <= length(z1); i++){ - split(z1[i], z2, " ") - printf template, z2[2], z2[1] - } -} diff --git a/tests/ci/cover.sh b/tests/ci/cover.sh deleted file mode 100644 index 780a85a22..000000000 --- a/tests/ci/cover.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/bin/bash -############################################################################## -# Copyright 2015: Mirantis Inc. -# All Rights Reserved. -# -# 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. -# yardstick comment: this is a modified copy of -# rally/tests/ci/cover.sh -############################################################################## - -if [[ -n $COVER_DIR_NAME ]]; then - : -elif [[ -n $_ ]]; then - COVER_DIR_NAME=$( dirname $_ ) -else - COVER_DIR_NAME=$( dirname $0 ) -fi - -show_diff () { - diff -U 0 $1 $2 | awk -f $COVER_DIR_NAME/cover.awk -} - -run_coverage_test() { - - ALLOWED_EXTRA_MISSING=10 - # enable debugging - set -x - - # Stash uncommitted changes, checkout master and save coverage report - uncommited=$(git status --porcelain | grep -v "^??") - [[ -n ${uncommited} ]] && git stash > /dev/null - git checkout HEAD^ - - baseline_report=$(mktemp -t yardstick_coverageXXXXXXX) - ls -l .testrepository - - # workaround 'db type could not be determined' bug - # https://bugs.launchpad.net/testrepository/+bug/1229445 - rm -rf .testrepository - find . -type f -name "*.pyc" -delete - - #python setup.py testr --coverage --testr-args="" - python setup.py testr --coverage --slowest --testr-args="$*" - testr failing - coverage report > ${baseline_report} - - # debug awk - tail -1 ${baseline_report} - baseline_missing=$(awk 'END { if (int($3) > 0) print $3 }' ${baseline_report}) - - if [[ -z $baseline_missing ]]; then - echo "Failed to determine baseline missing" - exit 1 - fi - - # Checkout back and unstash uncommitted changes (if any) - git checkout - - [[ -n ${uncommited} ]] && git stash pop > /dev/null - - # Generate and save coverage report - current_report=$(mktemp -t yardstick_coverageXXXXXXX) - ls -l .testrepository - - # workaround 'db type could not be determined' bug - # https://bugs.launchpad.net/testrepository/+bug/1229445 - rm -rf .testrepository - find . -type f -name "*.pyc" -delete - - #python setup.py testr --coverage --testr-args="" - python setup.py testr --coverage --slowest --testr-args="$*" - testr failing - coverage report > ${current_report} - - rm -rf cover-$PY_VER - coverage html -d cover-$PY_VER - - # debug awk - tail -1 ${current_report} - current_missing=$(awk 'END { if (int($3) > 0) print $3 }' ${current_report}) - - if [[ -z $current_missing ]]; then - echo "Failed to determine current missing" - exit 1 - fi - - # Show coverage details - new_missing=$((current_missing - baseline_missing)) - - echo "Missing lines allowed to introduce : ${ALLOWED_EXTRA_MISSING}" - echo "Missing lines introduced : ${new_missing}" - echo "Missing lines in master : ${baseline_missing}" - echo "Missing lines in proposed change : ${current_missing}" - - if [[ ${new_missing} -gt ${ALLOWED_EXTRA_MISSING} ]]; - then - show_diff ${baseline_report} ${current_report} - echo "Please write more unit tests, we should keep our test coverage :( " - rm ${baseline_report} ${current_report} - exit 1 - - elif [[ ${new_missing} -gt 0 ]]; - then - show_diff ${baseline_report} ${current_report} - echo "I believe you can cover all your code with 100% coverage!" - - else - echo "Thank you! You are awesome! Keep writing unit tests! :)" - fi - - rm ${baseline_report} ${current_report} -} diff --git a/tests/ci/load_images.sh b/tests/ci/load_images.sh index e73d7e800..666a78b40 100755 --- a/tests/ci/load_images.sh +++ b/tests/ci/load_images.sh @@ -63,11 +63,14 @@ build_yardstick_image() fi else if [ ! -f "${QCOW_IMAGE}" ];then - local cmd - cmd="sudo $(which yardstick-img-modify) $(pwd)/tools/ubuntu-server-cloudimg-modify.sh" - - # Build the image. Retry once if the build fails - $cmd || $cmd + ANSIBLE_SCRIPTS="${0%/*}/../../ansible" + cd ${ANSIBLE_SCRIPTS} &&\ + ansible-playbook \ + -e img_modify_playbook='ubuntu_server_cloudimg_modify.yml' \ + -e target_os='Ubuntu' \ + -e YARD_IMG_ARCH='amd64' \ + -e ubuntu_img_file="${QCOW_IMAGE}" \ + -vvv -i inventory.ini build_yardstick_image.yml if [ ! -f "${QCOW_IMAGE}" ]; then echo "Failed building QCOW image" @@ -209,7 +212,7 @@ create_nova_flavor() echo echo "========== Creating yardstick-flavor ==========" # Create the nova flavor used by some sample test cases - openstack ${SECURE} flavor create --id 100 --ram 1024 --disk 3 --vcpus 1 yardstick-flavor + openstack ${SECURE} flavor create --id 100 --ram 1024 --disk 10 --vcpus 1 yardstick-flavor # DPDK-enabled OVS requires guest memory to be backed by large pages if [[ $DEPLOY_SCENARIO == *[_-]ovs[_-]* ]]; then openstack ${SECURE} flavor set --property hw:mem_page_size=large yardstick-flavor diff --git a/tests/functional/test_cli_scenario.py b/tests/functional/test_cli_scenario.py index 4741e8244..63b533b85 100755 --- a/tests/functional/test_cli_scenario.py +++ b/tests/functional/test_cli_scenario.py @@ -32,31 +32,25 @@ class ScenarioTestCase(unittest.TestCase): def test_scenario_show_Lmbench(self): res = self.yardstick("scenario show Lmbench") - lmbench = "Execute lmbench memory read latency" - "or memory bandwidth benchmark in a host" in res - self.assertTrue(lmbench) + self.assertIn("Execute lmbench memory read latency or memory " + "bandwidth benchmark in a hos", res) def test_scenario_show_Perf(self): res = self.yardstick("scenario show Perf") - perf = "Execute perf benchmark in a host" in res - self.assertTrue(perf) + self.assertIn("Execute perf benchmark in a host", res) def test_scenario_show_Fio(self): res = self.yardstick("scenario show Fio") - fio = "Execute fio benchmark in a host" in res - self.assertTrue(fio) + self.assertIn("Execute fio benchmark in a host", res) def test_scenario_show_Ping(self): res = self.yardstick("scenario show Ping") - ping = "Execute ping between two hosts" in res - self.assertTrue(ping) + self.assertIn("Execute ping between two hosts", res) def test_scenario_show_Iperf3(self): res = self.yardstick("scenario show Iperf3") - iperf3 = "Execute iperf3 between two hosts" in res - self.assertTrue(iperf3) + self.assertIn("Execute iperf3 between two hosts", res) def test_scenario_show_Pktgen(self): res = self.yardstick("scenario show Pktgen") - pktgen = "Execute pktgen between two hosts" in res - self.assertTrue(pktgen) + self.assertIn("Execute pktgen between two hosts", res) diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc019.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc019.yaml index 852424d8e..08037d9fa 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc019.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc019.yaml @@ -10,10 +10,13 @@ schema: "yardstick:task:0.1" description: > - Sample test case for the HA of controller node Openstack service. + + Yardstick TC019 config file; + HA test case: HA test case: Control node Openstack service down - nova-api. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set attack_host = attack_host or "node1" %} +{% set attack_process = attack_process or "nova-api" %} scenarios: - @@ -21,7 +24,7 @@ scenarios: options: attackers: - fault_type: "kill-process" - process_name: "nova-api" + process_name: "{{ attack_process }}" host: {{attack_host}} wait_time: 10 @@ -33,7 +36,7 @@ scenarios: sla: max_outage_time: 5 - monitor_type: "process" - process_name: "nova-api" + process_name: "{{ attack_process }}" host: {{attack_host}} monitor_time: 30 monitor_number: 3 diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc023.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc023.yaml index f2cad4cc8..7136a9e7e 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc023.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc023.yaml @@ -9,6 +9,9 @@ --- schema: "yardstick:task:0.1" +description: > + Yardstick TC023 config file; + Measure VM availability during VM live migration. {% set file = file or "etc/yardstick/nodes/compass_sclab_virtual/pod.yaml" %} {% set cpu_set = cpu_set or "0,1,2,3" %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc025.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc025.yaml index 3e630caf2..ac2db0dbf 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc025.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc025.yaml @@ -10,11 +10,8 @@ schema: "yardstick:task:0.1" description: > - Sample test case for the HA of OpenStack Controll Node abnormally shutdown. - In order to power on the shutdown node after testing, the jumphost is - required to install ipmitool. Ipmi jumphost info and each nodes' ipmi ip, - username, password are needed in pod file (There is a sample pod file in - "etc/yardstick/nodes/pod.yaml.ipmi.sample"). + Yardstick TC025 config file; + HA test case: OpenStack Controll Node abnormally shutdown. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set jump_host = jump_host or 'node0' %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc045.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc045.yaml index f9d9dde48..bc7cd3d28 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc045.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc045.yaml @@ -10,10 +10,12 @@ schema: "yardstick:task:0.1" description: > - Test case for TC045 :Control node Openstack service down - neutron server. + Yardstick TC045 config file; + HA test case: Control node Openstack service down - neutron-server. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set attack_host = attack_host or "node1" %} +{% set attack_process = attack_process or "neutron-server" %} scenarios: - @@ -21,7 +23,7 @@ scenarios: options: attackers: - fault_type: "kill-process" - process_name: "neutron-server" + process_name: "{{ attack_process }}" host: {{attack_host}} monitors: @@ -32,7 +34,7 @@ scenarios: sla: max_outage_time: 5 - monitor_type: "process" - process_name: "neutron-server" + process_name: "{{ attack_process }}" host: {{attack_host}} monitor_time: 30 monitor_number: 3 diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc046.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc046.yaml index 129489968..3b04cc4bd 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc046.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc046.yaml @@ -10,10 +10,12 @@ schema: "yardstick:task:0.1" description: > - Test case for TC046 :Control node Openstack service down - keystone. + Yardstick TC046 config file; + HA test case: Control node Openstack service down - keystone. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set attack_host = attack_host or "node1" %} +{% set attack_process = attack_process or "keystone" %} scenarios: - @@ -21,7 +23,7 @@ scenarios: options: attackers: - fault_type: "kill-process" - process_name: "keystone" + process_name: "{{ attack_process }}" host: {{attack_host}} monitors: @@ -32,7 +34,7 @@ scenarios: sla: max_outage_time: 5 - monitor_type: "process" - process_name: "keystone" + process_name: "{{ attack_process }}" host: {{attack_host}} monitor_time: 30 monitor_number: 3 diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc047.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc047.yaml index 4a0b65b8d..d199e5117 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc047.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc047.yaml @@ -10,10 +10,12 @@ schema: "yardstick:task:0.1" description: > - Test case for TC047 :Control node Openstack service down - glance api. + Yardstick TC047 config file; + HA test case: Control node Openstack service down - glance-api. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set attack_host = attack_host or "node1" %} +{% set attack_process = attack_process or "glance-api" %} scenarios: - @@ -21,7 +23,7 @@ scenarios: options: attackers: - fault_type: "kill-process" - process_name: "glance-api" + process_name: "{{ attack_process }}" host: {{attack_host}} monitors: @@ -32,7 +34,7 @@ scenarios: sla: max_outage_time: 5 - monitor_type: "process" - process_name: "glance-api" + process_name: "{{ attack_process }}" host: {{attack_host}} monitor_time: 30 monitor_number: 3 diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc048.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc048.yaml index a1629c6d0..2bca1fb9d 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc048.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc048.yaml @@ -10,10 +10,12 @@ schema: "yardstick:task:0.1" description: > - Test case for TC048 :Control node Openstack service down - cinder api. + Yardstick TC048 config file; + HA test case: Control node Openstack service down - cinder-api. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set attack_host = attack_host or "node1" %} +{% set attack_process = attack_process or "cinder-api" %} scenarios: - @@ -21,7 +23,7 @@ scenarios: options: attackers: - fault_type: "kill-process" - process_name: "cinder-api" + process_name: "{{ attack_process }}" host: {{attack_host}} monitors: @@ -32,7 +34,7 @@ scenarios: sla: max_outage_time: 5 - monitor_type: "process" - process_name: "cinder-api" + process_name: "{{ attack_process }}" host: {{attack_host}} monitor_time: 30 monitor_number: 3 diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc049.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc049.yaml index 7b8383e4e..a3df57ce8 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc049.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc049.yaml @@ -10,10 +10,12 @@ schema: "yardstick:task:0.1" description: > - Test case for TC049 :Control node Openstack service down - swift proxy. + Yardstick TC049 config file; + HA test case: Control node Openstack service down - swift-proxy. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set attack_host = attack_host or "node1" %} +{% set attack_process = attack_process or "swift-proxy" %} scenarios: - @@ -21,7 +23,7 @@ scenarios: options: attackers: - fault_type: "kill-process" - process_name: "swift-proxy" + process_name: "{{ attack_process }}" host: {{attack_host}} monitors: @@ -32,7 +34,7 @@ scenarios: sla: max_outage_time: 5 - monitor_type: "process" - process_name: "swift-proxy" + process_name: "{{ attack_process }}" host: {{attack_host}} monitor_time: 30 monitor_number: 3 diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc050.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc050.yaml index b765feb68..dde3a1077 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc050.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc050.yaml @@ -10,8 +10,8 @@ schema: "yardstick:task:0.1" description: > - Test case for TC050 :OpenStack Controller Node Network High Availability; - This test case is written by new scenario-based HA testing framework. + Yardstick TC050 config file; + HA test case: OpenStack Controller Node Network High Availability. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set attack_host = attack_host or "node1" %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc051.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc051.yaml index aade1aed2..3d4985f38 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc051.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc051.yaml @@ -10,8 +10,8 @@ schema: "yardstick:task:0.1" description: > - Test case for TC051 :OpenStack Controller Node CPU Overload High Availability; - This test case is written by new scenario-based HA testing framework. + Yardstick TC051 config file; + HA test case: OpenStack Controller Node CPU Overload High Availability. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set attack_host = attack_host or "node1" %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc052.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc052.yaml index 62cabd1a2..8052f5450 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc052.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc052.yaml @@ -10,8 +10,8 @@ schema: "yardstick:task:0.1" description: > - Test case for TC052 :OpenStack Controller Node Disk I/O Block High Availability; - This test case is written by new scenario-based HA testing framework. + Yardstick TC052 config file; + HA test case: OpenStack Controller Node Disk I/O Block High Availability. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set attack_host = attack_host or "node1" %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc053.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc053.yaml index 64c67c0b3..c2a4f9ede 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc053.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc053.yaml @@ -10,11 +10,12 @@ schema: "yardstick:task:0.1" description: > - Test case for TC053 :Openstack Controller Load Balance Service High Availability; - This test case is written by new scenario-based HA testing framework. + Yardstick TC053 config file; + HA test case: Openstack Controller Load Balance Service High Availability. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set attack_host = attack_host or "node1" %} +{% set attack_process = attack_process or "haproxy" %} scenarios: - @@ -25,13 +26,13 @@ scenarios: fault_type: "kill-process" host: {{attack_host}} key: "kill-process" - process_name: "haproxy" + process_name: "{{ attack_process }}" monitors: - monitor_type: "process" key: "service-status" - process_name: "haproxy" + process_name: "{{ attack_process }}" host: {{attack_host}} monitor_time: 30 monitor_number: 3 diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc054.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc054.yaml index 5eb34e56a..a1fa38ef0 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc054.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc054.yaml @@ -10,8 +10,8 @@ schema: "yardstick:task:0.1" description: > - Test case for TC054 :OpenStack VIP Master Node abnormally shutdown High Availability; - This test case is written by new scenario-based HA testing framework. + Yardstick TC054 config file; + HA test case: OpenStack VIP Master Node abnormally shutdown High Availability. {% set jump_host = jump_host or 'node0' %} {% set attack_host = attack_host or 'node1' %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc056.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc056.yaml index 40e8f9c13..9194d9d4e 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc056.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc056.yaml @@ -10,13 +10,14 @@ schema: "yardstick:task:0.1" description: > - Test case for TC056 :OpenStack Controller Messaging Queue Service High - Availability. + Yardstick TC056 config file; + HA test case: OpenStack Controller Messaging Queue Service High Availability. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set attack_host = attack_host or 'node1' %} {% set monitor_time = monitor_time or 10 %} {% set monitor_number = monitor_number or 3 %} +{% set attack_process = attack_process or "rabbitmq-server" %} scenarios: - @@ -24,7 +25,7 @@ scenarios: options: attackers: - fault_type: "kill-process" - process_name: "rabbitmq-server" + process_name: "{{ attack_process }}" host: {{attack_host}} monitors: @@ -57,7 +58,7 @@ scenarios: max_outage_time: 5 - monitor_type: "process" - process_name: "rabbitmq-server" + process_name: "{{ attack_process }}" host: {{attack_host}} monitor_time: 30 sla: diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc057.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc057.yaml index 28aa0b6bd..f6a35e915 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc057.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc057.yaml @@ -10,9 +10,8 @@ schema: "yardstick:task:0.1" description: > - Test case for TC057 :OpenStack Controller Cluster Management Service High - Availability; - This test case is written by scenario-based HA testing framework. + Yardstick TC057 config file; + HA test case: OpenStack Controller Cluster Management Service High Availability. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set vip_mgmt = vip_mgmt or 'vip__management' %} @@ -21,6 +20,7 @@ description: > {% set check_host = check_host or 'node2' %} {% set monitor_time = monitor_time or 10 %} {% set monitor_number = monitor_number or 3 %} +{% set attack_process = attack_process or "corosync" %} scenarios: - @@ -33,7 +33,7 @@ scenarios: key: "kill-process" attack_key: "kill-corosync" action_parameter: - process_name: "corosync" + process_name: "{{ attack_process }}" monitors: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc058.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc058.yaml index 7fb7daf62..06d460032 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc058.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc058.yaml @@ -10,14 +10,14 @@ schema: "yardstick:task:0.1" description: > - Test case for TC058 :OpenStack Controller Virtual Router Service High - Availability; - This test case is written by scenario-based HA testing framework. + Yardstick TC058 config file; + HA test case: OpenStack Controller Virtual Router Service High Availability. {% set file = file or '/etc/yardstick/pod.yaml' %} {% set image = image or 'yardstick-image' %} {% set flavor = flavor or 'yardstick-flavor' %} {% set attack_host = attack_host or 'node1' %} +{% set attack_process = attack_process or "neutron-l3-agent" %} scenarios: - @@ -28,12 +28,12 @@ scenarios: fault_type: "kill-process" host: {{attack_host}} key: "kill-process" - process_name: "neutron-l3-agent" + process_name: "{{ attack_process }}" monitors: - monitor_type: "process" - process_name: "neutron-l3-agent" + process_name: "{{ attack_process }}" host: {{attack_host}} key: "monitor-recovery" monitor_time: 30 diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc081.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc081.yaml index 0d79a41ed..fc7eb006c 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc081.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc081.yaml @@ -46,9 +46,9 @@ contexts: - type: Heat name: openstack - image: cirros-0.3.5 + image: yardstick-image flavor: yardstick-flavor - user: cirros + user: ubuntu servers: target: diff --git a/tests/unit/benchmark/contexts/standalone/test_model.py b/tests/unit/benchmark/contexts/standalone/test_model.py index 6899a0af6..31ec2b7d1 100644 --- a/tests/unit/benchmark/contexts/standalone/test_model.py +++ b/tests/unit/benchmark/contexts/standalone/test_model.py @@ -16,70 +16,137 @@ # Unittest for yardstick.benchmark.contexts.standalone.model - from __future__ import absolute_import +import copy import os import unittest -import errno import mock -from yardstick.common import constants as consts -from yardstick.benchmark.contexts.standalone.model import Libvirt -from yardstick.benchmark.contexts.standalone.model import StandaloneContextHelper -from yardstick.benchmark.contexts.standalone import model -from yardstick.network_services.utils import PciAddress +from xml.etree import ElementTree +from yardstick.benchmark.contexts.standalone import model +from yardstick.network_services import utils +from yardstick.network_services.helpers import cpu + + +XML_SAMPLE = """<?xml version="1.0"?> +<domain type="kvm"> + <devices> + </devices> +</domain> +""" + +XML_SAMPLE_INTERFACE = """<?xml version="1.0"?> +<domain type="kvm"> + <devices> + <interface> + </interface> + </devices> +</domain> +""" class ModelLibvirtTestCase(unittest.TestCase): + def setUp(self): + self.xml = ElementTree.ElementTree( + element=ElementTree.fromstring(XML_SAMPLE)) + self.pci_address_str = '0001:04:03.2' + self.pci_address = utils.PciAddress(self.pci_address_str) + self.mac = '00:00:00:00:00:01' + self._mock_write_xml = mock.patch.object(ElementTree.ElementTree, + 'write') + self.mock_write_xml = self._mock_write_xml.start() + + self.addCleanup(self._cleanup) + + def _cleanup(self): + self._mock_write_xml.stop() + def test_check_if_vm_exists_and_delete(self): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) - ssh_mock.execute = \ - mock.Mock(return_value=(0, "a", "")) + ssh_mock.execute = mock.Mock(return_value=(0, "a", "")) ssh.return_value = ssh_mock - result = Libvirt.check_if_vm_exists_and_delete("vm_0", ssh_mock) - self.assertIsNone(result) + # NOTE(ralonsoh): this test doesn't cover function execution. + model.Libvirt.check_if_vm_exists_and_delete("vm_0", ssh_mock) def test_virsh_create_vm(self): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) - ssh_mock.execute = \ - mock.Mock(return_value=(0, "a", "")) + ssh_mock.execute = mock.Mock(return_value=(0, "a", "")) ssh.return_value = ssh_mock - result = Libvirt.virsh_create_vm(ssh_mock, "vm_0") - self.assertIsNone(result) + # NOTE(ralonsoh): this test doesn't cover function execution. + model.Libvirt.virsh_create_vm(ssh_mock, "vm_0") def test_virsh_destroy_vm(self): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) - ssh_mock.execute = \ - mock.Mock(return_value=(0, "a", "")) + ssh_mock.execute = mock.Mock(return_value=(0, "a", "")) ssh.return_value = ssh_mock - result = Libvirt.virsh_destroy_vm("vm_0", ssh_mock) - self.assertIsNone(result) - - @mock.patch('yardstick.benchmark.contexts.standalone.model.ET') - def test_add_interface_address(self, mock_et): - pci_address = PciAddress.parse_address("0000:00:04.0", multi_line=True) - result = Libvirt.add_interface_address("<interface/>", pci_address) - self.assertIsNotNone(result) - - @mock.patch('yardstick.benchmark.contexts.standalone.model.Libvirt.add_interface_address') - @mock.patch('yardstick.benchmark.contexts.standalone.model.ET') - def test_add_ovs_interfaces(self, mock_et, mock_add_interface_address): - pci_address = PciAddress.parse_address("0000:00:04.0", multi_line=True) - result = Libvirt.add_ovs_interface("/usr/local", 0, "0000:00:04.0", - "00:00:00:00:00:01", "xml") - self.assertIsNone(result) - - @mock.patch('yardstick.benchmark.contexts.standalone.model.Libvirt.add_interface_address') - @mock.patch('yardstick.benchmark.contexts.standalone.model.ET') - def test_add_sriov_interfaces(self, mock_et, mock_add_interface_address): - pci_address = PciAddress.parse_address("0000:00:04.0", multi_line=True) - result = Libvirt.add_sriov_interfaces("0000:00:05.0", "0000:00:04.0", - "00:00:00:00:00:01", "xml") - self.assertIsNone(result) + # NOTE(ralonsoh): this test doesn't cover function execution. + model.Libvirt.virsh_destroy_vm("vm_0", ssh_mock) + + def test_add_interface_address(self): + xml = ElementTree.ElementTree( + element=ElementTree.fromstring(XML_SAMPLE_INTERFACE)) + interface = xml.find('devices').find('interface') + result = model.Libvirt._add_interface_address(interface, self.pci_address) + self.assertEqual('pci', result.get('type')) + self.assertEqual('0x{}'.format(self.pci_address.domain), + result.get('domain')) + self.assertEqual('0x{}'.format(self.pci_address.bus), + result.get('bus')) + self.assertEqual('0x{}'.format(self.pci_address.slot), + result.get('slot')) + self.assertEqual('0x{}'.format(self.pci_address.function), + result.get('function')) + + def test_add_ovs_interfaces(self): + xml_input = mock.Mock() + with mock.patch.object(ElementTree, 'parse', return_value=self.xml) \ + as mock_parse: + xml = copy.deepcopy(self.xml) + mock_parse.return_value = xml + model.Libvirt.add_ovs_interface( + '/usr/local', 0, self.pci_address_str, self.mac, xml_input) + mock_parse.assert_called_once_with(xml_input) + self.mock_write_xml.assert_called_once_with(xml_input) + interface = xml.find('devices').find('interface') + self.assertEqual('vhostuser', interface.get('type')) + mac = interface.find('mac') + self.assertEqual(self.mac, mac.get('address')) + source = interface.find('source') + self.assertEqual('unix', source.get('type')) + self.assertEqual('/usr/local/var/run/openvswitch/dpdkvhostuser0', + source.get('path')) + self.assertEqual('client', source.get('mode')) + _model = interface.find('model') + self.assertEqual('virtio', _model.get('type')) + driver = interface.find('driver') + self.assertEqual('4', driver.get('queues')) + host = driver.find('host') + self.assertEqual('off', host.get('mrg_rxbuf')) + self.assertIsNotNone(interface.find('address')) + + def test_add_sriov_interfaces(self): + xml_input = mock.Mock() + with mock.patch.object(ElementTree, 'parse', return_value=self.xml) \ + as mock_parse: + xml = copy.deepcopy(self.xml) + mock_parse.return_value = xml + vf_pci = '0001:05:04.2' + model.Libvirt.add_sriov_interfaces( + self.pci_address_str, vf_pci, self.mac, xml_input) + mock_parse.assert_called_once_with(xml_input) + self.mock_write_xml.assert_called_once_with(xml_input) + interface = xml.find('devices').find('interface') + self.assertEqual('yes', interface.get('managed')) + self.assertEqual('hostdev', interface.get('type')) + mac = interface.find('mac') + self.assertEqual(self.mac, mac.get('address')) + source = interface.find('source') + self.assertIsNotNone(source.find('address')) + self.assertIsNotNone(interface.find('address')) def test_create_snapshot_qemu(self): result = "/var/lib/libvirt/images/0.qcow2" @@ -88,15 +155,15 @@ class ModelLibvirtTestCase(unittest.TestCase): ssh_mock.execute = \ mock.Mock(return_value=(0, "a", "")) ssh.return_value = ssh_mock - image = Libvirt.create_snapshot_qemu(ssh_mock, "0", "ubuntu.img") + image = model.Libvirt.create_snapshot_qemu(ssh_mock, "0", "ubuntu.img") self.assertEqual(image, result) - @mock.patch("yardstick.benchmark.contexts.standalone.model.Libvirt.pin_vcpu_for_perf") - @mock.patch("yardstick.benchmark.contexts.standalone.model.Libvirt.create_snapshot_qemu") - @mock.patch('yardstick.benchmark.contexts.standalone.model.open') - @mock.patch('yardstick.benchmark.contexts.standalone.model.write_file') - def test_build_vm_xml(self, mock_open, mock_write_file, mock_create_snapshot_qemu, - mock_pin_vcpu_for_perf): + @mock.patch.object(model.Libvirt, 'pin_vcpu_for_perf') + @mock.patch.object(model.Libvirt, 'create_snapshot_qemu') + def test_build_vm_xml(self, mock_create_snapshot_qemu, + *args): + # NOTE(ralonsoh): this test doesn't cover function execution. This test + # should also check mocked function calls. result = [4] with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) @@ -105,7 +172,7 @@ class ModelLibvirtTestCase(unittest.TestCase): ssh.return_value = ssh_mock mock_create_snapshot_qemu.return_value = "0.img" - status = Libvirt.build_vm_xml(ssh_mock, {}, "test", "vm_0", 0) + status = model.Libvirt.build_vm_xml(ssh_mock, {}, "test", "vm_0", 0) self.assertEqual(status[0], result[0]) def test_update_interrupts_hugepages_perf(self): @@ -114,19 +181,21 @@ class ModelLibvirtTestCase(unittest.TestCase): ssh_mock.execute = \ mock.Mock(return_value=(0, "a", "")) ssh.return_value = ssh_mock - status = Libvirt.update_interrupts_hugepages_perf(ssh_mock) - self.assertIsNone(status) + # NOTE(ralonsoh): this test doesn't cover function execution. This test + # should also check mocked function calls. + model.Libvirt.update_interrupts_hugepages_perf(ssh_mock) + + @mock.patch.object(cpu.CpuSysCores, 'get_core_socket') + def test_pin_vcpu_for_perf(self, mock_get_core_socket): + mock_get_core_socket.return_value = { + 'cores_per_socket': 1, + 'thread_per_core': 1, + '0': [1, 2] + } + # NOTE(ralonsoh): this test doesn't cover function execution. This + # function needs more tests. + model.Libvirt.pin_vcpu_for_perf(mock.Mock()) - @mock.patch("yardstick.benchmark.contexts.standalone.model.CpuSysCores") - @mock.patch("yardstick.benchmark.contexts.standalone.model.Libvirt.update_interrupts_hugepages_perf") - def test_pin_vcpu_for_perf(self, mock_update_interrupts_hugepages_perf, mock_CpuSysCores): - with mock.patch("yardstick.ssh.SSH") as ssh: - ssh_mock = mock.Mock(autospec=ssh.SSH) - ssh_mock.execute = \ - mock.Mock(return_value=(0, "a", "")) - ssh.return_value = ssh_mock - status = Libvirt.pin_vcpu_for_perf(ssh_mock, "vm_0", 4) - self.assertIsNotNone(status) class StandaloneContextHelperTestCase(unittest.TestCase): @@ -148,7 +217,7 @@ class StandaloneContextHelperTestCase(unittest.TestCase): } def setUp(self): - self.helper = StandaloneContextHelper() + self.helper = model.StandaloneContextHelper() def test___init__(self): self.assertIsNone(self.helper.file_path) @@ -159,8 +228,9 @@ class StandaloneContextHelperTestCase(unittest.TestCase): ssh_mock.execute = \ mock.Mock(return_value=(1, "a", "")) ssh.return_value = ssh_mock - status = StandaloneContextHelper.install_req_libs(ssh_mock) - self.assertIsNone(status) + # NOTE(ralonsoh): this test doesn't cover function execution. This test + # should also check mocked function calls. + model.StandaloneContextHelper.install_req_libs(ssh_mock) def test_get_kernel_module(self): with mock.patch("yardstick.ssh.SSH") as ssh: @@ -168,10 +238,12 @@ class StandaloneContextHelperTestCase(unittest.TestCase): ssh_mock.execute = \ mock.Mock(return_value=(1, "i40e", "")) ssh.return_value = ssh_mock - status = StandaloneContextHelper.get_kernel_module(ssh_mock, "05:00.0", None) - self.assertEqual(status, "i40e") + # NOTE(ralonsoh): this test doesn't cover function execution. This test + # should also check mocked function calls. + model.StandaloneContextHelper.get_kernel_module( + ssh_mock, "05:00.0", None) - @mock.patch('yardstick.benchmark.contexts.standalone.model.StandaloneContextHelper.get_kernel_module') + @mock.patch.object(model.StandaloneContextHelper, 'get_kernel_module') def test_get_nic_details(self, mock_get_kernel_module): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) @@ -179,8 +251,10 @@ class StandaloneContextHelperTestCase(unittest.TestCase): mock.Mock(return_value=(1, "i40e ixgbe", "")) ssh.return_value = ssh_mock mock_get_kernel_module.return_value = "i40e" - status = StandaloneContextHelper.get_nic_details(ssh_mock, self.NETWORKS, "dpdk-devbind.py") - self.assertIsNotNone(status) + # NOTE(ralonsoh): this test doesn't cover function execution. This test + # should also check mocked function calls. + model.StandaloneContextHelper.get_nic_details( + ssh_mock, self.NETWORKS, 'dpdk-devbind.py') def test_get_virtual_devices(self): pattern = "PCI_SLOT_NAME=0000:05:00.0" @@ -189,8 +263,10 @@ class StandaloneContextHelperTestCase(unittest.TestCase): ssh_mock.execute = \ mock.Mock(return_value=(1, pattern, "")) ssh.return_value = ssh_mock - status = StandaloneContextHelper.get_virtual_devices(ssh_mock, "0000:00:05.0") - self.assertIsNotNone(status) + # NOTE(ralonsoh): this test doesn't cover function execution. This test + # should also check mocked function calls. + model.StandaloneContextHelper.get_virtual_devices( + ssh_mock, '0000:00:05.0') def _get_file_abspath(self, filename): curr_path = os.path.dirname(os.path.abspath(__file__)) @@ -204,40 +280,48 @@ class StandaloneContextHelperTestCase(unittest.TestCase): def test_parse_pod_file(self): self.helper.file_path = self._get_file_abspath("dummy") - self.assertRaises(IOError, self.helper.parse_pod_file, self.helper.file_path) + self.assertRaises(IOError, self.helper.parse_pod_file, + self.helper.file_path) self.helper.file_path = self._get_file_abspath(self.NODE_SAMPLE) - self.assertRaises(TypeError, self.helper.parse_pod_file, self.helper.file_path) + self.assertRaises(TypeError, self.helper.parse_pod_file, + self.helper.file_path) self.helper.file_path = self._get_file_abspath(self.NODE_SRIOV_SAMPLE) self.assertIsNotNone(self.helper.parse_pod_file(self.helper.file_path)) def test_get_mac_address(self): - status = StandaloneContextHelper.get_mac_address() + status = model.StandaloneContextHelper.get_mac_address() self.assertIsNotNone(status) @mock.patch('yardstick.ssh.SSH') - def test_get_mgmt_ip(self, mock_ssh): + def test_get_mgmt_ip(self, *args): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) - ssh_mock.execute = \ - mock.Mock(return_value=(1, "1.2.3.4 00:00:00:00:00:01", "")) + ssh_mock.execute = mock.Mock( + return_value=(1, "1.2.3.4 00:00:00:00:00:01", "")) ssh.return_value = ssh_mock - status = StandaloneContextHelper.get_mgmt_ip(ssh_mock, "00:00:00:00:00:01", "1.1.1.1/24", {}) + # NOTE(ralonsoh): this test doesn't cover function execution. This test + # should also check mocked function calls. + status = model.StandaloneContextHelper.get_mgmt_ip( + ssh_mock, "00:00:00:00:00:01", "1.1.1.1/24", {}) self.assertIsNotNone(status) @mock.patch('yardstick.ssh.SSH') - def test_get_mgmt_ip_no(self, mock_ssh): + def test_get_mgmt_ip_no(self, *args): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) ssh_mock.execute = \ mock.Mock(return_value=(1, "", "")) ssh.return_value = ssh_mock - + # NOTE(ralonsoh): this test doesn't cover function execution. This test + # should also check mocked function calls. model.WAIT_FOR_BOOT = 0 - status = StandaloneContextHelper.get_mgmt_ip(ssh_mock, "99", "1.1.1.1/24", {}) + status = model.StandaloneContextHelper.get_mgmt_ip( + ssh_mock, "99", "1.1.1.1/24", {}) self.assertIsNone(status) + class ServerTestCase(unittest.TestCase): NETWORKS = { @@ -257,6 +341,7 @@ class ServerTestCase(unittest.TestCase): 'cidr': '152.16.40.10/24', 'gateway_ip': '152.16.100.20'} } + def setUp(self): self.server = model.Server() @@ -282,7 +367,8 @@ class ServerTestCase(unittest.TestCase): 'xe1': ['public_0'], } } - status = self.server.generate_vnf_instance({}, self.NETWORKS, "1.1.1.1/24", 'vm_0', vnf, '00:00:00:00:00:01') + status = self.server.generate_vnf_instance( + {}, self.NETWORKS, '1.1.1.1/24', 'vm_0', vnf, '00:00:00:00:00:01') self.assertIsNotNone(status) class OvsDeployTestCase(unittest.TestCase): @@ -312,14 +398,17 @@ class OvsDeployTestCase(unittest.TestCase): self.assertIsNotNone(self.ovs_deploy.connection) @mock.patch('yardstick.benchmark.contexts.standalone.model.os') - def test_prerequisite(self, mock_ssh): + def test_prerequisite(self, *args): + # NOTE(ralonsoh): this test should check mocked function calls. self.ovs_deploy.helper = mock.Mock() self.assertIsNone(self.ovs_deploy.prerequisite()) @mock.patch('yardstick.benchmark.contexts.standalone.model.os') - def test_prerequisite(self, mock_ssh): + def test_prerequisite_2(self, *args): + # NOTE(ralonsoh): this test should check mocked function calls. Rename + # this test properly. self.ovs_deploy.helper = mock.Mock() - self.ovs_deploy.connection.execute = \ - mock.Mock(return_value=(1, "1.2.3.4 00:00:00:00:00:01", "")) + self.ovs_deploy.connection.execute = mock.Mock( + return_value=(1, '1.2.3.4 00:00:00:00:00:01', '')) self.ovs_deploy.prerequisite = mock.Mock() self.assertIsNone(self.ovs_deploy.ovs_deploy()) diff --git a/tests/unit/benchmark/contexts/standalone/test_sriov.py b/tests/unit/benchmark/contexts/standalone/test_sriov.py index 50ae5fe13..3ea673abc 100644 --- a/tests/unit/benchmark/contexts/standalone/test_sriov.py +++ b/tests/unit/benchmark/contexts/standalone/test_sriov.py @@ -17,12 +17,10 @@ from __future__ import absolute_import import os import unittest -import errno import mock -from yardstick.common import constants as consts +from yardstick import ssh from yardstick.benchmark.contexts.standalone import sriov -from yardstick.network_services.utils import PciAddress class SriovContextTestCase(unittest.TestCase): @@ -66,6 +64,9 @@ class SriovContextTestCase(unittest.TestCase): @mock.patch('yardstick.benchmark.contexts.standalone.sriov.Libvirt') @mock.patch('yardstick.benchmark.contexts.standalone.model.Server') def test___init__(self, mock_helper, mock_libvirt, mock_server): + # pylint: disable=unused-argument + # NOTE(ralonsoh): this test doesn't cover function execution. + # The pylint exception should be removed. self.sriov.helper = mock_helper self.sriov.vnf_node = mock_server self.assertIsNone(self.sriov.file_path) @@ -75,14 +76,11 @@ class SriovContextTestCase(unittest.TestCase): self.sriov.helper.parse_pod_file = mock.Mock(return_value=[{}, {}, {}]) self.assertIsNone(self.sriov.init(self.ATTRS)) - @mock.patch('yardstick.ssh.SSH') + @mock.patch.object(ssh, 'SSH', return_value=(0, "a", "")) def test_deploy(self, mock_ssh): - with mock.patch("yardstick.ssh.SSH") as ssh: - ssh_mock = mock.Mock(autospec=ssh.SSH) - ssh_mock.execute = \ - mock.Mock(return_value=(0, "a", "")) - ssh.return_value = ssh_mock - + # pylint: disable=unused-argument + # NOTE(ralonsoh): this test doesn't cover function execution. + # The pylint exception should be removed. self.sriov.vm_deploy = False self.assertIsNone(self.sriov.deploy()) @@ -94,20 +92,16 @@ class SriovContextTestCase(unittest.TestCase): self.sriov.wait_for_vnfs_to_start = mock.Mock(return_value={}) self.assertIsNone(self.sriov.deploy()) - @mock.patch('yardstick.ssh.SSH') + @mock.patch.object(ssh, 'SSH', return_value=(0, "a", "")) @mock.patch('yardstick.benchmark.contexts.standalone.sriov.Libvirt') def test_undeploy(self, mock_libvirt, mock_ssh): - with mock.patch("yardstick.ssh.SSH") as ssh: - ssh_mock = mock.Mock(autospec=ssh.SSH) - ssh_mock.execute = \ - mock.Mock(return_value=(0, "a", "")) - ssh.return_value = ssh_mock - + # pylint: disable=unused-argument + # NOTE(ralonsoh): the pylint exception should be removed. self.sriov.vm_deploy = False self.assertIsNone(self.sriov.undeploy()) self.sriov.vm_deploy = True - self.sriov.connection = ssh_mock + self.sriov.connection = mock_ssh self.sriov.vm_names = ['vm_0', 'vm_1'] self.sriov.drivers = ['vm_0', 'vm_1'] self.assertIsNone(self.sriov.undeploy()) @@ -246,27 +240,27 @@ class SriovContextTestCase(unittest.TestCase): self.sriov.drivers = [] self.sriov.networks = self.NETWORKS self.sriov.helper.get_mac_address = mock.Mock(return_value="") - self.sriov.get_vf_data = mock.Mock(return_value="") + self.sriov._get_vf_data = mock.Mock(return_value="") self.assertIsNone(self.sriov.configure_nics_for_sriov()) + @mock.patch.object(ssh, 'SSH', return_value=(0, "a", "")) @mock.patch('yardstick.benchmark.contexts.standalone.sriov.Libvirt') - def test__enable_interfaces(self, mock_libvirt): - with mock.patch("yardstick.ssh.SSH") as ssh: - ssh_mock = mock.Mock(autospec=ssh.SSH) - ssh_mock.execute = \ - mock.Mock(return_value=(0, "a", "")) - ssh.return_value = ssh_mock + def test__enable_interfaces(self, mock_libvirt, mock_ssh): + # pylint: disable=unused-argument + # NOTE(ralonsoh): the pylint exception should be removed. self.sriov.vm_deploy = True - self.sriov.connection = ssh_mock + self.sriov.connection = mock_ssh self.sriov.vm_names = ['vm_0', 'vm_1'] self.sriov.drivers = [] self.sriov.networks = self.NETWORKS - self.sriov.get_vf_data = mock.Mock(return_value="") + self.sriov._get_vf_data = mock.Mock(return_value="") self.assertIsNone(self.sriov._enable_interfaces(0, 0, ["private_0"], 'test')) @mock.patch('yardstick.benchmark.contexts.standalone.model.Server') @mock.patch('yardstick.benchmark.contexts.standalone.sriov.Libvirt') def test_setup_sriov_context(self, mock_libvirt, mock_server): + # pylint: disable=unused-argument + # NOTE(ralonsoh): the pylint exception should be removed. with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) ssh_mock.execute = \ @@ -296,7 +290,7 @@ class SriovContextTestCase(unittest.TestCase): self.sriov.vnf_node.generate_vnf_instance = mock.Mock(return_value={}) self.assertIsNotNone(self.sriov.setup_sriov_context()) - def test_get_vf_data(self): + def test__get_vf_data(self): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) ssh_mock.execute = \ @@ -318,5 +312,7 @@ class SriovContextTestCase(unittest.TestCase): } } self.sriov.networks = self.NETWORKS - self.sriov.helper.get_virtual_devices = mock.Mock(return_value={"0000:00:01.0": ""}) - self.assertIsNotNone(self.sriov.get_vf_data("", "0000:00:01.0", "00:00:00:00:00:01", "if0")) + self.sriov.helper.get_virtual_devices = mock.Mock( + return_value={'0000:00:01.0': ''}) + self.assertIsNotNone(self.sriov._get_vf_data( + '0000:00:01.0', '00:00:00:00:00:01', 'if0')) diff --git a/tests/unit/benchmark/contexts/test_heat.py b/tests/unit/benchmark/contexts/test_heat.py index 223d64060..f2e725df2 100644 --- a/tests/unit/benchmark/contexts/test_heat.py +++ b/tests/unit/benchmark/contexts/test_heat.py @@ -119,8 +119,12 @@ class HeatContextTestCase(unittest.TestCase): "2f2e4997-0a8e-4eb7-9fa4-f3f8fbbc393b") mock_template.add_security_group.assert_called_with("foo-secgroup") # mock_template.add_network.assert_called_with("bar-fool-network", 'physnet1', None) - mock_template.add_router.assert_called_with("bar-fool-network-router", netattrs["external_network"], "bar-fool-network-subnet") - mock_template.add_router_interface.assert_called_with("bar-fool-network-router-if0", "bar-fool-network-router", "bar-fool-network-subnet") + mock_template.add_router.assert_called_with("bar-fool-network-router", + netattrs["external_network"], + "bar-fool-network-subnet") + mock_template.add_router_interface.assert_called_with("bar-fool-network-router-if0", + "bar-fool-network-router", + "bar-fool-network-subnet") @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate') def test_attrs_get(self, mock_template): diff --git a/tests/unit/benchmark/contexts/test_model.py b/tests/unit/benchmark/contexts/test_model.py index 48ee01cf0..53b035b82 100644 --- a/tests/unit/benchmark/contexts/test_model.py +++ b/tests/unit/benchmark/contexts/test_model.py @@ -282,6 +282,178 @@ class ServerTestCase(unittest.TestCase): scheduler_hints='hints', availability_zone='zone') + def test_override_ip(self): + network_ports = { + 'mgmt': ['mgmt'], + 'uplink_0': [ + {'xe0': {'local_ip': '10.44.0.20', 'netmask': '255.255.255.0'}}, + ], + 'downlink_0': [ + {'xe1': {'local_ip': '10.44.0.30', 'netmask': '255.255.255.0'}}, + ], + } + attrs = { + 'image': 'some-image', 'flavor': 'some-flavor', + } + test_server = model.Server('foo', self.mock_context, attrs) + test_server.interfaces = { + "xe0": { + "local_ip": "1.2.3.4", + "netmask": "255.255.255.0", + }, + "xe1": { + "local_ip": "1.2.3.5", + "netmask": "255.255.255.0" + } + } + test_server.network_ports = network_ports + + test_server.override_ip("uplink_0", {"port": "xe0"}) + self.assertEqual(test_server.interfaces["xe0"], network_ports["uplink_0"][0]["xe0"]) + + def test_override_ip_multiple(self): + network_ports = { + 'mgmt': ['mgmt'], + 'uplink_0': [ + {'xe0': {'local_ip': '10.44.0.20', 'netmask': '255.255.255.0'}}, + {'xe0': {'local_ip': '10.44.0.21', 'netmask': '255.255.255.0'}}, + ], + 'downlink_0': [ + {'xe1': {'local_ip': '10.44.0.30', 'netmask': '255.255.255.0'}}, + ], + } + attrs = { + 'image': 'some-image', 'flavor': 'some-flavor', + } + test_server = model.Server('foo', self.mock_context, attrs) + test_server.interfaces = { + "xe0": { + "local_ip": "1.2.3.4", + "netmask": "255.255.255.0", + }, + "xe1": { + "local_ip": "1.2.3.5", + "netmask": "255.255.255.0" + } + } + test_server.network_ports = network_ports + test_server.override_ip("uplink_0", {"port": "xe0"}) + self.assertEqual(test_server.interfaces["xe0"], network_ports["uplink_0"][0]["xe0"]) + + def test_override_ip_mixed(self): + network_ports = { + 'mgmt': ['mgmt'], + 'uplink_0': [ + 'xe0', + {'xe0': {'local_ip': '10.44.0.21', 'netmask': '255.255.255.0'}}, + ], + 'downlink_0': [ + {'xe1': {'local_ip': '10.44.0.30', 'netmask': '255.255.255.0'}}, + ], + } + attrs = { + 'image': 'some-image', 'flavor': 'some-flavor', + } + test_server = model.Server('foo', self.mock_context, attrs) + test_server.interfaces = { + "xe0": { + "local_ip": "1.2.3.4", + "netmask": "255.255.255.0", + }, + "xe1": { + "local_ip": "1.2.3.5", + "netmask": "255.255.255.0" + } + } + test_server.network_ports = network_ports + test_server.override_ip("uplink_0", {"port": "xe0"}) + self.assertEqual(test_server.interfaces["xe0"], network_ports["uplink_0"][1]["xe0"]) + + @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate') + def test__add_instance_with_ip_override_invalid_syntax(self, mock_template): + network_ports = { + 'mgmt': ['mgmt'], + 'uplink_0': 'xe0', + 'downlink_0': [ + {'xe1': {'local_ip': '10.44.0.30', 'netmask': '255.255.255.0'}}, + ], + } + attrs = { + 'image': 'some-image', 'flavor': 'some-flavor', + } + test_server = model.Server('foo', self.mock_context, attrs) + test_server.network_ports = network_ports + context = type("Context", (object,), {}) + # can't use Mock because Mock.name is reserved + context.name = "context" + networks = [model.Network(n, context, {}) for n in network_ports] + + with self.assertRaises(SyntaxError): + test_server._add_instance(mock_template, 'some-server', + networks, 'hints') + + @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate') + def test__add_instance_with_ip_override(self, mock_template): + network_ports = { + 'mgmt': ['mgmt'], + 'uplink_0': [ + {'xe0': {'local_ip': '10.44.0.20', 'netmask': '255.255.255.0'}}, + ], + 'downlink_0': [ + {'xe1': {'local_ip': '10.44.0.30', 'netmask': '255.255.255.0'}}, + ], + } + attrs = { + 'image': 'some-image', 'flavor': 'some-flavor', + } + test_server = model.Server('foo', self.mock_context, attrs) + test_server.network_ports = network_ports + context = type("Context", (object,), {}) + # can't use Mock because Mock.name is reserved + context.name = "context" + networks = [model.Network(n, context, {}) for n in network_ports] + + test_server._add_instance(mock_template, 'some-server', + networks, 'hints') + self.assertEqual(test_server.ports, { + 'downlink_0': [{'port': 'xe1', 'stack_name': 'some-server-xe1-port'}], + 'mgmt': [{'port': 'mgmt', 'stack_name': 'some-server-mgmt-port'}], + 'uplink_0': [{'port': 'xe0', 'stack_name': 'some-server-xe0-port'}] + }) + + @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate') + def test__add_instance_with_multiple_ip_override(self, mock_template): + network_ports = { + 'mgmt': ['mgmt'], + 'uplink_0': [ + {'xe0': {'local_ip': '10.44.0.20', 'netmask': '255.255.255.0'}}, + {'xe0': {'local_ip': '10.44.0.21', 'netmask': '255.255.255.0'}}, + ], + 'downlink_0': [ + {'xe1': {'local_ip': '10.44.0.30', 'netmask': '255.255.255.0'}}, + ], + } + attrs = { + 'image': 'some-image', 'flavor': 'some-flavor', + } + test_server = model.Server('foo', self.mock_context, attrs) + test_server.network_ports = network_ports + context = type("Context", (object,), {}) + # can't use Mock because Mock.name is reserved + context.name = "context" + networks = [model.Network(n, context, {}) for n in network_ports] + + test_server._add_instance(mock_template, 'some-server', + networks, 'hints') + self.assertEqual(test_server.ports, { + 'downlink_0': [{'port': 'xe1', 'stack_name': 'some-server-xe1-port'}], + 'mgmt': [{'port': 'mgmt', 'stack_name': 'some-server-mgmt-port'}], + 'uplink_0': [{'port': 'xe0', 'stack_name': 'some-server-xe0-port'}, + # this is not an error, we can produce this, it is left to Heat + # to detect duplicate ports and error + {'port': 'xe0', 'stack_name': 'some-server-xe0-port'}] + }) + @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate') def test__add_instance_with_user_data(self, mock_template): user_data = "USER_DATA" diff --git a/tests/unit/benchmark/scenarios/compute/test_qemumigrate.py b/tests/unit/benchmark/scenarios/compute/test_qemumigrate.py index f163f1914..1f0ff3c29 100644 --- a/tests/unit/benchmark/scenarios/compute/test_qemumigrate.py +++ b/tests/unit/benchmark/scenarios/compute/test_qemumigrate.py @@ -16,6 +16,7 @@ from __future__ import absolute_import import unittest import mock +from oslo_serialization import jsonutils from yardstick.benchmark.scenarios.compute import qemu_migrate @@ -83,7 +84,7 @@ class QemuMigrateTestCase(unittest.TestCase): mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') q.run(result) - expected_result = {} + expected_result = jsonutils.loads(sample_output) self.assertEqual(result, expected_result) def test_qemu_migrate_successful_sla(self, mock_ssh): @@ -103,7 +104,7 @@ class QemuMigrateTestCase(unittest.TestCase): mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') q.run(result) - expected_result = {} + expected_result = jsonutils.loads(sample_output) self.assertEqual(result, expected_result) def test_qemu_migrate_unsuccessful_sla_totaltime(self, mock_ssh): @@ -117,8 +118,7 @@ class QemuMigrateTestCase(unittest.TestCase): sample_output = '{"totaltime": 15, "downtime": 2, "setuptime": 1}' mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') - with self.assertRaises(AssertionError): - q.run(result) + self.assertRaises(AssertionError, q.run, result) def test_qemu_migrate_unsuccessful_sla_downtime(self, mock_ssh): @@ -131,8 +131,7 @@ class QemuMigrateTestCase(unittest.TestCase): sample_output = '{"totaltime": 15, "downtime": 2, "setuptime": 1}' mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') - with self.assertRaises(AssertionError): - q.run(result) + self.assertRaises(AssertionError, q.run, result) def test_qemu_migrate_unsuccessful_sla_setuptime(self, mock_ssh): @@ -145,8 +144,7 @@ class QemuMigrateTestCase(unittest.TestCase): sample_output = '{"totaltime": 15, "downtime": 2, "setuptime": 1}' mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '') - with self.assertRaises(AssertionError): - q.run(result) + self.assertRaises(AssertionError, q.run, result) def test_qemu_migrate_unsuccessful_script_error(self, mock_ssh): @@ -156,9 +154,10 @@ class QemuMigrateTestCase(unittest.TestCase): mock_ssh.SSH.from_node().execute.return_value = (0, '', '') q.setup() + mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') - with self.assertRaises(RuntimeError): - q.run(result) + self.assertRaises(RuntimeError, q.run, result) + def main(): unittest.main() diff --git a/tests/unit/benchmark/scenarios/test_base.py b/tests/unit/benchmark/scenarios/test_base.py new file mode 100644 index 000000000..78e342978 --- /dev/null +++ b/tests/unit/benchmark/scenarios/test_base.py @@ -0,0 +1,53 @@ +# Copyright 2017: Intel Ltd. +# All Rights Reserved. +# +# 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. + +import unittest + +from yardstick.benchmark.scenarios import base + + +class ScenarioTestCase(unittest.TestCase): + + def test_get_scenario_type(self): + scenario_type = 'dummy scenario' + + class DummyScenario(base.Scenario): + __scenario_type__ = scenario_type + + self.assertEqual(scenario_type, DummyScenario.get_scenario_type()) + + def test_get_scenario_type_not_defined(self): + class DummyScenario(base.Scenario): + pass + + self.assertEqual(str(None), DummyScenario.get_scenario_type()) + + def test_get_description(self): + docstring = """First line + Second line + Third line + """ + + class DummyScenario(base.Scenario): + __doc__ = docstring + + self.assertEqual(docstring.splitlines()[0], + DummyScenario.get_description()) + + def test_get_description_empty(self): + class DummyScenario(base.Scenario): + pass + + self.assertEqual(str(None), DummyScenario.get_description()) diff --git a/tests/unit/common/test_ansible_common.py b/tests/unit/common/test_ansible_common.py index a1eaf969e..1ef8eee5f 100644 --- a/tests/unit/common/test_ansible_common.py +++ b/tests/unit/common/test_ansible_common.py @@ -23,6 +23,7 @@ import mock import unittest from six.moves.configparser import ConfigParser +from six.moves import StringIO from yardstick.common import ansible_common @@ -30,19 +31,18 @@ PREFIX = 'yardstick.common.ansible_common' class OverwriteDictTestCase(unittest.TestCase): - def test_overwrite_dict_cfg(self): c = ConfigParser(allow_no_value=True) d = { "section_a": "empty_value", - "section_b": {"key_c": "val_d", "key_d": "val_d"}, + "section_b": {"key_c": "Val_d", "key_d": "VAL_D"}, "section_c": ["key_c", "key_d"], } ansible_common.overwrite_dict_to_cfg(c, d) # Python3 and Python2 convert empty values into None or '' # we don't really care but we need to compare correctly for unittest self.assertTrue(c.has_option("section_a", "empty_value")) - self.assertEqual(sorted(c.items("section_b")), [('key_c', 'val_d'), ('key_d', 'val_d')]) + self.assertEqual(sorted(c.items("section_b")), [('key_c', 'Val_d'), ('key_d', 'VAL_D')]) self.assertTrue(c.has_option("section_c", "key_c")) self.assertTrue(c.has_option("section_c", "key_d")) @@ -50,23 +50,23 @@ class OverwriteDictTestCase(unittest.TestCase): class FilenameGeneratorTestCase(unittest.TestCase): @mock.patch('{}.NamedTemporaryFile'.format(PREFIX)) def test__handle_existing_file(self, mock_tmp): - f = ansible_common.FileNameGenerator._handle_existing_file("/dev/null") + ansible_common.FileNameGenerator._handle_existing_file("/dev/null") def test_get_generator_from_file(self): - f = ansible_common.FileNameGenerator.get_generator_from_filename("/dev/null", "", "", "") + ansible_common.FileNameGenerator.get_generator_from_filename("/dev/null", "", "", "") def test_get_generator_from_file_middle(self): - f = ansible_common.FileNameGenerator.get_generator_from_filename("/dev/null", "", "", - "null") + ansible_common.FileNameGenerator.get_generator_from_filename("/dev/null", "", "", + "null") def test_get_generator_from_file_prefix(self): - f = ansible_common.FileNameGenerator.get_generator_from_filename("/dev/null", "", "null", - "middle") + ansible_common.FileNameGenerator.get_generator_from_filename("/dev/null", "", "null", + "middle") class AnsibleNodeTestCase(unittest.TestCase): def test_ansible_node(self): - a = ansible_common.AnsibleNode() + ansible_common.AnsibleNode() def test_ansible_node_len(self): a = ansible_common.AnsibleNode() @@ -104,42 +104,51 @@ class AnsibleNodeTestCase(unittest.TestCase): class AnsibleNodeDictTestCase(unittest.TestCase): def test_ansible_node_dict(self): - n = ansible_common.AnsibleNode() - a = ansible_common.AnsibleNodeDict(n, {}) + n = ansible_common.AnsibleNode + ansible_common.AnsibleNodeDict(n, {}) def test_ansible_node_dict_len(self): - n = ansible_common.AnsibleNode() + n = ansible_common.AnsibleNode a = ansible_common.AnsibleNodeDict(n, {}) len(a) def test_ansible_node_dict_repr(self): - n = ansible_common.AnsibleNode() + n = ansible_common.AnsibleNode a = ansible_common.AnsibleNodeDict(n, {}) repr(a) def test_ansible_node_dict_iter(self): - n = ansible_common.AnsibleNode() + n = ansible_common.AnsibleNode a = ansible_common.AnsibleNodeDict(n, {}) for _ in a: pass def test_ansible_node_dict_get(self): - n = ansible_common.AnsibleNode() + n = ansible_common.AnsibleNode a = ansible_common.AnsibleNodeDict(n, {}) self.assertIsNone(a.get("")) def test_gen_inventory_lines_for_all_of_type(self): - n = ansible_common.AnsibleNode() + n = ansible_common.AnsibleNode a = ansible_common.AnsibleNodeDict(n, {}) self.assertEqual(a.gen_inventory_lines_for_all_of_type(""), []) + def test_gen_inventory_lines(self): + n = ansible_common.AnsibleNode + a = ansible_common.AnsibleNodeDict(n, [{ + "name": "name", "user": "user", "password": "PASS", + "role": "role", + }]) + self.assertEqual(a.gen_all_inventory_lines(), + ["name ansible_ssh_pass=PASS ansible_user=user"]) + class AnsibleCommonTestCase(unittest.TestCase): def test_get_timeouts(self): self.assertAlmostEquals(ansible_common.AnsibleCommon.get_timeout(-100), 1200.0) def test__init__(self): - a = ansible_common.AnsibleCommon({}) + ansible_common.AnsibleCommon({}) def test_reset(self): a = ansible_common.AnsibleCommon({}) @@ -150,9 +159,16 @@ class AnsibleCommonTestCase(unittest.TestCase): self.assertRaises(OSError, a.do_install, '', '') def test_gen_inventory_dict(self): - a = ansible_common.AnsibleCommon({}) - a.inventory_dict = {} - self.assertIsNone(a.gen_inventory_ini_dict()) + nodes = [{ + "name": "name", "user": "user", "password": "PASS", + "role": "role", + }] + a = ansible_common.AnsibleCommon(nodes) + a.gen_inventory_ini_dict() + self.assertEqual(a.inventory_dict, { + 'nodes': ['name ansible_ssh_pass=PASS ansible_user=user'], + 'role': ['name'] + }) def test_deploy_dir(self): a = ansible_common.AnsibleCommon({}) @@ -178,6 +194,25 @@ class AnsibleCommonTestCase(unittest.TestCase): @mock.patch('{}.NamedTemporaryFile'.format(PREFIX)) @mock.patch('{}.open'.format(PREFIX)) + def test__gen_ansible_inventory_file(self, mock_open, mock_tmp): + nodes = [{ + "name": "name", "user": "user", "password": "PASS", + "role": "role", + }] + d = tempfile.mkdtemp() + try: + a = ansible_common.AnsibleCommon(nodes) + a.gen_inventory_ini_dict() + inv_context = a._gen_ansible_inventory_file(d) + with inv_context: + c = StringIO() + inv_context.write_func(c) + self.assertIn("ansible_ssh_pass=PASS", c.getvalue()) + finally: + os.rmdir(d) + + @mock.patch('{}.NamedTemporaryFile'.format(PREFIX)) + @mock.patch('{}.open'.format(PREFIX)) def test__gen_ansible_playbook_file_list_multiple(self, mock_open, mock_tmp): d = tempfile.mkdtemp() try: diff --git a/tests/unit/network_services/test_utils.py b/tests/unit/network_services/test_utils.py index 993adbeae..bf98a4474 100644 --- a/tests/unit/network_services/test_utils.py +++ b/tests/unit/network_services/test_utils.py @@ -15,8 +15,6 @@ # Unittest for yardstick.network_services.utils -from __future__ import absolute_import - import os import unittest import mock @@ -62,3 +60,84 @@ class UtilsTestCase(unittest.TestCase): ssh.return_value = ssh_mock tool_path = utils.provision_tool(ssh_mock, self.DPDK_PATH) self.assertEqual(tool_path, self.DPDK_PATH) + + +class PciAddressTestCase(unittest.TestCase): + + PCI_ADDRESS_DBSF = '000A:07:03.2' + PCI_ADDRESS_BSF = '06:02.1' + PCI_ADDRESS_DBSF_MULTILINE_1 = '0001:08:04.3\nother text\n' + PCI_ADDRESS_DBSF_MULTILINE_2 = 'first line\n 0001:08:04.3 \nother text\n' + # Will match and return the first address found. + PCI_ADDRESS_DBSF_MULTILINE_3 = ' 0001:08:04.1 \n 05:03.1 \nother\n' + PCI_ADDRESS_BSF_MULTILINE_1 = 'first line\n 08:04.3 \n 0002:05:03.1\n' + BAD_INPUT_1 = 'no address found' + BAD_INPUT_2 = '001:08:04.1' + BAD_INPUT_3 = '08:4.1' + + def test_pciaddress_dbsf(self): + pci_address = utils.PciAddress(PciAddressTestCase.PCI_ADDRESS_DBSF) + self.assertEqual('000a', pci_address.domain) + self.assertEqual('07', pci_address.bus) + self.assertEqual('03', pci_address.slot) + self.assertEqual('2', pci_address.function) + + def test_pciaddress_bsf(self): + pci_address = utils.PciAddress(PciAddressTestCase.PCI_ADDRESS_BSF) + self.assertEqual('0000', pci_address.domain) + self.assertEqual('06', pci_address.bus) + self.assertEqual('02', pci_address.slot) + self.assertEqual('1', pci_address.function) + + def test_pciaddress_dbsf_multiline_1(self): + pci_address = utils.PciAddress( + PciAddressTestCase.PCI_ADDRESS_DBSF_MULTILINE_1) + self.assertEqual('0001', pci_address.domain) + self.assertEqual('08', pci_address.bus) + self.assertEqual('04', pci_address.slot) + self.assertEqual('3', pci_address.function) + + def test_pciaddress_dbsf_multiline_2(self): + pci_address = utils.PciAddress( + PciAddressTestCase.PCI_ADDRESS_DBSF_MULTILINE_2) + self.assertEqual('0001', pci_address.domain) + self.assertEqual('08', pci_address.bus) + self.assertEqual('04', pci_address.slot) + self.assertEqual('3', pci_address.function) + + def test_pciaddress_dbsf_multiline_3(self): + pci_address = utils.PciAddress( + PciAddressTestCase.PCI_ADDRESS_DBSF_MULTILINE_3) + self.assertEqual('0001', pci_address.domain) + self.assertEqual('08', pci_address.bus) + self.assertEqual('04', pci_address.slot) + self.assertEqual('1', pci_address.function) + + def test_pciaddress_bsf_multiline_1(self): + pci_address = utils.PciAddress( + PciAddressTestCase.PCI_ADDRESS_BSF_MULTILINE_1) + self.assertEqual('0000', pci_address.domain) + self.assertEqual('08', pci_address.bus) + self.assertEqual('04', pci_address.slot) + self.assertEqual('3', pci_address.function) + + def test_pciaddress_bad_input_no_address(self): + with self.assertRaises(ValueError) as exception: + utils.PciAddress(PciAddressTestCase.BAD_INPUT_1) + self.assertEqual('Invalid PCI address: {}'.format( + PciAddressTestCase.BAD_INPUT_1), str(exception.exception)) + + def test_pciaddress_bad_input_dbsf_bad_formatted(self): + # In this test case, the domain has only 3 characters instead of 4. + pci_address = utils.PciAddress( + PciAddressTestCase.BAD_INPUT_2) + self.assertEqual('0000', pci_address.domain) + self.assertEqual('08', pci_address.bus) + self.assertEqual('04', pci_address.slot) + self.assertEqual('1', pci_address.function) + + def test_pciaddress_bad_input_bsf_bad_formatted(self): + with self.assertRaises(ValueError) as exception: + utils.PciAddress(PciAddressTestCase.BAD_INPUT_3) + self.assertEqual('Invalid PCI address: {}'.format( + PciAddressTestCase.BAD_INPUT_3), str(exception.exception)) diff --git a/tests/unit/network_services/traffic_profile/test_prox_mpls.py b/tests/unit/network_services/traffic_profile/test_prox_mpls.py deleted file mode 100644 index 00a690d2a..000000000 --- a/tests/unit/network_services/traffic_profile/test_prox_mpls.py +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright (c) 2017 Intel Corporation -# -# 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. -# - -from __future__ import absolute_import - -import unittest -import mock - -from tests.unit import STL_MOCKS - -STLClient = mock.MagicMock() -stl_patch = mock.patch.dict("sys.modules", STL_MOCKS) -stl_patch.start() - -if stl_patch: - from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxTestDataTuple - from yardstick.network_services.traffic_profile.prox_mpls_tag_untag import ProxMplsTagUntagProfile - - -class TestProxMplsTagUntagProfile(unittest.TestCase): - - def test_mpls_1(self): - def target(*args, **kwargs): - runs.append(args[2]) - if args[2] < 0 or args[2] > 100: - raise RuntimeError(' '.join([str(args), str(runs)])) - if args[2] > 75.0: - return fail_tuple, {} - return success_tuple, {} - - tp_config = { - 'traffic_profile': { - 'packet_sizes': [200], - }, - } - - runs = [] - success_tuple = ProxTestDataTuple(10.0, 1, 2, 3, 4, [5.1, 5.2, 5.3], 995, 1000, 123.4) - fail_tuple = ProxTestDataTuple(10.0, 1, 2, 3, 4, [5.6, 5.7, 5.8], 850, 1000, 123.4) - - traffic_generator = mock.MagicMock() - - profile = ProxMplsTagUntagProfile(tp_config) - profile.init(mock.MagicMock()) - profile._profile_helper = profile_helper = mock.MagicMock() - profile_helper.run_test = target - - profile.execute_traffic(traffic_generator) - self.assertEqual(round(profile.current_lower, 2), 74.69) - self.assertEqual(round(profile.current_upper, 2), 75.39) - self.assertEqual(len(runs), 8) - - def test_mpls_2(self): - def target(*args, **kwargs): - runs.append(args[2]) - if args[2] < 0 or args[2] > 100: - raise RuntimeError(' '.join([str(args), str(runs)])) - if args[2] > 25.0: - return fail_tuple, {} - return success_tuple, {} - - tp_config = { - 'traffic_profile': { - 'packet_sizes': [200], - 'test_precision': 2.0, - }, - } - - runs = [] - success_tuple = ProxTestDataTuple(10.0, 1, 2, 3, 4, [5.1, 5.2, 5.3], 995, 1000, 123.4) - fail_tuple = ProxTestDataTuple(10.0, 1, 2, 3, 4, [5.6, 5.7, 5.8], 850, 1000, 123.4) - - traffic_generator = mock.MagicMock() - - profile = ProxMplsTagUntagProfile(tp_config) - profile.init(mock.MagicMock()) - profile._profile_helper = profile_helper = mock.MagicMock() - profile_helper.run_test = target - - profile.execute_traffic(traffic_generator) - self.assertEqual(round(profile.current_lower, 2), 24.06) - self.assertEqual(round(profile.current_upper, 2), 25.47) - self.assertEqual(len(runs), 7) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_base.py b/tests/unit/network_services/vnf_generic/vnf/test_base.py index 478ce186b..f812d67ef 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_base.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_base.py @@ -243,31 +243,13 @@ class TestGenericVNF(unittest.TestCase): class TestGenericTrafficGen(unittest.TestCase): - def test___init__(self): - vnfd = TestGenericVNF.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - generic_traffic_gen = GenericTrafficGen('vnf1', vnfd) - assert generic_traffic_gen.name == "vnf1" - - def test_listen_traffic(self): - vnfd = TestGenericVNF.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - generic_traffic_gen = GenericTrafficGen('vnf1', vnfd) - traffic_profile = {} - self.assertIsNone(generic_traffic_gen.listen_traffic(traffic_profile)) - - def test_run_traffic(self): - vnfd = TestGenericVNF.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - generic_traffic_gen = GenericTrafficGen('vnf1', vnfd) - traffic_profile = {} - self.assertRaises(NotImplementedError, - generic_traffic_gen.run_traffic, traffic_profile) - - def test_terminate(self): - vnfd = TestGenericVNF.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - generic_traffic_gen = GenericTrafficGen('vnf1', vnfd) - self.assertRaises(NotImplementedError, generic_traffic_gen.terminate) - def test_verify_traffic(self): + def test_definition(self): + """Make sure that the abstract class cannot be instantiated""" vnfd = TestGenericVNF.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - generic_traffic_gen = GenericTrafficGen('vnf1', vnfd) - traffic_profile = {} - self.assertIsNone(generic_traffic_gen.verify_traffic(traffic_profile)) + name = 'vnf1' + with self.assertRaises(TypeError) as exc: + GenericTrafficGen(name, vnfd) + msg = ("Can't instantiate abstract class GenericTrafficGen with " + "abstract methods run_traffic, terminate") + self.assertEqual(msg, str(exc.exception)) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_router_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_router_vnf.py new file mode 100644 index 000000000..9ed6fd5b3 --- /dev/null +++ b/tests/unit/network_services/vnf_generic/vnf/test_router_vnf.py @@ -0,0 +1,267 @@ +#!/usr/bin/env python + +# Copyright (c) 2016-2017 Intel Corporation +# +# 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. +# + +from __future__ import absolute_import + +import unittest +import mock + +from tests.unit import STL_MOCKS +from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh + + +STLClient = mock.MagicMock() +stl_patch = mock.patch.dict("sys.modules", STL_MOCKS) +stl_patch.start() + +if stl_patch: + from yardstick.network_services.vnf_generic.vnf.router_vnf import RouterVNF + + +TEST_FILE_YAML = 'nsb_test_case.yaml' +SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper' + + +name = 'vnf__1' + + +class TestRouterVNF(unittest.TestCase): + VNFD = {'vnfd:vnfd-catalog': + {'vnfd': + [{'short-name': 'RouterVNF', + 'vdu': + [{'routing_table': [], + 'description': 'RouterVNF', + 'name': 'router-baremetal', + 'nd_route_tbl': [], + 'id': 'router-baremetal', + 'external-interface': + [{'virtual-interface': + {'dst_mac': '00:00:00:00:00:04', + 'vpci': '0000:05:00.0', + 'local_ip': '152.16.100.19', + 'type': 'PCI-PASSTHROUGH', + 'netmask': '255.255.255.0', + 'dpdk_port_num': 0, + 'bandwidth': '10 Gbps', + 'driver': "i40e", + 'dst_ip': '152.16.100.20', + 'local_iface_name': 'xe0', + 'local_mac': '00:00:00:00:00:02'}, + 'vnfd-connection-point-ref': 'xe0', + 'name': 'xe0'}, + {'virtual-interface': + {'dst_mac': '00:00:00:00:00:03', + 'vpci': '0000:05:00.1', + 'local_ip': '152.16.40.19', + 'type': 'PCI-PASSTHROUGH', + 'driver': "i40e", + 'netmask': '255.255.255.0', + 'dpdk_port_num': 1, + 'bandwidth': '10 Gbps', + 'dst_ip': '152.16.40.20', + 'local_iface_name': 'xe1', + 'local_mac': '00:00:00:00:00:01'}, + 'vnfd-connection-point-ref': 'xe1', + 'name': 'xe1'}]}], + 'description': 'RouterVNF', + 'mgmt-interface': + {'vdu-id': 'router-baremetal', + 'host': '1.2.1.1', + 'password': 'r00t', + 'user': 'root', + 'ip': '1.2.1.1'}, + 'benchmark': + {'kpi': ['packets_in', 'packets_fwd', 'packets_dropped']}, + 'connection-point': [{'type': 'VPORT', 'name': 'xe0'}, + {'type': 'VPORT', 'name': 'xe1'}], + 'id': 'RouterVNF', 'name': 'VPEVnfSsh'}]}} + + scenario_cfg = {'nodes': {'cpt__0': 'compute_0.compute_nodes', + 'tg__0': 'trafficgen_1.baremetal', + 'vnf__0': 'vnf.yardstick'}, + 'options': {'flow': {'count': 128000, + 'dst_ip': ['10.0.3.26-10.0.3.105'], + 'dst_port': ['2001-2004'], + 'src_ip': ['10.0.2.26-10.0.2.105'], + 'src_port': ['1234-1238']}, + 'framesize': {'downlink': {'1024B': 100}, + 'uplink': {'1024B': 100}}, + 'rfc2544': {'allowed_drop_rate': '0.0001 - 0.1'}, + 'tg__0': {'queues_per_port': 7}, + 'traffic_type': 4, + 'vnf__0': {'nfvi_enable': True}}, + 'runner': {'interval': 35, + 'iterations': 10, + 'type': 'Iteration'}, + 'topology': 'router-tg-topology.yaml', + 'traffic_profile': '../../traffic_profiles/ipv4_throughput.yaml', + 'type': 'NSPerf'} + + context_cfg = {'nodes': {'tg__1': + {'member-vnf-index': '1', + 'role': 'TrafficGen', + 'name': 'trafficgen_1.yardstick', + 'vnfd-id-ref': 'tg__1', + 'ip': '1.2.1.1', + 'interfaces': + {'xe0': {'local_iface_name': 'ens785f0', + 'vld_id': RouterVNF.UPLINK, + 'netmask': '255.255.255.0', + 'local_ip': '152.16.100.20', + 'dst_mac': '00:00:00:00:00:02', + 'local_mac': '00:00:00:00:00:04', + 'dst_ip': '152.16.100.19', + 'driver': 'i40e', + 'vpci': '0000:05:00.0', + 'dpdk_port_num': 0}, + 'xe1': {'local_iface_name': 'ens785f1', + 'netmask': '255.255.255.0', + 'local_ip': '152.16.100.21', + 'local_mac': '00:00:00:00:00:01', + 'driver': 'i40e', + 'vpci': '0000:05:00.1', + 'dpdk_port_num': 1}}, + 'password': 'r00t', + 'VNF model': 'tg_rfc2544_tpl.yaml', + 'user': 'root'}, + 'vnf__1': + {'name': 'vnf.yardstick', + 'vnfd-id-ref': 'vnf__1', + 'ip': '1.2.1.1', + 'interfaces': + {'xe0': {'local_iface_name': 'ens786f0', + 'vld_id': RouterVNF.UPLINK, + 'netmask': '255.255.255.0', + 'local_ip': '152.16.100.19', + 'dst_mac': '00:00:00:00:00:04', + 'local_mac': '00:00:00:00:00:02', + 'dst_ip': '152.16.100.20', + 'driver': 'i40e', + 'vpci': '0000:05:00.0', + 'dpdk_port_num': 0}, + 'xe1': {'local_iface_name': 'ens786f1', + 'vld_id': RouterVNF.DOWNLINK, + 'netmask': '255.255.255.0', + 'local_ip': '152.16.40.19', + 'dst_mac': '00:00:00:00:00:03', + 'local_mac': '00:00:00:00:00:01', + 'dst_ip': '152.16.40.20', + 'driver': 'i40e', + 'vpci': '0000:05:00.1', + 'dpdk_port_num': 1}}, + 'routing_table': [], + 'member-vnf-index': '2', + 'host': '1.2.1.1', + 'role': 'vnf', + 'user': 'root', + 'nd_route_tbl': [], + 'password': 'r00t', + 'VNF model': 'router_vnf.yaml'}}} + + IP_SHOW_STATS_OUTPUT = """\ +2: em1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 + link/ether d4:c9:ef:52:7c:4d brd ff:ff:ff:ff:ff:ff + RX: bytes packets errors dropped overrun mcast + 2781945429 3202213 0 0 0 30131 + RX errors: length crc frame fifo missed + 0 0 0 0 0 + TX: bytes packets errors dropped carrier collsns + 646221183 2145799 0 0 0 0 + TX errors: aborted fifo window heartbeat + 0 0 0 0 +""" + STATS = { + 'RX:bytes': '2781945429', + 'RX:dropped': '0', + 'RX:errors': '0', + 'RX:mcast': '30131', + 'RX:overrun': '0', + 'RX:packets': '3202213', + 'RX errors:length': '0', + 'RX errors:crc': '0', + 'RX errors:frame': '0', + 'RX errors:fifo': '0', + 'RX errors:missed': '0', + 'TX:bytes': '646221183', + 'TX:carrier': '0', + 'TX:collsns': '0', + 'TX:dropped': '0', + 'TX:errors': '0', + 'TX:packets': '2145799', + 'TX errors:aborted': '0', + 'TX errors:fifo': '0', + 'TX errors:window': '0', + 'TX errors:heartbeat': '0', + } + + def test___init__(self): + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + router_vnf = RouterVNF(name, vnfd) + self.assertIsNone(router_vnf._vnf_process) + + def test_get_stats(self): + stats = RouterVNF.get_stats(self.IP_SHOW_STATS_OUTPUT) + self.assertDictEqual(stats, self.STATS) + + @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") + @mock.patch(SSH_HELPER) + def test_collect_kpi(self, ssh, _): + m = mock_ssh(ssh) + + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + router_vnf = RouterVNF(name, vnfd) + router_vnf.ssh_helper = m + result = {'packets_dropped': 0, 'packets_fwd': 0, 'packets_in': 0, 'link_stats': {}} + self.assertEqual(result, router_vnf.collect_kpi()) + + @mock.patch(SSH_HELPER) + def test_run_router(self, ssh): + mock_ssh(ssh) + + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + router_vnf = RouterVNF(name, vnfd) + router_vnf.scenario_helper.scenario_cfg = self.scenario_cfg + router_vnf._run() + router_vnf.ssh_helper.drop_connection.assert_called_once() + + @mock.patch("yardstick.network_services.vnf_generic.vnf.router_vnf.Context") + @mock.patch(SSH_HELPER) + def test_instantiate(self, ssh, _): + mock_ssh(ssh) + + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + router_vnf = RouterVNF(name, vnfd) + router_vnf.WAIT_TIME = 0 + router_vnf.INTERFACE_WAIT = 0 + self.scenario_cfg.update({"nodes": {"vnf__1": ""}}) + self.assertIsNone(router_vnf.instantiate(self.scenario_cfg, + self.context_cfg)) + + @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") + @mock.patch(SSH_HELPER) + def test_terminate(self, ssh, _): + mock_ssh(ssh) + + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + router_vnf = RouterVNF(name, vnfd) + router_vnf._vnf_process = mock.MagicMock() + router_vnf._vnf_process.terminate = mock.Mock() + self.assertEqual(None, router_vnf.terminate()) + +if __name__ == '__main__': + unittest.main() diff --git a/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py index 57f9fac61..85b10c5a9 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py @@ -2022,55 +2022,32 @@ class TestSampleVNFTrafficGen(unittest.TestCase): sample_vnf_tg.terminate() - @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') - @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG') - def test_wait_for_instantiate(self, mock_logger, mock_time): + def test__wait_for_process(self): sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0) - sample_vnf_tg._check_status = mock.Mock(side_effect=iter([1, 0])) - sample_vnf_tg._tg_process = mock.Mock() - sample_vnf_tg._tg_process.is_alive.return_value = True - sample_vnf_tg._tg_process.exitcode = 234 - - self.assertEqual(sample_vnf_tg.wait_for_instantiate(), 234) - - @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') - @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG') - def test_wait_for_instantiate_not_alive(self, mock_logger, mock_time): + with mock.patch.object(sample_vnf_tg, '_check_status', + return_value=0) as mock_status, \ + mock.patch.object(sample_vnf_tg, '_tg_process') as mock_proc: + mock_proc.is_alive.return_value = True + mock_proc.exitcode = 234 + self.assertEqual(sample_vnf_tg._wait_for_process(), 234) + mock_proc.is_alive.assert_called_once() + mock_status.assert_called_once() + + def test__wait_for_process_not_alive(self): sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0) - sample_vnf_tg._check_status = mock.Mock(return_value=1) - sample_vnf_tg._tg_process = mock.Mock() - sample_vnf_tg._tg_process.is_alive.side_effect = iter([True, False]) - sample_vnf_tg._tg_process.exitcode = 234 - - with self.assertRaises(RuntimeError): - sample_vnf_tg.wait_for_instantiate() - - @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') - @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG') - @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.Process') - def test_wait_for_instantiate_delayed(self, mock_process, mock_logger, mock_time): - class MockClientStarted(mock.Mock): - - def __init__(self, *args, **kwargs): - super(MockClientStarted, self).__init__(*args, **kwargs) - self.iter = iter([0, 0, 1]) - - @property - def value(self): - return next(self.iter) - - mock_traffic_profile = mock.Mock(autospec=TrafficProfile) - mock_traffic_profile.get_traffic_definition.return_value = "64" - mock_traffic_profile.execute_traffic.return_value = "64" - mock_traffic_profile.params = self.TRAFFIC_PROFILE + with mock.patch.object(sample_vnf_tg, '_tg_process') as mock_proc: + mock_proc.is_alive.return_value = False + self.assertRaises(RuntimeError, sample_vnf_tg._wait_for_process) + mock_proc.is_alive.assert_called_once() + def test__wait_for_process_delayed(self): sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0) - sample_vnf_tg._check_status = mock.Mock(side_effect=iter([1, 0])) - sample_vnf_tg._tg_process = mock.Mock() - sample_vnf_tg._tg_process.is_alive.return_value = True - sample_vnf_tg._tg_process.exitcode = 234 - sample_vnf_tg.resource_helper = mock.Mock() - sample_vnf_tg.resource_helper.client_started = MockClientStarted() - - self.assertTrue(sample_vnf_tg.run_traffic(mock_traffic_profile)) - self.assertEqual(mock_time.sleep.call_count, 2) + with mock.patch.object(sample_vnf_tg, '_check_status', + side_effect=[1, 0]) as mock_status, \ + mock.patch.object(sample_vnf_tg, + '_tg_process') as mock_proc: + mock_proc.is_alive.return_value = True + mock_proc.exitcode = 234 + self.assertEqual(sample_vnf_tg._wait_for_process(), 234) + mock_proc.is_alive.assert_has_calls([mock.call(), mock.call()]) + mock_status.assert_has_calls([mock.call(), mock.call()]) |