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
This commit is contained in:
Zhiteng Huang 2013-12-11 23:56:14 +08:00
parent ace214a87f
commit 1b437d937d
2 changed files with 58 additions and 18 deletions

View File

@ -20,12 +20,15 @@ Tests for Volume Code.
""" """
import contextlib
import datetime import datetime
import os import os
import shutil import shutil
import socket import socket
import tempfile import tempfile
import eventlet
import mock
import mox import mox
from oslo.config import cfg from oslo.config import cfg
@ -604,19 +607,54 @@ class VolumeTestCase(BaseVolumeTestCase):
image_id='fake_id', image_id='fake_id',
source_volume='fake_id') source_volume='fake_id')
def test_too_big_volume(self): @mock.patch.object(db, 'volume_get')
"""Ensure failure if a too large of a volume is requested.""" @mock.patch.object(db, 'volume_admin_metadata_get')
# FIXME(vish): validation needs to move into the data layer in def test_initialize_connection_fetchqos(self,
# volume_create _mock_volume_admin_metadata_get,
return True _mock_volume_get):
try: """Make sure initialize_connection returns correct information."""
volume = tests_utils.create_volume(self.context, size=1001, _mock_volume_get.return_value = {'volume_type_id': 'fake_type_id',
status='creating', 'volume_admin_metadata': {}}
host=CONF.host) _mock_volume_admin_metadata_get.return_value = {}
self.volume.create_volume(self.context, volume) connector = {'ip': 'IP', 'initiator': 'INITIATOR'}
self.fail("Should have thrown TypeError") qos_values = {'consumer': 'front-end',
except TypeError: 'specs': {
pass '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): def test_run_attach_detach_volume_for_instance(self):
"""Make sure volume can be attached and detached from instance.""" """Make sure volume can be attached and detached from instance."""

View File

@ -625,14 +625,16 @@ class VolumeManager(manager.SchedulerDependentManager):
# Add qos_specs to connection info # Add qos_specs to connection info
typeid = volume['volume_type_id'] typeid = volume['volume_type_id']
specs = {} specs = None
if typeid: if typeid:
res = volume_types.get_volume_type_qos_specs(typeid) res = volume_types.get_volume_type_qos_specs(typeid)
specs = res['qos_specs'] qos = res['qos_specs']
# only pass qos_specs that is designated to be consumed by
# Don't pass qos_spec as empty dict # front-end, or both front-end and back-end.
qos_spec = dict(qos_spec=specs if specs else None) 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) conn_info['data'].update(qos_spec)
# Add access_mode to connection info # Add access_mode to connection info