]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Fix QoS information in initialize_connection() result
authorZhiteng Huang <zhithuang@ebaysf.com>
Wed, 11 Dec 2013 15:56:14 +0000 (23:56 +0800)
committerZhiteng Huang <zhithuang@ebaysf.com>
Fri, 20 Dec 2013 16:48:40 +0000 (00:48 +0800)
Currently the entire QoS information (if any) is included in the result of
initialize_connection() even if the consumer of the QoS is 'back-end'. Also
the format for QoS specs also is changed so that front-end (Nova) can
parse correctly. Add unit test to cover initialize_connection().

Closes-bug: 1259957

DocImpact

Change-Id: Ibc5e92cc1ddf6404e5b234ef524698feae282eec

cinder/tests/test_volume.py
cinder/volume/manager.py

index 98f83c068e6b16e4958d43ee988e6f32d26e9906..8ef886fc90a35142e7c2936f32c6e4f70eb5fdd7 100644 (file)
@@ -20,14 +20,16 @@ Tests for Volume Code.
 
 """
 
+import contextlib
 import datetime
-import mock
 import os
 import re
 import shutil
 import socket
 import tempfile
 
+import eventlet
+import mock
 import mox
 from oslo.config import cfg
 from taskflow.engines.action_engine import engine
@@ -62,7 +64,6 @@ from cinder.volume.drivers import lvm
 from cinder.volume import rpcapi as volume_rpcapi
 from cinder.volume import utils as volutils
 
-import eventlet
 
 QUOTAS = quota.QUOTAS
 
@@ -840,6 +841,55 @@ class VolumeTestCase(BaseVolumeTestCase):
                           image_id='fake_id',
                           source_volume='fake_id')
 
+    @mock.patch.object(db, 'volume_get')
+    @mock.patch.object(db, 'volume_admin_metadata_get')
+    def test_initialize_connection_fetchqos(self,
+                                            _mock_volume_admin_metadata_get,
+                                            _mock_volume_get):
+        """Make sure initialize_connection returns correct information."""
+        _mock_volume_get.return_value = {'volume_type_id': 'fake_type_id',
+                                         'volume_admin_metadata': {}}
+        _mock_volume_admin_metadata_get.return_value = {}
+        connector = {'ip': 'IP', 'initiator': 'INITIATOR'}
+        qos_values = {'consumer': 'front-end',
+                      'specs': {
+                          'key1': 'value1',
+                          'key2': 'value2'}
+                      }
+
+        with contextlib.nested(
+            mock.patch.object(cinder.volume.volume_types,
+                              'get_volume_type_qos_specs'),
+            mock.patch.object(cinder.tests.fake_driver.FakeISCSIDriver,
+                              'initialize_connection')
+        ) as (type_qos, driver_init):
+            type_qos.return_value = dict(qos_specs=qos_values)
+            driver_init.return_value = {'data': {}}
+            qos_specs_expected = {'key1': 'value1',
+                                  'key2': 'value2'}
+            # initialize_connection() passes qos_specs that is designated to
+            # be consumed by front-end or both front-end and back-end
+            conn_info = self.volume.initialize_connection(self.context,
+                                                          'fake_volume_id',
+                                                          connector)
+            self.assertDictMatch(qos_specs_expected,
+                                 conn_info['data']['qos_specs'])
+
+            qos_values.update({'consumer': 'both'})
+            conn_info = self.volume.initialize_connection(self.context,
+                                                          'fake_volume_id',
+                                                          connector)
+            self.assertDictMatch(qos_specs_expected,
+                                 conn_info['data']['qos_specs'])
+            # initialize_connection() skips qos_specs that is designated to be
+            # consumed by back-end only
+            qos_values.update({'consumer': 'back-end'})
+            type_qos.return_value = dict(qos_specs=qos_values)
+            conn_info = self.volume.initialize_connection(self.context,
+                                                          'fake_volume_id',
+                                                          connector)
+            self.assertEqual(None, conn_info['data']['qos_specs'])
+
     def test_run_attach_detach_volume_for_instance(self):
         """Make sure volume can be attached and detached from instance."""
         mountpoint = "/dev/sdf"
index d9825f4e7a0d8a6a4371363ff3166b039bf7d3c8..7f95a88d51a7074d211508e4f5930d9a6e0eba53 100644 (file)
@@ -712,14 +712,16 @@ class VolumeManager(manager.SchedulerDependentManager):
 
         # Add qos_specs to connection info
         typeid = volume['volume_type_id']
-        specs = {}
+        specs = None
         if typeid:
             res = volume_types.get_volume_type_qos_specs(typeid)
-            specs = res['qos_specs']
-
-        # Don't pass qos_spec as empty dict
-        qos_spec = dict(qos_spec=specs if specs else None)
+            qos = res['qos_specs']
+            # only pass qos_specs that is designated to be consumed by
+            # front-end, or both front-end and back-end.
+            if qos and qos.get('consumer') in ['front-end', 'both']:
+                specs = qos.get('specs')
 
+        qos_spec = dict(qos_specs=specs)
         conn_info['data'].update(qos_spec)
 
         # Add access_mode to connection info