aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--INFO1
-rw-r--r--INFO.yaml4
-rw-r--r--ansible/roles/infra_destroy_previous_configuration/tasks/delete_vm.yml29
-rw-r--r--ansible/roles/infra_destroy_previous_configuration/tasks/main.yml15
-rw-r--r--docker/Dockerfile2
-rw-r--r--docker/Dockerfile.aarch64.patch2
-rwxr-xr-xnsb_setup.sh2
-rw-r--r--samples/storage_bottlenecks.yaml77
-rw-r--r--samples/vnf_samples/nsut/vfw/tc_heat_rfc2544_ipv4_1rule_1flow_64B_trex.yaml7
-rw-r--r--tests/unit/network_services/traffic_profile/test_traffic_profile.py45
-rw-r--r--tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py53
-rw-r--r--yardstick/benchmark/contexts/heat.py6
-rw-r--r--yardstick/benchmark/core/task.py6
-rw-r--r--yardstick/benchmark/scenarios/lib/delete_network.py9
-rw-r--r--yardstick/common/ansible_common.py5
-rw-r--r--yardstick/common/constants.py1
-rw-r--r--yardstick/common/exceptions.py7
-rw-r--r--yardstick/common/openstack_utils.py52
-rw-r--r--yardstick/network_services/traffic_profile/traffic_profile.py86
-rw-r--r--yardstick/network_services/vnf_generic/vnf/sample_vnf.py18
-rw-r--r--yardstick/orchestrator/heat.py9
-rw-r--r--yardstick/tests/fixture.py47
-rw-r--r--yardstick/tests/unit/benchmark/core/test_plugin.py204
-rw-r--r--yardstick/tests/unit/benchmark/core/test_task.py132
-rw-r--r--yardstick/tests/unit/benchmark/scenarios/lib/test_delete_network.py54
-rw-r--r--yardstick/tests/unit/common/test_openstack_utils.py29
-rw-r--r--yardstick/tests/unit/orchestrator/test_heat.py12
27 files changed, 589 insertions, 325 deletions
diff --git a/INFO b/INFO
index 35b282845..1a49af295 100644
--- a/INFO
+++ b/INFO
@@ -22,6 +22,7 @@ ross.b.brattain@intel.com
chenjiankun1@huawei.com
rodolfo.alonso.hernandez@intel.com
emma.l.foley@intel.com
+abhijit.sinha@intel.com
Link to TSC approval: http://meetbot.opnfv.org/meetings/
Link to approval of additional submitters:
diff --git a/INFO.yaml b/INFO.yaml
index f84f6952e..730cd4a6b 100644
--- a/INFO.yaml
+++ b/INFO.yaml
@@ -74,6 +74,10 @@ committers:
email: '14_ykl@tongji.edu.cn'
company: 'tongji.edu.cn'
id: 'tjuyinkanglin'
+ - name: 'Abhijit Sinha'
+ email: 'abhijit.sinha@intel.com'
+ company: 'intel.com'
+ id: 'abhijitsinha'
tsc:
# yamllint disable rule:line-length
approval: 'http//meetbot.opnfv.org/meetings/'
diff --git a/ansible/roles/infra_destroy_previous_configuration/tasks/delete_vm.yml b/ansible/roles/infra_destroy_previous_configuration/tasks/delete_vm.yml
new file mode 100644
index 000000000..5e43ee81e
--- /dev/null
+++ b/ansible/roles/infra_destroy_previous_configuration/tasks/delete_vm.yml
@@ -0,0 +1,29 @@
+# Copyright (c) 2017-2018 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.
+---
+# Ignore errors as VM can be destroyed without been undefined.
+- name: Destroy old VMs
+ virt:
+ command: destroy
+ name: "{{ node_item.hostname }}"
+ when: node_item.hostname in virt_vms.list_vms
+ ignore_errors: yes
+
+# Ignore errors as VM can be running while undefined
+- name: Undefine old VMs
+ virt:
+ command: undefine
+ name: "{{ node_item.hostname }}"
+ when: node_item.hostname in virt_vms.list_vms
+ ignore_errors: yes
diff --git a/ansible/roles/infra_destroy_previous_configuration/tasks/main.yml b/ansible/roles/infra_destroy_previous_configuration/tasks/main.yml
index 5595cd501..e6c2c0229 100644
--- a/ansible/roles/infra_destroy_previous_configuration/tasks/main.yml
+++ b/ansible/roles/infra_destroy_previous_configuration/tasks/main.yml
@@ -26,17 +26,10 @@
register: virt_vms
- name: Destroy old VMs
- virt:
- command: destroy
- name: "{{ item.hostname }}"
- when: item.hostname in virt_vms.list_vms
- with_items: "{{ infra_deploy_vars.nodes }}"
-
-- name: Undefine old VMs
- virt:
- command: undefine
- name: "{{ item.hostname }}"
- when: item.hostname in virt_vms.list_vms
+ include_tasks: delete_vm.yml
+ extra_vars: "{{ virt_vms }}"
+ loop_control:
+ loop_var: node_item
with_items: "{{ infra_deploy_vars.nodes }}"
- name: Delete old networks
diff --git a/docker/Dockerfile b/docker/Dockerfile
index ddd8dfaf8..46e52d557 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -26,7 +26,7 @@ ENV YARDSTICK_REPO_DIR="${REPOS_DIR}/yardstick" \
RUN apt-get update && apt-get install -y git python-setuptools python-pip && apt-get -y autoremove && apt-get clean
RUN easy_install -U setuptools==30.0.0
-RUN pip install appdirs==1.4.0 pyopenssl==17.5.0 python-openstackclient==3.11.0
+RUN pip install appdirs==1.4.0 pyopenssl==17.5.0 python-openstackclient==3.11.0 python-heatclient==1.11.0
RUN mkdir -p ${REPOS_DIR}
diff --git a/docker/Dockerfile.aarch64.patch b/docker/Dockerfile.aarch64.patch
index ca933514a..24e3952fb 100644
--- a/docker/Dockerfile.aarch64.patch
+++ b/docker/Dockerfile.aarch64.patch
@@ -39,7 +39,7 @@ index 2ee5b4c..23e5ea5 100644
+RUN apt-get update && apt-get install -y git python-setuptools python-pip && apt-get -y autoremove && \
+ apt-get install -y libssl-dev && apt-get -y install libffi-dev && apt-get clean
RUN easy_install -U setuptools==30.0.0
- RUN pip install appdirs==1.4.0 pyopenssl==17.5.0
+ RUN pip install appdirs==1.4.0 pyopenssl==17.5.0 python-openstackclient==3.11.0
@@ -43,8 +44,8 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf
diff --git a/nsb_setup.sh b/nsb_setup.sh
index 4a8e4db93..50fc017d1 100755
--- a/nsb_setup.sh
+++ b/nsb_setup.sh
@@ -63,7 +63,7 @@ for i in "${pkg[@]}"; do
fi
done
-pip install ansible==2.3.2 shade==1.17.0 docker-py==1.10.6
+pip install ansible==2.4.2 shade==1.22.2 docker-py==1.10.6
ANSIBLE_SCRIPTS="ansible"
diff --git a/samples/storage_bottlenecks.yaml b/samples/storage_bottlenecks.yaml
new file mode 100644
index 000000000..1aa0d7e35
--- /dev/null
+++ b/samples/storage_bottlenecks.yaml
@@ -0,0 +1,77 @@
+##############################################################################
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+---
+# Sample benchmark task config file
+# measure storage performance using fio
+#
+# For this sample just like running the command below on the test vm and
+# getting benchmark info back to the yardstick.
+#
+# sudo fio -filename=/home/ubuntu/data.raw -bs=4k -ipdepth=1 -rw=rw \
+# -ramp_time=10 -runtime=60 -name=yardstick-fio -ioengine=libaio \
+# -direct=1 -group_reporting -numjobs=1 -time_based \
+# --output-format=json
+
+schema: "yardstick:task:0.1"
+run_in_parallel: true
+
+{% set directory = directory or '/FIO_Test' %}
+{% set stack_num = stack_num or 1 %}
+{% set volume_num = volume_num or "1" %}
+{% set rw = rw or "randrw" %}
+{% set bs = bs or "4k" %}
+{% set size = size or "30g" %}
+{% set rwmixwrite = rwmixwrite or "50" %}
+{% set numjobs = numjobs or "1" %}
+{% set direct = direct or "1" %}
+{% set volume_size = volume_size or 50 %}
+
+scenarios:
+{% for num in range(stack_num) %}
+-
+ type: Fio
+ options:
+ filename: {{ directory }}/test
+ directory: {{ directory }}
+ bs: {{bs}}
+ rw: {{rw}}
+ size: {{size}}
+ rwmixwrite: {{rwmixwrite}}
+ numjobs: {{numjobs}}
+ direct: {{direct}}
+ ramp_time: 10
+
+ host: demo.storage_bottlenecks-{{num}}-{{volume_num}}
+
+ runner:
+ type: Duration
+ duration: 60
+ interval: 1
+{% endfor %}
+
+contexts:
+{% for context_num in range(stack_num) %}
+-
+ name: storage_bottlenecks-{{context_num}}-{{volume_num}}
+ image: yardstick-image
+ flavor: yardstick-flavor
+ user: ubuntu
+
+ servers:
+ demo:
+ volume:
+ size: {{volume_size}}
+ volume_mountpoint: "/dev/vdb"
+ floating_ip: true
+
+ networks:
+ test:
+ cidr: "10.0.1.0/24"
+ port_security_enabled: true
+{% endfor %} \ No newline at end of file
diff --git a/samples/vnf_samples/nsut/vfw/tc_heat_rfc2544_ipv4_1rule_1flow_64B_trex.yaml b/samples/vnf_samples/nsut/vfw/tc_heat_rfc2544_ipv4_1rule_1flow_64B_trex.yaml
index 13fe5a5a5..2e096a126 100644
--- a/samples/vnf_samples/nsut/vfw/tc_heat_rfc2544_ipv4_1rule_1flow_64B_trex.yaml
+++ b/samples/vnf_samples/nsut/vfw/tc_heat_rfc2544_ipv4_1rule_1flow_64B_trex.yaml
@@ -15,6 +15,7 @@
---
{% set provider = provider or none %}
{% set physical_networks = physical_networks or ['physnet1', 'physnet2'] %}
+{% set segmentation_id = segmentation_id or none %}
schema: yardstick:task:0.1
scenarios:
@@ -74,6 +75,9 @@ context:
{% if provider %}
provider: {{ provider }}
physical_network: {{ physical_networks[0] }}
+ {% if segmentation_id %}
+ segmentation_id: {{ segmentation_id }}
+ {% endif %}
{% endif %}
port_security_enabled: False
enable_dhcp: 'false'
@@ -83,6 +87,9 @@ context:
{% if provider %}
provider: {{ provider }}
physical_network: {{ physical_networks[1] }}
+ {% if segmentation_id %}
+ segmentation_id: {{ segmentation_id }}
+ {% endif %}
{% endif %}
port_security_enabled: False
enable_dhcp: 'false'
diff --git a/tests/unit/network_services/traffic_profile/test_traffic_profile.py b/tests/unit/network_services/traffic_profile/test_traffic_profile.py
index 0bb0a88a6..37b9a08d0 100644
--- a/tests/unit/network_services/traffic_profile/test_traffic_profile.py
+++ b/tests/unit/network_services/traffic_profile/test_traffic_profile.py
@@ -13,14 +13,15 @@
# 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 ipaddress
-import unittest
import mock
+import six
+import unittest
from tests.unit import STL_MOCKS
+from yardstick.common import exceptions as y_exc
STLClient = mock.MagicMock()
stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
@@ -215,11 +216,27 @@ class TestTrexProfile(unittest.TestCase):
TrexProfile(TrafficProfile)
self.assertEqual({}, trex_profile.generate_imix_data(False))
- def test__get_start_end_ipv6(self):
- trex_profile = \
- TrexProfile(TrafficProfile)
- self.assertRaises(SystemExit, trex_profile._get_start_end_ipv6,
- "1.1.1.3", "1.1.1.1")
+ def test__count_ip_ipv4(self):
+ start, end, count = TrexProfile._count_ip('1.1.1.1', '1.2.3.4')
+ self.assertEqual('1.1.1.1', str(start))
+ self.assertEqual('1.2.3.4', str(end))
+ diff = (int(ipaddress.IPv4Address(six.u('1.2.3.4'))) -
+ int(ipaddress.IPv4Address(six.u('1.1.1.1'))))
+ self.assertEqual(diff, count)
+
+ def test__count_ip_ipv6(self):
+ start_ip = '0064:ff9b:0:0:0:0:9810:6414'
+ end_ip = '0064:ff9b:0:0:0:0:9810:6420'
+ start, end, count = TrexProfile._count_ip(start_ip, end_ip)
+ self.assertEqual(0x98106414, start)
+ self.assertEqual(0x98106420, end)
+ self.assertEqual(0x98106420 - 0x98106414, count)
+
+ def test__count_ip_ipv6_exception(self):
+ start_ip = '0064:ff9b:0:0:0:0:9810:6420'
+ end_ip = '0064:ff9b:0:0:0:0:9810:6414'
+ with self.assertRaises(y_exc.IPv6RangeError):
+ TrexProfile._count_ip(start_ip, end_ip)
def test__dscp_range_action_partial_actual_count_zero(self):
traffic_profile = TrexProfile(TrafficProfile)
@@ -258,13 +275,17 @@ class TestTrexProfile(unittest.TestCase):
def test__general_single_action_partial(self):
trex_profile = TrexProfile(TrafficProfile)
- trex_profile._general_single_action_partial(ETHERNET)(SRC)(self.EXAMPLE_ETHERNET_ADDR)
- self.assertEqual(self.EXAMPLE_ETHERNET_ADDR, trex_profile.ether_packet.src)
+ trex_profile._general_single_action_partial(ETHERNET)(SRC)(
+ self.EXAMPLE_ETHERNET_ADDR)
+ self.assertEqual(self.EXAMPLE_ETHERNET_ADDR,
+ trex_profile.ether_packet.src)
- trex_profile._general_single_action_partial(IP)(DST)(self.EXAMPLE_IP_ADDR)
+ trex_profile._general_single_action_partial(IP)(DST)(
+ self.EXAMPLE_IP_ADDR)
self.assertEqual(self.EXAMPLE_IP_ADDR, trex_profile.ip_packet.dst)
- trex_profile._general_single_action_partial(IPv6)(DST)(self.EXAMPLE_IPv6_ADDR)
+ trex_profile._general_single_action_partial(IPv6)(DST)(
+ self.EXAMPLE_IPv6_ADDR)
self.assertEqual(self.EXAMPLE_IPv6_ADDR, trex_profile.ip6_packet.dst)
trex_profile._general_single_action_partial(UDP)(SRC_PORT)(5060)
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 af941c04f..25633384e 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
@@ -624,37 +624,34 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase):
self.assertIsInstance(dpdk_vnf_setup_env_helper.setup_vnf_environment(), ResourceProfile)
- def test__setup_dpdk_early_success(self):
- vnfd_helper = VnfdHelper(self.VNFD_0)
+ def test__setup_dpdk(self):
ssh_helper = mock.Mock()
- ssh_helper.execute.return_value = 0, 'output', ''
- ssh_helper.join_bin_path.return_value = 'joined_path'
- ssh_helper.provision_tool.return_value = 'provision string'
- scenario_helper = mock.Mock()
- dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
- dpdk_setup_helper._setup_hugepages = mock.Mock()
-
- self.assertIsNone(dpdk_setup_helper._setup_dpdk())
- self.assertEqual(dpdk_setup_helper.ssh_helper.execute.call_count, 2)
-
- @mock.patch('yardstick.ssh.SSH')
- def test__setup_dpdk_short(self, _):
- def execute_side(cmd):
- if 'joined_path' in cmd:
- return 0, 'output', ''
- return 1, 'bad output', 'error output'
+ ssh_helper.execute = mock.Mock()
+ ssh_helper.execute.return_value = (0, 0, 0)
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(mock.ANY, ssh_helper, mock.ANY)
+ with mock.patch.object(dpdk_setup_helper, '_setup_hugepages') as \
+ mock_setup_hp:
+ dpdk_setup_helper._setup_dpdk()
+ mock_setup_hp.assert_called_once()
+ ssh_helper.execute.assert_has_calls([
+ mock.call('sudo modprobe uio && sudo modprobe igb_uio'),
+ mock.call('lsmod | grep -i igb_uio')
+ ])
- vnfd_helper = VnfdHelper(self.VNFD_0)
+ def test__setup_dpdk_igb_uio_not_loaded(self):
ssh_helper = mock.Mock()
- ssh_helper.execute.side_effect = execute_side
- ssh_helper.join_bin_path.return_value = 'joined_path'
- ssh_helper.provision_tool.return_value = 'provision string'
- scenario_helper = mock.Mock()
- dpdk_setup_helper = DpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper)
- dpdk_setup_helper._setup_hugepages = mock.Mock()
-
- self.assertIsNone(dpdk_setup_helper._setup_dpdk())
- self.assertEqual(dpdk_setup_helper.ssh_helper.execute.call_count, 3)
+ ssh_helper.execute = mock.Mock()
+ ssh_helper.execute.side_effect = [(0, 0, 0), (1, 0, 0)]
+ dpdk_setup_helper = DpdkVnfSetupEnvHelper(mock.ANY, ssh_helper, mock.ANY)
+ with mock.patch.object(dpdk_setup_helper, '_setup_hugepages') as \
+ mock_setup_hp:
+ with self.assertRaises(y_exceptions.DPDKSetupDriverError):
+ dpdk_setup_helper._setup_dpdk()
+ mock_setup_hp.assert_called_once()
+ ssh_helper.execute.assert_has_calls([
+ mock.call('sudo modprobe uio && sudo modprobe igb_uio'),
+ mock.call('lsmod | grep -i igb_uio')
+ ])
@mock.patch('yardstick.ssh.SSH')
def test__setup_resources(self, _):
diff --git a/yardstick/benchmark/contexts/heat.py b/yardstick/benchmark/contexts/heat.py
index 4ba543b9e..7b7f1be32 100644
--- a/yardstick/benchmark/contexts/heat.py
+++ b/yardstick/benchmark/contexts/heat.py
@@ -95,13 +95,15 @@ class HeatContext(Context):
return sorted_networks
def init(self, attrs):
- self.check_environment()
"""initializes itself from the supplied arguments"""
+ self.check_environment()
self.name = attrs["name"]
self._user = attrs.get("user")
self.template_file = attrs.get("heat_template")
+
+ self.heat_timeout = attrs.get("timeout", DEFAULT_HEAT_TIMEOUT)
if self.template_file:
self.heat_parameters = attrs.get("heat_parameters")
return
@@ -113,8 +115,6 @@ class HeatContext(Context):
self._flavor = attrs.get("flavor")
- self.heat_timeout = attrs.get("timeout", DEFAULT_HEAT_TIMEOUT)
-
self.placement_groups = [PlacementGroup(name, self, pg_attrs["policy"])
for name, pg_attrs in attrs.get(
"placement_groups", {}).items()]
diff --git a/yardstick/benchmark/core/task.py b/yardstick/benchmark/core/task.py
index 9b1b3f851..5fcc9182c 100644
--- a/yardstick/benchmark/core/task.py
+++ b/yardstick/benchmark/core/task.py
@@ -57,7 +57,7 @@ class Task(object): # pragma: no cover
out_types = [s.strip() for s in dispatchers.split(',')]
output_config['DEFAULT']['dispatcher'] = out_types
- def start(self, args, **kwargs):
+ def start(self, args):
"""Start a benchmark scenario."""
atexit.register(self.atexit_handler)
@@ -69,7 +69,7 @@ class Task(object): # pragma: no cover
try:
output_config = utils.parse_ini_file(CONF_FILE)
- except Exception:
+ except Exception: # pylint: disable=broad-except
# all error will be ignore, the default value is {}
output_config = {}
@@ -123,7 +123,7 @@ class Task(object): # pragma: no cover
data = self._run(scenarios, run_in_parallel, args.output_file)
except KeyboardInterrupt:
raise
- except Exception:
+ except Exception: # pylint: disable=broad-except
LOG.error('Testcase: "%s" FAILED!!!', case_name, exc_info=True)
testcases[case_name] = {'criteria': 'FAIL', 'tc_data': []}
else:
diff --git a/yardstick/benchmark/scenarios/lib/delete_network.py b/yardstick/benchmark/scenarios/lib/delete_network.py
index e8796bf82..2e8b595f9 100644
--- a/yardstick/benchmark/scenarios/lib/delete_network.py
+++ b/yardstick/benchmark/scenarios/lib/delete_network.py
@@ -7,14 +7,12 @@
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-from __future__ import print_function
-from __future__ import absolute_import
-
import logging
from yardstick.benchmark.scenarios import base
import yardstick.common.openstack_utils as op_utils
+
LOG = logging.getLogger(__name__)
@@ -30,7 +28,7 @@ class DeleteNetwork(base.Scenario):
self.network_id = self.options.get("network_id", None)
- self.neutron_client = op_utils.get_neutron_client()
+ self.shade_client = op_utils.get_shade_client()
self.setup_done = False
@@ -45,7 +43,7 @@ class DeleteNetwork(base.Scenario):
if not self.setup_done:
self.setup()
- status = op_utils.delete_neutron_net(self.neutron_client,
+ status = op_utils.delete_neutron_net(self.shade_client,
network_id=self.network_id)
if status:
result.update({"delete_network": 1})
@@ -53,3 +51,4 @@ class DeleteNetwork(base.Scenario):
else:
result.update({"delete_network": 0})
LOG.error("Delete network failed!")
+ return status
diff --git a/yardstick/common/ansible_common.py b/yardstick/common/ansible_common.py
index 9a4426bf9..be262c215 100644
--- a/yardstick/common/ansible_common.py
+++ b/yardstick/common/ansible_common.py
@@ -33,7 +33,7 @@ from six import StringIO
from chainmap import ChainMap
from yardstick.common.utils import Timer
-
+from yardstick.common import constants as consts
cgitb.enable(format="text")
@@ -435,6 +435,7 @@ class AnsibleCommon(object):
ansible_dict = dict(os.environ, **{
"ANSIBLE_LOG_PATH": os.path.join(directory, log_file),
"ANSIBLE_LOG_BASE": directory,
+ "ANSIBLE_ROLES_PATH": consts.ANSIBLE_ROLES_PATH,
# # required for SSH to work
# "ANSIBLE_SSH_ARGS": "-o UserKnownHostsFile=/dev/null "
# "-o GSSAPIAuthentication=no "
@@ -516,7 +517,7 @@ class AnsibleCommon(object):
# playbook dir: use include to point to files in consts.ANSIBLE_DIR
if not os.path.isdir(directory):
- raise OSError("Not a directory, %s", directory)
+ raise OSError("Not a directory, %s" % directory)
timeout = self.get_timeout(timeout, self.default_timeout)
self.counter += 1
diff --git a/yardstick/common/constants.py b/yardstick/common/constants.py
index 646a1f2ca..43c2c19cb 100644
--- a/yardstick/common/constants.py
+++ b/yardstick/common/constants.py
@@ -83,6 +83,7 @@ YARDSTICK_ROOT_PATH = dirname(
TASK_LOG_DIR = get_param('dir.tasklog', '/var/log/yardstick/')
CONF_SAMPLE_DIR = join(REPOS_DIR, 'etc/yardstick/')
ANSIBLE_DIR = join(REPOS_DIR, 'ansible')
+ANSIBLE_ROLES_PATH = join(REPOS_DIR, 'ansible/roles/')
SAMPLE_CASE_DIR = join(REPOS_DIR, 'samples')
TESTCASE_DIR = join(YARDSTICK_ROOT_PATH, 'tests/opnfv/test_cases/')
TESTSUITE_DIR = join(YARDSTICK_ROOT_PATH, 'tests/opnfv/test_suites/')
diff --git a/yardstick/common/exceptions.py b/yardstick/common/exceptions.py
index e38dd246c..3e0635e46 100644
--- a/yardstick/common/exceptions.py
+++ b/yardstick/common/exceptions.py
@@ -63,3 +63,10 @@ class HeatTemplateError(YardstickException):
"""Error in Heat during the stack deployment"""
message = ('Error in Heat during the creation of the OpenStack stack '
'"%(stack_name)"')
+
+
+class IPv6RangeError(YardstickException):
+ message = 'Start IP "%(start_ip)s" is greater than end IP "%(end_ip)s"'
+
+class DPDKSetupDriverError(YardstickException):
+ message = '"igb_uio" driver is not loaded'
diff --git a/yardstick/common/openstack_utils.py b/yardstick/common/openstack_utils.py
index c5b17c270..8f666e268 100644
--- a/yardstick/common/openstack_utils.py
+++ b/yardstick/common/openstack_utils.py
@@ -15,6 +15,7 @@ import logging
from keystoneauth1 import loading
from keystoneauth1 import session
import shade
+from shade import exc
from cinderclient import client as cinderclient
from novaclient import client as novaclient
@@ -174,6 +175,7 @@ def get_glance_client(): # pragma: no cover
def get_shade_client():
return shade.openstack_cloud()
+
# *********************************************
# NOVA
# *********************************************
@@ -272,7 +274,8 @@ def create_aggregate_with_host(nova_client, aggregate_name, av_zone,
def create_keypair(name, key_path=None): # pragma: no cover
try:
with open(key_path) as fpubkey:
- keypair = get_nova_client().keypairs.create(name=name, public_key=fpubkey.read())
+ keypair = get_nova_client().keypairs.create(
+ name=name, public_key=fpubkey.read())
return keypair
except Exception: # pylint: disable=broad-except
log.exception("Error [create_keypair(nova_client)]")
@@ -304,9 +307,11 @@ def create_instance_and_wait_for_active(json_body): # pragma: no cover
return None
-def attach_server_volume(server_id, volume_id, device=None): # pragma: no cover
+def attach_server_volume(server_id, volume_id,
+ device=None): # pragma: no cover
try:
- get_nova_client().volumes.create_server_volume(server_id, volume_id, device)
+ get_nova_client().volumes.create_server_volume(server_id,
+ volume_id, device)
except Exception: # pylint: disable=broad-except
log.exception("Error [attach_server_volume(nova_client, '%s', '%s')]",
server_id, volume_id)
@@ -370,7 +375,8 @@ def get_server_by_name(name): # pragma: no cover
def create_flavor(name, ram, vcpus, disk, **kwargs): # pragma: no cover
try:
- return get_nova_client().flavors.create(name, ram, vcpus, disk, **kwargs)
+ return get_nova_client().flavors.create(name, ram, vcpus,
+ disk, **kwargs)
except Exception: # pylint: disable=broad-except
log.exception("Error [create_flavor(nova_client, %s, %s, %s, %s, %s)]",
name, ram, disk, vcpus, kwargs['is_public'])
@@ -455,13 +461,11 @@ def create_neutron_net(neutron_client, json_body): # pragma: no cover
raise Exception("operation error")
-def delete_neutron_net(neutron_client, network_id): # pragma: no cover
+def delete_neutron_net(shade_client, network_id):
try:
- neutron_client.delete_network(network_id)
- return True
- except Exception: # pylint: disable=broad-except
- log.error("Error [delete_neutron_net(neutron_client, '%s')]",
- network_id)
+ return shade_client.delete_network(network_id)
+ except exc.OpenStackCloudException:
+ log.error("Error [delete_neutron_net(shade_client, '%s')]", network_id)
return False
@@ -558,7 +562,8 @@ def get_security_group_id(neutron_client, sg_name): # pragma: no cover
return id
-def create_security_group(neutron_client, sg_name, sg_description): # pragma: no cover
+def create_security_group(neutron_client, sg_name,
+ sg_description): # pragma: no cover
json_body = {'security_group': {'name': sg_name,
'description': sg_description}}
try:
@@ -611,8 +616,8 @@ def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
return False
-def create_security_group_full(neutron_client,
- sg_name, sg_description): # pragma: no cover
+def create_security_group_full(neutron_client, sg_name,
+ sg_description): # pragma: no cover
sg_id = get_security_group_id(neutron_client, sg_name)
if sg_id != '':
log.info("Using existing security group '%s'...", sg_name)
@@ -670,22 +675,18 @@ def create_image(glance_client, image_name, file_path, disk_format,
else:
log.info("Creating image '%s' from '%s'...", image_name, file_path)
- image = glance_client.images.create(name=image_name,
- visibility=public,
- disk_format=disk_format,
- container_format=container_format,
- min_disk=min_disk,
- min_ram=min_ram,
- tags=tag,
- protected=protected,
- **kwargs)
+ image = glance_client.images.create(
+ name=image_name, visibility=public, disk_format=disk_format,
+ container_format=container_format, min_disk=min_disk,
+ min_ram=min_ram, tags=tag, protected=protected, **kwargs)
image_id = image.id
with open(file_path) as image_data:
glance_client.images.upload(image_id, image_data)
return image_id
except Exception: # pylint: disable=broad-except
- log.error("Error [create_glance_image(glance_client, '%s', '%s', '%s')]",
- image_name, file_path, public)
+ log.error(
+ "Error [create_glance_image(glance_client, '%s', '%s', '%s')]",
+ image_name, file_path, public)
return None
@@ -725,7 +726,8 @@ def create_volume(cinder_client, volume_name, volume_size,
return None
-def delete_volume(cinder_client, volume_id, forced=False): # pragma: no cover
+def delete_volume(cinder_client, volume_id,
+ forced=False): # pragma: no cover
try:
if forced:
try:
diff --git a/yardstick/network_services/traffic_profile/traffic_profile.py b/yardstick/network_services/traffic_profile/traffic_profile.py
index 3b19ff9be..8cde5e4a7 100644
--- a/yardstick/network_services/traffic_profile/traffic_profile.py
+++ b/yardstick/network_services/traffic_profile/traffic_profile.py
@@ -11,16 +11,16 @@
# 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.
-""" Trex Traffic Profile definitions """
-from __future__ import absolute_import
import struct
import socket
import logging
from random import SystemRandom
-import six
import ipaddress
+import six
+
+from yardstick.common import exceptions as y_exc
from yardstick.network_services.traffic_profile.base import TrafficProfile
from trex_stl_lib.trex_stl_client import STLStream
from trex_stl_lib.trex_stl_streams import STLFlowLatencyStats
@@ -78,31 +78,32 @@ class TrexProfile(TrafficProfile):
op='inc',
step=1)
self.vm_flow_vars.append(stl_vm_flow_var)
- stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='mac_{}'.format(direction),
- pkt_offset='Ether.{}'.format(direction))
+ stl_vm_wr_flow_var = STLVmWrFlowVar(
+ fv_name='mac_{}'.format(direction),
+ pkt_offset='Ether.{}'.format(direction))
self.vm_flow_vars.append(stl_vm_wr_flow_var)
return partial
def _ip_range_action_partial(self, direction, count=1):
# pylint: disable=unused-argument
def partial(min_value, max_value, count):
- ip1 = int(ipaddress.IPv4Address(min_value))
- ip2 = int(ipaddress.IPv4Address(max_value))
- actual_count = (ip2 - ip1)
+ _, _, actual_count = self._count_ip(min_value, max_value)
if not actual_count:
count = 1
elif actual_count < int(count):
count = actual_count
- stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="ip4_{}".format(direction),
- min_value=min_value,
- max_value=max_value,
- size=4,
- limit=int(count),
- seed=0x1235)
+ stl_vm_flow_var = STLVmFlowVarRepeatableRandom(
+ name="ip4_{}".format(direction),
+ min_value=min_value,
+ max_value=max_value,
+ size=4,
+ limit=int(count),
+ seed=0x1235)
self.vm_flow_vars.append(stl_vm_flow_var)
- stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='ip4_{}'.format(direction),
- pkt_offset='IP.{}'.format(direction))
+ stl_vm_wr_flow_var = STLVmWrFlowVar(
+ fv_name='ip4_{}'.format(direction),
+ pkt_offset='IP.{}'.format(direction))
self.vm_flow_vars.append(stl_vm_wr_flow_var)
stl_vm_fix_ipv4 = STLVmFixIpv4(offset="IP")
self.vm_flow_vars.append(stl_vm_fix_ipv4)
@@ -111,7 +112,7 @@ class TrexProfile(TrafficProfile):
def _ip6_range_action_partial(self, direction, _):
def partial(min_value, max_value, count):
# pylint: disable=unused-argument
- min_value, max_value = self._get_start_end_ipv6(min_value, max_value)
+ min_value, max_value, _ = self._count_ip(min_value, max_value)
stl_vm_flow_var = STLVmFlowVar(name="ip6_{}".format(direction),
min_value=min_value,
max_value=max_value,
@@ -119,9 +120,10 @@ class TrexProfile(TrafficProfile):
op='random',
step=1)
self.vm_flow_vars.append(stl_vm_flow_var)
- stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='ip6_{}'.format(direction),
- pkt_offset='IPv6.{}'.format(direction),
- offset_fixup=8)
+ stl_vm_wr_flow_var = STLVmWrFlowVar(
+ fv_name='ip6_{}'.format(direction),
+ pkt_offset='IPv6.{}'.format(direction),
+ offset_fixup=8)
self.vm_flow_vars.append(stl_vm_wr_flow_var)
return partial
@@ -149,15 +151,17 @@ class TrexProfile(TrafficProfile):
elif int(count) > actual_count:
count = actual_count
- stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="port_{}".format(field),
- min_value=min_value,
- max_value=max_value,
- size=2,
- limit=int(count),
- seed=0x1235)
+ stl_vm_flow_var = STLVmFlowVarRepeatableRandom(
+ name="port_{}".format(field),
+ min_value=min_value,
+ max_value=max_value,
+ size=2,
+ limit=int(count),
+ seed=0x1235)
self.vm_flow_vars.append(stl_vm_flow_var)
- stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='port_{}'.format(field),
- pkt_offset=self.udp[field])
+ stl_vm_wr_flow_var = STLVmWrFlowVar(
+ fv_name='port_{}'.format(field),
+ pkt_offset=self.udp[field])
self.vm_flow_vars.append(stl_vm_wr_flow_var)
return partial
@@ -448,20 +452,18 @@ class TrexProfile(TrafficProfile):
self.profile = STLProfile(self.streams)
@classmethod
- def _get_start_end_ipv6(cls, start_ip, end_ip):
- try:
- ip1 = socket.inet_pton(socket.AF_INET6, start_ip)
- ip2 = socket.inet_pton(socket.AF_INET6, end_ip)
- hi1, lo1 = struct.unpack('!QQ', ip1)
- hi2, lo2 = struct.unpack('!QQ', ip2)
- if ((hi1 << 64) | lo1) > ((hi2 << 64) | lo2):
- raise SystemExit("IPv6: start_ip is greater then end_ip")
- max_p1 = abs(int(lo1) - int(lo2))
- base_p1 = lo1
- except Exception as ex_error:
- raise SystemExit(ex_error)
- else:
- return base_p1, max_p1 + base_p1
+ def _count_ip(cls, start_ip, end_ip):
+ start = ipaddress.ip_address(six.u(start_ip))
+ end = ipaddress.ip_address(six.u(end_ip))
+ if start.version == 4:
+ return start, end, int(end) - int(start)
+ elif start.version == 6:
+ if int(start) > int(end):
+ raise y_exc.IPv6RangeError(start_ip=str(start),
+ end_ip=str(end))
+ _, lo1 = struct.unpack('!QQ', start.packed)
+ _, lo2 = struct.unpack('!QQ', end.packed)
+ return lo1, lo2, lo2 - lo1
@classmethod
def _get_random_value(cls, min_port, max_port):
diff --git a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py
index fbaaa0ca8..d57d7e601 100644
--- a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py
+++ b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py
@@ -250,20 +250,12 @@ class DpdkVnfSetupEnvHelper(SetupEnvHelper):
self.ssh_helper.execute("sudo killall %s" % self.APP_NAME)
def _setup_dpdk(self):
- """ setup dpdk environment needed for vnf to run """
-
+ """Setup DPDK environment needed for VNF to run"""
self._setup_hugepages()
- self.ssh_helper.execute("sudo modprobe uio && sudo modprobe igb_uio")
-
- exit_status = self.ssh_helper.execute("lsmod | grep -i igb_uio")[0]
- if exit_status == 0:
- return
-
- dpdk = self.ssh_helper.join_bin_path(DPDK_VERSION)
- dpdk_setup = self.ssh_helper.provision_tool(tool_file="nsb_setup.sh")
- exit_status = self.ssh_helper.execute("which {} >/dev/null 2>&1".format(dpdk))[0]
- if exit_status != 0:
- self.ssh_helper.execute("bash %s dpdk >/dev/null 2>&1" % dpdk_setup)
+ self.ssh_helper.execute('sudo modprobe uio && sudo modprobe igb_uio')
+ exit_status = self.ssh_helper.execute('lsmod | grep -i igb_uio')[0]
+ if exit_status:
+ raise y_exceptions.DPDKSetupDriverError()
def get_collectd_options(self):
options = self.scenario_helper.all_options.get("collectd", {})
diff --git a/yardstick/orchestrator/heat.py b/yardstick/orchestrator/heat.py
index 754482e4f..558b5d2a6 100644
--- a/yardstick/orchestrator/heat.py
+++ b/yardstick/orchestrator/heat.py
@@ -74,7 +74,14 @@ class HeatStack(object):
if self.uuid is None:
return
- ret = self._cloud.delete_stack(self.uuid, wait=wait)
+ try:
+ ret = self._cloud.delete_stack(self.uuid, wait=wait)
+ except TypeError:
+ # NOTE(ralonsoh): this exception catch solves a bug in Shade, which
+ # tries to retrieve and read the stack status when it's already
+ # deleted.
+ ret = True
+
_DEPLOYED_STACKS.pop(self.uuid)
self._stack = None
return ret
diff --git a/yardstick/tests/fixture.py b/yardstick/tests/fixture.py
new file mode 100644
index 000000000..94d20eb34
--- /dev/null
+++ b/yardstick/tests/fixture.py
@@ -0,0 +1,47 @@
+# Copyright 2017 Intel Corporation
+# 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 fixtures
+import mock
+import six
+
+from yardstick.common import task_template
+
+
+class PluginParserFixture(fixtures.Fixture):
+ """PluginParser fixture.
+
+ This class is intended to be used as a fixture within unit tests and
+ therefore consumers must register it using useFixture() within their
+ unit test class.
+ """
+
+ def __init__(self, rendered_plugin):
+ super(PluginParserFixture, self).__init__()
+ self._rendered_plugin = rendered_plugin
+
+ def _setUp(self):
+ self.addCleanup(self._restore)
+ self._mock_tasktemplate_render = mock.patch.object(
+ task_template.TaskTemplate, 'render')
+ self.mock_tasktemplate_render = self._mock_tasktemplate_render.start()
+ self.mock_tasktemplate_render.return_value = self._rendered_plugin
+ self._mock_open = mock.patch.object(six.moves.builtins, 'open', create=True)
+ self.mock_open = self._mock_open.start()
+ self.mock_open.side_effect = mock.mock_open()
+
+ def _restore(self):
+ self._mock_tasktemplate_render.stop()
+ self._mock_open.stop()
diff --git a/yardstick/tests/unit/benchmark/core/test_plugin.py b/yardstick/tests/unit/benchmark/core/test_plugin.py
index 1d6e80574..0d14e4e86 100644
--- a/yardstick/tests/unit/benchmark/core/test_plugin.py
+++ b/yardstick/tests/unit/benchmark/core/test_plugin.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
##############################################################################
# Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
#
@@ -9,94 +7,136 @@
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-# Unittest for yardstick.benchmark.core.plugin
-from __future__ import absolute_import
+import copy
import os
-from os.path import dirname as dirname
+import pkg_resources
-try:
- from unittest import mock
-except ImportError:
- import mock
-import unittest
+import mock
+import testtools
+from yardstick import ssh
from yardstick.benchmark.core import plugin
+from yardstick.tests import fixture
+
+class PluginTestCase(testtools.TestCase):
-class Arg(object):
+ FILE = """
+schema: "yardstick:plugin:0.1"
- def __init__(self):
- # self.input_file = ('plugin/sample_config.yaml',)
- self.input_file = [
- os.path.join(os.path.abspath(
- dirname(dirname(dirname(dirname(dirname(dirname(__file__))))))),
- 'plugin/sample_config.yaml')]
+plugins:
+ name: sample
+deployment:
+ ip: 10.1.0.50
+ user: root
+ password: root
+"""
-@mock.patch('yardstick.benchmark.core.plugin.ssh')
-class pluginTestCase(unittest.TestCase):
+ NAME = 'sample'
+ DEPLOYMENT = {'ip': '10.1.0.50', 'user': 'root', 'password': 'root'}
def setUp(self):
- self.result = {}
-
- def test_install(self, mock_ssh):
- p = plugin.Plugin()
- mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
- input_file = Arg()
- p.install(input_file)
- expected_result = {}
- self.assertEqual(self.result, expected_result)
-
- def test_remove(self, mock_ssh):
- p = plugin.Plugin()
- mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
- input_file = Arg()
- p.remove(input_file)
- expected_result = {}
- self.assertEqual(self.result, expected_result)
-
- def test_install_setup_run(self, mock_ssh):
- p = plugin.Plugin()
- mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
- plugins = {
- "name": "sample"
- }
- deployment = {
- "ip": "10.1.0.50",
- "user": "root",
- "password": "root"
- }
- plugin_name = plugins.get("name")
- p._install_setup(plugin_name, deployment)
- self.assertIsNotNone(p.client)
-
- p._run(plugin_name)
- expected_result = {}
- self.assertEqual(self.result, expected_result)
-
- def test_remove_setup_run(self, mock_ssh):
- p = plugin.Plugin()
- mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
- plugins = {
- "name": "sample"
- }
- deployment = {
- "ip": "10.1.0.50",
- "user": "root",
- "password": "root"
- }
- plugin_name = plugins.get("name")
- p._remove_setup(plugin_name, deployment)
- self.assertIsNotNone(p.client)
-
- p._run(plugin_name)
- expected_result = {}
- self.assertEqual(self.result, expected_result)
-
-
-def main():
- unittest.main()
-
-
-if __name__ == '__main__':
- main()
+ super(PluginTestCase, self).setUp()
+ self.plugin_parser = plugin.PluginParser(mock.Mock())
+ self.plugin = plugin.Plugin()
+ self.useFixture(fixture.PluginParserFixture(PluginTestCase.FILE))
+
+ self._mock_ssh_from_node = mock.patch.object(ssh.SSH, 'from_node')
+ self.mock_ssh_from_node = self._mock_ssh_from_node.start()
+ self.mock_ssh_obj = mock.Mock()
+ self.mock_ssh_from_node.return_value = self.mock_ssh_obj
+ self.mock_ssh_obj.wait = mock.Mock()
+ self.mock_ssh_obj._put_file_shell = mock.Mock()
+
+ self.addCleanup(self._cleanup)
+
+ def _cleanup(self):
+ self._mock_ssh_from_node.stop()
+
+ def test_install(self):
+ args = mock.Mock()
+ args.input_file = [mock.Mock()]
+ with mock.patch.object(self.plugin, '_install_setup') as \
+ mock_install, \
+ mock.patch.object(self.plugin, '_run') as mock_run:
+ self.plugin.install(args)
+ mock_install.assert_called_once_with(PluginTestCase.NAME,
+ PluginTestCase.DEPLOYMENT)
+ mock_run.assert_called_once_with(PluginTestCase.NAME)
+
+ def test_remove(self):
+ args = mock.Mock()
+ args.input_file = [mock.Mock()]
+ with mock.patch.object(self.plugin, '_remove_setup') as \
+ mock_remove, \
+ mock.patch.object(self.plugin, '_run') as mock_run:
+ self.plugin.remove(args)
+ mock_remove.assert_called_once_with(PluginTestCase.NAME,
+ PluginTestCase.DEPLOYMENT)
+ mock_run.assert_called_once_with(PluginTestCase.NAME)
+
+ @mock.patch.object(pkg_resources, 'resource_filename',
+ return_value='script')
+ def test__install_setup(self, mock_resource_filename):
+ plugin_name = 'plugin_name'
+ self.plugin._install_setup(plugin_name, PluginTestCase.DEPLOYMENT)
+ mock_resource_filename.assert_called_once_with(
+ 'yardstick.resources', 'scripts/install/' + plugin_name + '.bash')
+ self.mock_ssh_from_node.assert_called_once_with(
+ PluginTestCase.DEPLOYMENT)
+ self.mock_ssh_obj.wait.assert_called_once_with(timeout=600)
+ self.mock_ssh_obj._put_file_shell.assert_called_once_with(
+ 'script', '~/{0}.sh'.format(plugin_name))
+
+ @mock.patch.object(pkg_resources, 'resource_filename',
+ return_value='script')
+ @mock.patch.object(os, 'environ', return_value='1.2.3.4')
+ def test__install_setup_with_ip_local(self, mock_os_environ,
+ mock_resource_filename):
+ plugin_name = 'plugin_name'
+ deployment = copy.deepcopy(PluginTestCase.DEPLOYMENT)
+ deployment['ip'] = 'local'
+ self.plugin._install_setup(plugin_name, deployment)
+ mock_os_environ.__getitem__.assert_called_once_with('JUMP_HOST_IP')
+ mock_resource_filename.assert_called_once_with(
+ 'yardstick.resources',
+ 'scripts/install/' + plugin_name + '.bash')
+ self.mock_ssh_from_node.assert_called_once_with(
+ deployment, overrides={'ip': os.environ["JUMP_HOST_IP"]})
+ self.mock_ssh_obj.wait.assert_called_once_with(timeout=600)
+ self.mock_ssh_obj._put_file_shell.assert_called_once_with(
+ 'script', '~/{0}.sh'.format(plugin_name))
+
+ @mock.patch.object(pkg_resources, 'resource_filename',
+ return_value='script')
+ def test__remove_setup(self, mock_resource_filename):
+ plugin_name = 'plugin_name'
+ self.plugin._remove_setup(plugin_name, PluginTestCase.DEPLOYMENT)
+ mock_resource_filename.assert_called_once_with(
+ 'yardstick.resources',
+ 'scripts/remove/' + plugin_name + '.bash')
+ self.mock_ssh_from_node.assert_called_once_with(
+ PluginTestCase.DEPLOYMENT)
+ self.mock_ssh_obj.wait.assert_called_once_with(timeout=600)
+ self.mock_ssh_obj._put_file_shell.assert_called_once_with(
+ 'script', '~/{0}.sh'.format(plugin_name))
+
+ @mock.patch.object(pkg_resources, 'resource_filename',
+ return_value='script')
+ @mock.patch.object(os, 'environ', return_value='1.2.3.4')
+ def test__remove_setup_with_ip_local(self, mock_os_environ,
+ mock_resource_filename):
+ plugin_name = 'plugin_name'
+ deployment = copy.deepcopy(PluginTestCase.DEPLOYMENT)
+ deployment['ip'] = 'local'
+ self.plugin._remove_setup(plugin_name, deployment)
+ mock_os_environ.__getitem__.assert_called_once_with('JUMP_HOST_IP')
+ mock_resource_filename.assert_called_once_with(
+ 'yardstick.resources',
+ 'scripts/remove/' + plugin_name + '.bash')
+ self.mock_ssh_from_node.assert_called_once_with(
+ deployment, overrides={'ip': os.environ["JUMP_HOST_IP"]})
+ self.mock_ssh_obj.wait.assert_called_once_with(timeout=600)
+ self.mock_ssh_obj._put_file_shell.mock_os_environ(
+ 'script', '~/{0}.sh'.format(plugin_name))
diff --git a/yardstick/tests/unit/benchmark/core/test_task.py b/yardstick/tests/unit/benchmark/core/test_task.py
index 3d9a10d88..bac035fb9 100644
--- a/yardstick/tests/unit/benchmark/core/test_task.py
+++ b/yardstick/tests/unit/benchmark/core/test_task.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
##############################################################################
# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others.
#
@@ -9,43 +7,32 @@
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-# Unittest for yardstick.benchmark.core.task
-
-from __future__ import print_function
-
-from __future__ import absolute_import
import os
-import unittest
-
-try:
- from unittest import mock
-except ImportError:
- import mock
+import mock
+import unittest
from yardstick.benchmark.core import task
from yardstick.common import constants as consts
-# pylint: disable=unused-argument
-# disable this for now because I keep forgetting mock patch arg ordering
-
-
class TaskTestCase(unittest.TestCase):
- @mock.patch('yardstick.benchmark.core.task.Context')
- def test_parse_nodes_host_target_same_context(self, mock_context):
- nodes = {
- "host": "node1.LF",
- "target": "node2.LF"
+ @mock.patch.object(task, 'Context')
+ def test_parse_nodes_with_context_same_context(self, mock_context):
+ scenario_cfg = {
+ "nodes": {
+ "host": "node1.LF",
+ "target": "node2.LF"
+ }
}
- scenario_cfg = {"nodes": nodes}
server_info = {
"ip": "10.20.0.3",
"user": "root",
"key_filename": "/root/.ssh/id_rsa"
}
mock_context.get_server.return_value = server_info
+
context_cfg = task.parse_nodes_with_context(scenario_cfg)
self.assertEqual(context_cfg["host"], server_info)
@@ -57,7 +44,7 @@ class TaskTestCase(unittest.TestCase):
t._set_dispatchers(output_config)
self.assertEqual(output_config, output_config)
- @mock.patch('yardstick.benchmark.core.task.DispatcherBase')
+ @mock.patch.object(task, 'DispatcherBase')
def test__do_output(self, mock_dispatcher):
t = task.Task()
output_config = {"DEFAULT": {"dispatcher": "file, http"}}
@@ -65,7 +52,7 @@ class TaskTestCase(unittest.TestCase):
mock.MagicMock()])
self.assertEqual(None, t._do_output(output_config, {}))
- @mock.patch('yardstick.benchmark.core.task.Context')
+ @mock.patch.object(task, 'Context')
def test_parse_networks_from_nodes(self, mock_context):
nodes = {
'node1': {
@@ -129,9 +116,9 @@ class TaskTestCase(unittest.TestCase):
self.assertEqual(mock_context.get_network.call_count, expected_get_network_calls)
self.assertDictEqual(networks, expected)
- @mock.patch('yardstick.benchmark.core.task.Context')
- @mock.patch('yardstick.benchmark.core.task.base_runner')
- def test_run(self, mock_base_runner, mock_ctx):
+ @mock.patch.object(task, 'Context')
+ @mock.patch.object(task, 'base_runner')
+ def test_run(self, mock_base_runner, *args):
scenario = {
'host': 'athena.demo',
'target': 'ares.demo',
@@ -152,8 +139,8 @@ class TaskTestCase(unittest.TestCase):
t._run([scenario], False, "yardstick.out")
self.assertTrue(runner.run.called)
- @mock.patch('yardstick.benchmark.core.task.os')
- def test_check_precondition(self, mock_os):
+ @mock.patch.object(os, 'environ')
+ def test_check_precondition(self, mock_os_environ):
cfg = {
'precondition': {
'installer_type': 'compass',
@@ -163,7 +150,7 @@ class TaskTestCase(unittest.TestCase):
}
t = task.TaskParser('/opt')
- mock_os.environ.get.side_effect = ['compass',
+ mock_os_environ.get.side_effect = ['compass',
'os-nosdn',
'huawei-pod1']
result = t._check_precondition(cfg)
@@ -172,82 +159,75 @@ class TaskTestCase(unittest.TestCase):
def test_parse_suite_no_constraint_no_args(self):
SAMPLE_SCENARIO_PATH = "no_constraint_no_args_scenario_sample.yaml"
t = task.TaskParser(self._get_file_abspath(SAMPLE_SCENARIO_PATH))
- with mock.patch('yardstick.benchmark.core.task.os.environ',
+ with mock.patch.object(os, 'environ',
new={'NODE_NAME': 'huawei-pod1', 'INSTALLER_TYPE': 'compass'}):
task_files, task_args, task_args_fnames = t.parse_suite()
- print("files=%s, args=%s, fnames=%s" % (task_files, task_args,
- task_args_fnames))
+
self.assertEqual(task_files[0], self.change_to_abspath(
'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml'))
self.assertEqual(task_files[1], self.change_to_abspath(
'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml'))
- self.assertEqual(task_args[0], None)
- self.assertEqual(task_args[1], None)
- self.assertEqual(task_args_fnames[0], None)
- self.assertEqual(task_args_fnames[1], None)
- @mock.patch('yardstick.benchmark.core.task.os.environ')
- def test_parse_suite_no_constraint_with_args(self, mock_environ):
+ self.assertIsNone(task_args[0])
+ self.assertIsNone(task_args[1])
+ self.assertIsNone(task_args_fnames[0])
+ self.assertIsNone(task_args_fnames[1])
+
+ def test_parse_suite_no_constraint_with_args(self):
SAMPLE_SCENARIO_PATH = "no_constraint_with_args_scenario_sample.yaml"
t = task.TaskParser(self._get_file_abspath(SAMPLE_SCENARIO_PATH))
- with mock.patch('yardstick.benchmark.core.task.os.environ',
+ with mock.patch.object(os, 'environ',
new={'NODE_NAME': 'huawei-pod1', 'INSTALLER_TYPE': 'compass'}):
task_files, task_args, task_args_fnames = t.parse_suite()
- print("files=%s, args=%s, fnames=%s" % (task_files, task_args,
- task_args_fnames))
+
self.assertEqual(task_files[0], self.change_to_abspath(
'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml'))
self.assertEqual(task_files[1], self.change_to_abspath(
'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml'))
- self.assertEqual(task_args[0], None)
+ self.assertIsNone(task_args[0])
self.assertEqual(task_args[1],
'{"host": "node1.LF","target": "node2.LF"}')
- self.assertEqual(task_args_fnames[0], None)
- self.assertEqual(task_args_fnames[1], None)
+ self.assertIsNone(task_args_fnames[0])
+ self.assertIsNone(task_args_fnames[1])
- @mock.patch('yardstick.benchmark.core.task.os.environ')
- def test_parse_suite_with_constraint_no_args(self, mock_environ):
+ def test_parse_suite_with_constraint_no_args(self):
SAMPLE_SCENARIO_PATH = "with_constraint_no_args_scenario_sample.yaml"
t = task.TaskParser(self._get_file_abspath(SAMPLE_SCENARIO_PATH))
- with mock.patch('yardstick.benchmark.core.task.os.environ',
+ with mock.patch.object(os, 'environ',
new={'NODE_NAME': 'huawei-pod1', 'INSTALLER_TYPE': 'compass'}):
task_files, task_args, task_args_fnames = t.parse_suite()
- print("files=%s, args=%s, fnames=%s" % (task_files, task_args,
- task_args_fnames))
self.assertEqual(task_files[0], self.change_to_abspath(
'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml'))
self.assertEqual(task_files[1], self.change_to_abspath(
'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml'))
- self.assertEqual(task_args[0], None)
- self.assertEqual(task_args[1], None)
- self.assertEqual(task_args_fnames[0], None)
- self.assertEqual(task_args_fnames[1], None)
+ self.assertIsNone(task_args[0])
+ self.assertIsNone(task_args[1])
+ self.assertIsNone(task_args_fnames[0])
+ self.assertIsNone(task_args_fnames[1])
- @mock.patch('yardstick.benchmark.core.task.os.environ')
- def test_parse_suite_with_constraint_with_args(self, mock_environ):
+ def test_parse_suite_with_constraint_with_args(self):
SAMPLE_SCENARIO_PATH = "with_constraint_with_args_scenario_sample.yaml"
t = task.TaskParser(self._get_file_abspath(SAMPLE_SCENARIO_PATH))
- with mock.patch('yardstick.benchmark.core.task.os.environ',
+ with mock.patch('os.environ',
new={'NODE_NAME': 'huawei-pod1', 'INSTALLER_TYPE': 'compass'}):
task_files, task_args, task_args_fnames = t.parse_suite()
- print("files=%s, args=%s, fnames=%s" % (task_files, task_args,
- task_args_fnames))
+
self.assertEqual(task_files[0], self.change_to_abspath(
'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml'))
self.assertEqual(task_files[1], self.change_to_abspath(
'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml'))
- self.assertEqual(task_args[0], None)
+ self.assertIsNone(task_args[0])
self.assertEqual(task_args[1],
'{"host": "node1.LF","target": "node2.LF"}')
- self.assertEqual(task_args_fnames[0], None)
- self.assertEqual(task_args_fnames[1], None)
+ self.assertIsNone(task_args_fnames[0])
+ self.assertIsNone(task_args_fnames[1])
def test_parse_options(self):
options = {
'openstack': {
'EXTERNAL_NETWORK': '$network'
},
- 'ndoes': ['node1', '$node'],
+ 'nodes': ['node1', '$node'],
'host': '$host'
}
@@ -258,48 +238,50 @@ class TaskTestCase(unittest.TestCase):
'host': 'server.yardstick'
}
- idle_result = {
+ expected_result = {
'openstack': {
'EXTERNAL_NETWORK': 'ext-net'
},
- 'ndoes': ['node1', 'node2'],
+ 'nodes': ['node1', 'node2'],
'host': 'server.yardstick'
}
actual_result = t._parse_options(options)
- self.assertEqual(idle_result, actual_result)
+ self.assertEqual(expected_result, actual_result)
+
def test_change_server_name_host_str(self):
scenario = {'host': 'demo'}
suffix = '-8'
task.change_server_name(scenario, suffix)
- self.assertTrue(scenario['host'], 'demo-8')
+ self.assertEqual('demo-8', scenario['host'])
def test_change_server_name_host_dict(self):
scenario = {'host': {'name': 'demo'}}
suffix = '-8'
task.change_server_name(scenario, suffix)
- self.assertTrue(scenario['host']['name'], 'demo-8')
+ self.assertEqual('demo-8', scenario['host']['name'])
def test_change_server_name_target_str(self):
scenario = {'target': 'demo'}
suffix = '-8'
task.change_server_name(scenario, suffix)
- self.assertTrue(scenario['target'], 'demo-8')
+ self.assertEqual('demo-8', scenario['target'])
def test_change_server_name_target_dict(self):
scenario = {'target': {'name': 'demo'}}
suffix = '-8'
task.change_server_name(scenario, suffix)
- self.assertTrue(scenario['target']['name'], 'demo-8')
+ self.assertEqual('demo-8', scenario['target']['name'])
- @mock.patch('yardstick.benchmark.core.task.utils')
- @mock.patch('yardstick.benchmark.core.task.logging')
- def test_set_log(self, mock_logging, mock_utils):
+ @mock.patch('six.moves.builtins.open', side_effect=mock.mock_open())
+ @mock.patch.object(task, 'utils')
+ @mock.patch('logging.root')
+ def test_set_log(self, mock_logging_root, *args):
task_obj = task.Task()
task_obj.task_id = 'task_id'
task_obj._set_log()
- self.assertTrue(mock_logging.root.addHandler.called)
+ mock_logging_root.addHandler.assert_called()
def _get_file_abspath(self, filename):
curr_path = os.path.dirname(os.path.abspath(__file__))
diff --git a/yardstick/tests/unit/benchmark/scenarios/lib/test_delete_network.py b/yardstick/tests/unit/benchmark/scenarios/lib/test_delete_network.py
index 5f11713fa..aef99ee94 100644
--- a/yardstick/tests/unit/benchmark/scenarios/lib/test_delete_network.py
+++ b/yardstick/tests/unit/benchmark/scenarios/lib/test_delete_network.py
@@ -6,30 +6,44 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
+
+from oslo_utils import uuidutils
import unittest
import mock
-from yardstick.benchmark.scenarios.lib.delete_network import DeleteNetwork
+import yardstick.common.openstack_utils as op_utils
+from yardstick.benchmark.scenarios.lib import delete_network
class DeleteNetworkTestCase(unittest.TestCase):
- @mock.patch('yardstick.common.openstack_utils.get_neutron_client')
- @mock.patch('yardstick.common.openstack_utils.delete_neutron_net')
- def test_delete_network(self, mock_get_neutron_client, mock_delete_neutron_net):
- options = {
- 'network_id': '123-123-123'
- }
- args = {"options": options}
- obj = DeleteNetwork(args, {})
- obj.run({})
- self.assertTrue(mock_get_neutron_client.called)
- self.assertTrue(mock_delete_neutron_net.called)
-
-
-def main():
- unittest.main()
-
-
-if __name__ == '__main__':
- main()
+ def setUp(self):
+ self._mock_delete_neutron_net = mock.patch.object(
+ op_utils, 'delete_neutron_net')
+ self.mock_delete_neutron_net = self._mock_delete_neutron_net.start()
+ self._mock_get_shade_client = mock.patch.object(
+ op_utils, 'get_shade_client')
+ self.mock_get_shade_client = self._mock_get_shade_client.start()
+ self._mock_log = mock.patch.object(delete_network, 'LOG')
+ self.mock_log = self._mock_log.start()
+ _uuid = uuidutils.generate_uuid()
+ self.args = {'options': {'network_id': _uuid}}
+ self._del_obj = delete_network.DeleteNetwork(self.args, mock.ANY)
+
+ self.addCleanup(self._stop_mock)
+
+ def _stop_mock(self):
+ self._mock_delete_neutron_net.stop()
+ self._mock_get_shade_client.stop()
+ self._mock_log.stop()
+
+ def test_run(self):
+ self.mock_delete_neutron_net.return_value = True
+ self.assertTrue(self._del_obj.run({}))
+ self.mock_log.info.assert_called_once_with(
+ "Delete network successful!")
+
+ def test_run_fail(self):
+ self.mock_delete_neutron_net.return_value = False
+ self.assertFalse(self._del_obj.run({}))
+ self.mock_log.error.assert_called_once_with("Delete network failed!")
diff --git a/yardstick/tests/unit/common/test_openstack_utils.py b/yardstick/tests/unit/common/test_openstack_utils.py
index b685e63be..8a2f5f95b 100644
--- a/yardstick/tests/unit/common/test_openstack_utils.py
+++ b/yardstick/tests/unit/common/test_openstack_utils.py
@@ -11,6 +11,7 @@ from oslo_utils import uuidutils
import unittest
import mock
+from shade import exc
from yardstick.common import openstack_utils
@@ -54,3 +55,31 @@ class GetNetworkIdTestCase(unittest.TestCase):
output = openstack_utils.get_network_id(mock_shade_client,
'network_name')
self.assertEqual(None, output)
+
+
+class DeleteNeutronNetTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.mock_shade_client = mock.Mock()
+ self.mock_shade_client.delete_network = mock.Mock()
+
+ def test_delete_neutron_net(self):
+ self.mock_shade_client.delete_network.return_value = True
+ output = openstack_utils.delete_neutron_net(self.mock_shade_client,
+ 'network_id')
+ self.assertTrue(output)
+
+ def test_delete_neutron_net_fail(self):
+ self.mock_shade_client.delete_network.return_value = False
+ output = openstack_utils.delete_neutron_net(self.mock_shade_client,
+ 'network_id')
+ self.assertFalse(output)
+
+ @mock.patch.object(openstack_utils, 'log')
+ def test_delete_neutron_net_exception(self, mock_logger):
+ self.mock_shade_client.delete_network.side_effect = (
+ exc.OpenStackCloudException('error message'))
+ output = openstack_utils.delete_neutron_net(self.mock_shade_client,
+ 'network_id')
+ self.assertFalse(output)
+ mock_logger.error.assert_called_once()
diff --git a/yardstick/tests/unit/orchestrator/test_heat.py b/yardstick/tests/unit/orchestrator/test_heat.py
index f53c9b78c..e0a353812 100644
--- a/yardstick/tests/unit/orchestrator/test_heat.py
+++ b/yardstick/tests/unit/orchestrator/test_heat.py
@@ -89,6 +89,18 @@ class HeatStackTestCase(unittest.TestCase):
self.assertFalse(heat._DEPLOYED_STACKS)
self.mock_stack_delete.assert_called_once_with(id, wait=True)
+ def test_delete_bug_in_shade(self):
+ id = uuidutils.generate_uuid()
+ self.heatstack._stack = FakeStack(
+ outputs=mock.Mock(), status=mock.Mock(), id=id)
+ heat._DEPLOYED_STACKS[id] = self.heatstack._stack
+ self.mock_stack_delete.side_effect = TypeError()
+
+ ret = self.heatstack.delete(wait=True)
+ self.assertTrue(ret)
+ self.assertFalse(heat._DEPLOYED_STACKS)
+ self.mock_stack_delete.assert_called_once_with(id, wait=True)
+
class HeatTemplateTestCase(unittest.TestCase):