Add support for enhanced features to the QNAP Manila driver

This adds enhanced supports to the QNAP Manila driver:
 - Thin Provisioning
 - SSD Cache
 - Deduplication
 - Compression

Change-Id: I0c92ecf6ac55e2f6fbf1d41132e97fa2d40c3ebd
Implements: blueprint qnap-enhance-support
This commit is contained in:
Chris Yang 2017-10-03 15:05:21 +08:00
parent 098546fbf4
commit 487aa691fd
7 changed files with 335 additions and 33 deletions

View File

@ -272,7 +272,7 @@ More information: :ref:`capabilities_and_extra_specs`
+----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+
| MapRFS | \- | N | \- | \- | \- | N | \- | O | \- | \- | P | \- |
+----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+
| QNAP | \- | O | \- | \- | O | \- | \- | O | \- | \- | P | \- |
| QNAP | \- | O | Q | Q | O | Q | \- | O | \- | \- | P | \- |
+----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+
.. note::

View File

@ -184,7 +184,8 @@ class QnapAPIExecutor(object):
return sanitized_params
@_connection_checker
def create_share(self, share, pool_name, create_share_name, share_proto):
def create_share(self, share, pool_name, create_share_name,
share_proto, **kwargs):
"""Create share."""
LOG.debug('create_share_name: %s', create_share_name)
@ -194,10 +195,12 @@ class QnapAPIExecutor(object):
'vol_name': create_share_name,
'vol_size': six.text_type(share['size']) + 'GB',
'threshold': '80',
'dedup': 'off',
'compression': '1',
'thin_pro': '0',
'cache': '0',
'dedup': ('sha512'
if kwargs['qnap_deduplication'] is True
else 'off'),
'compression': '1' if kwargs['qnap_compression'] is True else '0',
'thin_pro': '1' if kwargs['qnap_thin_provision'] is True else '0',
'cache': '1' if kwargs['qnap_ssd_cache'] is True else '0',
'cifs_enable': '0' if share_proto == 'NFS' else '1',
'nfs_enable': '0' if share_proto == 'CIFS' else '1',
'afp_enable': '0',
@ -497,10 +500,10 @@ class QnapAPIExecutor(object):
'sharename': share_dict['sharename'],
'old_sharename': share_dict['old_sharename'],
'vol_size': six.text_type(share_dict['new_size']) + 'GB',
'dedup': '0',
'compression': '1',
'thin_pro': '0',
'cache': '0',
'dedup': 'sha512' if share_dict['deduplication'] else 'off',
'compression': '1' if share_dict['compression'] else '0',
'thin_pro': '1' if share_dict['thin_provision'] else '0',
'cache': '1' if share_dict['ssd_cache'] else '0',
'cifs_enable': '1' if share_dict['share_proto'] == 'CIFS' else '0',
'nfs_enable': '1' if share_dict['share_proto'] == 'NFS' else '0',
'afp_enable': '0',

View File

