QNAP: Add support for QES 1.1.4
This patch do the following changes to the QNAP Manila driver: 1. Add support for QNAP QES firmware 1.1.4. 2. Correct the default parameters in edit share function. 2. Remove unused code flow. 4. Add more debug log and write more test cases. Implements: blueprint support-qes-114 Change-Id: I977ef3e66a21a52116b44059ad5aeaf1560b47b7
This commit is contained in:
parent
3088bf8ebf
commit
4c2b5e9335
@ -39,10 +39,10 @@ MSG_SESSION_EXPIRED = _("Session ID expired")
|
||||
MSG_UNEXPECT_RESP = _("Unexpected response from QNAP API")
|
||||
|
||||
|
||||
@utils.retry(exception=exception.ShareBackendException,
|
||||
retries=5)
|
||||
def _connection_checker(func):
|
||||
"""Decorator to check session has expired or not."""
|
||||
@utils.retry(exception=exception.ShareBackendException,
|
||||
retries=5)
|
||||
@functools.wraps(func)
|
||||
def inner_connection_checker(self, *args, **kwargs):
|
||||
LOG.debug('in _connection_checker')
|
||||
@ -225,7 +225,8 @@ class QnapAPIExecutor(object):
|
||||
if root.find('authPassed').text == '0':
|
||||
raise exception.ShareBackendException(msg=MSG_SESSION_EXPIRED)
|
||||
if root.find('ES_RET_CODE').text < '0':
|
||||
msg = _('Create share %s failed') % share['display_name']
|
||||
msg = _("Fail to create share %s on NAS.") % create_share_name
|
||||
LOG.error(msg)
|
||||
raise exception.ShareBackendException(msg=msg)
|
||||
|
||||
vol_list = root.find('func').find('ownContent').find('volumeList')
|
||||
@ -319,26 +320,22 @@ class QnapAPIExecutor(object):
|
||||
if root.find('authPassed').text == '0':
|
||||
raise exception.ShareBackendException(msg=MSG_SESSION_EXPIRED)
|
||||
|
||||
if ('vol_no' in kwargs) or ('vol_label' in kwargs):
|
||||
vol_list = root.find('Volume_Info')
|
||||
vol_info_tree = vol_list.findall('row')
|
||||
for vol in vol_info_tree:
|
||||
LOG.debug('Iterating vol name: %(name)s, index: %(id)s',
|
||||
{'name': vol.find('vol_label').text,
|
||||
'id': vol.find('vol_no').text})
|
||||
if 'vol_no' in kwargs:
|
||||
if kwargs['vol_no'] == vol.find('vol_no').text:
|
||||
LOG.debug('vol_no:%s',
|
||||
vol.find('vol_no').text)
|
||||
return vol
|
||||
elif 'vol_label' in kwargs:
|
||||
if kwargs['vol_label'] == vol.find('vol_label').text:
|
||||
LOG.debug('vol_label:%s', vol.find('vol_label').text)
|
||||
return vol
|
||||
if vol is vol_info_tree[-1]:
|
||||
return None
|
||||
else:
|
||||
return res_details['data']
|
||||
vol_list = root.find('Volume_Info')
|
||||
vol_info_tree = vol_list.findall('row')
|
||||
for vol in vol_info_tree:
|
||||
LOG.debug('Iterating vol name: %(name)s, index: %(id)s',
|
||||
{'name': vol.find('vol_label').text,
|
||||
'id': vol.find('vol_no').text})
|
||||
if 'vol_no' in kwargs:
|
||||
if kwargs['vol_no'] == vol.find('vol_no').text:
|
||||
LOG.debug('vol_no:%s',
|
||||
vol.find('vol_no').text)
|
||||
return vol
|
||||
elif 'vol_label' in kwargs:
|
||||
if kwargs['vol_label'] == vol.find('vol_label').text:
|
||||
LOG.debug('vol_label:%s', vol.find('vol_label').text)
|
||||
return vol
|
||||
return None
|
||||
|
||||
@_connection_checker
|
||||
def get_specific_volinfo(self, vol_id, **kwargs):
|
||||
@ -453,9 +450,11 @@ class QnapAPIExecutor(object):
|
||||
raise exception.ShareBackendException(msg=MSG_SESSION_EXPIRED)
|
||||
# snapshot not exist
|
||||
if root.find('result').text == '-206021':
|
||||
LOG.warning('Snapshot id %s does not exist', snapshot_id)
|
||||
return
|
||||
# lun not exist
|
||||
# share not exist
|
||||
if root.find('result').text == '-200005':
|
||||
LOG.warning('Share of snapshot id %s does not exist', snapshot_id)
|
||||
return
|
||||
if root.find('result').text < '0':
|
||||
msg = _('Failed to delete snapshot.')
|
||||
@ -499,8 +498,10 @@ class QnapAPIExecutor(object):
|
||||
'compression': '1',
|
||||
'thin_pro': '0',
|
||||
'cache': '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',
|
||||
'ftp_enable': '1',
|
||||
'ftp_enable': '0',
|
||||
'hidden': '0',
|
||||
'oplocks': '1',
|
||||
'sync': 'always',
|
||||
|
@ -61,9 +61,10 @@ class QnapShareDriver(driver.ShareDriver):
|
||||
|
||||
Version history:
|
||||
1.0.0 - Initial driver (Only NFS)
|
||||
1.0.1 - Add support for QES fw 1.1.4.
|
||||
"""
|
||||
|
||||
DRIVER_VERSION = '1.0.0'
|
||||
DRIVER_VERSION = '1.0.1'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize QnapShareDriver."""
|
||||
@ -152,17 +153,14 @@ class QnapShareDriver(driver.ShareDriver):
|
||||
username=self.configuration.qnap_nas_login,
|
||||
password=self.configuration.qnap_nas_password,
|
||||
management_url=self.configuration.qnap_management_url)
|
||||
|
||||
if (fw_version.startswith("1.1.2") or
|
||||
fw_version.startswith("1.1.3")):
|
||||
elif "1.1.2" <= fw_version <= "1.1.4":
|
||||
LOG.debug('Create ES API Executor')
|
||||
return api.QnapAPIExecutor(
|
||||
username=self.configuration.qnap_nas_login,
|
||||
password=self.configuration.qnap_nas_password,
|
||||
management_url=self.configuration.qnap_management_url)
|
||||
elif model_type in es_model_types:
|
||||
if (fw_version.startswith("1.1.2") or
|
||||
fw_version.startswith("1.1.3")):
|
||||
if "1.1.2" <= fw_version <= "1.1.4":
|
||||
LOG.debug('Create ES API Executor')
|
||||
return api.QnapAPIExecutor(
|
||||
username=self.configuration.qnap_nas_login,
|
||||
@ -195,13 +193,9 @@ class QnapShareDriver(driver.ShareDriver):
|
||||
{'ifx': infix,
|
||||
'time': timeutils.utcnow().strftime('%Y%m%d%H%M%S%f')})
|
||||
|
||||
def _get_location_path(self, share_name, share_proto, ip):
|
||||
def _get_location_path(self, share_name, share_proto, ip, vol_id):
|
||||
if share_proto == 'NFS':
|
||||
created_share = self.api_executor.get_share_info(
|
||||
self.configuration.qnap_poolname,
|
||||
vol_label=share_name)
|
||||
vol_no = created_share.find('vol_no').text
|
||||
vol = self.api_executor.get_specific_volinfo(vol_no)
|
||||
vol = self.api_executor.get_specific_volinfo(vol_id)
|
||||
vol_mount_path = vol.find('vol_mount_path').text
|
||||
|
||||
location = '%s:%s' % (ip, vol_mount_path)
|
||||
@ -263,7 +257,8 @@ class QnapShareDriver(driver.ShareDriver):
|
||||
|
||||
@utils.retry(exception=exception.ShareBackendException,
|
||||
interval=3,
|
||||
retries=200)
|
||||
retries=5)
|
||||
@utils.synchronized('qnap-create_share')
|
||||
def create_share(self, context, share, share_server=None):
|
||||
"""Create a new share."""
|
||||
LOG.debug('share: %s', share.__dict__)
|
||||
@ -277,25 +272,48 @@ class QnapShareDriver(driver.ShareDriver):
|
||||
created_share = self.api_executor.get_share_info(
|
||||
self.configuration.qnap_poolname,
|
||||
vol_label=create_share_name)
|
||||
|
||||
LOG.debug('created_share: %s', created_share)
|
||||
if created_share is not None:
|
||||
msg = _("Failed to create an unused share name.")
|
||||
msg = (_("The share name %s is used by other share on NAS.") %
|
||||
create_share_name)
|
||||
LOG.error(msg)
|
||||
raise exception.ShareBackendException(msg=msg)
|
||||
|
||||
create_volID = self.api_executor.create_share(
|
||||
self.api_executor.create_share(
|
||||
share,
|
||||
self.configuration.qnap_poolname,
|
||||
create_share_name,
|
||||
share_proto)
|
||||
|
||||
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.
|
||||
_metadata = {'volID': create_volID, 'volName': create_share_name}
|
||||
LOG.debug('volID: %(volID)s '
|
||||
'volName: %(create_share_name)s',
|
||||
{'volID': volID,
|
||||
'create_share_name': create_share_name})
|
||||
_metadata = {'volID': volID,
|
||||
'volName': create_share_name}
|
||||
self.private_storage.update(share['id'], _metadata)
|
||||
|
||||
return self._get_location_path(create_share_name,
|
||||
share['share_proto'],
|
||||
self.configuration.qnap_share_ip)
|
||||
self.configuration.qnap_share_ip,
|
||||
volID)
|
||||
|
||||
@utils.retry(exception=exception.ShareBackendException,
|
||||
interval=5, retries=5, backoff_rate=1)
|
||||
def _get_share_info(self, share_name):
|
||||
share = self.api_executor.get_share_info(
|
||||
self.configuration.qnap_poolname,
|
||||
vol_label=share_name)
|
||||
if share is None:
|
||||
msg = _("Fail to get share info of %s on NAS.") % share_name
|
||||
LOG.error(msg)
|
||||
raise exception.ShareBackendException(msg=msg)
|
||||
else:
|
||||
return share
|
||||
|
||||
@utils.synchronized('qnap-delete_share')
|
||||
def delete_share(self, context, share, share_server=None):
|
||||
"""Delete the specified share."""
|
||||
# Use private_storage to retrieve volume ID created in the NAS.
|
||||
@ -317,11 +335,15 @@ class QnapShareDriver(driver.ShareDriver):
|
||||
self.api_executor.delete_share(vol_no)
|
||||
self.private_storage.delete(share['id'])
|
||||
|
||||
@utils.synchronized('qnap-extend_share')
|
||||
def extend_share(self, share, new_size, share_server=None):
|
||||
"""Extend an existing share."""
|
||||
LOG.debug('Entering extend_share share=%(share)s '
|
||||
LOG.debug('Entering extend_share share_name=%(share_name)s '
|
||||
'share_id=%(share_id)s '
|
||||
'new_size=%(size)s',
|
||||
{'share': share['display_name'], 'size': new_size})
|
||||
{'share_name': share['display_name'],
|
||||
'share_id': share['id'],
|
||||
'size': new_size})
|
||||
|
||||
# Use private_storage to retrieve volume Name created in the NAS.
|
||||
volName = self.private_storage.get(share['id'], 'volName')
|
||||
@ -331,15 +353,17 @@ class QnapShareDriver(driver.ShareDriver):
|
||||
LOG.debug('volName: %s', volName)
|
||||
|
||||
share_dict = {
|
||||
"sharename": volName,
|
||||
"old_sharename": volName,
|
||||
"new_size": new_size,
|
||||
'sharename': volName,
|
||||
'old_sharename': volName,
|
||||
'new_size': new_size,
|
||||
'share_proto': share['share_proto']
|
||||
}
|
||||
self.api_executor.edit_share(share_dict)
|
||||
|
||||
@utils.retry(exception=exception.ShareBackendException,
|
||||
interval=3,
|
||||
retries=200)
|
||||
retries=5)
|
||||
@utils.synchronized('qnap-create_snapshot')
|
||||
def create_snapshot(self, context, snapshot, share_server=None):
|
||||
"""Create a snapshot."""
|
||||
LOG.debug('snapshot[share][share_id]: %s',
|
||||
@ -393,6 +417,7 @@ class QnapShareDriver(driver.ShareDriver):
|
||||
|
||||
return {'provider_location': snapshot_id}
|
||||
|
||||
@utils.synchronized('qnap-delete_snapshot')
|
||||
def delete_snapshot(self, context, snapshot, share_server=None):
|
||||
"""Delete a snapshot."""
|
||||
LOG.debug('Entering delete_snapshot. The deleted snapshot=%(snap)s',
|
||||
@ -410,7 +435,8 @@ class QnapShareDriver(driver.ShareDriver):
|
||||
|
||||
@utils.retry(exception=exception.ShareBackendException,
|
||||
interval=3,
|
||||
retries=200)
|
||||
retries=5)
|
||||
@utils.synchronized('qnap-create_share_from_snapshot')
|
||||
def create_share_from_snapshot(self, context, share, snapshot,
|
||||
share_server=None):
|
||||
"""Create a share from a snapshot."""
|
||||
@ -441,20 +467,24 @@ class QnapShareDriver(driver.ShareDriver):
|
||||
created_share = self.api_executor.get_share_info(
|
||||
self.configuration.qnap_poolname,
|
||||
vol_label=create_share_name)
|
||||
if created_share.find('vol_no') is not None:
|
||||
if created_share is not None:
|
||||
create_volID = created_share.find('vol_no').text
|
||||
LOG.debug('create_volID: %s', create_volID)
|
||||
else:
|
||||
msg = _("Failed to clone a snapshot in time.")
|
||||
raise exception.ShareBackendException(msg=msg)
|
||||
|
||||
snap_share = self.share_api.get(context,
|
||||
snapshot['share_instance']['share_id'])
|
||||
snap_share = self.share_api.get(
|
||||
context, snapshot['share_instance']['share_id'])
|
||||
LOG.debug('snap_share[size]: %s', snap_share['size'])
|
||||
|
||||
if (share['size'] > snap_share['size']):
|
||||
share_dict = {'sharename': create_share_name,
|
||||
'old_sharename': create_share_name,
|
||||
'new_size': share['size']}
|
||||
share_dict = {
|
||||
'sharename': create_share_name,
|
||||
'old_sharename': create_share_name,
|
||||
'new_size': share['size'],
|
||||
'share_proto': share['share_proto']
|
||||
}
|
||||
self.api_executor.edit_share(share_dict)
|
||||
|
||||
# Use private_storage to record volume ID and Name created in the NAS.
|
||||
@ -470,7 +500,8 @@ class QnapShareDriver(driver.ShareDriver):
|
||||
|
||||
return self._get_location_path(create_share_name,
|
||||
share['share_proto'],
|
||||
self.configuration.qnap_share_ip)
|
||||
self.configuration.qnap_share_ip,
|
||||
create_volID)
|
||||
|
||||
def _get_manila_hostIPv4s(self, hostlist):
|
||||
host_dict_IPs = []
|
||||
@ -656,7 +687,8 @@ class QnapShareDriver(driver.ShareDriver):
|
||||
export_locations = self._get_location_path(
|
||||
share_name,
|
||||
share['share_proto'],
|
||||
self.configuration.qnap_share_ip)
|
||||
self.configuration.qnap_share_ip,
|
||||
vol_no)
|
||||
|
||||
return {'size': vol_size_gb, 'export_locations': export_locations}
|
||||
|
||||
|
@ -19,7 +19,18 @@ FAKE_RES_DETAIL_DATA_LOGIN = """
|
||||
<authSid><![CDATA[fakeSid]]></authSid>
|
||||
</QDocRoot>"""
|
||||
|
||||
FAKE_RES_DETAIL_DATA_GETBASIC_INFO_ES = """
|
||||
FAKE_RES_DETAIL_DATA_GETBASIC_INFO_ES_1_1_1 = """
|
||||
<QDocRoot version="1.0">
|
||||
<model>
|
||||
<displayModelName><![CDATA[ES1640dc]]></displayModelName>
|
||||
<internalModelName><![CDATA[ES1640dc]]></internalModelName>
|
||||
</model>
|
||||
<firmware>
|
||||
<version><![CDATA[1.1.1]]></version>
|
||||
</firmware>
|
||||
</QDocRoot>"""
|
||||
|
||||
FAKE_RES_DETAIL_DATA_GETBASIC_INFO_ES_1_1_3 = """
|
||||
<QDocRoot version="1.0">
|
||||
<model>
|
||||
<displayModelName><![CDATA[ES1640dc]]></displayModelName>
|
||||
@ -30,7 +41,18 @@ FAKE_RES_DETAIL_DATA_GETBASIC_INFO_ES = """
|
||||
</firmware>
|
||||
</QDocRoot>"""
|
||||
|
||||
FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TS = """
|
||||
FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TS_4_0_0 = """
|
||||
<QDocRoot version="1.0">
|
||||
<model>
|
||||
<displayModelName><![CDATA[TS-870U]]></displayModelName>
|
||||
<internalModelName><![CDATA[TS-870U]]></internalModelName>
|
||||
</model>
|
||||
<firmware>
|
||||
<version><![CDATA[4.0.0]]></version>
|
||||
</firmware>
|
||||
</QDocRoot>"""
|
||||
|
||||
FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TS_4_3_0 = """
|
||||
<QDocRoot version="1.0">
|
||||
<model>
|
||||
<displayModelName><![CDATA[TS-870U]]></displayModelName>
|
||||
@ -41,7 +63,18 @@ FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TS = """
|
||||
</firmware>
|
||||
</QDocRoot>"""
|
||||
|
||||
FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_TS = """
|
||||
FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_TS_4_0_0 = """
|
||||
<QDocRoot version="1.0">
|
||||
<model>
|
||||
<displayModelName><![CDATA[TES-1885U]]></displayModelName>
|
||||
<internalModelName><![CDATA[TS-1885U]]></internalModelName>
|
||||
</model>
|
||||
<firmware>
|
||||
<version><![CDATA[4.0.0]]></version>
|
||||
</firmware>
|
||||
</QDocRoot>"""
|
||||
|
||||
FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_TS_4_3_0 = """
|
||||
<QDocRoot version="1.0">
|
||||
<model>
|
||||
<displayModelName><![CDATA[TES-1885U]]></displayModelName>
|
||||
@ -52,7 +85,18 @@ FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_TS = """
|
||||
</firmware>
|
||||
</QDocRoot>"""
|
||||
|
||||
FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_ES = """
|
||||
FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_ES_1_1_1 = """
|
||||
<QDocRoot version="1.0">
|
||||
<model>
|
||||
<displayModelName><![CDATA[TES-1885U]]></displayModelName>
|
||||
<internalModelName><![CDATA[ES-1885U]]></internalModelName>
|
||||
</model>
|
||||
<firmware>
|
||||
<version><![CDATA[1.1.1]]></version>
|
||||
</firmware>
|
||||
</QDocRoot>"""
|
||||
|
||||
FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_ES_1_1_3 = """
|
||||
<QDocRoot version="1.0">
|
||||
<model>
|
||||
<displayModelName><![CDATA[TES-1885U]]></displayModelName>
|
||||
@ -208,6 +252,20 @@ FAKE_RES_DETAIL_DATA_DELETE_SNAPSHOT = """
|
||||
<result>0</result>
|
||||
</QDocRoot>"""
|
||||
|
||||
FAKE_RES_DETAIL_DATA_DELETE_SNAPSHOT_SNAPSHOT_NOT_EXIST = """
|
||||
<QDocRoot version="1.0">
|
||||
<authPassed><![CDATA[1]]></authPassed>
|
||||
<ES_RET_CODE><![CDATA[1]]></ES_RET_CODE>
|
||||
<result>-206021</result>
|
||||
</QDocRoot>"""
|
||||
|
||||
FAKE_RES_DETAIL_DATA_DELETE_SNAPSHOT_SHARE_NOT_EXIST = """
|
||||
<QDocRoot version="1.0">
|
||||
<authPassed><![CDATA[1]]></authPassed>
|
||||
<ES_RET_CODE><![CDATA[1]]></ES_RET_CODE>
|
||||
<result>-200005</result>
|
||||
</QDocRoot>"""
|
||||
|
||||
FAKE_RES_DETAIL_DATA_GET_HOST_LIST_API = """
|
||||
<QDocRoot version="1.0">
|
||||
<authPassed><![CDATA[1]]></authPassed>
|
||||
@ -347,44 +405,84 @@ class AccessClass(object):
|
||||
}[arg]
|
||||
|
||||
|
||||
class FakeGetBasicInfoResponseEs(object):
|
||||
class FakeGetBasicInfoResponseEs_1_1_1(object):
|
||||
"""Fake GetBasicInfo response from ES nas."""
|
||||
|
||||
status = 'fackStatus'
|
||||
|
||||
def read(self):
|
||||
"""Mock response.read."""
|
||||
return FAKE_RES_DETAIL_DATA_GETBASIC_INFO_ES
|
||||
return FAKE_RES_DETAIL_DATA_GETBASIC_INFO_ES_1_1_1
|
||||
|
||||
|
||||
class FakeGetBasicInfoResponseTs(object):
|
||||
class FakeGetBasicInfoResponseEs_1_1_3(object):
|
||||
"""Fake GetBasicInfo response from ES nas."""
|
||||
|
||||
status = 'fackStatus'
|
||||
|
||||
def read(self):
|
||||
"""Mock response.read."""
|
||||
return FAKE_RES_DETAIL_DATA_GETBASIC_INFO_ES_1_1_3
|
||||
|
||||
|
||||
class FakeGetBasicInfoResponseTs_4_0_0(object):
|
||||
"""Fake GetBasicInfoTS response from TS nas."""
|
||||
|
||||
status = 'fackStatus'
|
||||
|
||||
def read(self):
|
||||
"""Mock response.read."""
|
||||
return FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TS
|
||||
return FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TS_4_0_0
|
||||
|
||||
|
||||
class FakeGetBasicInfoResponseTesTs(object):
|
||||
class FakeGetBasicInfoResponseTs_4_3_0(object):
|
||||
"""Fake GetBasicInfoTS response from TS nas."""
|
||||
|
||||
status = 'fackStatus'
|
||||
|
||||
def read(self):
|
||||
"""Mock response.read."""
|
||||
return FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_TS
|
||||
return FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TS_4_3_0
|
||||
|
||||
|
||||
class FakeGetBasicInfoResponseTesEs(object):
|
||||
class FakeGetBasicInfoResponseTesTs_4_0_0(object):
|
||||
"""Fake GetBasicInfoTS response from TS nas."""
|
||||
|
||||
status = 'fackStatus'
|
||||
|
||||
def read(self):
|
||||
"""Mock response.read."""
|
||||
return FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_ES
|
||||
return FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_TS_4_0_0
|
||||
|
||||
|
||||
class FakeGetBasicInfoResponseTesTs_4_3_0(object):
|
||||
"""Fake GetBasicInfoTS response from TS nas."""
|
||||
|
||||
status = 'fackStatus'
|
||||
|
||||
def read(self):
|
||||
"""Mock response.read."""
|
||||
return FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_TS_4_3_0
|
||||
|
||||
|
||||
class FakeGetBasicInfoResponseTesEs_1_1_1(object):
|
||||
"""Fake GetBasicInfoTS response from TS nas."""
|
||||
|
||||
status = 'fackStatus'
|
||||
|
||||
def read(self):
|
||||
"""Mock response.read."""
|
||||
return FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_ES_1_1_1
|
||||
|
||||
|
||||
class FakeGetBasicInfoResponseTesEs_1_1_3(object):
|
||||
"""Fake GetBasicInfoTS response from TS nas."""
|
||||
|
||||
status = 'fackStatus'
|
||||
|
||||
def read(self):
|
||||
"""Mock response.read."""
|
||||
return FAKE_RES_DETAIL_DATA_GETBASIC_INFO_TES_ES_1_1_3
|
||||
|
||||
|
||||
class FakeGetBasicInfoResponseError(object):
|
||||
@ -418,7 +516,7 @@ class FakeDeleteShareResponse(object):
|
||||
|
||||
|
||||
class FakeDeleteSnapshotResponse(object):
|
||||
"""Fake pool info response."""
|
||||
"""Fake delete snapshot response."""
|
||||
|
||||
status = 'fackStatus'
|
||||
|
||||
@ -427,6 +525,26 @@ class FakeDeleteSnapshotResponse(object):
|
||||
return FAKE_RES_DETAIL_DATA_DELETE_SNAPSHOT
|
||||
|
||||
|
||||
class FakeDeleteSnapshotResponseSnapshotNotExist(object):
|
||||
"""Fake delete snapshot response."""
|
||||
|
||||
status = 'fackStatus'
|
||||
|
||||
def read(self):
|
||||
"""Mock response.read."""
|
||||
return FAKE_RES_DETAIL_DATA_DELETE_SNAPSHOT_SNAPSHOT_NOT_EXIST
|
||||
|
||||
|
||||
class FakeDeleteSnapshotResponseShareNotExist(object):
|
||||
"""Fake delete snapshot response."""
|
||||
|
||||
status = 'fackStatus'
|
||||
|
||||
def read(self):
|
||||
"""Mock response.read."""
|
||||
return FAKE_RES_DETAIL_DATA_DELETE_SNAPSHOT_SHARE_NOT_EXIST
|
||||
|
||||
|
||||
class FakeGetHostListResponse(object):
|
||||
"""Fake pool info response."""
|
||||
|
||||
|
@ -19,6 +19,7 @@ import ddt
|
||||
import mock
|
||||
import six
|
||||
from six.moves import urllib
|
||||
import time
|
||||
|
||||
from manila import exception
|
||||
from manila.share.drivers.qnap import qnap
|
||||
@ -106,7 +107,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeCreateShareResponse()]
|
||||
|
||||
@ -164,7 +165,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeDeleteShareResponse()]
|
||||
|
||||
@ -198,7 +199,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeSpecificPoolInfoResponse()]
|
||||
|
||||
@ -235,7 +236,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeShareInfoResponse()]
|
||||
|
||||
@ -268,7 +269,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeSpecificVolInfoResponse()]
|
||||
|
||||
@ -302,7 +303,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeSnapshotInfoResponse()]
|
||||
|
||||
@ -337,7 +338,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeCreateSnapshotResponse()]
|
||||
|
||||
@ -368,14 +369,17 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
expected_call_list,
|
||||
mock_http_connection.return_value.request.call_args_list)
|
||||
|
||||
def test_delete_snapshot_api(self):
|
||||
@ddt.data(fakes.FakeDeleteSnapshotResponse(),
|
||||
fakes.FakeDeleteSnapshotResponseSnapshotNotExist(),
|
||||
fakes.FakeDeleteSnapshotResponseShareNotExist())
|
||||
def test_delete_snapshot_api(self, fakeDeleteSnapshotResponse):
|
||||
"""Test delete snapshot api."""
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeDeleteSnapshotResponse()]
|
||||
fakeDeleteSnapshotResponse]
|
||||
|
||||
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
|
||||
'qnapadmin', 'Storage Pool 1')
|
||||
@ -405,7 +409,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeDeleteSnapshotResponse()]
|
||||
|
||||
@ -440,7 +444,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseTs(),
|
||||
fakes.FakeGetBasicInfoResponseTs_4_3_0(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeCreateSnapshotResponse()]
|
||||
|
||||
@ -450,6 +454,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
"sharename": 'fakeVolId',
|
||||
"old_sharename": 'fakeVolId',
|
||||
"new_size": 100,
|
||||
"share_proto": "NFS"
|
||||
}
|
||||
self.driver.api_executor.edit_share(
|
||||
expect_share_dict)
|
||||
@ -464,8 +469,10 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
'compression': '1',
|
||||
'thin_pro': '0',
|
||||
'cache': '0',
|
||||
'cifs_enable': '0',
|
||||
'nfs_enable': '1',
|
||||
'afp_enable': '0',
|
||||
'ftp_enable': '1',
|
||||
'ftp_enable': '0',
|
||||
'hidden': '0',
|
||||
'oplocks': '1',
|
||||
'sync': 'always',
|
||||
@ -491,7 +498,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetHostListResponse()]
|
||||
|
||||
@ -523,7 +530,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetHostListResponse()]
|
||||
|
||||
@ -558,7 +565,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetHostListResponse()]
|
||||
|
||||
@ -594,7 +601,7 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseTs(),
|
||||
fakes.FakeGetBasicInfoResponseTs_4_3_0(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeSnapshotInfoResponse()]
|
||||
|
||||
@ -633,14 +640,20 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
mock_http_connection = six.moves.http_client.HTTPConnection
|
||||
mock_http_connection.return_value.getresponse.side_effect = [
|
||||
fakes.FakeLoginResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs(),
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
fakes.FakeLoginResponse(),
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response]
|
||||
|
||||
self.mock_object(time, 'sleep')
|
||||
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
|
||||
'qnapadmin', 'Storage Pool 1')
|
||||
self.assertRaises(
|
||||
@ -655,115 +668,117 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
@ddt.data(['self.driver.api_executor.get_share_info',
|
||||
{'pool_id': 'fakeId'},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.get_specific_volinfo',
|
||||
{'vol_id': 'fakeId'},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.create_snapshot_api',
|
||||
{'volumeID': 'fakeVolumeId',
|
||||
'snapshot_name': 'fakeSnapshotName'},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.create_snapshot_api',
|
||||
{'volumeID': 'fakeVolumeId',
|
||||
'snapshot_name': 'fakeSnapshotName'},
|
||||
fakes.FakeEsResCodeNegativeResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.get_snapshot_info',
|
||||
{'volID': 'volId'},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.get_snapshot_info',
|
||||
{'volID': 'volId'},
|
||||
fakes.FakeResultNegativeResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.get_specific_poolinfo',
|
||||
{'pool_id': 'Storage Pool 1'},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.get_specific_poolinfo',
|
||||
{'pool_id': 'Storage Pool 1'},
|
||||
fakes.FakeResultNegativeResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.delete_share',
|
||||
{'vol_id': 'fakeId'},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.delete_share',
|
||||
{'vol_id': 'fakeId'},
|
||||
fakes.FakeResultNegativeResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.delete_snapshot_api',
|
||||
{'snapshot_id': 'fakeSnapshotId'},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.delete_snapshot_api',
|
||||
{'snapshot_id': 'fakeSnapshotId'},
|
||||
fakes.FakeResultNegativeResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.clone_snapshot',
|
||||
{'snapshot_id': 'fakeSnapshotId',
|
||||
'new_sharename': 'fakeNewShareName'},
|
||||
fakes.FakeResultNegativeResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.clone_snapshot',
|
||||
{'snapshot_id': 'fakeSnapshotId',
|
||||
'new_sharename': 'fakeNewShareName'},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.edit_share',
|
||||
{'share_dict': {"sharename": 'fakeVolId',
|
||||
"old_sharename": 'fakeVolId',
|
||||
"new_size": 100}},
|
||||
"new_size": 100,
|
||||
"share_proto": "NFS"}},
|
||||
fakes.FakeEsResCodeNegativeResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.edit_share',
|
||||
{'share_dict': {"sharename": 'fakeVolId',
|
||||
"old_sharename": 'fakeVolId',
|
||||
"new_size": 100}},
|
||||
"new_size": 100,
|
||||
"share_proto": "NFS"}},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.add_host',
|
||||
{'hostname': 'fakeHostName',
|
||||
'ipv4': 'fakeIpV4'},
|
||||
fakes.FakeResultNegativeResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.add_host',
|
||||
{'hostname': 'fakeHostName',
|
||||
'ipv4': 'fakeIpV4'},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.get_host_list',
|
||||
{},
|
||||
fakes.FakeResultNegativeResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.get_host_list',
|
||||
{},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.set_nfs_access',
|
||||
{'sharename': 'fakeShareName',
|
||||
'access': 'fakeAccess',
|
||||
'host_name': 'fakeHostName'},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.set_nfs_access',
|
||||
{'sharename': 'fakeShareName',
|
||||
'access': 'fakeAccess',
|
||||
'host_name': 'fakeHostName'},
|
||||
fakes.FakeResultNegativeResponse(),
|
||||
fakes.FakeGetBasicInfoResponseEs()],
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3()],
|
||||
['self.driver.api_executor.get_snapshot_info',
|
||||
{'snapshot_name': 'fakeSnapshoName',
|
||||
'lun_index': 'fakeLunIndex'},
|
||||
fakes.FakeAuthPassFailResponse(),
|
||||
fakes.FakeGetBasicInfoResponseTs()],
|
||||
fakes.FakeGetBasicInfoResponseTs_4_3_0()],
|
||||
['self.driver.api_executor.get_snapshot_info',
|
||||
{'snapshot_name': 'fakeSnapshoName',
|
||||
'lun_index': 'fakeLunIndex'},
|
||||
fakes.FakeResultNegativeResponse(),
|
||||
fakes.FakeGetBasicInfoResponseTs()])
|
||||
fakes.FakeGetBasicInfoResponseTs_4_3_0()])
|
||||
def test_get_snapshot_info_ts_with_fail_response(
|
||||
self, api, dict_parm,
|
||||
fake_fail_response, fake_basic_info):
|
||||
@ -777,11 +792,16 @@ class QnapAPITestCase(QnapShareDriverBaseTestCase):
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response,
|
||||
fake_fail_response]
|
||||
|
||||
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
|
||||
'qnapadmin', 'Storage Pool 1')
|
||||
|
||||
self.mock_object(time, 'sleep')
|
||||
self.assertRaises(
|
||||
exception.ShareBackendException,
|
||||
eval(api),
|
||||
|
@ -23,8 +23,11 @@ import ddt
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
import six
|
||||
import time
|
||||
|
||||
from eventlet import greenthread
|
||||
from manila import exception
|
||||
from manila.share.drivers.qnap import api
|
||||
from manila.share.drivers.qnap import qnap
|
||||
from manila import test
|
||||
from manila.tests import fake_share
|
||||
@ -86,7 +89,8 @@ class QnapShareDriverLoginTestCase(QnapShareDriverBaseTestCase):
|
||||
def test_do_setup_positive(self, mng_url, port, ssl):
|
||||
"""Test do_setup with http://1.2.3.4:8080."""
|
||||
fake_login_response = fakes.FakeLoginResponse()
|
||||
fake_get_basic_info_response_es = fakes.FakeGetBasicInfoResponseEs()
|
||||
fake_get_basic_info_response_es = (
|
||||
fakes.FakeGetBasicInfoResponseEs_1_1_3())
|
||||
if ssl:
|
||||
mock_connection = six.moves.http_client.HTTPSConnection
|
||||
else:
|
||||
@ -117,13 +121,12 @@ class QnapShareDriverLoginTestCase(QnapShareDriverBaseTestCase):
|
||||
self.assertEqual(port, self.driver.api_executor.port)
|
||||
self.assertEqual(ssl, self.driver.api_executor.ssl)
|
||||
|
||||
@ddt.data(fakes.FakeGetBasicInfoResponseTs(),
|
||||
fakes.FakeGetBasicInfoResponseTesTs(),
|
||||
fakes.FakeGetBasicInfoResponseTesEs())
|
||||
@ddt.data(fakes.FakeGetBasicInfoResponseTs_4_3_0(),
|
||||
fakes.FakeGetBasicInfoResponseTesTs_4_3_0(),
|
||||
fakes.FakeGetBasicInfoResponseTesEs_1_1_3())
|
||||
def test_do_setup_positive_with_diff_nas(self, fake_basic_info):
|
||||
"""Test do_setup with different NAS model."""
|
||||
fake_login_response = fakes.FakeLoginResponse()
|
||||
# fake_get_basic_info_response_ts = FakeGetBasicInfoResponseTs()
|
||||
mock_connection = six.moves.http_client.HTTPSConnection
|
||||
mock_connection.return_value.getresponse.side_effect = [
|
||||
fake_login_response,
|
||||
@ -140,6 +143,64 @@ class QnapShareDriverLoginTestCase(QnapShareDriverBaseTestCase):
|
||||
self.assertEqual('443', self.driver.api_executor.port)
|
||||
self.assertTrue(self.driver.api_executor.ssl)
|
||||
|
||||
@ddt.data({
|
||||
'fake_basic_info': fakes.FakeGetBasicInfoResponseTs_4_3_0(),
|
||||
'expect_result': api.QnapAPIExecutorTS
|
||||
}, {
|
||||
'fake_basic_info': fakes.FakeGetBasicInfoResponseTesTs_4_3_0(),
|
||||
'expect_result': api.QnapAPIExecutorTS
|
||||
}, {
|
||||
'fake_basic_info': fakes.FakeGetBasicInfoResponseTesEs_1_1_3(),
|
||||
'expect_result': api.QnapAPIExecutor
|
||||
}, {
|
||||
'fake_basic_info': fakes.FakeGetBasicInfoResponseEs_1_1_3(),
|
||||
'expect_result': api.QnapAPIExecutor
|
||||
})
|
||||
@ddt.unpack
|
||||
def test_create_api_executor(self, fake_basic_info, expect_result):
|
||||
"""Test do_setup with different NAS model."""
|
||||
fake_login_response = fakes.FakeLoginResponse()
|
||||
mock_connection = six.moves.http_client.HTTPSConnection
|
||||
mock_connection.return_value.getresponse.side_effect = [
|
||||
fake_login_response,
|
||||
fake_basic_info,
|
||||
fake_login_response]
|
||||
self._do_setup('https://1.2.3.4:443', '1.2.3.4', 'admin',
|
||||
'qnapadmin', 'Storage Pool 1')
|
||||
self.assertIsInstance(self.driver.api_executor, expect_result)
|
||||
|
||||
@ddt.data({
|
||||
'fake_basic_info': fakes.FakeGetBasicInfoResponseTs_4_0_0(),
|
||||
'expect_result': exception.ShareBackendException
|
||||
}, {
|
||||
'fake_basic_info': fakes.FakeGetBasicInfoResponseTesTs_4_0_0(),
|
||||
'expect_result': exception.ShareBackendException
|
||||
}, {
|
||||
'fake_basic_info': fakes.FakeGetBasicInfoResponseTesEs_1_1_1(),
|
||||
'expect_result': exception.ShareBackendException
|
||||
}, {
|
||||
'fake_basic_info': fakes.FakeGetBasicInfoResponseEs_1_1_1(),
|
||||
'expect_result': exception.ShareBackendException
|
||||
})
|
||||
@ddt.unpack
|
||||
def test_create_api_executor_negative(self,
|
||||
fake_basic_info, expect_result):
|
||||
"""Test do_setup with different NAS model."""
|
||||
fake_login_response = fakes.FakeLoginResponse()
|
||||
mock_connection = six.moves.http_client.HTTPSConnection
|
||||
mock_connection.return_value.getresponse.side_effect = [
|
||||
fake_login_response,
|
||||
fake_basic_info,
|
||||
fake_login_response]
|
||||
self.assertRaises(
|
||||
exception.ShareBackendException,
|
||||
self._do_setup,
|
||||
'https://1.2.3.4:443',
|
||||
'1.2.3.4',
|
||||
'admin',
|
||||
'qnapadmin',
|
||||
'Storage Pool 1')
|
||||
|
||||
def test_do_setup_with_exception(self):
|
||||
"""Test do_setup with exception."""
|
||||
fake_login_response = fakes.FakeLoginResponse()
|
||||
@ -243,28 +304,81 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
|
||||
mock_get_location_path):
|
||||
"""Test create share."""
|
||||
mock_api_executor = qnap.QnapShareDriver._create_api_executor
|
||||
mock_api_executor.return_value.get_share_info.return_value = None
|
||||
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_api_executor.return_value.create_share.return_value = (
|
||||
'fakeCreateShareId')
|
||||
mock_get_location_path.return_value = None
|
||||
mock_private_storage = mock.Mock()
|
||||
|
||||
self.mock_object(greenthread, 'sleep')
|
||||
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
|
||||
'qnapadmin', 'Storage Pool 1',
|
||||
private_storage=mock_private_storage)
|
||||
self.driver.create_share('context', self.share)
|
||||
|
||||
mock_api_executor.return_value.get_share_info.assert_called_once_with(
|
||||
'Storage Pool 1',
|
||||
vol_label='fakeShareName')
|
||||
mock_api_return = mock_api_executor.return_value
|
||||
expected_call_list = [
|
||||
mock.call('Storage Pool 1', vol_label='fakeShareName'),
|
||||
mock.call('Storage Pool 1', vol_label='fakeShareName')]
|
||||
self.assertEqual(
|
||||
expected_call_list,
|
||||
mock_api_return.get_share_info.call_args_list)
|
||||
mock_api_executor.return_value.create_share.assert_called_once_with(
|
||||
self.share,
|
||||
self.driver.configuration.qnap_poolname,
|
||||
'fakeShareName',
|
||||
'NFS')
|
||||
mock_get_location_path.assert_called_once_with(
|
||||
'fakeShareName', 'NFS', '1.2.3.4')
|
||||
'fakeShareName', 'NFS', '1.2.3.4', 'fakeNo')
|
||||
|
||||
@mock.patch.object(qnap.QnapShareDriver, '_get_location_path')
|
||||
@mock.patch.object(qnap.QnapShareDriver, '_gen_random_name')
|
||||
def test_create_share_negative_share_exist(
|
||||
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.return_value = (
|
||||
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.mock_object(time, 'sleep')
|
||||
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
|
||||
'qnapadmin', 'Storage Pool 1',
|
||||
private_storage=mock_private_storage)
|
||||
|
||||
self.assertRaises(
|
||||
exception.ShareBackendException,
|
||||
self.driver.create_share,
|
||||
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_create_fail(
|
||||
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.return_value = None
|
||||
mock_gen_random_name.return_value = 'fakeShareName'
|
||||
mock_get_location_path.return_value = None
|
||||
mock_private_storage = mock.Mock()
|
||||
self.mock_object(time, 'sleep')
|
||||
self.mock_object(greenthread, 'sleep')
|
||||
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
|
||||
'qnapadmin', 'Storage Pool 1',
|
||||
private_storage=mock_private_storage)
|
||||
|
||||
self.assertRaises(
|
||||
exception.ShareBackendException,
|
||||
self.driver.create_share,
|
||||
context='context',
|
||||
share=self.share)
|
||||
|
||||
def test_delete_share_positive(self):
|
||||
"""Test delete share with fake_share."""
|
||||
@ -323,7 +437,7 @@ 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 = 'fakeVolId'
|
||||
mock_private_storage.get.return_value = 'fakeVolName'
|
||||
|
||||
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
|
||||
'qnapadmin', 'Storage Pool 1',
|
||||
@ -331,9 +445,10 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
|
||||
self.driver.extend_share(self.share, 100, share_server=None)
|
||||
|
||||
expect_share_dict = {
|
||||
"sharename": 'fakeVolId',
|
||||
"old_sharename": 'fakeVolId',
|
||||
"new_size": 100,
|
||||
'sharename': 'fakeVolName',
|
||||
'old_sharename': 'fakeVolName',
|
||||
'new_size': 100,
|
||||
'share_proto': 'NFS'
|
||||
}
|
||||
mock_api_executor.return_value.edit_share.assert_called_once_with(
|
||||
expect_share_dict)
|
||||
@ -455,10 +570,8 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
|
||||
|
||||
mock_api_executor = qnap.QnapShareDriver._create_api_executor
|
||||
mock_gen_random_name.return_value = 'fakeShareName'
|
||||
mock_api_executor.return_value.get_share_info.side_effect = (
|
||||
None, self.get_share_info_return_value())
|
||||
mock_api_executor.return_value.clone_snapshot.return_value = (
|
||||
None)
|
||||
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 = 'fakeSnapshotId'
|
||||
mock_share_api.return_value.get.return_value = {'size': 10}
|
||||
@ -495,12 +608,10 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
|
||||
|
||||
mock_gen_random_name.return_value = 'fakeShareName'
|
||||
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_api_executor.return_value.clone_snapshot.return_value = (
|
||||
None)
|
||||
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 = 'fakeSnapshotId'
|
||||
mock_private_storage.get.return_value = 'fakeVolName'
|
||||
mock_share_api.return_value.get.return_value = {'size': 5}
|
||||
mock_api_executor.return_value.edit_share.return_value = (
|
||||
None)
|
||||
@ -525,7 +636,8 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
|
||||
expect_share_dict = {
|
||||
'sharename': 'fakeShareName',
|
||||
'old_sharename': 'fakeShareName',
|
||||
'new_size': 10
|
||||
'new_size': 10,
|
||||
'share_proto': 'NFS'
|
||||
}
|
||||
mock_api_return.edit_share.assert_called_once_with(
|
||||
expect_share_dict)
|
||||
@ -548,6 +660,67 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
|
||||
snapshot=fake_snapshot,
|
||||
share_server=None)
|
||||
|
||||
@mock.patch.object(qnap.QnapShareDriver, '_get_location_path')
|
||||
@mock.patch('manila.share.API')
|
||||
@mock.patch.object(qnap.QnapShareDriver, '_gen_random_name')
|
||||
def test_create_share_from_snapshot_negative_name_exist(
|
||||
self,
|
||||
mock_gen_random_name,
|
||||
mock_share_api,
|
||||
mock_get_location_path):
|
||||
"""Test create share from snapshot."""
|
||||
fake_snapshot = fakes.SnapshotClass(
|
||||
10, 'fakeShareName@fakeSnapshotName')
|
||||
|
||||
mock_api_executor = qnap.QnapShareDriver._create_api_executor
|
||||
mock_gen_random_name.return_value = 'fakeShareName'
|
||||
mock_api_executor.return_value.get_share_info.return_value = (
|
||||
self.get_share_info_return_value())
|
||||
mock_private_storage = mock.Mock()
|
||||
mock_private_storage.get.return_value = 'fakeSnapshotId'
|
||||
mock_share_api.return_value.get.return_value = {'size': 10}
|
||||
self.mock_object(time, 'sleep')
|
||||
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
|
||||
'qnapadmin', 'Storage Pool 1',
|
||||
private_storage=mock_private_storage)
|
||||
self.assertRaises(
|
||||
exception.ShareBackendException,
|
||||
self.driver.create_share_from_snapshot,
|
||||
context='context',
|
||||
share=self.share,
|
||||
snapshot=fake_snapshot,
|
||||
share_server=None)
|
||||
|
||||
@mock.patch.object(qnap.QnapShareDriver, '_get_location_path')
|
||||
@mock.patch('manila.share.API')
|
||||
@mock.patch.object(qnap.QnapShareDriver, '_gen_random_name')
|
||||
def test_create_share_from_snapshot_negative_clone_fail(
|
||||
self,
|
||||
mock_gen_random_name,
|
||||
mock_share_api,
|
||||
mock_get_location_path):
|
||||
"""Test create share from snapshot."""
|
||||
fake_snapshot = fakes.SnapshotClass(
|
||||
10, 'fakeShareName@fakeSnapshotName')
|
||||
|
||||
mock_api_executor = qnap.QnapShareDriver._create_api_executor
|
||||
mock_gen_random_name.return_value = 'fakeShareName'
|
||||
mock_api_executor.return_value.get_share_info.return_value = None
|
||||
mock_private_storage = mock.Mock()
|
||||
mock_private_storage.get.return_value = 'fakeSnapshotId'
|
||||
mock_share_api.return_value.get.return_value = {'size': 10}
|
||||
self.mock_object(time, 'sleep')
|
||||
self._do_setup('http://1.2.3.4:8080', '1.2.3.4', 'admin',
|
||||
'qnapadmin', 'Storage Pool 1',
|
||||
private_storage=mock_private_storage)
|
||||
self.assertRaises(
|
||||
exception.ShareBackendException,
|
||||
self.driver.create_share_from_snapshot,
|
||||
context='context',
|
||||
share=self.share,
|
||||
snapshot=fake_snapshot,
|
||||
share_server=None)
|
||||
|
||||
@mock.patch.object(qnap.QnapShareDriver, '_allow_access')
|
||||
def test_update_access_allow_access(
|
||||
self, mock_allow_access):
|
||||
@ -644,7 +817,28 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
|
||||
mock_api_return.get_specific_volinfo.assert_called_once_with(
|
||||
'fakeNo')
|
||||
mock_get_location_path.assert_called_once_with(
|
||||
'fakeShareName', 'NFS', '1.2.3.4')
|
||||
'fakeShareName', 'NFS', '1.2.3.4', 'fakeNo')
|
||||
|
||||
def test_manage_invalid_protocol(self):
|
||||
"""Test manage existing."""
|
||||
share = fake_share.fake_share(
|
||||
share_proto='fakeProtocol',
|
||||
id='fakeId',
|
||||
display_name='fakeDisplayName',
|
||||
export_locations=[{'path': ''}],
|
||||
host='QnapShareDriver',
|
||||
size=10)
|
||||
|
||||
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.assertRaises(
|
||||
exception.InvalidInput,
|
||||
self.driver.manage_existing,
|
||||
share=share,
|
||||
driver_options='driver_options')
|
||||
|
||||
def test_manage_existing_nfs_without_export_locations(self):
|
||||
share = fake_share.fake_share(
|
||||
@ -820,14 +1014,15 @@ class QnapShareDriverTestCase(QnapShareDriverBaseTestCase):
|
||||
}
|
||||
self.assertEqual(
|
||||
expect_result, self.driver._get_location_path(
|
||||
'fakeShareName', 'NFS', 'fakeIp'))
|
||||
'fakeShareName', 'NFS', 'fakeIp', 'fakeVolId'))
|
||||
|
||||
self.assertRaises(
|
||||
exception.InvalidInput,
|
||||
self.driver._get_location_path,
|
||||
share_name='fakeShareName',
|
||||
share_proto='fakeProto',
|
||||
ip='fakeIp')
|
||||
ip='fakeIp',
|
||||
vol_id='fakeVolId')
|
||||
|
||||
def test_update_share_stats(self):
|
||||
"""Test update share stats."""
|
||||
|
4
releasenotes/notes/support-qes-114-5881c0ff0e7da512.yaml
Normal file
4
releasenotes/notes/support-qes-114-5881c0ff0e7da512.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
QNAP Manila driver adds support for QES fw 1.1.4.
|
Loading…
Reference in New Issue
Block a user