]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Notify the transfer volume action in cinder
authorwanghao <wanghao749@huawei.com>
Tue, 26 May 2015 07:32:42 +0000 (15:32 +0800)
committerwanghao <wanghao749@huawei.com>
Tue, 7 Jul 2015 09:14:34 +0000 (17:14 +0800)
Now when we transfer a volume, there is not corresponding action
notification that is sent to ceilometer. Include the actions of create,
accept and delete.

The bp that this patch implements, proposes adding those action to enrich
the notification in cinder.

Notify is added in Create, Accept, and Delete actions.

Change-Id: I9d71c55d103cc501f60585b64902d364af21d4d9
Implements:  blueprint notify-the-transfer-volume-action-in-cinder

cinder/tests/unit/test_volume_transfer.py
cinder/transfer/api.py

index 524cb6ab0f4c1ed5c4bfc78f54152ee11f99676d..cf45cb9ce7dcd6feef8a55f7da8fbab7edde6f4d 100644 (file)
@@ -15,6 +15,7 @@
 
 import datetime
 
+import mock
 from oslo_log import log as logging
 
 from cinder import context
@@ -36,7 +37,8 @@ class VolumeTransferTestCase(test.TestCase):
                                            project_id='project_id')
         self.updated_at = datetime.datetime(1, 1, 1, 1, 1, 1)
 
-    def test_transfer_volume_create_delete(self):
+    @mock.patch('cinder.volume.utils.notify_about_volume_usage')
+    def test_transfer_volume_create_delete(self, mock_notify):
         tx_api = transfer_api.API()
         utils.create_volume(self.ctxt, id='1',
                             updated_at=self.updated_at)
@@ -44,10 +46,18 @@ class VolumeTransferTestCase(test.TestCase):
         volume = db.volume_get(self.ctxt, '1')
         self.assertEqual('awaiting-transfer', volume['status'],
                          'Unexpected state')
+        calls = [mock.call(self.ctxt, mock.ANY, "transfer.create.start"),
+                 mock.call(self.ctxt, mock.ANY, "transfer.create.end")]
+        mock_notify.assert_has_calls(calls)
+        self.assertEqual(2, mock_notify.call_count)
 
         tx_api.delete(self.ctxt, response['id'])
         volume = db.volume_get(self.ctxt, '1')
         self.assertEqual('available', volume['status'], 'Unexpected state')
+        calls = [mock.call(self.ctxt, mock.ANY, "transfer.delete.start"),
+                 mock.call(self.ctxt, mock.ANY, "transfer.delete.end")]
+        mock_notify.assert_has_calls(calls)
+        self.assertEqual(4, mock_notify.call_count)
 
     def test_transfer_invalid_volume(self):
         tx_api = transfer_api.API()
@@ -59,7 +69,8 @@ class VolumeTransferTestCase(test.TestCase):
         volume = db.volume_get(self.ctxt, '1')
         self.assertEqual('in-use', volume['status'], 'Unexpected state')
 
-    def test_transfer_accept(self):
+    @mock.patch('cinder.volume.utils.notify_about_volume_usage')
+    def test_transfer_accept(self, mock_notify):
         svc = self.start_service('volume', host='test_host')
         tx_api = transfer_api.API()
         utils.create_volume(self.ctxt, id='1',
@@ -77,12 +88,23 @@ class VolumeTransferTestCase(test.TestCase):
                           tx_api.accept,
                           self.ctxt, transfer['id'], 'wrong')
 
+        calls = [mock.call(self.ctxt, mock.ANY, "transfer.create.start"),
+                 mock.call(self.ctxt, mock.ANY, "transfer.create.end")]
+        mock_notify.assert_has_calls(calls)
+        self.assertEqual(2, mock_notify.call_count)
+
         db.volume_update(self.ctxt, '1', {'status': 'wrong'})
         self.assertRaises(exception.InvalidVolume,
                           tx_api.accept,
                           self.ctxt, transfer['id'], transfer['auth_key'])
         db.volume_update(self.ctxt, '1', {'status': 'awaiting-transfer'})
 
