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

View File

@ -20,14 +20,16 @@ Tests for Volume Code.
""" """
import contextlib
import datetime import datetime
import mock
import os import os
import re import re
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
from taskflow.engines.action_engine import engine 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 rpcapi as volume_rpcapi
from cinder.volume import utils as volutils from cinder.volume import utils as volutils
import eventlet
QUOTAS = quota.QUOTAS QUOTAS = quota.QUOTAS
@ -840,6 +841,55 @@ class VolumeTestCase(BaseVolumeTestCase):
image_id='fake_id', image_id='fake_id',
source_volume='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): 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."""
mountpoint = "/dev/sdf" mountpoint = "/dev/sdf"

View File

@ -712,14 +712,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