Merge "QNAP: Add support for QES 1.1.4"
This commit is contained in:
commit
2c67dc9f4e
@ -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