Merge "HP 3PAR use one filestore per tenant"

This commit is contained in:
Jenkins 2015-03-05 05:40:55 +00:00 committed by Gerrit Code Review
commit 4351cf145c
5 changed files with 654 additions and 210 deletions

View File

@ -59,6 +59,9 @@ HP3PAR_OPTS = [
cfg.StrOpt('hp3par_share_ip_address',
default='',
help="The IP address for shares not using a share server"),
cfg.BoolOpt('hp3par_fstore_per_share',
default=False,
help="Use one filestore per share"),
cfg.BoolOpt('hp3par_debug',
default=False,
help="Enable HTTP debugging to 3PAR"),
@ -105,6 +108,7 @@ class HP3ParShareDriver(driver.ShareDriver):
hp3par_san_login=self.configuration.hp3par_san_login,
hp3par_san_password=self.configuration.hp3par_san_password,
hp3par_san_ssh_port=self.configuration.hp3par_san_ssh_port,
hp3par_fstore_per_share=self.configuration.hp3par_fstore_per_share,
ssh_conn_timeout=self.configuration.ssh_conn_timeout,
)
@ -170,6 +174,7 @@ class HP3ParShareDriver(driver.ShareDriver):
protocol = share['share_proto']
path = self._hp3par.create_share(
share['project_id'],
share['id'],
protocol,
self.fpg, self.vfs,
@ -188,7 +193,9 @@ class HP3ParShareDriver(driver.ShareDriver):
path = self._hp3par.create_share_from_snapshot(
share['id'],
protocol,
snapshot['share']['project_id'],
snapshot['share']['id'],
snapshot['share']['share_proto'],
snapshot['id'],
self.fpg,
self.vfs
@ -199,7 +206,8 @@ class HP3ParShareDriver(driver.ShareDriver):
def delete_share(self, context, share, share_server=None):
"""Deletes share and its fstore."""
self._hp3par.delete_share(share['id'],
self._hp3par.delete_share(share['project_id'],
share['id'],
share['share_proto'],
self.fpg,
self.vfs)
@ -207,7 +215,9 @@ class HP3ParShareDriver(driver.ShareDriver):
def create_snapshot(self, context, snapshot, share_server=None):
"""Creates a snapshot of a share."""
self._hp3par.create_snapshot(snapshot['share']['id'],
self._hp3par.create_snapshot(snapshot['share']['project_id'],
snapshot['share']['id'],
snapshot['share']['share_proto'],
snapshot['id'],
self.fpg,
self.vfs)
@ -215,7 +225,9 @@ class HP3ParShareDriver(driver.ShareDriver):
def delete_snapshot(self, context, snapshot, share_server=None):
"""Deletes a snapshot of a share."""
self._hp3par.delete_snapshot(snapshot['share']['id'],
self._hp3par.delete_snapshot(snapshot['share']['project_id'],
snapshot['share']['id'],
snapshot['share']['share_proto'],
snapshot['id'],
self.fpg,
self.vfs)
@ -225,7 +237,8 @@ class HP3ParShareDriver(driver.ShareDriver):
def allow_access(self, context, share, access, share_server=None):
"""Allow access to the share."""
self._hp3par.allow_access(share['id'],
self._hp3par.allow_access(share['project_id'],
share['id'],
share['share_proto'],
access['access_type'],
access['access_to'],
@ -234,7 +247,8 @@ class HP3ParShareDriver(driver.ShareDriver):
def deny_access(self, context, share, access, share_server=None):
"""Deny access to the share."""
self._hp3par.deny_access(share['id'],
self._hp3par.deny_access(share['project_id'],
share['id'],
share['share_proto'],
access['access_type'],
access['access_to'],

View File

@ -24,7 +24,6 @@ import six
from manila import exception
from manila.i18n import _
from manila.i18n import _LI
from manila.openstack.common import log as logging
hp3parclient = importutils.try_import("hp3parclient")
@ -51,6 +50,7 @@ class HP3ParMediator(object):
self.hp3par_san_password = kwargs.get('hp3par_san_password')
self.hp3par_san_ssh_port = kwargs.get('hp3par_san_ssh_port')
self.hp3par_san_private_key = kwargs.get('hp3par_san_private_key')
self.hp3par_fstore_per_share = kwargs.get('hp3par_fstore_per_share')
self.ssh_conn_timeout = kwargs.get('ssh_conn_timeout')
self._client = None
@ -132,13 +132,22 @@ class HP3ParMediator(object):
return protocol
@staticmethod
def ensure_prefix(id):
if id.startswith('osf-'):
return id
else:
return 'osf-%s' % id
def other_protocol(share_proto):
"""Given 'nfs' or 'smb' (or equivalent) return the other one."""
protocol = HP3ParMediator.ensure_supported_protocol(share_proto)
return 'nfs' if protocol == 'smb' else 'smb'
def create_share(self, share_id, share_proto, fpg, vfs,
@staticmethod
def ensure_prefix(uid, protocol=None):
if uid.startswith('osf-'):
return uid
elif protocol:
return 'osf-%s-%s' % (
HP3ParMediator.ensure_supported_protocol(protocol), uid)
else:
return 'osf-%s' % uid
def create_share(self, project_id, share_id, share_proto, fpg, vfs,
fstore=None, sharedir=None, readonly=False, size=None):
"""Create the share and return its path.
@ -146,6 +155,7 @@ class HP3ParMediator(object):
called locally from create_share_from_snapshot(). The optional
parameters allow re-use.
:param project_id: The tenant ID.
:param share_id: The share-id with or without osf- prefix.
:param share_proto: The protocol (to map to smb or nfs)
:param fpg: The file provisioning group
@ -162,7 +172,11 @@ class HP3ParMediator(object):
share_name = self.ensure_prefix(share_id)
if not fstore:
fstore = share_name
if self.hp3par_fstore_per_share:
fstore = share_name
else:
fstore = self.ensure_prefix(project_id, protocol)
try:
result = self._client.createfstore(
vfs, fstore, fpg=fpg,
@ -175,11 +189,26 @@ class HP3ParMediator(object):
raise exception.ShareBackendException(msg)
if size:
if self.hp3par_fstore_per_share:
hcapacity = six.text_type(size * units.Ki)
scapacity = hcapacity
else:
hard_size_mb = size * units.Ki
soft_size_mb = hard_size_mb
result = self._client.getfsquota(
fpg=fpg, vfs=vfs, fstore=fstore)
LOG.debug("getfsquota result=%s", result)
quotas = result['members']
if len(quotas) == 1:
hard_size_mb += int(quotas[0].get('hardBlock', '0'))
soft_size_mb += int(quotas[0].get('softBlock', '0'))
hcapacity = six.text_type(hard_size_mb)
scapacity = six.text_type(soft_size_mb)
try:
size_str = six.text_type(size)
result = self._client.setfsquota(
vfs, fpg=fpg, fstore=fstore,
scapacity=size_str, hcapacity=size_str)
scapacity=scapacity, hcapacity=hcapacity)
LOG.debug("setfsquota result=%s", result)
except Exception as e:
msg = (_('Failed to setfsquota on %(fstore)s: %(e)s') %
@ -187,6 +216,9 @@ class HP3ParMediator(object):
LOG.exception(msg)
raise exception.ShareBackendException(msg)
if not (sharedir or self.hp3par_fstore_per_share):
sharedir = share_name
try:
if protocol == 'nfs':
if readonly:
@ -239,30 +271,45 @@ class HP3ParMediator(object):
else:
return result['members'][0]['shareName']
def create_share_from_snapshot(self, share_id, share_proto, orig_share_id,
def create_share_from_snapshot(self, share_id, share_proto,
orig_project_id, orig_share_id, orig_proto,
snapshot_id, fpg, vfs):
share_name = self.ensure_prefix(share_id)
orig_share_name = self.ensure_prefix(orig_share_id)
fstore = orig_share_name
protocol = self.ensure_supported_protocol(share_proto)
snapshot_tag = self.ensure_prefix(snapshot_id)
snapshots = self.get_snapshots(fstore, snapshot_tag, fpg, vfs)
orig_share_name = self.ensure_prefix(orig_share_id)
if len(snapshots) != 1:
snapshot = self._find_fsnap(orig_project_id,
orig_share_name,
orig_proto,
snapshot_tag,
fpg,
vfs)
if not snapshot:
msg = (_('Failed to create share from snapshot for '
'FPG/VFS/fstore/tag %(fpg)s/%(vfs)s/%(fstore)s/%(tag)s.'
' Expected to find 1 snapshot, found %(count)s.') %
{'fpg': fpg, 'vfs': vfs, 'fstore': fstore,
'tag': snapshot_tag, 'count': len(snapshots)})
'FPG/VFS/tag %(fpg)s/%(vfs)s/%(tag)s. '
'Snapshot not found.') %
{
'fpg': fpg,
'vfs': vfs,
'tag': snapshot_tag})
LOG.exception(msg)
raise exception.ShareBackendException(msg)
snapshot = snapshots[0]
sharedir = '.snapshot/%s' % snapshot['snapName']
fstore = snapshot['fstoreName']
share_name = self.ensure_prefix(share_id)
if fstore == orig_share_name:
# No subdir for original share created with fstore_per_share
sharedir = '.snapshot/%s' % snapshot['snapName']
else:
sharedir = '.snapshot/%s/%s' % (snapshot['snapName'],
orig_share_name)
return self.create_share(
orig_project_id,
share_name,
share_proto,
protocol,
fpg,
vfs,
fstore=fstore,
@ -270,11 +317,12 @@ class HP3ParMediator(object):
readonly=True,
)
def delete_share(self, share_id, share_proto, fpg, vfs):
def delete_share(self, project_id, share_id, share_proto, fpg, vfs):
share_name = self.ensure_prefix(share_id)
fstore = self.get_fstore(share_id, share_proto, fpg, vfs)
protocol = self.ensure_supported_protocol(share_proto)
share_name = self.ensure_prefix(share_id)
fstore = self._find_fstore(project_id, share_name, protocol, fpg, vfs,
allow_cross_protocol=True)
if not fstore:
# Share does not exist.
@ -289,13 +337,14 @@ class HP3ParMediator(object):
LOG.exception(msg)
raise exception.ShareBackendException(message=msg)
try:
self._client.removefstore(vfs, fstore, fpg=fpg)
except Exception as e:
msg = (_('Failed to remove fstore %(fstore)s: %(e)s') %
{'fstore': fstore, 'e': six.text_type(e)})
LOG.exception(msg)
raise exception.ShareBackendException(message=msg)
if fstore == share_name:
try:
self._client.removefstore(vfs, fstore, fpg=fpg)
except Exception as e:
msg = (_('Failed to remove fstore %(fstore)s: %(e)s') %
{'fstore': fstore, 'e': six.text_type(e)})
LOG.exception(msg)
raise exception.ShareBackendException(message=msg)
def get_vfs_name(self, fpg):
return self.get_vfs(fpg)['vfsname']
@ -331,10 +380,33 @@ class HP3ParMediator(object):
return result['members'][0]
def create_snapshot(self, orig_share_id, snapshot_id, fpg, vfs):
def create_snapshot(self, orig_project_id, orig_share_id, orig_share_proto,
snapshot_id, fpg, vfs):
"""Creates a snapshot of a share."""
fstore = self.ensure_prefix(orig_share_id)
fshare = self._find_fshare(orig_project_id,
orig_share_id,
orig_share_proto,
fpg,
vfs)
if not fshare:
msg = (_('Failed to create snapshot for FPG/VFS/fshare '
'%(fpg)s/%(vfs)s/%(fshare)s: Failed to find fshare.') %
{'fpg': fpg, 'vfs': vfs, 'fshare': orig_share_id})
LOG.exception(msg)
raise exception.ShareBackendException(msg)
sharedir = fshare.get('shareDir')
if sharedir and sharedir.startswith('.snapshot'):
msg = (_('Failed to create snapshot for FPG/VFS/fshare '
'%(fpg)s/%(vfs)s/%(fshare)s: Share is a read-only '
'share of an existing snapshot.') %
{'fpg': fpg, 'vfs': vfs, 'fshare': orig_share_id})
LOG.exception(msg)
raise exception.ShareBackendException(msg)
fstore = fshare.get('fstoreName')
snapshot_tag = self.ensure_prefix(snapshot_id)
try:
result = self._client.createfsnap(
@ -350,41 +422,20 @@ class HP3ParMediator(object):
LOG.exception(msg)
raise exception.ShareBackendException(msg)
def get_snapshots(self, orig_share_id, snapshot_tag, fpg, vfs):
fstore = self.ensure_prefix(orig_share_id)
try:
pattern = '*_%s' % snapshot_tag
result = self._client.getfsnap(
pattern, fpg=fpg, vfs=vfs, fstore=fstore, pat=True)
LOG.debug("getfsnap result=%s", result)
except Exception as e:
msg = (_('Failed to get snapshot for FPG/VFS/fstore/tag '
'%(fpg)s/%(vfs)s/%(fstore)s/%(tag)s: %(e)s') %
{'fpg': fpg, 'vfs': vfs, 'fstore': fstore,
'tag': snapshot_tag, 'e': six.text_type(e)})
LOG.exception(msg)
raise exception.ShareBackendException(msg)
if result['total'] == 0:
LOG.info((_LI('Found zero snapshots for FPG/VFS/fstore/tag '
'%(fpg)s/%(vfs)s/%(fstore)s/%(tag)s.') %
{'fpg': fpg, 'vfs': vfs, 'fstore': fstore,
'tag': snapshot_tag}))
return result['members']
def delete_snapshot(self, orig_share_id, snapshot_id, fpg, vfs):
def delete_snapshot(self, orig_project_id, orig_share_id, orig_proto,
snapshot_id, fpg, vfs):
"""Deletes a snapshot of a share."""
fstore = self.ensure_prefix(orig_share_id)
snapshot_tag = self.ensure_prefix(snapshot_id)
snapshots = self.get_snapshots(fstore, snapshot_tag, fpg, vfs)
if not snapshots:
snapshot = self._find_fsnap(orig_project_id, orig_share_id, orig_proto,
snapshot_tag, fpg, vfs)
if not snapshot:
return
fstore = snapshot.get('fstoreName')
for protocol in ('nfs', 'smb'):
try:
shares = self._client.getfshare(protocol,
@ -417,23 +468,24 @@ class HP3ParMediator(object):
'dependent share.'))
raise exception.Invalid(msg)
# Tag should be unique enough to only return one, but this method
# doesn't really need to know that. So just loop.
for snapshot in snapshots:
try:
snapname = snapshot['snapName']
result = self._client.removefsnap(
vfs, fstore, snapname=snapname, fpg=fpg)
snapname = snapshot['snapName']
try:
result = self._client.removefsnap(
vfs, fstore, snapname=snapname, fpg=fpg)
LOG.debug("removefsnap result=%s", result)
LOG.debug("removefsnap result=%s", result)
except Exception as e:
msg = (_('Failed to delete snapshot for FPG/VFS/fstore '
'%(fpg)s/%(vfs)s/%(fstore)s: %(e)s') %
{'fpg': fpg, 'vfs': vfs, 'fstore': fstore,
'e': six.text_type(e)})
LOG.exception(msg)
raise exception.ShareBackendException(msg)
except Exception as e:
msg = (_('Failed to delete snapshot for FPG/VFS/fstore/snapshot '
'%(fpg)s/%(vfs)s/%(fstore)s/%(snapname)s: %(e)s') %
{
'fpg': fpg,
'vfs': vfs,
'fstore': fstore,
'snapname': snapname,
'e': six.text_type(e)})
LOG.exception(msg)
raise exception.ShareBackendException(msg)
# Try to reclaim the space
try:
@ -461,7 +513,7 @@ class HP3ParMediator(object):
return protocol
def _change_access(self, plus_or_minus, fstore, share_id, share_proto,
def _change_access(self, plus_or_minus, project_id, share_id, share_proto,
access_type, access_to, fpg, vfs):
"""Allow or deny access to a share.
@ -469,12 +521,13 @@ class HP3ParMediator(object):
allow list (-).
"""
share_name = self.ensure_prefix(share_id)
fstore = self.ensure_prefix(fstore)
protocol = self.ensure_supported_protocol(share_proto)
self.validate_access_type(protocol, access_type)
share_name = self.ensure_prefix(share_id)
fstore = self._find_fstore(project_id, share_id, protocol, fpg, vfs,
allow_cross_protocol=True)
try:
if protocol == 'nfs':
result = self._client.setfshare(
@ -507,37 +560,80 @@ class HP3ParMediator(object):
LOG.exception(msg)
raise exception.ShareBackendException(msg)
def get_fstore(self, share_id, share_proto, fpg, vfs):
def _find_fstore(self, project_id, share_id, share_proto, fpg, vfs,
allow_cross_protocol=False):
share = self._find_fshare(project_id, share_id, share_proto, fpg, vfs)
if not share and allow_cross_protocol:
share = self._find_fshare(project_id,
share_id,
self.other_protocol(share_proto),
fpg,
vfs)
return share.get('fstoreName') if share else None
def _find_fshare(self, project_id, share_id, share_proto, fpg, vfs):
protocol = self.ensure_supported_protocol(share_proto)
share_name = self.ensure_prefix(share_id)
project_fstore = self.ensure_prefix(project_id, share_proto)
search_order = [
{'fpg': fpg, 'vfs': vfs, 'fstore': project_fstore},
{'fpg': fpg, 'vfs': vfs, 'fstore': share_name},
{'fpg': fpg},
{}
]
try:
shares = self._client.getfshare(protocol,
share_name,
fpg=fpg,
vfs=vfs)
for search_params in search_order:
result = self._client.getfshare(protocol, share_name,
**search_params)
shares = result.get('members', [])
if len(shares) == 1:
return shares[0]
except Exception as e:
msg = (_('Unexpected exception while getting share list: %s') %
six.text_type(e))
raise exception.ShareBackendException(msg)
members = shares['members']
if members:
return members[0].get('fstoreName')
def _find_fsnap(self, project_id, share_id, orig_proto, snapshot_tag,
fpg, vfs):
def allow_access(self, share_id, share_proto, access_type, access_to,
fpg, vfs):
share_name = self.ensure_prefix(share_id)
osf_project_id = self.ensure_prefix(project_id, orig_proto)
pattern = '*_%s' % self.ensure_prefix(snapshot_tag)
search_order = [
{'pat': True, 'fpg': fpg, 'vfs': vfs, 'fstore': osf_project_id},
{'pat': True, 'fpg': fpg, 'vfs': vfs, 'fstore': share_name},
{'pat': True, 'fpg': fpg},
{'pat': True},
]
try:
for search_params in search_order:
result = self._client.getfsnap(pattern, **search_params)
snapshots = result.get('members', [])
if len(snapshots) == 1:
return snapshots[0]
except Exception as e:
msg = (_('Unexpected exception while getting snapshots: %s') %
six.text_type(e))
raise exception.ShareBackendException(msg)
def allow_access(self, project_id, share_id, share_proto, access_type,
access_to, fpg, vfs):
"""Grant access to a share."""
fstore = self.get_fstore(share_id, share_proto, fpg, vfs)
self._change_access(ALLOW, fstore, share_id, share_proto,
self._change_access(ALLOW, project_id, share_id, share_proto,
access_type, access_to, fpg, vfs)
def deny_access(self, share_id, share_proto, access_type, access_to,
fpg, vfs):
def deny_access(self, project_id, share_id, share_proto, access_type,
access_to, fpg, vfs):
"""Deny access to a share."""
fstore = self.get_fstore(share_id, share_proto, fpg, vfs)
if fstore:
self._change_access(DENY, fstore, share_id, share_proto,
access_type, access_to, fpg, vfs)
self._change_access(DENY, project_id, share_id, share_proto,
access_type, access_to, fpg, vfs)

View File

@ -29,6 +29,7 @@ PORT = 22
EXPECTED_IP_10203040 = '10.20.30.40'
EXPECTED_IP_1234 = '1.2.3.4'
EXPECTED_IP_127 = '127.0.0.1'
EXPECTED_PROJECT_ID = 'osf-nfs-project-id'
EXPECTED_SHARE_ID = 'osf-share-id'
EXPECTED_SHARE_NAME = 'share-name'
EXPECTED_SHARE_PATH = '/anyfpg/anyvfs/anyfstore'
@ -38,11 +39,12 @@ EXPECTED_SNAP_NAME = 'osf-snap-name'
EXPECTED_SNAP_ID = 'osf-snap-id'
EXPECTED_STATS = {'test': 'stats'}
EXPECTED_FPG = 'FPG_1'
EXPECTED_FSTORE = 'osf-test_fstore'
EXPECTED_FSTORE = EXPECTED_PROJECT_ID
EXPECTED_VFS = 'test_vfs'
EXPECTED_HP_DEBUG = True
NFS_SHARE_INFO = {
'project_id': EXPECTED_PROJECT_ID,
'id': EXPECTED_SHARE_ID,
'share_proto': NFS,
}
@ -55,5 +57,9 @@ ACCESS_INFO = {
SNAPSHOT_INFO = {
'name': EXPECTED_SNAP_NAME,
'id': EXPECTED_SNAP_ID,
'share': {'id': EXPECTED_SHARE_ID},
'share': {
'project_id': EXPECTED_PROJECT_ID,
'id': EXPECTED_SHARE_ID,
'share_proto': NFS,
},
}

View File

@ -39,11 +39,12 @@ class HP3ParDriverTestCase(test.TestCase):
self.conf.hp3par_api_url = constants.API_URL
self.conf.hp3par_san_login = constants.SAN_LOGIN
self.conf.hp3par_san_password = constants.SAN_PASSWORD
self.conf.hp3par.san_ip = constants.EXPECTED_IP_1234
self.conf.hp3par_san_ip = constants.EXPECTED_IP_1234
self.conf.hp3par_fpg = constants.EXPECTED_FPG
self.conf.hp3par_san_ssh_port = constants.PORT
self.conf.ssh_conn_timeout = constants.TIMEOUT
self.conf.hp3par_share_ip_address = constants.EXPECTED_IP_10203040
self.conf.hp3par_fstore_per_share = False
self.conf.network_config_group = 'test_network_config_group'
def safe_get(attr):
@ -66,20 +67,22 @@ class HP3ParDriverTestCase(test.TestCase):
self.mock_mediator.get_vfs_name.return_value = constants.EXPECTED_VFS
self.driver.do_setup(None)
conf = self.conf
self.mock_mediator_constructor.assert_has_calls([
mock.call(hp3par_san_ssh_port=self.conf.hp3par_san_ssh_port,
hp3par_san_password=self.conf.hp3par_san_password,
hp3par_username=self.conf.hp3par_username,
hp3par_san_login=self.conf.hp3par_san_login,
hp3par_debug=self.conf.hp3par_debug,
hp3par_api_url=self.conf.hp3par_api_url,
hp3par_password=self.conf.hp3par_password,
hp3par_san_ip=self.conf.hp3par_san_ip,
ssh_conn_timeout=self.conf.ssh_conn_timeout)])
mock.call(hp3par_san_ssh_port=conf.hp3par_san_ssh_port,
hp3par_san_password=conf.hp3par_san_password,
hp3par_username=conf.hp3par_username,
hp3par_san_login=conf.hp3par_san_login,
hp3par_debug=conf.hp3par_debug,
hp3par_api_url=conf.hp3par_api_url,
hp3par_password=conf.hp3par_password,
hp3par_san_ip=conf.hp3par_san_ip,
hp3par_fstore_per_share=conf.hp3par_fstore_per_share,
ssh_conn_timeout=conf.ssh_conn_timeout)])
self.mock_mediator.assert_has_calls([
mock.call.do_setup(),
mock.call.get_vfs_name(self.conf.hp3par_fpg)])
mock.call.get_vfs_name(conf.hp3par_fpg)])
self.assertEqual(constants.EXPECTED_VFS, self.driver.vfs)
@ -92,16 +95,18 @@ class HP3ParDriverTestCase(test.TestCase):
self.assertRaises(exception.ShareBackendException,
self.driver.do_setup, None)
conf = self.conf
self.mock_mediator_constructor.assert_has_calls([
mock.call(hp3par_san_ssh_port=self.conf.hp3par_san_ssh_port,
hp3par_san_password=self.conf.hp3par_san_password,
hp3par_username=self.conf.hp3par_username,
hp3par_san_login=self.conf.hp3par_san_login,
hp3par_debug=self.conf.hp3par_debug,
hp3par_api_url=self.conf.hp3par_api_url,
hp3par_password=self.conf.hp3par_password,
hp3par_san_ip=self.conf.hp3par_san_ip,
ssh_conn_timeout=self.conf.ssh_conn_timeout)])
mock.call(hp3par_san_ssh_port=conf.hp3par_san_ssh_port,
hp3par_san_password=conf.hp3par_san_password,
hp3par_username=conf.hp3par_username,
hp3par_san_login=conf.hp3par_san_login,
hp3par_debug=conf.hp3par_debug,
hp3par_api_url=conf.hp3par_api_url,
hp3par_password=conf.hp3par_password,
hp3par_san_ip=conf.hp3par_san_ip,
hp3par_fstore_per_share=conf.hp3par_fstore_per_share,
ssh_conn_timeout=conf.ssh_conn_timeout)])
self.mock_mediator.assert_has_calls([mock.call.do_setup()])
@ -114,20 +119,22 @@ class HP3ParDriverTestCase(test.TestCase):
self.assertRaises(exception.ShareBackendException,
self.driver.do_setup, None)
conf = self.conf
self.mock_mediator_constructor.assert_has_calls([
mock.call(hp3par_san_ssh_port=self.conf.hp3par_san_ssh_port,
hp3par_san_password=self.conf.hp3par_san_password,
hp3par_username=self.conf.hp3par_username,
hp3par_san_login=self.conf.hp3par_san_login,
hp3par_debug=self.conf.hp3par_debug,
hp3par_api_url=self.conf.hp3par_api_url,
hp3par_password=self.conf.hp3par_password,
hp3par_san_ip=self.conf.hp3par_san_ip,
ssh_conn_timeout=self.conf.ssh_conn_timeout)])
mock.call(hp3par_san_ssh_port=conf.hp3par_san_ssh_port,
hp3par_san_password=conf.hp3par_san_password,
hp3par_username=conf.hp3par_username,
hp3par_san_login=conf.hp3par_san_login,
hp3par_debug=conf.hp3par_debug,
hp3par_api_url=conf.hp3par_api_url,
hp3par_password=conf.hp3par_password,
hp3par_san_ip=conf.hp3par_san_ip,
hp3par_fstore_per_share=conf.hp3par_fstore_per_share,
ssh_conn_timeout=conf.ssh_conn_timeout)])
self.mock_mediator.assert_has_calls([
mock.call.do_setup(),
mock.call.get_vfs_name(self.conf.hp3par_fpg)])
mock.call.get_vfs_name(conf.hp3par_fpg)])
def init_driver(self):
"""Simple driver setup for re-use with tests that need one."""
@ -137,11 +144,13 @@ class HP3ParDriverTestCase(test.TestCase):
self.driver.fpg = constants.EXPECTED_FPG
self.driver.share_ip_address = self.conf.hp3par_share_ip_address
def do_create_share(self, protocol, expected_share_id, expected_size):
def do_create_share(self, protocol, expected_project_id, expected_share_id,
expected_size):
"""Re-usable code for create share."""
context = None
share_server = None
share = {
'project_id': expected_project_id,
'id': expected_share_id,
'share_proto': protocol,
'size': expected_size,
@ -188,11 +197,13 @@ class HP3ParDriverTestCase(test.TestCase):
constants.EXPECTED_SHARE_NAME)
location = self.do_create_share(constants.CIFS,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SIZE_2)
self.assertEqual(expected_location, location)
expected_calls = [mock.call.create_share(
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_FPG,
@ -210,12 +221,14 @@ class HP3ParDriverTestCase(test.TestCase):
constants.EXPECTED_SHARE_PATH)
location = self.do_create_share(constants.NFS,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SIZE_1)
self.assertEqual(expected_location, location)
expected_calls = [
mock.call.create_share(constants.EXPECTED_SHARE_ID,
mock.call.create_share(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS,
@ -242,7 +255,9 @@ class HP3ParDriverTestCase(test.TestCase):
expected_calls = [
mock.call.create_share_from_snapshot(constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_FSTORE,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)]
@ -267,7 +282,9 @@ class HP3ParDriverTestCase(test.TestCase):
expected_calls = [
mock.call.create_share_from_snapshot(constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)]
@ -280,6 +297,7 @@ class HP3ParDriverTestCase(test.TestCase):
context = None
share_server = None
share = {
'project_id': constants.EXPECTED_PROJECT_ID,
'id': constants.EXPECTED_SHARE_ID,
'share_proto': constants.CIFS,
'size': constants.EXPECTED_SIZE_1,
@ -288,7 +306,8 @@ class HP3ParDriverTestCase(test.TestCase):
self.driver.delete_share(context, share, share_server)
expected_calls = [
mock.call.delete_share(constants.EXPECTED_SHARE_ID,
mock.call.delete_share(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)]
@ -305,7 +324,9 @@ class HP3ParDriverTestCase(test.TestCase):
share_server)
expected_calls = [
mock.call.create_snapshot(constants.EXPECTED_SHARE_ID,
mock.call.create_snapshot(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)]
@ -321,7 +342,9 @@ class HP3ParDriverTestCase(test.TestCase):
share_server)
expected_calls = [
mock.call.delete_snapshot(constants.EXPECTED_SHARE_ID,
mock.call.delete_snapshot(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -337,7 +360,8 @@ class HP3ParDriverTestCase(test.TestCase):
constants.ACCESS_INFO)
expected_calls = [
mock.call.allow_access(constants.EXPECTED_SHARE_ID,
mock.call.allow_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.IP,
constants.EXPECTED_IP_1234,
@ -355,7 +379,8 @@ class HP3ParDriverTestCase(test.TestCase):
constants.ACCESS_INFO)
expected_calls = [
mock.call.deny_access(constants.EXPECTED_SHARE_ID,
mock.call.deny_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.IP,
constants.EXPECTED_IP_1234,

View File

@ -14,10 +14,10 @@
import sys
import ddt
import mock
if 'hp3parclient' not in sys.modules:
sys.modules['hp3parclient'] = mock.Mock()
import six
from manila import exception
from manila.share.drivers.hp import hp_3par_mediator as hp3parmediator
@ -27,6 +27,7 @@ from manila.tests.share.drivers.hp import test_hp_3par_constants as constants
from oslo_utils import units
@ddt.ddt
class HP3ParMediatorTestCase(test.TestCase):
def setUp(self):
@ -143,20 +144,23 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_fpg,
expected_vfsname,
expected_protocol,
expected_share_id,
expected_size):
size = six.text_type(expected_size)
expected_sharedir = None
expected_project_id,
expected_share_id):
expected_sharedir = expected_share_id
if expected_protocol == constants.NFS_LOWER:
expected_calls = [
mock.call.createfstore(expected_vfsname, expected_share_id,
mock.call.createfstore(expected_vfsname, expected_project_id,
comment='OpenStack Manila fstore',
fpg=expected_fpg),
mock.call.setfsquota(expected_vfsname, fpg=expected_fpg,
hcapacity=size,
scapacity=size,
fstore=expected_share_id),
mock.call.getfsquota(fpg=expected_fpg,
vfs=expected_vfsname,
fstore=expected_project_id),
mock.call.setfsquota(expected_vfsname,
fpg=expected_fpg,
hcapacity='2048',
scapacity='2048',
fstore=expected_project_id),
mock.call.createfshare(expected_protocol, expected_vfsname,
expected_share_id,
comment='OpenStack Manila fshare',
@ -164,29 +168,33 @@ class HP3ParMediatorTestCase(test.TestCase):
sharedir=expected_sharedir,
clientip='127.0.0.1',
options='rw,no_root_squash,insecure',
fstore=expected_share_id),
fstore=expected_project_id),
mock.call.getfshare(expected_protocol, expected_share_id,
fpg=expected_fpg, vfs=expected_vfsname,
fstore=expected_share_id)]
fstore=expected_project_id)]
else:
expected_calls = [
mock.call.createfstore(expected_vfsname, expected_share_id,
mock.call.createfstore(expected_vfsname, expected_project_id,
comment='OpenStack Manila fstore',
fpg=expected_fpg),
mock.call.setfsquota(expected_vfsname, fpg=expected_fpg,
hcapacity=size,
scapacity=size,
fstore=expected_share_id),
mock.call.getfsquota(fpg=expected_fpg,
vfs=expected_vfsname,
fstore=expected_project_id),
mock.call.setfsquota(expected_vfsname,
fpg=expected_fpg,
hcapacity='2048',
scapacity='2048',
fstore=expected_project_id),
mock.call.createfshare(expected_protocol, expected_vfsname,
expected_share_id,
comment='OpenStack Manila fshare',
fpg=expected_fpg,
sharedir=expected_sharedir,
allowip='127.0.0.1',
fstore=expected_share_id),
fstore=expected_project_id),
mock.call.getfshare(expected_protocol, expected_share_id,
fpg=expected_fpg, vfs=expected_vfsname,
fstore=expected_share_id)]
fstore=expected_project_id)]
return expected_calls
def test_mediator_create_cifs_share(self):
@ -198,11 +206,18 @@ class HP3ParMediatorTestCase(test.TestCase):
'members': [{'shareName': constants.EXPECTED_SHARE_NAME}]
}
location = self.mediator.create_share(constants.EXPECTED_SHARE_ID,
self.mock_client.getfsquota.return_value = {
'message': None,
'total': 1,
'members': [{'hardBlock': '1024', 'softBlock': '1024'}]
}
location = self.mediator.create_share(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS,
size=constants.EXPECTED_SIZE_2)
size=constants.EXPECTED_SIZE_1)
self.assertEqual(constants.EXPECTED_SHARE_NAME, location)
@ -210,8 +225,8 @@ class HP3ParMediatorTestCase(test.TestCase):
constants.EXPECTED_FPG,
constants.EXPECTED_VFS,
constants.SMB_LOWER,
constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SIZE_2)
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID)
self.mock_client.assert_has_calls(expected_calls)
@ -224,7 +239,14 @@ class HP3ParMediatorTestCase(test.TestCase):
'members': [{'sharePath': constants.EXPECTED_SHARE_PATH}]
}
location = self.mediator.create_share(constants.EXPECTED_SHARE_ID,
self.mock_client.getfsquota.return_value = {
'message': None,
'total': 1,
'members': [{'hardBlock': '1024', 'softBlock': '1024'}]
}
location = self.mediator.create_share(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS.lower(),
constants.EXPECTED_FPG,
constants.EXPECTED_VFS,
@ -233,10 +255,11 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertEqual(constants.EXPECTED_SHARE_PATH, location)
expected_calls = self.get_expected_calls_for_create_share(
constants.EXPECTED_FPG, constants.EXPECTED_VFS,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS,
constants.NFS.lower(),
constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SIZE_1)
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID)
self.mock_client.assert_has_calls(expected_calls)
@ -246,13 +269,16 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mock_client.getfsnap.return_value = {
'message': None,
'total': 1,
'members': [{'snapName': constants.EXPECTED_SNAP_ID}]
'members': [{'snapName': constants.EXPECTED_SNAP_ID,
'fstoreName': constants.EXPECTED_FSTORE}]
}
location = self.mediator.create_share_from_snapshot(
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -264,21 +290,22 @@ class HP3ParMediatorTestCase(test.TestCase):
vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG,
pat=True,
fstore=constants.EXPECTED_SHARE_ID),
fstore=constants.EXPECTED_FSTORE),
mock.call.createfshare(constants.SMB_LOWER,
constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID,
comment=mock.ANY,
fpg=constants.EXPECTED_FPG,
sharedir='.snapshot/%s' %
sharedir='.snapshot/%s/%s' % (
constants.EXPECTED_SNAP_ID,
fstore=constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SHARE_ID),
fstore=constants.EXPECTED_FSTORE,
allowip=constants.EXPECTED_IP_127),
mock.call.getfshare(constants.SMB_LOWER,
constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID)]
fstore=constants.EXPECTED_FSTORE)]
self.mock_client.assert_has_calls(expected_calls)
@ -288,13 +315,16 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mock_client.getfsnap.return_value = {
'message': None,
'total': 1,
'members': [{'snapName': constants.EXPECTED_SNAP_ID}]
'members': [{'snapName': constants.EXPECTED_SNAP_ID,
'fstoreName': constants.EXPECTED_FSTORE}]
}
location = self.mediator.create_share_from_snapshot(
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -306,22 +336,23 @@ class HP3ParMediatorTestCase(test.TestCase):
vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG,
pat=True,
fstore=constants.EXPECTED_SHARE_ID),
fstore=constants.EXPECTED_FSTORE),
mock.call.createfshare(constants.NFS_LOWER,
constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID,
comment=mock.ANY,
fpg=constants.EXPECTED_FPG,
sharedir='.snapshot/%s' %
constants.EXPECTED_SNAP_ID,
fstore=constants.EXPECTED_SHARE_ID,
sharedir='.snapshot/%s/%s' %
(constants.EXPECTED_SNAP_ID,
constants.EXPECTED_SHARE_ID),
fstore=constants.EXPECTED_FSTORE,
clientip=constants.EXPECTED_IP_127,
options='ro,no_root_squash,insecure'),
mock.call.getfshare(constants.NFS_LOWER,
constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID)]
fstore=constants.EXPECTED_FSTORE)]
self.mock_client.assert_has_calls(expected_calls)
@ -338,7 +369,9 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mediator.create_share_from_snapshot,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -346,7 +379,12 @@ class HP3ParMediatorTestCase(test.TestCase):
def test_mediator_delete_share(self):
self.init_mediator()
self.mediator.delete_share(constants.EXPECTED_SHARE_ID,
self.mock_object(self.mediator,
'_find_fstore',
mock.Mock(return_value=constants.EXPECTED_SHARE_ID))
self.mediator.delete_share(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -356,10 +394,10 @@ class HP3ParMediatorTestCase(test.TestCase):
constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG,
fstore=constants.EXPECTED_FSTORE),
fstore=constants.EXPECTED_SHARE_ID),
mock.call.removefstore(constants.EXPECTED_VFS,
constants.EXPECTED_FSTORE,
fpg=constants.EXPECTED_FPG)
constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG),
]
self.mock_client.assert_has_calls(expected_calls)
@ -367,14 +405,16 @@ class HP3ParMediatorTestCase(test.TestCase):
def test_mediator_create_snapshot(self):
self.init_mediator()
self.mediator.create_snapshot(constants.EXPECTED_SHARE_ID,
self.mediator.create_snapshot(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call.createfsnap(constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SNAP_NAME,
fpg=constants.EXPECTED_FPG)
]
@ -389,7 +429,9 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertRaises(exception.ShareBackendException,
self.mediator.create_snapshot,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -401,7 +443,13 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mock_client.getfsnap.return_value = {
'total': 1,
'members': [{'snapName': expected_name_from_array}]
'members': [
{
'snapName': expected_name_from_array,
'fstoreName': constants.EXPECTED_PROJECT_ID,
}
],
'message': None
}
self.mock_client.getfshare.side_effect = [
@ -416,7 +464,9 @@ class HP3ParMediatorTestCase(test.TestCase):
}
]
self.mediator.delete_snapshot(constants.EXPECTED_SHARE_ID,
self.mediator.delete_snapshot(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -426,17 +476,17 @@ class HP3ParMediatorTestCase(test.TestCase):
vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG,
pat=True,
fstore=constants.EXPECTED_SHARE_ID),
fstore=constants.EXPECTED_PROJECT_ID),
mock.call.getfshare(constants.NFS_LOWER,
fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID),
fstore=constants.EXPECTED_PROJECT_ID),
mock.call.getfshare(constants.SMB_LOWER,
fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID),
fstore=constants.EXPECTED_PROJECT_ID),
mock.call.removefsnap(constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID,
constants.EXPECTED_PROJECT_ID,
fpg=constants.EXPECTED_FPG,
snapname=expected_name_from_array),
mock.call.startfsnapclean(constants.EXPECTED_FPG,
@ -452,7 +502,9 @@ class HP3ParMediatorTestCase(test.TestCase):
'members': [],
}
self.mediator.delete_snapshot(constants.EXPECTED_SHARE_ID,
self.mediator.delete_snapshot(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -497,7 +549,9 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertRaises(exception.Invalid,
self.mediator.delete_snapshot,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -527,7 +581,9 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertRaises(exception.Invalid,
self.mediator.delete_snapshot,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -535,7 +591,9 @@ class HP3ParMediatorTestCase(test.TestCase):
def _assert_delete_snapshot_raises(self):
self.assertRaises(exception.ShareBackendException,
self.mediator.delete_snapshot,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -551,7 +609,8 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mock_client.getfsnap.side_effect = None
self.mock_client.getfsnap.return_value = {
'total': 1,
'members': [{'snapName': constants.EXPECTED_SNAP_NAME}]
'members': [{'snapName': constants.EXPECTED_SNAP_NAME,
'fstoreName': constants.EXPECTED_FSTORE}]
}
# getfshare exception
@ -563,12 +622,14 @@ class HP3ParMediatorTestCase(test.TestCase):
if args[0] == constants.NFS_LOWER:
return {
'total': 1,
'members': [{'sharePath': '/anyfpg/anyvfs/anyfstore'}]
'members': [{'sharePath': '/anyfpg/anyvfs/anyfstore',
'fstoreName': constants.EXPECTED_FSTORE}]
}
else:
return {
'total': 1,
'members': [{'shareDir': []}]
'members': [{'shareDir': [],
'fstoreName': constants.EXPECTED_FSTORE}]
}
self.mock_client.getfshare.side_effect = mock_fshare
@ -587,7 +648,9 @@ class HP3ParMediatorTestCase(test.TestCase):
'startfsnapclean fail.')
mock_log = self.mock_object(hp3parmediator, 'LOG')
self.mediator.delete_snapshot(constants.EXPECTED_SHARE_ID,
self.mediator.delete_snapshot(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -597,17 +660,17 @@ class HP3ParMediatorTestCase(test.TestCase):
vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG,
pat=True,
fstore=constants.EXPECTED_SHARE_ID),
fstore=constants.EXPECTED_FSTORE),
mock.call.getfshare(constants.NFS_LOWER,
fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID),
fstore=constants.EXPECTED_FSTORE),
mock.call.getfshare(constants.SMB_LOWER,
fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID),
fstore=constants.EXPECTED_FSTORE),
mock.call.removefsnap(constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID,
constants.EXPECTED_FSTORE,
fpg=constants.EXPECTED_FPG,
snapname=constants.EXPECTED_SNAP_NAME),
mock.call.startfsnapclean(constants.EXPECTED_FPG,
@ -651,7 +714,8 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_allowperm = '+%s:fullcontrol' % constants.USERNAME
self.mediator.allow_access(constants.EXPECTED_SHARE_ID,
self.mediator.allow_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.USER,
constants.USERNAME,
@ -675,7 +739,8 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_denyperm = '-%s:fullcontrol' % constants.USERNAME
self.mediator.deny_access(constants.EXPECTED_SHARE_ID,
self.mediator.deny_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.USER,
constants.USERNAME,
@ -699,7 +764,8 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_allowip = '+%s' % constants.EXPECTED_IP_1234
self.mediator.allow_access(constants.EXPECTED_SHARE_ID,
self.mediator.allow_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.IP,
constants.EXPECTED_IP_1234,
@ -722,7 +788,8 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_denyip = '-%s' % constants.EXPECTED_IP_1234
self.mediator.deny_access(constants.EXPECTED_SHARE_ID,
self.mediator.deny_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.IP,
constants.EXPECTED_IP_1234,
@ -745,7 +812,8 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_clientip = '+%s' % constants.EXPECTED_IP_1234
self.mediator.allow_access(constants.EXPECTED_SHARE_ID,
self.mediator.allow_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.IP,
constants.EXPECTED_IP_1234,
@ -768,7 +836,8 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_clientip = '-%s' % constants.EXPECTED_IP_1234
self.mediator.deny_access(constants.EXPECTED_SHARE_ID,
self.mediator.deny_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.IP,
constants.EXPECTED_IP_1234,
@ -791,6 +860,7 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertRaises(exception.HP3ParInvalid,
self.mediator.allow_access,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.USER,
@ -804,6 +874,7 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertRaises(exception.InvalidInput,
self.mediator.allow_access,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
'unsupported_other_protocol',
constants.USER,
@ -817,9 +888,241 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertRaises(exception.InvalidInput,
self.mediator.allow_access,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
'unsupported_other_type',
constants.USERNAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ddt.data((('nfs', 'NFS', 'nFs'), 'smb'),
(('smb', 'SMB', 'SmB', 'CIFS', 'cifs', 'CiFs'), 'nfs'))
@ddt.unpack
def test_other_protocol(self, protocols, expected_other):
for protocol in protocols:
self.assertEqual(expected_other,
hp3parmediator.HP3ParMediator().other_protocol(
protocol))
@ddt.data('', 'bogus')
def test_other_protocol_exception(self, protocol):
self.assertRaises(exception.InvalidInput,
hp3parmediator.HP3ParMediator().other_protocol,
protocol)
@ddt.data(('osf-uid', None, 'osf-uid'),
('uid', None, 'osf-uid'),
('uid', 'smb', 'osf-smb-uid'),
('uid', 'smb', 'osf-smb-uid'))
@ddt.unpack
def test_ensure_prefix(self, uid, protocol, expected):
self.assertEqual(expected,
hp3parmediator.HP3ParMediator().ensure_prefix(
uid, protocol=protocol))
def test_find_fstore_search(self):
self.init_mediator()
mock_find_fshare = self.mock_object(self.mediator,
'_find_fshare',
mock.Mock(return_value=None))
result = self.mediator._find_fstore(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
mock_find_fshare.assert_called_once_with(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.assertIsNone(result)
def test_find_fstore_search_xproto(self):
self.init_mediator()
mock_find_fshare = self.mock_object(self.mediator,
'_find_fshare',
mock.Mock(return_value=None))
result = self.mediator._find_fstore(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS,
allow_cross_protocol=True)
expected_calls = [
mock.call(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS),
mock.call(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.SMB_LOWER,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS),
]
mock_find_fshare.assert_has_calls(expected_calls)
self.assertIsNone(result)
def test_find_fshare_search(self):
self.init_mediator()
self.mock_client.getfshare.return_value = {}
result = self.mediator._find_fshare(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call.getfshare(constants.NFS_LOWER,
constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_PROJECT_ID),
mock.call.getfshare(constants.NFS_LOWER,
constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID),
mock.call.getfshare(constants.NFS_LOWER,
constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG),
mock.call.getfshare(constants.NFS_LOWER,
constants.EXPECTED_SHARE_ID),
]
self.mock_client.assert_has_calls(expected_calls)
self.assertIsNone(result)
def test_find_fshare_exception(self):
self.init_mediator()
self.mock_client.getfshare.side_effect = Exception('test unexpected')
self.assertRaises(exception.ShareBackendException,
self.mediator._find_fshare,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.mock_client.getfshare.assert_called_once_with(
constants.NFS_LOWER,
constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_PROJECT_ID)
def test_find_fshare_hit(self):
self.init_mediator()
expected_result = {'shareName': 'hit'}
self.mock_client.getfshare.return_value = {
'total': 1,
'members': [expected_result]
}
result = self.mediator._find_fshare(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.mock_client.getfshare.assert_called_once_with(
constants.NFS_LOWER,
constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_PROJECT_ID),
self.assertEqual(expected_result, result)
def test_find_fsnap_search(self):
self.init_mediator()
self.mock_client.getfsnap.return_value = {}
result = self.mediator._find_fsnap(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_snap_pattern = '*_%s' % constants.EXPECTED_SNAP_ID
expected_calls = [
mock.call.getfsnap(expected_snap_pattern,
vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG,
pat=True,
fstore=constants.EXPECTED_PROJECT_ID),
mock.call.getfsnap(expected_snap_pattern,
vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG,
pat=True,
fstore=constants.EXPECTED_SHARE_ID),
mock.call.getfsnap(expected_snap_pattern,
fpg=constants.EXPECTED_FPG,
pat=True),
mock.call.getfsnap(expected_snap_pattern, pat=True),
]
self.mock_client.assert_has_calls(expected_calls)
self.assertIsNone(result)
def test_find_fsnap_exception(self):
self.init_mediator()
self.mock_client.getfsnap.side_effect = Exception('test unexpected')
self.assertRaises(exception.ShareBackendException,
self.mediator._find_fsnap,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_snap_pattern = '*_%s' % constants.EXPECTED_SNAP_ID
self.mock_client.getfsnap.assert_called_once_with(
expected_snap_pattern,
vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG,
pat=True,
fstore=constants.EXPECTED_PROJECT_ID)
def test_find_fsnap_hit(self):
self.init_mediator()
expected_result = {'snapName': 'hit'}
self.mock_client.getfsnap.return_value = {
'total': 1,
'members': [expected_result]
}
result = self.mediator._find_fsnap(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_snap_pattern = '*_%s' % constants.EXPECTED_SNAP_ID
self.mock_client.getfsnap.assert_called_once_with(
expected_snap_pattern,
vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG,
pat=True,
fstore=constants.EXPECTED_PROJECT_ID)
self.assertEqual(expected_result, result)