Replace nova delete instance with shade client. 21/59121/1
authorShobhi Jain <shobhi.jain@intel.com>
Mon, 26 Mar 2018 13:56:59 +0000 (14:56 +0100)
committerEmma Foley <emma.l.foley@intel.com>
Wed, 27 Jun 2018 16:06:33 +0000 (17:06 +0100)
Function delete_instance now uses shade client.

JIRA: YARDSTICK-1088

Change-Id: I5772a74c6dc2d103edd410042a8eaf721d1bcc5c
Signed-off-by: Shobhi Jain <shobhi.jain@intel.com>
(cherry picked from commit 05f97c4e4ce1e8c7c97cda16f12215e663a13c23)

yardstick/benchmark/scenarios/lib/delete_server.py
yardstick/common/exceptions.py
yardstick/common/openstack_utils.py
yardstick/tests/unit/benchmark/scenarios/lib/test_delete_server.py
yardstick/tests/unit/common/test_openstack_utils.py

index bcd8fab..46229ff 100644 (file)
@@ -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,9 +23,13 @@ class DeleteServer(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.server_id = self.options.get("server_id", None)
-        self.nova_client = op_utils.get_nova_client()
+        self.options = self.scenario_cfg["options"]
+        self.server_name_or_id = self.options["name_or_id"]
+        self.wait = self.options.get("wait", False)
+        self.timeout = self.options.get("timeout", 180)
+        self.delete_ips = self.options.get("delete_ips", False)
+        self.delete_ip_retry = self.options.get("delete_ip_retry", 1)
+        self.shade_client = openstack_utils.get_shade_client()
 
         self.setup_done = False
 
@@ -43,9 +44,15 @@ class DeleteServer(base.Scenario):
         if not self.setup_done:
             self.setup()
 
-        status = op_utils.delete_instance(self.nova_client,
-                                          instance_id=self.server_id)
-        if status:
-            LOG.info("Delete server successful!")
-        else:
+        status = openstack_utils.delete_instance(
+            self.shade_client, self.server_name_or_id, wait=self.wait,
+            timeout=self.timeout, delete_ips=self.delete_ips,
+            delete_ip_retry=self.delete_ip_retry)
+
+        if not status:
+            result.update({"delete_server": 0})
             LOG.error("Delete server failed!")
+            raise exceptions.ScenarioDeleteServerError
+
+        result.update({"delete_server": 1})
+        LOG.info("Delete server successful!")
index 219d039..fa92179 100644 (file)
@@ -222,6 +222,10 @@ class ScenarioCreateServerError(YardstickException):
     message = 'Nova Create Server Scenario failed'
 
 
+class ScenarioDeleteServerError(YardstickException):
+    message = 'Delete Server Scenario failed'
+
+
 class ApiServerError(YardstickException):
     message = 'An unkown exception happened to Api Server!'
 
index c2ef267..e542a1d 100644 (file)
@@ -351,15 +351,29 @@ def attach_server_volume(server_id, volume_id,
         return True
 
 
-def delete_instance(nova_client, instance_id):      # pragma: no cover
+def delete_instance(shade_client, name_or_id, wait=False, timeout=180,
+                    delete_ips=False, delete_ip_retry=1):
+    """Delete a server instance.
+
+    :param name_or_id: name or ID of the server to delete
+    :param wait:(bool) If true, waits for server to be deleted.
+    :param timeout:(int) Seconds to wait for server deletion.
+    :param delete_ips:(bool) If true, deletes any floating IPs associated with
+                      the instance.
+    :param delete_ip_retry:(int) Number of times to retry deleting
+                           any floating ips, should the first try be
+                           unsuccessful.
+    :returns: True if delete succeeded, False otherwise.
+    """
     try:
-        nova_client.servers.force_delete(instance_id)
-    except Exception:  # pylint: disable=broad-except
-        log.exception("Error [delete_instance(nova_client, '%s')]",
-                      instance_id)
+        return shade_client.delete_server(
+            name_or_id, wait=wait, timeout=timeout, delete_ips=delete_ips,
+            delete_ip_retry=delete_ip_retry)
+    except exc.OpenStackCloudException as o_exc:
+        log.error("Error [delete_instance(shade_client, '%s')]. "
+                  "Exception message: %s", name_or_id,
+                  o_exc.orig_message)
         return False
-    else:
-        return True
 
 
 def remove_host_from_aggregate(nova_client, aggregate_name,
index eee565d..55fe53d 100644 (file)
@@ -6,22 +6,49 @@
 # 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_server import DeleteServer
+from yardstick.common import openstack_utils
+from yardstick.common import exceptions
+from yardstick.benchmark.scenarios.lib import delete_server
 
 
 class DeleteServerTestCase(unittest.TestCase):
 
-    @mock.patch('yardstick.common.openstack_utils.delete_instance')
-    @mock.patch('yardstick.common.openstack_utils.get_nova_client')
-    def test_delete_server(self, mock_get_nova_client, mock_delete_instance):
-        options = {
-            'server_id': '1234-4567-0000'
-        }
-        args = {"options": options}
-        obj = DeleteServer(args, {})
-        obj.run({})
-        mock_get_nova_client.assert_called_once()
-        mock_delete_instance.assert_called_once()
+    def setUp(self):
+        self._mock_delete_instance = mock.patch.object(
+            openstack_utils, 'delete_instance')
+        self.mock_delete_instance = (
+            self._mock_delete_instance.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_server, 'LOG')
+        self.mock_log = self._mock_log.start()
+        self.args = {'options': {'name_or_id': uuidutils.generate_uuid()
+                                 }}
+        self.result = {}
+
+        self.delserver_obj = delete_server.DeleteServer(self.args, mock.ANY)
+
+        self.addCleanup(self._stop_mock)
+
+    def _stop_mock(self):
+        self._mock_delete_instance.stop()
+        self._mock_get_shade_client.stop()
+        self._mock_log.stop()
+
+    def test_run(self):
+        self.mock_delete_instance.return_value = True
+        self.assertIsNone(self.delserver_obj.run(self.result))
+        self.assertEqual({'delete_server': 1}, self.result)
+        self.mock_log.info.assert_called_once_with('Delete server successful!')
+
+    def test_run_fail(self):
+        self.mock_delete_instance.return_value = False
+        with self.assertRaises(exceptions.ScenarioDeleteServerError):
+            self.delserver_obj.run(self.result)
+        self.assertEqual({'delete_server': 0}, self.result)
+        self.mock_log.error.assert_called_once_with('Delete server failed!')
index a7c5aa5..de0f5c4 100644 (file)
@@ -366,3 +366,30 @@ class CreateInstanceTestCase(unittest.TestCase):
             self.mock_shade_client, 'server_name', 'image_name', 'flavor_name')
         mock_logger.error.assert_called_once()
         self.assertIsNone(output)
+
+
+class DeleteInstanceTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.mock_shade_client = mock.Mock()
+
+    def test_delete_instance(self):
+        self.mock_shade_client.delete_server.return_value = True
+        output = openstack_utils.delete_instance(self.mock_shade_client,
+                                                 'instance_name_id')
+        self.assertTrue(output)
+
+    def test_delete_instance_fail(self):
+        self.mock_shade_client.delete_server.return_value = False
+        output = openstack_utils.delete_instance(self.mock_shade_client,
+                                                 'instance_name_id')
+        self.assertFalse(output)
+
+    @mock.patch.object(openstack_utils, 'log')
+    def test_delete_instance_exception(self, mock_logger):
+        self.mock_shade_client.delete_server.side_effect = (
+            exc.OpenStackCloudException('error message'))
+        output = openstack_utils.delete_instance(self.mock_shade_client,
+                                                 'instance_name_id')
+        mock_logger.error.assert_called_once()
+        self.assertFalse(output)