From e40dafd54411f0e4648fc051ef4d9c806f337f9d Mon Sep 17 00:00:00 2001 From: Zhiteng Huang Date: Wed, 11 Dec 2013 23:56:14 +0800 Subject: [PATCH] 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 --- cinder/tests/test_volume.py | 54 +++++++++++++++++++++++++++++++++++-- cinder/volume/manager.py | 12 +++++---- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/cinder/tests/test_volume.py b/cinder/tests/test_volume.py index 98f83c068..8ef886fc9 100644 --- a/cinder/tests/test_volume.py +++ b/cinder/tests/test_volume.py @@ -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" diff --git a/cinder/volume/manager.py b/cinder/volume/manager.py index d9825f4e7..7f95a88d5 100644 --- a/cinder/volume/manager.py +++ b/cinder/volume/manager.py @@ -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 -- 2.45.2