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

(cherry-pick: e40dafd544)

Change-Id: Ibc5e92cc1ddf6404e5b234ef524698feae282eec
tags/2013.2.2
Zhiteng Huang 5 years ago
parent
commit
1b437d937d
2 changed files with 58 additions and 18 deletions
  1. 51
    13
      cinder/tests/test_volume.py
  2. 7
    5
      cinder/volume/manager.py

+ 51
- 13
cinder/tests/test_volume.py View File

@@ -20,12 +20,15 @@ Tests for Volume Code.
20 20
 
21 21
 """
22 22
 
23
+import contextlib
23 24
 import datetime
24 25
 import os
25 26
 import shutil
26 27
 import socket
27 28
 import tempfile
28 29
 
30
+import eventlet
31
+import mock
29 32
 import mox
30 33
 from oslo.config import cfg
31 34
 
@@ -604,19 +607,54 @@ class VolumeTestCase(BaseVolumeTestCase):
604 607
                           image_id='fake_id',
605 608
                           source_volume='fake_id')
606 609
 
607
-    def test_too_big_volume(self):
608
-        """Ensure failure if a too large of a volume is requested."""
609
-        # FIXME(vish): validation needs to move into the data layer in
610
-        #              volume_create
611
-        return True
612
-        try:
613
-            volume = tests_utils.create_volume(self.context, size=1001,
614
-                                               status='creating',
615
-                                               host=CONF.host)
616
-            self.volume.create_volume(self.context, volume)
617
-            self.fail("Should have thrown TypeError")
618
-        except TypeError:
619
-            pass
610
+    @mock.patch.object(db, 'volume_get')
611
+    @mock.patch.object(db, 'volume_admin_metadata_get')
612
+    def test_initialize_connection_fetchqos(self,
613
+                                            _mock_volume_admin_metadata_get,
614
+                                            _mock_volume_get):
615
+        """Make sure initialize_connection returns correct information."""
616
+        _mock_volume_get.return_value = {'volume_type_id': 'fake_type_id',
617
+                                         'volume_admin_metadata': {}}
618
+        _mock_volume_admin_metadata_get.return_value = {}
619
+        connector = {'ip': 'IP', 'initiator': 'INITIATOR'}
620
+        qos_values = {'consumer': 'front-end',
621
+                      'specs': {
622
+                          'key1': 'value1',
623
+                          'key2': 'value2'}
624
+                      }
625
+
626
+        with contextlib.nested(
627
+            mock.patch.object(cinder.volume.volume_types,
628
+                              'get_volume_type_qos_specs'),
629
+            mock.patch.object(cinder.tests.fake_driver.FakeISCSIDriver,
630
+                              'initialize_connection')
631
+        ) as (type_qos, driver_init):
632
+            type_qos.return_value = dict(qos_specs=qos_values)
633
+            driver_init.return_value = {'data': {}}
634
+            qos_specs_expected = {'key1': 'value1',
635
+                                  'key2': 'value2'}
636
+            # initialize_connection() passes qos_specs that is designated to
637
+            # be consumed by front-end or both front-end and back-end
638
+            conn_info = self.volume.initialize_connection(self.context,
639
+                                                          'fake_volume_id',
640
+                                                          connector)
641
+            self.assertDictMatch(qos_specs_expected,
642
+                                 conn_info['data']['qos_specs'])
643
+
644
+            qos_values.update({'consumer': 'both'})
645
+            conn_info = self.volume.initialize_connection(self.context,
646
+                                                          'fake_volume_id',
647
+                                                          connector)
648
+            self.assertDictMatch(qos_specs_expected,
649
+                                 conn_info['data']['qos_specs'])
650
+            # initialize_connection() skips qos_specs that is designated to be
651
+            # consumed by back-end only
652
+            qos_values.update({'consumer': 'back-end'})
653
+            type_qos.return_value = dict(qos_specs=qos_values)
654
+            conn_info = self.volume.initialize_connection(self.context,
655
+                                                          'fake_volume_id',
656
+                                                          connector)
657
+            self.assertEqual(None, conn_info['data']['qos_specs'])
620 658
 
621 659
     def test_run_attach_detach_volume_for_instance(self):
622 660
         """Make sure volume can be attached and detached from instance."""

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

@@ -625,14 +625,16 @@ class VolumeManager(manager.SchedulerDependentManager):
625 625
 
626 626
         # Add qos_specs to connection info
627 627
         typeid = volume['volume_type_id']
628
-        specs = {}
628
+        specs = None
629 629
         if typeid:
630 630
             res = volume_types.get_volume_type_qos_specs(typeid)
631
-            specs = res['qos_specs']
632
-
633
-        # Don't pass qos_spec as empty dict
634
-        qos_spec = dict(qos_spec=specs if specs else None)
631
+            qos = res['qos_specs']
632
+            # only pass qos_specs that is designated to be consumed by
633
+            # front-end, or both front-end and back-end.
634
+            if qos and qos.get('consumer') in ['front-end', 'both']:
635
+                specs = qos.get('specs')
635 636
 
637
+        qos_spec = dict(qos_specs=specs)
636 638
         conn_info['data'].update(qos_spec)
637 639
 
638 640
         # Add access_mode to connection info

Loading…
Cancel
Save