@ -31,6 +31,7 @@ from manila.i18n import _
from manila import share
from manila.share import driver
from manila.share.drivers.qnap import api
from manila.share import share_types
from manila import utils
LOG = logging.getLogger(__name__)
@ -66,9 +67,11 @@ class QnapShareDriver(driver.ShareDriver):
1.0.1 - Add support for QES fw 1.1.4.
1.0.2 - Fix bug #1736370, QNAP Manila driver: Access rule setting is
override by the another access rule.
1.0.3 - Add supports for Thin Provisioning, SSD Cache, Deduplication
and Compression.
"""
DRIVER_VERSION = '1.0.2'
DRIVER_VERSION = '1.0.3'
def __init__(self, *args, **kwargs):
"""Initialize QnapShareDriver."""
@ -254,6 +257,10 @@ class QnapShareDriver(driver.ShareDriver):
"allocated_capacity_gb": alloc_capacity_gb,
"reserved_percentage": reserved_percentage,
"qos": False,
"dedupe": [True, False],
"compression": [True, False],
"thin_provisioning": [True, False],
"qnap_ssd_cache": [True, False]
}
data = {
@ -276,6 +283,28 @@ class QnapShareDriver(driver.ShareDriver):
def create_share(self, context, share, share_server=None):
"""Create a new share."""
LOG.debug('share: %s', share.__dict__)
extra_specs = share_types.get_extra_specs_from_share(share)
LOG.debug('extra_specs: %s', extra_specs)
qnap_thin_provision = share_types.parse_boolean_extra_spec(
'thin_provisioning', extra_specs.get("thin_provisioning") or
extra_specs.get('capabilities:thin_provisioning') or 'true')
qnap_compression = share_types.parse_boolean_extra_spec(
'compression', extra_specs.get("compression") or
extra_specs.get('capabilities:compression') or 'true')
qnap_deduplication = share_types.parse_boolean_extra_spec(
'dedupe', extra_specs.get("dedupe") or
extra_specs.get('capabilities:dedupe') or 'false')
qnap_ssd_cache = share_types.parse_boolean_extra_spec(
'qnap_ssd_cache', extra_specs.get("qnap_ssd_cache") or
extra_specs.get("capabilities:qnap_ssd_cache") or 'false')
LOG.debug('qnap_thin_provision: %(qnap_thin_provision)s '
'qnap_compression: %(qnap_compression)s '
'qnap_deduplication: %(qnap_deduplication)s '
'qnap_ssd_cache: %(qnap_ssd_cache)s',
{'qnap_thin_provision': qnap_thin_provision,
'qnap_compression': qnap_compression,
'qnap_deduplication': qnap_deduplication,
'qnap_ssd_cache': qnap_ssd_cache})
share_proto = share['share_proto']
@ -293,11 +322,19 @@ class QnapShareDriver(driver.ShareDriver):
LOG.error(msg)
raise exception.ShareBackendException(msg=msg)
if (qnap_deduplication and not qnap_thin_provision):
msg = _("Dedupe cannot be enabled without thin_provisioning.")
LOG.debug('Dedupe cannot be enabled without thin_provisioning.')
raise exception.InvalidExtraSpec(reason=msg)
self.api_executor.create_share(
share,
self.configuration.qnap_poolname,
create_share_name,
share_proto)
share_proto,
qnap_thin_provision=qnap_thin_provision,
qnap_compression=qnap_compression,
qnap_deduplication=qnap_deduplication,
qnap_ssd_cache=qnap_ssd_cache)
created_share = self._get_share_info(create_share_name)
volID = created_share.find('vol_no').text
# Use private_storage to record volume ID and Name created in the NAS.
@ -306,7 +343,11 @@ class QnapShareDriver(driver.ShareDriver):
{'volID': volID,
'create_share_name': create_share_name})
_metadata = {'volID': volID,
'volName': create_share_name}
'volName': create_share_name,
'thin_provision': qnap_thin_provision,
'compression': qnap_compression,
'deduplication': qnap_deduplication,
'ssd_cache': qnap_ssd_cache}
self.private_storage.update(share['id'], _metadata)
return self._get_location_path(create_share_name,
@ -365,11 +406,27 @@ class QnapShareDriver(driver.ShareDriver):
LOG.debug('Share %s does not exist', share['id'])
raise exception.ShareResourceNotFound(share_id=share['id'])
LOG.debug('volName: %s', volName)
thin_provision = self.private_storage.get(
share['id'], 'thin_provision')
compression = self.private_storage.get(share['id'], 'compression')
deduplication = self.private_storage.get(share['id'], 'deduplication')
ssd_cache = self.private_storage.get(share['id'], 'ssd_cache')
LOG.debug('thin_provision: %(thin_provision)s '
'compression: %(compression)s '
'deduplication: %(deduplication)s '
'ssd_cache: %(ssd_cache)s',
{'thin_provision': thin_provision,
'compression': compression,
'deduplication': deduplication,
'ssd_cache': ssd_cache})
share_dict = {
'sharename': volName,
'old_sharename': volName,
'new_size': new_size,
'thin_provision': thin_provision == 'True',
'compression': compression == 'True',
'deduplication': deduplication == 'True',
'ssd_cache': ssd_cache == 'True',
'share_proto': share['share_proto']
}
self.api_executor.edit_share(share_dict)
@ -492,11 +549,32 @@ class QnapShareDriver(driver.ShareDriver):
context, snapshot['share_instance']['share_id'])
LOG.debug('snap_share[size]: %s', snap_share['size'])
thin_provision = self.private_storage.get(
snapshot['share_instance_id'], 'thin_provision')
compression = self.private_storage.get(
snapshot['share_instance_id'], 'compression')
deduplication = self.private_storage.get(
snapshot['share_instance_id'], 'deduplication')
ssd_cache = self.private_storage.get(
snapshot['share_instance_id'], 'ssd_cache')
LOG.debug('thin_provision: %(thin_provision)s '
'compression: %(compression)s '
'deduplication: %(deduplication)s '
'ssd_cache: %(ssd_cache)s',
{'thin_provision': thin_provision,
'compression': compression,
'deduplication': deduplication,
'ssd_cache': ssd_cache})
if (share['size'] > snap_share['size']):
share_dict = {
'sharename': create_share_name,
'old_sharename': create_share_name,
'new_size': share['size'],
'thin_provision': thin_provision == 'True',
'compression': compression == 'True',
'deduplication': deduplication == 'True',
'ssd_cache': ssd_cache == 'True',
'share_proto': share['share_proto']
}
self.api_executor.edit_share(share_dict)
@ -505,6 +583,10 @@ class QnapShareDriver(driver.ShareDriver):
_metadata = {
'volID': create_volID,
'volName': create_share_name,
'thin_provision': thin_provision,
'compression': compression,
'deduplication': deduplication,
'ssd_cache': ssd_cache
}
self.private_storage.update(share['id'], _metadata)
@ -726,25 +808,62 @@ class QnapShareDriver(driver.ShareDriver):
"backend.") % share['id']
raise exception.ManageInvalidShare(reason=msg)
_metadata = {}
extra_specs = share_types.get_extra_specs_from_share(share)
qnap_thin_provision = share_types.parse_boolean_extra_spec(
'thin_provisioning', extra_specs.get("thin_provisioning") or
extra_specs.get('capabilities:thin_provisioning') or 'true')
qnap_compression = share_types.parse_boolean_extra_spec(
'compression', extra_specs.get("compression") or
extra_specs.get('capabilities:compression') or 'true')
qnap_deduplication = share_types.parse_boolean_extra_spec(
'dedupe', extra_specs.get("dedupe") or
extra_specs.get('capabilities:dedupe') or 'false')
qnap_ssd_cache = share_types.parse_boolean_extra_spec(
'qnap_ssd_cache', extra_specs.get("qnap_ssd_cache") or
extra_specs.get("capabilities:qnap_ssd_cache") or 'false')
LOG.debug('qnap_thin_provision: %(qnap_thin_provision)s '
'qnap_compression: %(qnap_compression)s '
'qnap_deduplication: %(qnap_deduplication)s '
'qnap_ssd_cache: %(qnap_ssd_cache)s',
{'qnap_thin_provision': qnap_thin_provision,
'qnap_compression': qnap_compression,
'qnap_deduplication': qnap_deduplication,
'qnap_ssd_cache': qnap_ssd_cache})
if (qnap_deduplication and not qnap_thin_provision):
msg = _("Dedupe cannot be enabled without thin_provisioning.")
LOG.debug('Dedupe cannot be enabled without thin_provisioning.')
raise exception.InvalidExtraSpec(reason=msg)
vol_no = existing_share.find('vol_no').text
vol = self.api_executor.get_specific_volinfo(vol_no)
vol_size_gb = int(vol.find('size').text) / units.Gi
share_dict = {
'sharename': share_name,
'old_sharename': share_name,
'new_size': vol_size_gb,
'thin_provision': qnap_thin_provision,
'compression': qnap_compression,
'deduplication': qnap_deduplication,
'ssd_cache': qnap_ssd_cache,
'share_proto': share['share_proto']
}
self.api_executor.edit_share(share_dict)
_metadata = {}
_metadata['volID'] = vol_no
_metadata['volName'] = share_name
_metadata['thin_provision'] = qnap_thin_provision
_metadata['compression'] = qnap_compression
_metadata['deduplication'] = qnap_deduplication
_metadata['ssd_cache'] = qnap_ssd_cache
self.private_storage.update(share['id'], _metadata)
# Test to get value from private_storage.
volID = self.private_storage.get(share['id'], 'volID')
LOG.debug('volID: %s', volID)
volName = self.private_storage.get(share['id'], 'volName')
LOG.debug('volName: %s', volName)
LOG.info("Share %(shr_path)s was successfully managed with ID "
"%(shr_id)s.",
{'shr_path': share['export_locations'][0]['path'],
'shr_id': share['id']})
vol = self.api_executor.get_specific_volinfo(vol_no)
vol_size_gb = int(vol.find('size').text) / units.Gi
export_locations = self._get_location_path(
share_name,
share['share_proto'],

View File

@ -138,6 +138,10 @@ FAKE_RES_DETAIL_DATA_VOLUME_INFO = """
<vol_no><![CDATA[fakeNo]]></vol_no>
<size><![CDATA[10]]></size>
<vol_mount_path>fakeMountPath</vol_mount_path>
<dedup><![CDATA[off]]></dedup>
<compression><![CDATA[1]]></compression>
<thin_pro><![CDATA[1]]></thin_pro>
<cache><![CDATA[0]]></cache>
</row>
</Volume_Info>
<result><![CDATA[0]]></result>
@ -325,7 +329,8 @@ class SnapshotClass(object):
'id': 'fakeSnapshotId',
'share': {'share_id': 'fakeShareId', 'id': 'fakeId'},
'share_instance': {'share_id': 'fakeShareId', 'id': 'fakeId'},
'size': self.size
'size': self.size,
'share_instance_id': 'fakeShareId'
}[arg]
def __setitem__(self, key, value):

