Browse Source

Fix QoS information in initialize_connection() result

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
tags/2014.1.b2
Zhiteng Huang 5 years ago
parent
commit
e40dafd544
2 changed files with 59 additions and 7 deletions
  1. 52
    2
      cinder/tests/test_volume.py
  2. 7
    5
      cinder/volume/manager.py

+ 52
- 2
cinder/tests/test_volume.py View File

@@ -20,14 +20,16 @@ Tests for Volume Code.
20 20
 
21 21
 """
22 22
 
23
+import contextlib
23 24
 import datetime
24
-import mock
25 25
 import os
26 26
 import re
27 27
 import shutil
28 28
 import socket
29 29
 import tempfile
30 30
 
31
+import eventlet
32
+import mock
31 33
 import mox
32 34
 from oslo.config import cfg
33 35
 from taskflow.engines.action_engine import engine
@@ -62,7 +64,6 @@ from cinder.volume.drivers import lvm
62 64
 from cinder.volume import rpcapi as volume_rpcapi
63 65
 from cinder.volume import utils as volutils
64 66
 
65
-import eventlet
66 67
 
67 68
 QUOTAS = quota.QUOTAS
68 69
 
@@ -840,6 +841,55 @@ class VolumeTestCase(BaseVolumeTestCase):
840 841
                           image_id='fake_id',
841 842
                           source_volume='fake_id')
842 843
 
844
+    @mock.patch.object(db, 'volume_get')
845
+    @mock.patch.object(db, 'volume_admin_metadata_get')
846
+    def test_initialize_connection_fetchqos(self,
847
+                                            _mock_volume_admin_metadata_get,
848
+                                            _mock_volume_get):
849
+        """Make sure initialize_connection returns correct information."""
850
+        _mock_volume_get.return_value = {'volume_type_id': 'fake_type_id',
851
+                                         'volume_admin_metadata': {}}
852
+        _mock_volume_admin_metadata_get.return_value = {}
853
+        connector = {'ip': 'IP', 'initiator': 'INITIATOR'}
854
+        qos_values = {'consumer': 'front-end',
855
+                      'specs': {
856
+                          'key1': 'value1',
857
+                          'key2': 'value2'}
858
+                      }
859
+
860
+        with contextlib.nested(
861
+            mock.patch.object(cinder.volume.volume_types,
862
+                              'get_volume_type_qos_specs'),
863
+            mock.patch.object(cinder.tests.fake_driver.FakeISCSIDriver,
864
+                              'initialize_connection')
865
+        ) as (type_qos, driver_init):
866
+            type_qos.return_value = dict(qos_specs=qos_values)
867
+            driver_init.return_value = {'data': {}}
868
+            qos_specs_expected = {'key1': 'value1',
869
+                                  'key2': 'value2'}
870
+            # initialize_connection() passes qos_specs that is designated to
871
+            # be consumed by front-end or both front-end and back-end
872
+            conn_info = self.volume.initialize_connection(self.context,
873
+                                                          'fake_volume_id',
874
+                                                          connector)
875
+            self.assertDictMatch(qos_specs_expected,
876
+                                 conn_info['data']['qos_specs'])
877
+
878
+            qos_values.update({'consumer': 'both'})
879
+            conn_info = self.volume.initialize_connection(self.context,
880
+                                                          'fake_volume_id',
881
+                                                          connector)
882
+            self.assertDictMatch(qos_specs_expected,
883
+                                 conn_info['data']['qos_specs'])
884
+            # initialize_connection() skips qos_specs that is designated to be
885
+            # consumed by back-end only
886
+            qos_values.update({'consumer': 'back-end'})
887
+            type_qos.return_value = dict(qos_specs=qos_values)
888
+            conn_info = self.volume.initialize_connection(self.context,
889
+                                                          'fake_volume_id',
890
+                                                          connector)
891
+            self.assertEqual(None, conn_info['data']['qos_specs'])
892
+
843 893
     def test_run_attach_detach_volume_for_instance(self):
844 894
         """Make sure volume can be attached and detached from instance."""
845 895
         mountpoint = "/dev/sdf"

+ 7
- 5
cinder/volume/manager.py View File

@@ -712,14 +712,16 @@ class VolumeManager(manager.SchedulerDependentManager):
712 712
 
713 713
         # Add qos_specs to connection info
714 714
         typeid = volume['volume_type_id']
715
-        specs = {}
715
+        specs = None
716 716
         if typeid:
717 717
             res = volume_types.get_volume_type_qos_specs(typeid)
718
-            specs = res['qos_specs']
719
-
720
-        # Don't pass qos_spec as empty dict
721
-        qos_spec = dict(qos_spec=specs if specs else None)
718
+            qos = res['qos_specs']
719
+            # only pass qos_specs that is designated to be consumed by
720
+            # front-end, or both front-end and back-end.
721
+            if qos and qos.get('consumer') in ['front-end', 'both']:
722
+                specs = qos.get('specs')
722 723
 
724
+        qos_spec = dict(qos_specs=specs)
723 725
         conn_info['data'].update(qos_spec)
724 726
 
725 727
         # Add access_mode to connection info

Loading…
Cancel
Save