+        # Because the InvalidVolume exception is raised in tx_api, so there is
+        # only transfer.accept.start called and missing transfer.accept.end.
+        calls = [mock.call(self.ctxt, mock.ANY, "transfer.accept.start")]
+        mock_notify.assert_has_calls(calls)
+        self.assertEqual(3, mock_notify.call_count)
+
         self.ctxt.user_id = 'new_user_id'
         self.ctxt.project_id = 'new_project_id'
         response = tx_api.accept(self.ctxt,
@@ -99,6 +121,11 @@ class VolumeTransferTestCase(test.TestCase):
         self.assertEqual(transfer['id'], response['id'],
                          'Unexpected transfer id in response.')
 
+        calls = [mock.call(self.ctxt, mock.ANY, "transfer.accept.start"),
+                 mock.call(self.ctxt, mock.ANY, "transfer.accept.end")]
+        mock_notify.assert_has_calls(calls)
+        self.assertEqual(5, mock_notify.call_count)
+
         svc.stop()
 
     def test_transfer_get(self):
@@ -123,7 +150,8 @@ class VolumeTransferTestCase(test.TestCase):
         ts = tx_api.get_all(nctxt)
         self.assertEqual(len(ts), 0, 'Unexpected transfers listed.')
 
-    def test_delete_transfer_with_deleted_volume(self):
+    @mock.patch('cinder.volume.utils.notify_about_volume_usage')
+    def test_delete_transfer_with_deleted_volume(self, mock_notify):
         # create a volume
         volume = utils.create_volume(self.ctxt, id='1',
                                      updated_at=self.updated_at)
@@ -132,6 +160,11 @@ class VolumeTransferTestCase(test.TestCase):
         transfer = tx_api.create(self.ctxt, volume['id'], 'Description')
         t = tx_api.get(self.ctxt, transfer['id'])
         self.assertEqual(t['id'], transfer['id'], 'Unexpected transfer id')
+
+        calls = [mock.call(self.ctxt, mock.ANY, "transfer.create.start"),
+                 mock.call(self.ctxt, mock.ANY, "transfer.create.end")]
+        mock_notify.assert_has_calls(calls)
+        self.assertEqual(2, mock_notify.call_count)
         # force delete volume
         db.volume_destroy(context.get_admin_context(), volume['id'])
         # Make sure transfer has been deleted.
index 0ad3fccf3af2e9bb01bd63c5d65ce212c4fe73ca..e29dee773b1a66cfbd8c9e26d7eac1346b98a96e 100644 (file)
@@ -31,6 +31,7 @@ from cinder import exception
 from cinder.i18n import _, _LE, _LI, _LW
 from cinder import quota
 from cinder.volume import api as volume_api
+from cinder.volume import utils as volume_utils
 
 
 volume_transfer_opts = [
@@ -64,9 +65,13 @@ class API(base.Base):
         transfer = self.db.transfer_get(context, transfer_id)
 
         volume_ref = self.db.volume_get(context, transfer.volume_id)
+        volume_utils.notify_about_volume_usage(context, volume_ref,
+                                               "transfer.delete.start")
         if volume_ref['status'] != 'awaiting-transfer':
             LOG.error(_LE("Volume in unexpected state"))
         self.db.transfer_destroy(context, transfer_id)
+        volume_utils.notify_about_volume_usage(context, volume_ref,
+                                               "transfer.delete.end")
 
     def get_all(self, context, filters=None):
         filters = filters or {}
@@ -105,6 +110,8 @@ class API(base.Base):
         if volume_ref['status'] != "available":
             raise exception.InvalidVolume(reason=_("status must be available"))
 
+        volume_utils.notify_about_volume_usage(context, volume_ref,
+                                               "transfer.create.start")
         # The salt is just a short random string.
         salt = self._get_random_string(CONF.volume_transfer_salt_length)
         auth_key = self._get_random_string(CONF.volume_transfer_key_length)
@@ -123,6 +130,8 @@ class API(base.Base):
             LOG.error(_LE("Failed to create transfer record "
                           "for %s"), volume_id)
             raise
+        volume_utils.notify_about_volume_usage(context, volume_ref,
+                                               "transfer.create.end")
         return {'id': transfer['id'],
                 'volume_id': transfer['volume_id'],
                 'display_name': transfer['display_name'],
@@ -145,6 +154,8 @@ class API(base.Base):
 
         volume_id = transfer['volume_id']
         vol_ref = self.db.volume_get(context.elevated(), volume_id)
+        volume_utils.notify_about_volume_usage(context, vol_ref,
+                                               "transfer.accept.start")
 
         try:
             reservations = QUOTAS.reserve(context, volumes=1,
@@ -210,6 +221,8 @@ class API(base.Base):
                                     project_id=donor_id)
 
         vol_ref = self.db.volume_get(context, volume_id)
+        volume_utils.notify_about_volume_usage(context, vol_ref,
+                                               "transfer.accept.end")
         return {'id': transfer_id,
                 'display_name': transfer['display_name'],
                 'volume_id': vol_ref['id']}