View File

@ -120,7 +120,11 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
self.share,
'Storage Pool 1',
fake_name,
'NFS')
'NFS',
qnap_deduplication=False,
qnap_compression=True,
qnap_thin_provision=True,
qnap_ssd_cache=False)
fake_params = {
'wiz_func': 'share_create',
@ -130,7 +134,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
'threshold': '80',
'dedup': 'off',
'compression': '1',
'thin_pro': '0',
'thin_pro': '1',
'cache': '0',
'cifs_enable': '0',
'nfs_enable': '1',
@ -457,6 +461,10 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
"sharename": 'fakeVolId',
"old_sharename": 'fakeVolId',
"new_size": 100,
"deduplication": False,
"compression": True,
"thin_provision": True,
"ssd_cache": False,
"share_proto": "NFS"
}
self.driver.api_executor.edit_share(
@ -468,9 +476,9 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
'sharename': 'fakeVolId',
'old_sharename': 'fakeVolId',
'vol_size': '100GB',
'dedup': '0',
'dedup': 'off',
'compression': '1',
'thin_pro': '0',
'thin_pro': '1',
'cache': '0',
'cifs_enable': '0',
'nfs_enable': '1',
@ -736,7 +744,11 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
share=self.share,
pool_name='Storage Pool 1',
create_share_name='fake_share_name',
share_proto='NFS')
share_proto='NFS',
qnap_deduplication=False,
qnap_compression=True,
qnap_thin_provision=True,
qnap_ssd_cache=False)
@ddt.unpack
@ddt.data(['self.driver.api_executor.get_share_info',
@ -803,6 +815,10 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
{'share_dict': {"sharename": 'fakeVolId',
"old_sharename": 'fakeVolId',
"new_size": 100,
"deduplication": False,
"compression": True,
"thin_provision": False,
"ssd_cache": False,
"share_proto": "NFS"}},
fakes.FakeEsResCodeNegativeResponse(),
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
@ -810,6 +826,10 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
{'share_dict': {"sharename": 'fakeVolId',
"old_sharename": 'fakeVolId',
"new_size": 100,
"deduplication": False,
"compression": True,
"thin_provision": False,
"ssd_cache": False,
"share_proto": "NFS"}},
fakes.FakeAuthPassFailResponse(),
fakes.FakeGetBasicInfoResponseEs_1_1_3()],

View File

@ -29,6 +29,7 @@ from eventlet import greenthread
from manila import exception
from manila.share.drivers.qnap import api
from manila.share.drivers.qnap import qnap
from manila.share import share_types
from manila import test
from manila.tests import fake_share
from manila.tests.share.drivers.qnap import fakes
@ -296,12 +297,72 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
return hosts
@ddt.data({
'fake_extra_spec': {},
'expect_extra_spec': {
'qnap_thin_provision': True,
'qnap_compression': True,
'qnap_deduplication': False,
'qnap_ssd_cache': False
}
}, {
'fake_extra_spec': {
'thin_provisioning': u'true',
'compression': u'true',
'qnap_ssd_cache': u'true'
},
'expect_extra_spec': {
'qnap_thin_provision': True,
'qnap_compression': True,
'qnap_deduplication': False,
'qnap_ssd_cache': True
}
}, {
'fake_extra_spec': {
'thin_provisioning': u'<is> False',
'compression': u'<is> True',
'qnap_ssd_cache': u'<is> True'
},
'expect_extra_spec': {
'qnap_thin_provision': False,
'qnap_compression': True,
'qnap_deduplication': False,
'qnap_ssd_cache': True
}
}, {
'fake_extra_spec': {
'thin_provisioning': u'true',
'dedupe': u'<is> True',
'qnap_ssd_cache': u'False'
},
'expect_extra_spec': {
'qnap_thin_provision': True,
'qnap_compression': True,
'qnap_deduplication': True,
'qnap_ssd_cache': False
}
}, {
'fake_extra_spec': {
'thin_provisioning': u'<is> False',
'compression': u'false',
'dedupe': u'<is> False',
'qnap_ssd_cache': u'<is> False'
},
'expect_extra_spec': {
'qnap_thin_provision': False,
'qnap_compression': False,
'qnap_deduplication': False,
'qnap_ssd_cache': False
}
})
@ddt.unpack
@mock.patch.object(qnap.QnapShareDriver, '_get_location_path')
@mock.patch.object(qnap.QnapShareDriver, '_gen_random_name')
def test_create_share_positive(
self,
mock_gen_random_name,
mock_get_location_path):
mock_get_location_path,
fake_extra_spec, expect_extra_spec):
"""Test create share."""
mock_api_executor = qnap.QnapShareDriver._create_api_executor
mock_api_executor.return_value.get_share_info.side_effect = [
@ -315,6 +376,8 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
'qnapadmin', 'Storage Pool 1',
private_storage=mock_private_storage)
self.mock_object(share_types, 'get_extra_specs_from_share',
mock.Mock(return_value=fake_extra_spec))
self.driver.create_share('context', self.share)
mock_api_return = mock_api_executor.return_value
@ -328,7 +391,8 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
self.share,
self.driver.configuration.qnap_poolname,
'fakeShareName',
'NFS')
'NFS',
**expect_extra_spec)
mock_get_location_path.assert_called_once_with(
'fakeShareName', 'NFS', '1.2.3.4', 'fakeNo')
@ -349,6 +413,8 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
'qnapadmin', 'Storage Pool 1',
private_storage=mock_private_storage)
self.mock_object(share_types, 'get_extra_specs_from_share',
mock.Mock(return_value={}))
self.assertRaises(
exception.ShareBackendException,
@ -373,6 +439,8 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
'qnapadmin', 'Storage Pool 1',
private_storage=mock_private_storage)
self.mock_object(share_types, 'get_extra_specs_from_share',
mock.Mock(return_value={}))
self.assertRaises(
exception.ShareBackendException,
@ -380,6 +448,34 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
context='context',
share=self.share)
@mock.patch.object(qnap.QnapShareDriver, '_get_location_path')
@mock.patch.object(qnap.QnapShareDriver, '_gen_random_name')
def test_create_share_negative_configutarion(
self,
mock_gen_random_name,
mock_get_location_path):
"""Test create share."""
mock_api_executor = qnap.QnapShareDriver._create_api_executor
mock_api_executor.return_value.get_share_info.side_effect = [
None, self.get_share_info_return_value()]
mock_gen_random_name.return_value = 'fakeShareName'
mock_get_location_path.return_value = None
mock_private_storage = mock.Mock()
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
'qnapadmin', 'Storage Pool 1',
private_storage=mock_private_storage)
self.mock_object(share_types, 'get_extra_specs_from_share',
mock.Mock(return_value={
'dedupe': 'true',
'thin_provisioning': 'false'}))
self.assertRaises(
exception.InvalidExtraSpec,
self.driver.create_share,
context='context',
share=self.share)
def test_delete_share_positive(self):
"""Test delete share with fake_share."""
mock_api_executor = qnap.QnapShareDriver._create_api_executor
@ -437,7 +533,12 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
self.get_share_info_return_value())
mock_api_executor.return_value.edit_share.return_value = None
mock_private_storage = mock.Mock()
mock_private_storage.get.return_value = 'fakeVolName'
mock_private_storage.get.side_effect = [
'fakeVolName',
'True',
'True',
'False',
'False']
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
'qnapadmin', 'Storage Pool 1',
@ -448,6 +549,10 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
'sharename': 'fakeVolName',
'old_sharename': 'fakeVolName',
'new_size': 100,
'thin_provision': True,
'compression': True,
'deduplication': False,
'ssd_cache': False,
'share_proto': 'NFS'
}
mock_api_executor.return_value.edit_share.assert_called_once_with(
@ -611,7 +716,12 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
mock_api_executor.return_value.get_share_info.side_effect = [
None, self.get_share_info_return_value()]
mock_private_storage = mock.Mock()
mock_private_storage.get.return_value = 'fakeVolName'
mock_private_storage.get.side_effect = [
'True',
'True',
'False',
'False',
'fakeVolName']
mock_share_api.return_value.get.return_value = {'size': 5}
mock_api_executor.return_value.edit_share.return_value = (
None)
@ -637,6 +747,10 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
'sharename': 'fakeShareName',
'old_sharename': 'fakeShareName',
'new_size': 10,
'thin_provision': True,
'compression': True,
'deduplication': False,
'ssd_cache': False,
'share_proto': 'NFS'
}
mock_api_return.edit_share.assert_called_once_with(
@ -816,6 +930,8 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
'qnapadmin', 'Storage Pool 1',
private_storage=mock_private_storage)
self.mock_object(share_types, 'get_extra_specs_from_share',
mock.Mock(return_value={}))
self.driver.manage_existing(self.share, 'driver_options')
mock_api_return = mock_api_executor.return_value
@ -826,6 +942,39 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
mock_get_location_path.assert_called_once_with(
'fakeShareName', 'NFS', '1.2.3.4', 'fakeNo')
@mock.patch.object(qnap.QnapShareDriver, '_get_location_path')
def test_manage_existing_nfs_negative_configutarion(
self,
mock_get_location_path):
"""Test manage existing."""
mock_api_executor = qnap.QnapShareDriver._create_api_executor
mock_api_executor.return_value.get_share_info.return_value = (
self.get_share_info_return_value())
mock_private_storage = mock.Mock()
mock_private_storage.update.return_value = None
mock_private_storage.get.side_effect = [
'fakeVolId',
'fakeVolName']
mock_api_executor.return_value.get_specific_volinfo.return_value = (
self.get_specific_volinfo_return_value())
mock_api_executor.return_value.get_share_info.return_value = (
self.get_share_info_return_value())
mock_get_location_path.return_value = None
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
'qnapadmin', 'Storage Pool 1',
private_storage=mock_private_storage)
self.mock_object(share_types, 'get_extra_specs_from_share',
mock.Mock(return_value={
'dedupe': 'true',
'thin_provisioning': 'false'}))
self.assertRaises(
exception.InvalidExtraSpec,
self.driver.manage_existing,
share=self.share,
driver_options='driver_options')
def test_manage_invalid_protocol(self):
"""Test manage existing."""
share = fake_share.fake_share(

View File

@ -0,0 +1,6 @@
---
features:
- |
Added enhanced support to the QNAP Manila driver, including
``Thin Provisioning``, ``SSD Cache``, ``Deduplication``
and ``Compression``.