From 4c672aa7012a530806a2f8ff2d45a8badb7f7b21 Mon Sep 17 00:00:00 2001 From: Shobhi Jain Date: Tue, 10 Apr 2018 14:13:50 +0100 Subject: [PATCH] Replace cinder delete volume with shade client. Function delete volume now uses shade client. JIRA: YARDSTICK-891 Change-Id: I016e1d3bf5972879cad176b56c7282e35413945e Signed-off-by: Shobhi Jain --- yardstick/benchmark/scenarios/lib/delete_volume.py | 30 ++++++------- yardstick/common/exceptions.py | 4 ++ yardstick/common/openstack_utils.py | 32 +++++++------- .../benchmark/scenarios/lib/test_delete_volume.py | 49 ++++++++++++++++------ .../tests/unit/common/test_openstack_utils.py | 27 ++++++++++++ 5 files changed, 98 insertions(+), 44 deletions(-) diff --git a/yardstick/benchmark/scenarios/lib/delete_volume.py b/yardstick/benchmark/scenarios/lib/delete_volume.py index ea2b85812..59e19dfdf 100644 --- a/yardstick/benchmark/scenarios/lib/delete_volume.py +++ b/yardstick/benchmark/scenarios/lib/delete_volume.py @@ -6,14 +6,11 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## - -from __future__ import print_function -from __future__ import absolute_import - import logging +from yardstick.common import openstack_utils +from yardstick.common import exceptions from yardstick.benchmark.scenarios import base -import yardstick.common.openstack_utils as op_utils LOG = logging.getLogger(__name__) @@ -26,11 +23,13 @@ class DeleteVolume(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.volume_id = self.options.get("volume_id", None) + self.volume_name_or_id = self.options.get("name_or_id") + self.wait = self.options.get("wait", True) + self.timeout = self.options.get("timeout") - self.cinder_client = op_utils.get_cinder_client() + self.shade_client = openstack_utils.get_shade_client() self.setup_done = False @@ -45,11 +44,14 @@ class DeleteVolume(base.Scenario): if not self.setup_done: self.setup() - status = op_utils.delete_volume(self.cinder_client, self.volume_id) + status = openstack_utils.delete_volume( + self.shade_client, name_or_id=self.volume_name_or_id, + wait=self.wait, timeout=self.timeout) - if status: - result.update({"delete_volume": 1}) - LOG.info("Delete volume successful!") - else: + if not status: result.update({"delete_volume": 0}) - LOG.info("Delete volume failed!") + LOG.error("Delete volume failed!") + raise exceptions.ScenarioDeleteVolumeError + + result.update({"delete_volume": 1}) + LOG.info("Delete volume successful!") diff --git a/yardstick/common/exceptions.py b/yardstick/common/exceptions.py index 1aa734ae3..f82290036 100644 --- a/yardstick/common/exceptions.py +++ b/yardstick/common/exceptions.py @@ -234,3 +234,7 @@ class ScenarioGetFlavorError(YardstickException): class ScenarioCreateVolumeError(YardstickException): message = 'Cinder Create Volume Scenario failed' + + +class ScenarioDeleteVolumeError(YardstickException): + message = 'Cinder Delete Volume Scenario failed' diff --git a/yardstick/common/openstack_utils.py b/yardstick/common/openstack_utils.py index 026ec620f..3909bcb2e 100644 --- a/yardstick/common/openstack_utils.py +++ b/yardstick/common/openstack_utils.py @@ -10,7 +10,6 @@ import copy import logging import os -import sys from cinderclient import client as cinderclient from novaclient import client as novaclient @@ -822,24 +821,21 @@ def create_volume(shade_client, size, wait=True, timeout=None, "Exception message: %s", op_exc.orig_message) -def delete_volume(cinder_client, volume_id, - forced=False): # pragma: no cover +def delete_volume(shade_client, name_or_id=None, wait=True, timeout=None): + """Delete a volume. + + :param name_or_id:(string) Name or unique ID of the volume. + :param wait:(bool) If true, waits for volume to be deleted. + :param timeout:(string) Seconds to wait for volume deletion. None is forever. + + :return: True on success, False otherwise. + """ try: - if forced: - try: - cinder_client.volumes.detach(volume_id) - except Exception: # pylint: disable=broad-except - log.error(sys.exc_info()[0]) - cinder_client.volumes.force_delete(volume_id) - else: - while True: - volume = get_cinder_client().volumes.get(volume_id) - if volume.status.lower() == 'available': - break - cinder_client.volumes.delete(volume_id) - return True - except Exception: # pylint: disable=broad-except - log.exception("Error [delete_volume(cinder_client, '%s')]", volume_id) + return shade_client.delete_volume(name_or_id=name_or_id, + wait=wait, timeout=timeout) + except (exc.OpenStackCloudException, exc.OpenStackCloudTimeout) as o_exc: + log.error("Error [delete_volume(shade_client,'%s')]. " + "Exception message: %s", name_or_id, o_exc.orig_message) return False diff --git a/yardstick/tests/unit/benchmark/scenarios/lib/test_delete_volume.py b/yardstick/tests/unit/benchmark/scenarios/lib/test_delete_volume.py index 93f76e819..0db16f396 100644 --- a/yardstick/tests/unit/benchmark/scenarios/lib/test_delete_volume.py +++ b/yardstick/tests/unit/benchmark/scenarios/lib/test_delete_volume.py @@ -9,19 +9,44 @@ import unittest import mock -from yardstick.benchmark.scenarios.lib.delete_volume import DeleteVolume +from yardstick.common import openstack_utils +from yardstick.common import exceptions +from yardstick.benchmark.scenarios.lib import delete_volume class DeleteVolumeTestCase(unittest.TestCase): - @mock.patch('yardstick.common.openstack_utils.get_cinder_client') - @mock.patch('yardstick.common.openstack_utils.delete_volume') - def test_delete_volume(self, mock_get_cinder_client, mock_delete_volume): - options = { - 'volume_id': '123-123-123' - } - args = {"options": options} - obj = DeleteVolume(args, {}) - obj.run({}) - mock_get_cinder_client.assert_called_once() - mock_delete_volume.assert_called_once() + def setUp(self): + self._mock_delete_volume = mock.patch.object( + openstack_utils, 'delete_volume') + self.mock_delete_volume = ( + self._mock_delete_volume.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(delete_volume, 'LOG') + self.mock_log = self._mock_log.start() + self.args = {'options': {'name_or_id': 'yardstick_volume'}} + self.result = {} + + self.delvol_obj = delete_volume.DeleteVolume(self.args, mock.ANY) + + self.addCleanup(self._stop_mock) + + def _stop_mock(self): + self._mock_delete_volume.stop() + self._mock_get_shade_client.stop() + self._mock_log.stop() + + def test_run(self): + self.mock_delete_volume.return_value = True + self.assertIsNone(self.delvol_obj.run(self.result)) + self.assertEqual({'delete_volume': 1}, self.result) + self.mock_log.info.assert_called_once_with('Delete volume successful!') + + def test_run_fail(self): + self.mock_delete_volume.return_value = False + with self.assertRaises(exceptions.ScenarioDeleteVolumeError): + self.delvol_obj.run(self.result) + self.assertEqual({'delete_volume': 0}, self.result) + self.mock_log.error.assert_called_once_with('Delete volume failed!') diff --git a/yardstick/tests/unit/common/test_openstack_utils.py b/yardstick/tests/unit/common/test_openstack_utils.py index bc3c995b7..9498c3c99 100644 --- a/yardstick/tests/unit/common/test_openstack_utils.py +++ b/yardstick/tests/unit/common/test_openstack_utils.py @@ -602,3 +602,30 @@ class CreateVolumeTestCase(unittest.TestCase): self.size) mock_logger.error.assert_called_once() self.assertIsNone(output) + + +class DeleteVolumeTestCase(unittest.TestCase): + + def setUp(self): + self.mock_shade_client = mock.Mock() + + def test_delete_volume(self): + self.mock_shade_client.delete_volume.return_value = True + output = openstack_utils.delete_volume(self.mock_shade_client, + 'volume_name_or_id') + self.assertTrue(output) + + def test_delete_volume_fail(self): + self.mock_shade_client.delete_volume.return_value = False + output = openstack_utils.delete_volume(self.mock_shade_client, + 'volume_name_or_id') + self.assertFalse(output) + + @mock.patch.object(openstack_utils, 'log') + def test_delete_volume_exception(self, mock_logger): + self.mock_shade_client.delete_volume.side_effect = ( + exc.OpenStackCloudException('error message')) + output = openstack_utils.delete_volume(self.mock_shade_client, + 'volume_name_or_id') + mock_logger.error.assert_called_once() + self.assertFalse(output) -- 2.16.6