diff options
23 files changed, 387 insertions, 264 deletions
diff --git a/ansible/build_yardstick_image.yml b/ansible/build_yardstick_image.yml index c926af208..072c12c66 100644 --- a/ansible/build_yardstick_image.yml +++ b/ansible/build_yardstick_image.yml @@ -76,18 +76,17 @@ - name: Debug dump loop devices command: losetup -a - register: losetup_output ignore_errors: true - - debug: - var: losetup_output - verbosity: 2 - - name: delete loop devices for image file # use this because kpartx -dv will fail if raw_imgfile was delete # but in theory we could have deleted file still attached to loopback device? # use grep because of // and awk - shell: losetup -O NAME,BACK-FILE | grep "{{ raw_imgfile_basename }}" | awk '{ print $1 }' | xargs -l1 losetup -d + shell: losetup -O NAME,BACK-FILE | grep "{{ raw_imgfile_basename }}" | awk '{ print $1 }' | xargs -l1 losetup -v -d + ignore_errors: true + + - name: Debug dump loop devices again + command: losetup -a ignore_errors: true - name: delete {{ raw_imgfile }} diff --git a/ansible/roles/docker/tasks/Debian.yml b/ansible/roles/docker/tasks/Debian.yml index cf4128774..7f998de45 100644 --- a/ansible/roles/docker/tasks/Debian.yml +++ b/ansible/roles/docker/tasks/Debian.yml @@ -12,15 +12,5 @@ # See the License for the specific language governing permissions and # limitations under the License. --- - - name: add Ubuntu docker repo - apt_repository: repo='deb [trusted=yes] {{ ubuntu_docker_url }} ubuntu-{{ ansible_distribution_release }} main' state=present - - - name: ensure correct docker version - action: "{{ ansible_pkg_mgr }} name={{ item }} state=present force=yes" - with_items: "{{ docker_packages[ansible_os_family] }}" - - - name: remove Ubuntu docker repo - apt_repository: - repo: 'deb [trusted=yes] {{ ubuntu_docker_url }} ubuntu-{{ ansible_distribution_release }} main' - state: absent - update_cache: no + - name: Install docker.io + action: "{{ ansible_pkg_mgr }} name=docker.io state=present force=yes" diff --git a/ansible/roles/docker/vars/main.yml b/ansible/roles/docker/vars/main.yml index 8b5077490..a735d523d 100644 --- a/ansible/roles/docker/vars/main.yml +++ b/ansible/roles/docker/vars/main.yml @@ -16,5 +16,3 @@ docker_project_url: https://yum.dockerproject.org docker_packages: "RedHat": - docker-engine-1.13.1 - "Debian": - - docker-engine=1.13.1* diff --git a/ansible/roles/install_dpdk/vars/main.yml b/ansible/roles/install_dpdk/vars/main.yml index 5dec63776..957f47e99 100644 --- a/ansible/roles/install_dpdk/vars/main.yml +++ b/ansible/roles/install_dpdk/vars/main.yml @@ -1,5 +1,8 @@ --- -dpdk_make_arch: x86_64-native-linuxapp-gcc +dpdk_make_archs: + "amd64": "x86_64-native-linuxapp-gcc" + "arm64": "arm64-native-linuxapp-gcc" +dpdk_make_arch: "{{ dpdk_make_archs[YARD_IMG_ARCH] }}" dpdk_module_dir: "/lib/modules/{{ dpdk_kernel }}/extra" hugetable_mount: /mnt/huge dpdk_devbind_tools: "{{ dpdk_path }}/tools/dpdk-devbind.py" diff --git a/ansible/roles/install_dpdk_shared/vars/main.yml b/ansible/roles/install_dpdk_shared/vars/main.yml index eadf35a03..b663cedd2 100644 --- a/ansible/roles/install_dpdk_shared/vars/main.yml +++ b/ansible/roles/install_dpdk_shared/vars/main.yml @@ -1,5 +1,8 @@ --- -dpdk_make_arch: x86_64-native-linuxapp-gcc +dpdk_make_archs: + "amd64": "x86_64-native-linuxapp-gcc" + "arm64": "arm64-native-linuxapp-gcc" +dpdk_make_arch: "{{ dpdk_make_archs[YARD_IMG_ARCH] }}" dpdk_module_dir: "/lib/modules/{{ dpdk_kernel }}/extra" hugetable_mount: /mnt/huge dpdk_pmd_path: /usr/lib/dpdk-pmd/ diff --git a/docs/testing/user/userguide/13-nsb-installation.rst b/docs/testing/user/userguide/13-nsb-installation.rst index 00f8cfd97..1f6c79b0b 100644 --- a/docs/testing/user/userguide/13-nsb-installation.rst +++ b/docs/testing/user/userguide/13-nsb-installation.rst @@ -135,6 +135,15 @@ Ansible: ansible_user=root ansible_pass=root +.. note:: + + SSH access without password needs to be configured for all your nodes defined in + ``yardstick-install-inventory.ini`` file. + If you want to use password authentication you need to install sshpass + + .. code-block:: console + + sudo -EH apt-get install sshpass To execute an installation for a Bare-Metal or a Standalone context: diff --git a/tests/ci/load_images.sh b/tests/ci/load_images.sh index dee675981..1e1591ce3 100755 --- a/tests/ci/load_images.sh +++ b/tests/ci/load_images.sh @@ -43,6 +43,12 @@ if [ "${YARD_IMG_ARCH}" == "arm64" ]; then fi fi +cleanup_loopbacks() { + # try again to cleanup loopbacks in case of error + losetup -a + losetup -O NAME,BACK-FILE | awk '/yardstick/ { print $1 }' | xargs -l1 losetup -v -d || true +} + build_yardstick_image() { echo @@ -56,6 +62,7 @@ build_yardstick_image() # Build the image. Retry once if the build fails $cmd || $cmd + cleanup_loopbacks if [ ! -f "${RAW_IMAGE}" ]; then echo "Failed building RAW image" exit 1 @@ -70,16 +77,20 @@ build_yardstick_image() -e YARD_IMG_ARCH=${YARD_IMG_ARCH} \ -vvv -i inventory.ini build_yardstick_image.yml + cleanup_loopbacks if [ ! -f "${QCOW_IMAGE}" ]; then echo "Failed building QCOW image" exit 1 fi fi - if [[ $DEPLOY_SCENARIO == *[_-]ovs[_-]* ]]; then + # DPDK compile is not enabled for arm64 yet so disable for now + # JIRA: YARSTICK-1124 + if [[ ! -f "${QCOW_NSB_IMAGE}" && ${DEPLOY_SCENARIO} == *[_-]ovs_dpdk[_-]* && "${YARD_IMG_ARCH}" != "arm64" ]]; then ansible-playbook \ -e img_property="nsb" \ -e YARD_IMG_ARCH=${YARD_IMG_ARCH} \ -vvv -i inventory.ini build_yardstick_image.yml + cleanup_loopbacks if [ ! -f "${QCOW_NSB_IMAGE}" ]; then echo "Failed building QCOW NSB image" exit 1 @@ -122,7 +133,9 @@ load_yardstick_image() ${EXTRA_PARAMS} \ --file ${QCOW_IMAGE} \ yardstick-image) - if [[ $DEPLOY_SCENARIO == *[_-]ovs[_-]* ]]; then + # DPDK compile is not enabled for arm64 yet so disable NSB images for now + # JIRA: YARSTICK-1124 + if [[ $DEPLOY_SCENARIO == *[_-]ovs_dpdk[_-]* && "${YARD_IMG_ARCH}" != "arm64" ]]; then nsb_output=$(eval openstack ${SECURE} image create \ --public \ --disk-format qcow2 \ diff --git a/tests/opnfv/test_suites/opnfv_os-nosdn-fdio-noha_daily.yaml b/tests/opnfv/test_suites/opnfv_os-nosdn-fdio-noha_daily.yaml index ec0fd224c..bd91a75c7 100644 --- a/tests/opnfv/test_suites/opnfv_os-nosdn-fdio-noha_daily.yaml +++ b/tests/opnfv/test_suites/opnfv_os-nosdn-fdio-noha_daily.yaml @@ -21,18 +21,12 @@ test_cases: - file_name: opnfv_yardstick_tc006.yaml - - file_name: opnfv_yardstick_tc007.yaml -- file_name: opnfv_yardstick_tc008.yaml - file_name: opnfv_yardstick_tc009.yaml - file_name: opnfv_yardstick_tc011.yaml - - file_name: opnfv_yardstick_tc020.yaml -- - file_name: opnfv_yardstick_tc021.yaml -- file_name: opnfv_yardstick_tc037.yaml - file_name: opnfv_yardstick_tc038.yaml diff --git a/tests/opnfv/test_suites/opnfv_os-odl_l2-fdio-noha_daily.yaml b/tests/opnfv/test_suites/opnfv_os-odl_l2-fdio-noha_daily.yaml index 7172979c7..722d885b6 100644 --- a/tests/opnfv/test_suites/opnfv_os-odl_l2-fdio-noha_daily.yaml +++ b/tests/opnfv/test_suites/opnfv_os-odl_l2-fdio-noha_daily.yaml @@ -21,18 +21,12 @@ test_cases: - file_name: opnfv_yardstick_tc006.yaml - - file_name: opnfv_yardstick_tc007.yaml -- file_name: opnfv_yardstick_tc008.yaml - file_name: opnfv_yardstick_tc009.yaml - file_name: opnfv_yardstick_tc011.yaml - - file_name: opnfv_yardstick_tc020.yaml -- - file_name: opnfv_yardstick_tc021.yaml -- file_name: opnfv_yardstick_tc037.yaml - file_name: opnfv_yardstick_tc038.yaml diff --git a/tests/opnfv/test_suites/opnfv_vTC_daily.yaml b/tests/opnfv/test_suites/opnfv_vTC_daily.yaml deleted file mode 100644 index f7efe51fb..000000000 --- a/tests/opnfv/test_suites/opnfv_vTC_daily.yaml +++ /dev/null @@ -1,24 +0,0 @@ -############################################################################## -# Copyright (c) 2017 Ericsson AB 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 -############################################################################## ---- -# ERICSSON POD1 VTC daily task suite - -schema: "yardstick:suite:0.1" - -name: "opnfv_vTC_daily" -test_cases_dir: "tests/opnfv/test_cases/" -test_cases: -- - file_name: opnfv_yardstick_tc006.yaml -- - file_name: opnfv_yardstick_tc007.yaml -- - file_name: opnfv_yardstick_tc020.yaml -- - file_name: opnfv_yardstick_tc021.yaml diff --git a/tests/opnfv/test_suites/opnfv_vTC_weekly.yaml b/tests/opnfv/test_suites/opnfv_vTC_weekly.yaml deleted file mode 100644 index 04f607ed4..000000000 --- a/tests/opnfv/test_suites/opnfv_vTC_weekly.yaml +++ /dev/null @@ -1,24 +0,0 @@ -############################################################################## -# Copyright (c) 2017 Ericsson AB 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 -############################################################################## ---- -# ERICSSON POD1 VTC weekly task suite - -schema: "yardstick:suite:0.1" - -name: "opnfv_vTC_weekly" -test_cases_dir: "tests/opnfv/test_cases/" -test_cases: -- - file_name: opnfv_yardstick_tc006.yaml -- - file_name: opnfv_yardstick_tc007.yaml -- - file_name: opnfv_yardstick_tc020.yaml -- - file_name: opnfv_yardstick_tc021.yaml diff --git a/yardstick/benchmark/contexts/standalone/model.py b/yardstick/benchmark/contexts/standalone/model.py index f18d090d8..4d43f2611 100644 --- a/yardstick/benchmark/contexts/standalone/model.py +++ b/yardstick/benchmark/contexts/standalone/model.py @@ -232,14 +232,40 @@ class Libvirt(object): return ET.tostring(root) @staticmethod - def create_snapshot_qemu(connection, index, vm_image): - # build snapshot image - image = "/var/lib/libvirt/images/%s.qcow2" % index - connection.execute("rm %s" % image) - qemu_template = "qemu-img create -f qcow2 -o backing_file=%s %s" - connection.execute(qemu_template % (vm_image, image)) - - return image + def create_snapshot_qemu(connection, index, base_image): + """Create the snapshot image for a VM using a base image + + :param connection: SSH connection to the remote host + :param index: index of the VM to be spawn + :param base_image: path of the VM base image in the remote host + :return: snapshot image path + """ + vm_image = '/var/lib/libvirt/images/%s.qcow2' % index + connection.execute('rm -- "%s"' % vm_image) + status, _, _ = connection.execute('test -r %s' % base_image) + if status: + if not os.access(base_image, os.R_OK): + raise exceptions.LibvirtQemuImageBaseImageNotPresent( + vm_image=vm_image, base_image=base_image) + # NOTE(ralonsoh): done in two steps to avoid root permission + # issues. + LOG.info('Copy %s from execution host to remote host', base_image) + file_name = os.path.basename(os.path.normpath(base_image)) + connection.put_file(base_image, '/tmp/%s' % file_name) + status, _, error = connection.execute( + 'mv -- "/tmp/%s" "%s"' % (file_name, base_image)) + if status: + raise exceptions.LibvirtQemuImageCreateError( + vm_image=vm_image, base_image=base_image, error=error) + + LOG.info('Convert image %s to %s', base_image, vm_image) + qemu_cmd = ('qemu-img create -f qcow2 -o backing_file=%s %s' % + (base_image, vm_image)) + status, _, error = connection.execute(qemu_cmd) + if status: + raise exceptions.LibvirtQemuImageCreateError( + vm_image=vm_image, base_image=base_image, error=error) + return vm_image @classmethod def build_vm_xml(cls, connection, flavor, vm_name, index): diff --git a/yardstick/benchmark/scenarios/lib/create_sec_group.py b/yardstick/benchmark/scenarios/lib/create_sec_group.py index 3d1aec9e8..1d2e36488 100644 --- a/yardstick/benchmark/scenarios/lib/create_sec_group.py +++ b/yardstick/benchmark/scenarios/lib/create_sec_group.py @@ -7,13 +7,11 @@ # 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 +from yardstick.common import openstack_utils +from yardstick.common import exceptions LOG = logging.getLogger(__name__) @@ -26,11 +24,12 @@ class CreateSecgroup(base.Scenario): def __init__(self, scenario_cfg, context_cfg): self.scenario_cfg = scenario_cfg self.context_cfg = context_cfg - self.options = self.scenario_cfg['options'] + self.options = self.scenario_cfg["options"] - self.sg_name = self.options.get("sg_name", "yardstick_sec_group") - self.description = self.options.get("description", None) - self.neutron_client = op_utils.get_neutron_client() + self.sg_name = self.options["sg_name"] + self.description = self.options.get("description", "") + self.project_id = self.options.get("project_id") + self.shade_client = openstack_utils.get_shade_client() self.setup_done = False @@ -45,21 +44,16 @@ class CreateSecgroup(base.Scenario): if not self.setup_done: self.setup() - sg_id = op_utils.create_security_group_full(self.neutron_client, - sg_name=self.sg_name, - sg_description=self.description) - - if sg_id: - result.update({"sg_create": 1}) - LOG.info("Create security group successful!") - else: + sg_id = openstack_utils.create_security_group_full( + self.shade_client, self.sg_name, sg_description=self.description, + project_id=self.project_id) + if not sg_id: result.update({"sg_create": 0}) LOG.error("Create security group failed!") + raise exceptions.ScenarioCreateSecurityGroupError - try: - keys = self.scenario_cfg.get('output', '').split() - except KeyError: - pass - else: - values = [sg_id] - return self._push_to_outputs(keys, values) + result.update({"sg_create": 1}) + LOG.info("Create security group successful!") + keys = self.scenario_cfg.get("output", '').split() + values = [sg_id] + return self._push_to_outputs(keys, values) diff --git a/yardstick/benchmark/scenarios/lib/delete_network.py b/yardstick/benchmark/scenarios/lib/delete_network.py index 2e8b595f9..8874e8b1e 100644 --- a/yardstick/benchmark/scenarios/lib/delete_network.py +++ b/yardstick/benchmark/scenarios/lib/delete_network.py @@ -10,7 +10,8 @@ import logging from yardstick.benchmark.scenarios import base -import yardstick.common.openstack_utils as op_utils +from yardstick.common import openstack_utils +from yardstick.common import exceptions LOG = logging.getLogger(__name__) @@ -24,11 +25,11 @@ class DeleteNetwork(base.Scenario): def __init__(self, scenario_cfg, context_cfg): self.scenario_cfg = scenario_cfg self.context_cfg = context_cfg - self.options = self.scenario_cfg['options'] + self.options = self.scenario_cfg["options"] - self.network_id = self.options.get("network_id", None) + self.network_name_or_id = self.options["network_name_or_id"] - self.shade_client = op_utils.get_shade_client() + self.shade_client = openstack_utils.get_shade_client() self.setup_done = False @@ -43,12 +44,13 @@ class DeleteNetwork(base.Scenario): if not self.setup_done: self.setup() - status = op_utils.delete_neutron_net(self.shade_client, - network_id=self.network_id) - if status: - result.update({"delete_network": 1}) - LOG.info("Delete network successful!") - else: + status = openstack_utils.delete_neutron_net(self.shade_client, + self.network_name_or_id) + + if not status: result.update({"delete_network": 0}) LOG.error("Delete network failed!") - return status + raise exceptions.ScenarioDeleteNetworkError + + result.update({"delete_network": 1}) + LOG.info("Delete network successful!") diff --git a/yardstick/common/exceptions.py b/yardstick/common/exceptions.py index 65e444071..ec21c335b 100644 --- a/yardstick/common/exceptions.py +++ b/yardstick/common/exceptions.py @@ -117,6 +117,17 @@ class LibvirtCreateError(YardstickException): message = 'Error creating the virtual machine. Error: %(error)s.' +class LibvirtQemuImageBaseImageNotPresent(YardstickException): + message = ('Error creating the qemu image for %(vm_image)s. Base image: ' + '%(base_image)s. Base image not present in execution host or ' + 'remote host.') + + +class LibvirtQemuImageCreateError(YardstickException): + message = ('Error creating the qemu image for %(vm_image)s. Base image: ' + '%(base_image)s. Error: %(error)s.') + + class ScenarioConfigContextNameNotFound(YardstickException): message = 'Context name "%(context_name)s" not found' @@ -171,3 +182,11 @@ class ScenarioCreateFloatingIPError(YardstickException): class ScenarioDeleteFloatingIPError(YardstickException): message = 'Delete Neutron Floating IP Scenario failed' + + +class ScenarioCreateSecurityGroupError(YardstickException): + message = 'Create Neutron Security Group Scenario failed' + + +class ScenarioDeleteNetworkError(YardstickException): + message = 'Delete Neutron Network Scenario failed' diff --git a/yardstick/common/messaging/consumer.py b/yardstick/common/messaging/consumer.py index a0feeb300..24ec6f184 100644 --- a/yardstick/common/messaging/consumer.py +++ b/yardstick/common/messaging/consumer.py @@ -29,9 +29,9 @@ LOG = logging.getLogger(__name__) class NotificationHandler(object): """Abstract class to define a endpoint object for a MessagingConsumer""" - def __init__(self, id, ctx_pid, queue): - self._id = id - self._ctx_pid = ctx_pid + def __init__(self, _id, ctx_pids, queue): + self._id = _id + self._ctx_pids = ctx_pids self._queue = queue @@ -43,12 +43,12 @@ class MessagingConsumer(object): the messages published by a `MessagingNotifier`. """ - def __init__(self, topic, pid, endpoints, fanout=True): + def __init__(self, topic, pids, endpoints, fanout=True): """Init function. :param topic: (string) MQ exchange topic - :param pid: (int) PID of the process implementing the MQ Notifier which - will be in the message context + :param pids: (list of int) list of PIDs of the processes implementing + the MQ Notifier which will be in the message context :param endpoints: (list of class) list of classes implementing the methods (see `MessagingNotifier.send_message) used by the Notifier @@ -58,7 +58,7 @@ class MessagingConsumer(object): :returns: `MessagingConsumer` class object """ - self._pid = pid + self._pids = pids self._endpoints = endpoints self._transport = oslo_messaging.get_rpc_transport( cfg.CONF, url=messaging.TRANSPORT_URL) diff --git a/yardstick/common/openstack_utils.py b/yardstick/common/openstack_utils.py index 5208a2749..0d6afc54a 100644 --- a/yardstick/common/openstack_utils.py +++ b/yardstick/common/openstack_utils.py @@ -625,39 +625,6 @@ def delete_floating_ip(shade_client, floating_ip_id, retry=1): return False -def get_security_groups(neutron_client): # pragma: no cover - try: - security_groups = neutron_client.list_security_groups()[ - 'security_groups'] - return security_groups - except Exception: # pylint: disable=broad-except - log.error("Error [get_security_groups(neutron_client)]") - return None - - -def get_security_group_id(neutron_client, sg_name): # pragma: no cover - security_groups = get_security_groups(neutron_client) - id = '' - for sg in security_groups: - if sg['name'] == sg_name: - id = sg['id'] - break - return id - - -def create_security_group(neutron_client, sg_name, - sg_description): # pragma: no cover - json_body = {'security_group': {'name': sg_name, - 'description': sg_description}} - try: - secgroup = neutron_client.create_security_group(json_body) - return secgroup['security_group'] - except Exception: # pylint: disable=broad-except - log.error("Error [create_security_group(neutron_client, '%s', " - "'%s')]", sg_name, sg_description) - return None - - def create_security_group_rule(shade_client, secgroup_name_or_id, port_range_min=None, port_range_max=None, protocol=None, remote_ip_prefix=None, @@ -712,42 +679,52 @@ def create_security_group_rule(shade_client, secgroup_name_or_id, return False -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) - else: - log.info("Creating security group '%s'...", sg_name) - SECGROUP = create_security_group(neutron_client, - sg_name, - sg_description) - if not SECGROUP: - log.error("Failed to create the security group...") - return None - - sg_id = SECGROUP['id'] - - log.debug("Security group '%s' with ID=%s created successfully.", - SECGROUP['name'], sg_id) +def create_security_group_full(shade_client, sg_name, + sg_description, project_id=None): + security_group = shade_client.get_security_group(sg_name) - log.debug("Adding ICMP rules in security group '%s'...", sg_name) - if not create_security_group_rule(neutron_client, sg_id, - 'ingress', 'icmp'): - log.error("Failed to create the security group rule...") - return None - - log.debug("Adding SSH rules in security group '%s'...", sg_name) - if not create_security_group_rule( - neutron_client, sg_id, 'ingress', 'tcp', '22', '22'): - log.error("Failed to create the security group rule...") - return None - - if not create_security_group_rule( - neutron_client, sg_id, 'egress', 'tcp', '22', '22'): - log.error("Failed to create the security group rule...") - return None - return sg_id + if security_group: + log.info("Using existing security group '%s'...", sg_name) + return security_group['id'] + + log.info("Creating security group '%s'...", sg_name) + try: + security_group = shade_client.create_security_group( + sg_name, sg_description, project_id=project_id) + except (exc.OpenStackCloudException, + exc.OpenStackCloudUnavailableFeature) as op_exc: + log.error("Error [create_security_group(shade_client, %s, %s)]. " + "Exception message: %s", sg_name, sg_description, + op_exc.orig_message) + return + + log.debug("Security group '%s' with ID=%s created successfully.", + security_group['name'], security_group['id']) + + log.debug("Adding ICMP rules in security group '%s'...", sg_name) + if not create_security_group_rule(shade_client, security_group['id'], + direction='ingress', protocol='icmp'): + log.error("Failed to create the security group rule...") + shade_client.delete_security_group(sg_name) + return + + log.debug("Adding SSH rules in security group '%s'...", sg_name) + if not create_security_group_rule(shade_client, security_group['id'], + direction='ingress', protocol='tcp', + port_range_min='22', + port_range_max='22'): + log.error("Failed to create the security group rule...") + shade_client.delete_security_group(sg_name) + return + + if not create_security_group_rule(shade_client, security_group['id'], + direction='egress', protocol='tcp', + port_range_min='22', + port_range_max='22'): + log.error("Failed to create the security group rule...") + shade_client.delete_security_group(sg_name) + return + return security_group['id'] # ********************************************* diff --git a/yardstick/tests/functional/common/messaging/test_messaging.py b/yardstick/tests/functional/common/messaging/test_messaging.py index 96deeb35b..99874343b 100644 --- a/yardstick/tests/functional/common/messaging/test_messaging.py +++ b/yardstick/tests/functional/common/messaging/test_messaging.py @@ -13,7 +13,6 @@ # limitations under the License. import multiprocessing -import os import time from yardstick.common.messaging import consumer @@ -33,24 +32,25 @@ class DummyPayload(payloads.Payload): class DummyEndpoint(consumer.NotificationHandler): def info(self, ctxt, **kwargs): - if ctxt['pid'] == self._ctx_pid: - self._queue.put('ID {}, data: {}'.format(self._id, kwargs['data'])) + if ctxt['pid'] in self._ctx_pids: + self._queue.put('ID {}, data: {}, pid: {}'.format( + self._id, kwargs['data'], ctxt['pid'])) class DummyConsumer(consumer.MessagingConsumer): - def __init__(self, id, ctx_pid, queue): - self._id = id - endpoints = [DummyEndpoint(id, ctx_pid, queue)] - super(DummyConsumer, self).__init__(TOPIC, ctx_pid, endpoints) + def __init__(self, _id, ctx_pids, queue): + self._id = _id + endpoints = [DummyEndpoint(_id, ctx_pids, queue)] + super(DummyConsumer, self).__init__(TOPIC, ctx_pids, endpoints) class DummyProducer(producer.MessagingProducer): pass -def _run_consumer(id, ctx_pid, queue): - _consumer = DummyConsumer(id, ctx_pid, queue) +def _run_consumer(_id, ctx_pids, queue): + _consumer = DummyConsumer(_id, ctx_pids, queue) _consumer.start_rpc_server() _consumer.wait() @@ -65,30 +65,35 @@ class MessagingTestCase(base.BaseFunctionalTestCase): def test_run_five_consumers(self): output_queue = multiprocessing.Queue() num_consumers = 10 - ctx_id = os.getpid() - producer = DummyProducer(TOPIC, pid=ctx_id) + ctx_1 = 100001 + ctx_2 = 100002 + producers = [DummyProducer(TOPIC, pid=ctx_1), + DummyProducer(TOPIC, pid=ctx_2)] processes = [] for i in range(num_consumers): processes.append(multiprocessing.Process( name='consumer_{}'.format(i), target=_run_consumer, - args=(i, ctx_id, output_queue))) + args=(i, [ctx_1, ctx_2], output_queue))) processes[i].start() self.addCleanup(self._terminate_consumers, num_consumers, processes) time.sleep(2) # Let consumers to create the listeners - producer.send_message(METHOD_INFO, DummyPayload(version=1, - data='message 0')) - producer.send_message(METHOD_INFO, DummyPayload(version=1, - data='message 1')) - time.sleep(2) # Let consumers attend the calls + for producer in producers: + for message in ['message 0', 'message 1']: + producer.send_message(METHOD_INFO, + DummyPayload(version=1, data=message)) + time.sleep(2) # Let consumers attend the calls output = [] while not output_queue.empty(): output.append(output_queue.get(True, 1)) - self.assertEqual(num_consumers * 2, len(output)) + self.assertEqual(num_consumers * 4, len(output)) + msg_template = 'ID {}, data: {}, pid: {}' for i in range(num_consumers): - self.assertIn('ID {}, data: {}'.format(1, 'message 0'), output) - self.assertIn('ID {}, data: {}'.format(1, 'message 1'), output) + for ctx in [ctx_1, ctx_2]: + for message in ['message 0', 'message 1']: + msg = msg_template.format(i, message, ctx) + self.assertIn(msg, output) diff --git a/yardstick/tests/unit/benchmark/contexts/standalone/test_model.py b/yardstick/tests/unit/benchmark/contexts/standalone/test_model.py index b1dcee209..7078c89b2 100644 --- a/yardstick/tests/unit/benchmark/contexts/standalone/test_model.py +++ b/yardstick/tests/unit/benchmark/contexts/standalone/test_model.py @@ -13,11 +13,11 @@ # limitations under the License. import copy -import mock import os -import unittest import uuid +import mock +import unittest from xml.etree import ElementTree from yardstick import ssh @@ -172,14 +172,70 @@ class ModelLibvirtTestCase(unittest.TestCase): interface_address.get('function')) def test_create_snapshot_qemu(self): - result = "/var/lib/libvirt/images/0.qcow2" - 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 - image = model.Libvirt.create_snapshot_qemu(ssh_mock, "0", "ubuntu.img") - self.assertEqual(image, result) + self.mock_ssh.execute = mock.Mock(return_value=(0, 0, 0)) + index = 1 + vm_image = '/var/lib/libvirt/images/%s.qcow2' % index + base_image = '/tmp/base_image' + + model.Libvirt.create_snapshot_qemu(self.mock_ssh, index, base_image) + self.mock_ssh.execute.assert_has_calls([ + mock.call('rm -- "%s"' % vm_image), + mock.call('test -r %s' % base_image), + mock.call('qemu-img create -f qcow2 -o backing_file=%s %s' % + (base_image, vm_image)) + ]) + + @mock.patch.object(os.path, 'basename', return_value='base_image') + @mock.patch.object(os.path, 'normpath') + @mock.patch.object(os, 'access', return_value=True) + def test_create_snapshot_qemu_no_image_remote(self, + mock_os_access, mock_normpath, mock_basename): + self.mock_ssh.execute = mock.Mock( + side_effect=[(0, 0, 0), (1, 0, 0), (0, 0, 0), (0, 0, 0)]) + index = 1 + vm_image = '/var/lib/libvirt/images/%s.qcow2' % index + base_image = '/tmp/base_image' + mock_normpath.return_value = base_image + + model.Libvirt.create_snapshot_qemu(self.mock_ssh, index, base_image) + self.mock_ssh.execute.assert_has_calls([ + mock.call('rm -- "%s"' % vm_image), + mock.call('test -r %s' % base_image), + mock.call('mv -- "/tmp/%s" "%s"' % ('base_image', base_image)), + mock.call('qemu-img create -f qcow2 -o backing_file=%s %s' % + (base_image, vm_image)) + ]) + mock_os_access.assert_called_once_with(base_image, os.R_OK) + mock_normpath.assert_called_once_with(base_image) + mock_basename.assert_has_calls([mock.call(base_image)]) + self.mock_ssh.put_file.assert_called_once_with(base_image, + '/tmp/base_image') + + @mock.patch.object(os, 'access', return_value=False) + def test_create_snapshot_qemu_no_image_local(self, mock_os_access): + self.mock_ssh.execute = mock.Mock(side_effect=[(0, 0, 0), (1, 0, 0)]) + base_image = '/tmp/base_image' + + with self.assertRaises(exceptions.LibvirtQemuImageBaseImageNotPresent): + model.Libvirt.create_snapshot_qemu(self.mock_ssh, 3, base_image) + mock_os_access.assert_called_once_with(base_image, os.R_OK) + + def test_create_snapshot_qemu_error_qemuimg_command(self): + self.mock_ssh.execute = mock.Mock( + side_effect=[(0, 0, 0), (0, 0, 0), (1, 0, 0)]) + index = 1 + vm_image = '/var/lib/libvirt/images/%s.qcow2' % index + base_image = '/tmp/base_image' + + with self.assertRaises(exceptions.LibvirtQemuImageCreateError): + model.Libvirt.create_snapshot_qemu(self.mock_ssh, index, + base_image) + self.mock_ssh.execute.assert_has_calls([ + mock.call('rm -- "%s"' % vm_image), + mock.call('test -r %s' % base_image), + mock.call('qemu-img create -f qcow2 -o backing_file=%s %s' % + (base_image, vm_image)) + ]) @mock.patch.object(model.Libvirt, 'pin_vcpu_for_perf', return_value='4,5') @mock.patch.object(model.Libvirt, 'create_snapshot_qemu', diff --git a/yardstick/tests/unit/benchmark/contexts/test_heat.py b/yardstick/tests/unit/benchmark/contexts/test_heat.py index 625f97bf4..a40adf5ae 100644 --- a/yardstick/tests/unit/benchmark/contexts/test_heat.py +++ b/yardstick/tests/unit/benchmark/contexts/test_heat.py @@ -306,7 +306,7 @@ class HeatContextTestCase(unittest.TestCase): 'yardstick/resources/files/yardstick_key-', self.test_context._name]) mock_genkeys.assert_called_once_with(key_filename) - mock_path_exists.assert_called_once_with(key_filename) + mock_path_exists.assert_any_call(key_filename) @mock.patch.object(heat, 'HeatTemplate', return_value='heat_template') @mock.patch.object(heat.HeatContext, '_add_resources_to_template') diff --git a/yardstick/tests/unit/benchmark/scenarios/lib/test_create_sec_group.py b/yardstick/tests/unit/benchmark/scenarios/lib/test_create_sec_group.py index 21158ab17..0477a49d4 100644 --- a/yardstick/tests/unit/benchmark/scenarios/lib/test_create_sec_group.py +++ b/yardstick/tests/unit/benchmark/scenarios/lib/test_create_sec_group.py @@ -6,25 +6,54 @@ # 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.create_sec_group import CreateSecgroup - - -class CreateSecGroupTestCase(unittest.TestCase): - - @mock.patch('yardstick.common.openstack_utils.get_neutron_client') - @mock.patch('yardstick.common.openstack_utils.create_security_group_full') - def test_create_sec_group(self, mock_get_neutron_client, mock_create_security_group_full): - options = { - 'openstack_paras': { - 'sg_name': 'yardstick_sec_group', - 'description': 'security group for yardstick manual VM' - } - } - args = {"options": options} - obj = CreateSecgroup(args, {}) - obj.run({}) - mock_get_neutron_client.assert_called_once() - mock_create_security_group_full.assert_called_once() +from yardstick.common import openstack_utils +from yardstick.common import exceptions +from yardstick.benchmark.scenarios.lib import create_sec_group + + +class CreateSecurityGroupTestCase(unittest.TestCase): + + def setUp(self): + + self._mock_create_security_group_full = mock.patch.object( + openstack_utils, 'create_security_group_full') + self.mock_create_security_group_full = ( + self._mock_create_security_group_full.start()) + self._mock_get_shade_client = mock.patch.object( + openstack_utils, 'get_shade_client') + self.mock_get_shade_client = self._mock_get_shade_client.start() + self._mock_log = mock.patch.object(create_sec_group, 'LOG') + self.mock_log = self._mock_log.start() + self.args = {'options': {'sg_name': 'yardstick_sg'}} + self.result = {} + + self.csecgp_obj = create_sec_group.CreateSecgroup(self.args, mock.ANY) + self.addCleanup(self._stop_mock) + + def _stop_mock(self): + self._mock_create_security_group_full.stop() + self._mock_get_shade_client.stop() + self._mock_log.stop() + + def test_run(self): + _uuid = uuidutils.generate_uuid() + self.csecgp_obj.scenario_cfg = {'output': 'id'} + self.mock_create_security_group_full.return_value = _uuid + output = self.csecgp_obj.run(self.result) + self.assertEqual({'sg_create': 1}, self.result) + self.assertEqual({'id': _uuid}, output) + self.mock_log.info.asset_called_once_with( + 'Create security group successful!') + + def test_run_fail(self): + self.mock_create_security_group_full.return_value = None + with self.assertRaises(exceptions.ScenarioCreateSecurityGroupError): + self.csecgp_obj.run(self.result) + self.assertEqual({'sg_create': 0}, self.result) + self.mock_log.error.assert_called_once_with( + 'Create security group failed!') 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 aef99ee94..b6dbf4791 100644 --- a/yardstick/tests/unit/benchmark/scenarios/lib/test_delete_network.py +++ b/yardstick/tests/unit/benchmark/scenarios/lib/test_delete_network.py @@ -11,7 +11,8 @@ from oslo_utils import uuidutils import unittest import mock -import yardstick.common.openstack_utils as op_utils +from yardstick.common import openstack_utils +from yardstick.common import exceptions from yardstick.benchmark.scenarios.lib import delete_network @@ -19,16 +20,17 @@ class DeleteNetworkTestCase(unittest.TestCase): def setUp(self): self._mock_delete_neutron_net = mock.patch.object( - op_utils, 'delete_neutron_net') + openstack_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') + openstack_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 = 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.args = {"options": {"network_name_or_id": ( + uuidutils.generate_uuid())}} + self.result = {} + self.del_obj = delete_network.DeleteNetwork(self.args, mock.ANY) self.addCleanup(self._stop_mock) @@ -39,11 +41,14 @@ class DeleteNetworkTestCase(unittest.TestCase): def test_run(self): self.mock_delete_neutron_net.return_value = True - self.assertTrue(self._del_obj.run({})) + self.assertIsNone(self.del_obj.run(self.result)) + self.assertEqual({"delete_network": 1}, self.result) 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({})) + with self.assertRaises(exceptions.ScenarioDeleteNetworkError): + self.del_obj.run(self.result) + self.assertEqual({"delete_network": 0}, self.result) 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 5c7e5bfab..f03f2516c 100644 --- a/yardstick/tests/unit/common/test_openstack_utils.py +++ b/yardstick/tests/unit/common/test_openstack_utils.py @@ -39,18 +39,17 @@ 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') + 'network_name_or_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') + 'network_name_or_id') self.assertFalse(output) @mock.patch.object(openstack_utils, 'log') @@ -58,7 +57,7 @@ class DeleteNeutronNetTestCase(unittest.TestCase): self.mock_shade_client.delete_network.side_effect = ( exc.OpenStackCloudException('error message')) output = openstack_utils.delete_neutron_net(self.mock_shade_client, - 'network_id') + 'network_name_or_id') self.assertFalse(output) mock_logger.error.assert_called_once() @@ -282,3 +281,59 @@ class ListImageTestCase(unittest.TestCase): images = openstack_utils.list_images(mock_shade_client) mock_logger.error.assert_called_once() self.assertFalse(images) + + +class SecurityGroupTestCase(unittest.TestCase): + + def setUp(self): + self.mock_shade_client = mock.Mock() + self.sg_name = 'sg_name' + self.sg_description = 'sg_description' + self._uuid = uuidutils.generate_uuid() + + def test_create_security_group_full_existing_security_group(self): + self.mock_shade_client.get_security_group.return_value = ( + {'name': 'name', 'id': self._uuid}) + output = openstack_utils.create_security_group_full( + self.mock_shade_client, self.sg_name, self.sg_description) + self.mock_shade_client.get_security_group.assert_called_once() + self.assertEqual(self._uuid, output) + + @mock.patch.object(openstack_utils, 'log') + def test_create_security_group_full_non_existing_security_group( + self, mock_logger): + self.mock_shade_client.get_security_group.return_value = None + self.mock_shade_client.create_security_group.side_effect = ( + exc.OpenStackCloudException('error message')) + output = openstack_utils.create_security_group_full( + self.mock_shade_client, self.sg_name, self.sg_description) + mock_logger.error.assert_called_once() + self.assertIsNone(output) + + @mock.patch.object(openstack_utils, 'create_security_group_rule') + @mock.patch.object(openstack_utils, 'log') + def test_create_security_group_full_create_rule_fail( + self, mock_logger, mock_create_security_group_rule): + self.mock_shade_client.get_security_group.return_value = None + self.mock_shade_client.create_security_group.return_value = ( + {'name': 'name', 'id': self._uuid}) + mock_create_security_group_rule.return_value = False + output = openstack_utils.create_security_group_full( + self.mock_shade_client, self.sg_name, self.sg_description) + mock_create_security_group_rule.assert_called() + self.mock_shade_client.delete_security_group(self.sg_name) + mock_logger.error.assert_called_once() + self.assertIsNone(output) + + @mock.patch.object(openstack_utils, 'create_security_group_rule') + def test_create_security_group_full( + self, mock_create_security_group_rule): + self.mock_shade_client.get_security_group.return_value = None + self.mock_shade_client.create_security_group.return_value = ( + {'name': 'name', 'id': self._uuid}) + mock_create_security_group_rule.return_value = True + output = openstack_utils.create_security_group_full( + self.mock_shade_client, self.sg_name, self.sg_description) + mock_create_security_group_rule.assert_called() + self.mock_shade_client.delete_security_group(self.sg_name) + self.assertEqual(self._uuid, output) |