HP 3PAR use one filestore per tenant

Using one filestore per tenant allows more shares to be
created on an array.  The original behavior of one filestore
per share can still be used with the hp3par_fstore_per_share=True
configuration (default is False).

Change-Id: I17a8ee138eef0157819ea33c74a43c30ee644817
Implements: blueprint hp3par-filestore-per-tenant
This commit is contained in:
Mark Sturdevant 2015-02-27 01:12:02 -08:00
parent ca582354ed
commit b3aee0a201
5 changed files with 654 additions and 210 deletions

View File

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

View File

@ -24,7 +24,6 @@ import six
from manila import exception from manila import exception
from manila.i18n import _ from manila.i18n import _
from manila.i18n import _LI
from manila.openstack.common import log as logging from manila.openstack.common import log as logging
hp3parclient = importutils.try_import("hp3parclient") hp3parclient = importutils.try_import("hp3parclient")
@ -51,6 +50,7 @@ class HP3ParMediator(object):
self.hp3par_san_password = kwargs.get('hp3par_san_password') self.hp3par_san_password = kwargs.get('hp3par_san_password')
self.hp3par_san_ssh_port = kwargs.get('hp3par_san_ssh_port') self.hp3par_san_ssh_port = kwargs.get('hp3par_san_ssh_port')
self.hp3par_san_private_key = kwargs.get('hp3par_san_private_key') 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.ssh_conn_timeout = kwargs.get('ssh_conn_timeout')
self._client = None self._client = None
@ -132,13 +132,22 @@ class HP3ParMediator(object):
return protocol return protocol
@staticmethod @staticmethod
def ensure_prefix(id): def other_protocol(share_proto):
if id.startswith('osf-'): """Given 'nfs' or 'smb' (or equivalent) return the other one."""
return id protocol = HP3ParMediator.ensure_supported_protocol(share_proto)
else: return 'nfs' if protocol == 'smb' else 'smb'
return 'osf-%s' % id
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): fstore=None, sharedir=None, readonly=False, size=None):
"""Create the share and return its path. """Create the share and return its path.
@ -146,6 +155,7 @@ class HP3ParMediator(object):
called locally from create_share_from_snapshot(). The optional called locally from create_share_from_snapshot(). The optional
parameters allow re-use. parameters allow re-use.
:param project_id: The tenant ID.
:param share_id: The share-id with or without osf- prefix. :param share_id: The share-id with or without osf- prefix.
:param share_proto: The protocol (to map to smb or nfs) :param share_proto: The protocol (to map to smb or nfs)
:param fpg: The file provisioning group :param fpg: The file provisioning group
@ -162,7 +172,11 @@ class HP3ParMediator(object):
share_name = self.ensure_prefix(share_id) share_name = self.ensure_prefix(share_id)
if not fstore: if not fstore:
fstore = share_name if self.hp3par_fstore_per_share:
fstore = share_name
else:
fstore = self.ensure_prefix(project_id, protocol)
try: try:
result = self._client.createfstore( result = self._client.createfstore(
vfs, fstore, fpg=fpg, vfs, fstore, fpg=fpg,
@ -175,11 +189,26 @@ class HP3ParMediator(object):
raise exception.ShareBackendException(msg) raise exception.ShareBackendException(msg)
if size: 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: try:
size_str = six.text_type(size)
result = self._client.setfsquota( result = self._client.setfsquota(
vfs, fpg=fpg, fstore=fstore, vfs, fpg=fpg, fstore=fstore,
scapacity=size_str, hcapacity=size_str) scapacity=scapacity, hcapacity=hcapacity)
LOG.debug("setfsquota result=%s", result) LOG.debug("setfsquota result=%s", result)
except Exception as e: except Exception as e:
msg = (_('Failed to setfsquota on %(fstore)s: %(e)s') % msg = (_('Failed to setfsquota on %(fstore)s: %(e)s') %
@ -187,6 +216,9 @@ class HP3ParMediator(object):
LOG.exception(msg) LOG.exception(msg)
raise exception.ShareBackendException(msg) raise exception.ShareBackendException(msg)
if not (sharedir or self.hp3par_fstore_per_share):
sharedir = share_name
try: try:
if protocol == 'nfs': if protocol == 'nfs':
if readonly: if readonly:
@ -239,30 +271,45 @@ class HP3ParMediator(object):
else: else:
return result['members'][0]['shareName'] 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): snapshot_id, fpg, vfs):
share_name = self.ensure_prefix(share_id) protocol = self.ensure_supported_protocol(share_proto)
orig_share_name = self.ensure_prefix(orig_share_id)
fstore = orig_share_name
snapshot_tag = self.ensure_prefix(snapshot_id) 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 ' msg = (_('Failed to create share from snapshot for '
'FPG/VFS/fstore/tag %(fpg)s/%(vfs)s/%(fstore)s/%(tag)s.' 'FPG/VFS/tag %(fpg)s/%(vfs)s/%(tag)s. '
' Expected to find 1 snapshot, found %(count)s.') % 'Snapshot not found.') %
{'fpg': fpg, 'vfs': vfs, 'fstore': fstore, {
'tag': snapshot_tag, 'count': len(snapshots)}) 'fpg': fpg,
'vfs': vfs,
'tag': snapshot_tag})
LOG.exception(msg) LOG.exception(msg)
raise exception.ShareBackendException(msg) raise exception.ShareBackendException(msg)
snapshot = snapshots[0] fstore = snapshot['fstoreName']
sharedir = '.snapshot/%s' % snapshot['snapName'] 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( return self.create_share(
orig_project_id,
share_name, share_name,
share_proto, protocol,
fpg, fpg,
vfs, vfs,
fstore=fstore, fstore=fstore,
@ -270,11 +317,12 @@ class HP3ParMediator(object):
readonly=True, 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) 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: if not fstore:
# Share does not exist. # Share does not exist.
@ -289,13 +337,14 @@ class HP3ParMediator(object):
LOG.exception(msg) LOG.exception(msg)
raise exception.ShareBackendException(message=msg) raise exception.ShareBackendException(message=msg)
try: if fstore == share_name:
self._client.removefstore(vfs, fstore, fpg=fpg) try:
except Exception as e: self._client.removefstore(vfs, fstore, fpg=fpg)
msg = (_('Failed to remove fstore %(fstore)s: %(e)s') % except Exception as e:
{'fstore': fstore, 'e': six.text_type(e)}) msg = (_('Failed to remove fstore %(fstore)s: %(e)s') %
LOG.exception(msg) {'fstore': fstore, 'e': six.text_type(e)})
raise exception.ShareBackendException(message=msg) LOG.exception(msg)
raise exception.ShareBackendException(message=msg)
def get_vfs_name(self, fpg): def get_vfs_name(self, fpg):
return self.get_vfs(fpg)['vfsname'] return self.get_vfs(fpg)['vfsname']
@ -331,10 +380,33 @@ class HP3ParMediator(object):
return result['members'][0] 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.""" """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) snapshot_tag = self.ensure_prefix(snapshot_id)
try: try:
result = self._client.createfsnap( result = self._client.createfsnap(
@ -350,41 +422,20 @@ class HP3ParMediator(object):
LOG.exception(msg) LOG.exception(msg)
raise exception.ShareBackendException(msg) raise exception.ShareBackendException(msg)
def get_snapshots(self, orig_share_id, snapshot_tag, fpg, vfs): def delete_snapshot(self, orig_project_id, orig_share_id, orig_proto,
fstore = self.ensure_prefix(orig_share_id) snapshot_id, fpg, vfs):
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):
"""Deletes a snapshot of a share.""" """Deletes a snapshot of a share."""
fstore = self.ensure_prefix(orig_share_id)
snapshot_tag = self.ensure_prefix(snapshot_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 return
fstore = snapshot.get('fstoreName')
for protocol in ('nfs', 'smb'): for protocol in ('nfs', 'smb'):
try: try:
shares = self._client.getfshare(protocol, shares = self._client.getfshare(protocol,
@ -417,23 +468,24 @@ class HP3ParMediator(object):
'dependent share.')) 'dependent share.'))
raise exception.Invalid(msg) raise exception.Invalid(msg)
# Tag should be unique enough to only return one, but this method snapname = snapshot['snapName']
# doesn't really need to know that. So just loop. try:
for snapshot in snapshots: result = self._client.removefsnap(
try: vfs, fstore, snapname=snapname, fpg=fpg)
snapname = snapshot['snapName']
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: except Exception as e:
msg = (_('Failed to delete snapshot for FPG/VFS/fstore ' msg = (_('Failed to delete snapshot for FPG/VFS/fstore/snapshot '
'%(fpg)s/%(vfs)s/%(fstore)s: %(e)s') % '%(fpg)s/%(vfs)s/%(fstore)s/%(snapname)s: %(e)s') %
{'fpg': fpg, 'vfs': vfs, 'fstore': fstore, {
'e': six.text_type(e)}) 'fpg': fpg,
LOG.exception(msg) 'vfs': vfs,
raise exception.ShareBackendException(msg) 'fstore': fstore,
'snapname': snapname,
'e': six.text_type(e)})
LOG.exception(msg)
raise exception.ShareBackendException(msg)
# Try to reclaim the space # Try to reclaim the space
try: try:
@ -461,7 +513,7 @@ class HP3ParMediator(object):
return protocol 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): access_type, access_to, fpg, vfs):
"""Allow or deny access to a share. """Allow or deny access to a share.
@ -469,12 +521,13 @@ class HP3ParMediator(object):
allow list (-). allow list (-).
""" """
share_name = self.ensure_prefix(share_id)
fstore = self.ensure_prefix(fstore)
protocol = self.ensure_supported_protocol(share_proto) protocol = self.ensure_supported_protocol(share_proto)
self.validate_access_type(protocol, access_type) 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: try:
if protocol == 'nfs': if protocol == 'nfs':
result = self._client.setfshare( result = self._client.setfshare(
@ -507,37 +560,80 @@ class HP3ParMediator(object):
LOG.exception(msg) LOG.exception(msg)
raise exception.ShareBackendException(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) protocol = self.ensure_supported_protocol(share_proto)
share_name = self.ensure_prefix(share_id) 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: try:
shares = self._client.getfshare(protocol, for search_params in search_order:
share_name, result = self._client.getfshare(protocol, share_name,
fpg=fpg, **search_params)
vfs=vfs) shares = result.get('members', [])
if len(shares) == 1:
return shares[0]
except Exception as e: except Exception as e:
msg = (_('Unexpected exception while getting share list: %s') % msg = (_('Unexpected exception while getting share list: %s') %
six.text_type(e)) six.text_type(e))
raise exception.ShareBackendException(msg) raise exception.ShareBackendException(msg)
members = shares['members'] def _find_fsnap(self, project_id, share_id, orig_proto, snapshot_tag,
if members: fpg, vfs):
return members[0].get('fstoreName')
def allow_access(self, share_id, share_proto, access_type, access_to, share_name = self.ensure_prefix(share_id)
fpg, vfs): 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.""" """Grant access to a share."""
fstore = self.get_fstore(share_id, share_proto, fpg, vfs) self._change_access(ALLOW, project_id, share_id, share_proto,
self._change_access(ALLOW, fstore, share_id, share_proto,
access_type, access_to, fpg, vfs) access_type, access_to, fpg, vfs)
def deny_access(self, share_id, share_proto, access_type, access_to, def deny_access(self, project_id, share_id, share_proto, access_type,
fpg, vfs): access_to, fpg, vfs):
"""Deny access to a share.""" """Deny access to a share."""
fstore = self.get_fstore(share_id, share_proto, fpg, vfs) self._change_access(DENY, project_id, share_id, share_proto,
if fstore: access_type, access_to, fpg, vfs)
self._change_access(DENY, fstore, 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_10203040 = '10.20.30.40'
EXPECTED_IP_1234 = '1.2.3.4' EXPECTED_IP_1234 = '1.2.3.4'
EXPECTED_IP_127 = '127.0.0.1' EXPECTED_IP_127 = '127.0.0.1'
EXPECTED_PROJECT_ID = 'osf-nfs-project-id'
EXPECTED_SHARE_ID = 'osf-share-id' EXPECTED_SHARE_ID = 'osf-share-id'
EXPECTED_SHARE_NAME = 'share-name' EXPECTED_SHARE_NAME = 'share-name'
EXPECTED_SHARE_PATH = '/anyfpg/anyvfs/anyfstore' EXPECTED_SHARE_PATH = '/anyfpg/anyvfs/anyfstore'
@ -38,11 +39,12 @@ EXPECTED_SNAP_NAME = 'osf-snap-name'
EXPECTED_SNAP_ID = 'osf-snap-id' EXPECTED_SNAP_ID = 'osf-snap-id'
EXPECTED_STATS = {'test': 'stats'} EXPECTED_STATS = {'test': 'stats'}
EXPECTED_FPG = 'FPG_1' EXPECTED_FPG = 'FPG_1'
EXPECTED_FSTORE = 'osf-test_fstore' EXPECTED_FSTORE = EXPECTED_PROJECT_ID
EXPECTED_VFS = 'test_vfs' EXPECTED_VFS = 'test_vfs'
EXPECTED_HP_DEBUG = True EXPECTED_HP_DEBUG = True
NFS_SHARE_INFO = { NFS_SHARE_INFO = {
'project_id': EXPECTED_PROJECT_ID,
'id': EXPECTED_SHARE_ID, 'id': EXPECTED_SHARE_ID,
'share_proto': NFS, 'share_proto': NFS,
} }
@ -55,5 +57,9 @@ ACCESS_INFO = {
SNAPSHOT_INFO = { SNAPSHOT_INFO = {
'name': EXPECTED_SNAP_NAME, 'name': EXPECTED_SNAP_NAME,
'id': EXPECTED_SNAP_ID, '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_api_url = constants.API_URL
self.conf.hp3par_san_login = constants.SAN_LOGIN self.conf.hp3par_san_login = constants.SAN_LOGIN
self.conf.hp3par_san_password = constants.SAN_PASSWORD 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_fpg = constants.EXPECTED_FPG
self.conf.hp3par_san_ssh_port = constants.PORT self.conf.hp3par_san_ssh_port = constants.PORT
self.conf.ssh_conn_timeout = constants.TIMEOUT self.conf.ssh_conn_timeout = constants.TIMEOUT
self.conf.hp3par_share_ip_address = constants.EXPECTED_IP_10203040 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' self.conf.network_config_group = 'test_network_config_group'
def safe_get(attr): def safe_get(attr):
@ -66,20 +67,22 @@ class HP3ParDriverTestCase(test.TestCase):
self.mock_mediator.get_vfs_name.return_value = constants.EXPECTED_VFS self.mock_mediator.get_vfs_name.return_value = constants.EXPECTED_VFS
self.driver.do_setup(None) self.driver.do_setup(None)
conf = self.conf
self.mock_mediator_constructor.assert_has_calls([ self.mock_mediator_constructor.assert_has_calls([
mock.call(hp3par_san_ssh_port=self.conf.hp3par_san_ssh_port, mock.call(hp3par_san_ssh_port=conf.hp3par_san_ssh_port,
hp3par_san_password=self.conf.hp3par_san_password, hp3par_san_password=conf.hp3par_san_password,
hp3par_username=self.conf.hp3par_username, hp3par_username=conf.hp3par_username,
hp3par_san_login=self.conf.hp3par_san_login, hp3par_san_login=conf.hp3par_san_login,
hp3par_debug=self.conf.hp3par_debug, hp3par_debug=conf.hp3par_debug,
hp3par_api_url=self.conf.hp3par_api_url, hp3par_api_url=conf.hp3par_api_url,
hp3par_password=self.conf.hp3par_password, hp3par_password=conf.hp3par_password,
hp3par_san_ip=self.conf.hp3par_san_ip, hp3par_san_ip=conf.hp3par_san_ip,
ssh_conn_timeout=self.conf.ssh_conn_timeout)]) hp3par_fstore_per_share=conf.hp3par_fstore_per_share,
ssh_conn_timeout=conf.ssh_conn_timeout)])
self.mock_mediator.assert_has_calls([ self.mock_mediator.assert_has_calls([
mock.call.do_setup(), 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) self.assertEqual(constants.EXPECTED_VFS, self.driver.vfs)
@ -92,16 +95,18 @@ class HP3ParDriverTestCase(test.TestCase):
self.assertRaises(exception.ShareBackendException, self.assertRaises(exception.ShareBackendException,
self.driver.do_setup, None) self.driver.do_setup, None)
conf = self.conf
self.mock_mediator_constructor.assert_has_calls([ self.mock_mediator_constructor.assert_has_calls([
mock.call(hp3par_san_ssh_port=self.conf.hp3par_san_ssh_port, mock.call(hp3par_san_ssh_port=conf.hp3par_san_ssh_port,
hp3par_san_password=self.conf.hp3par_san_password, hp3par_san_password=conf.hp3par_san_password,
hp3par_username=self.conf.hp3par_username, hp3par_username=conf.hp3par_username,
hp3par_san_login=self.conf.hp3par_san_login, hp3par_san_login=conf.hp3par_san_login,
hp3par_debug=self.conf.hp3par_debug, hp3par_debug=conf.hp3par_debug,
hp3par_api_url=self.conf.hp3par_api_url, hp3par_api_url=conf.hp3par_api_url,
hp3par_password=self.conf.hp3par_password, hp3par_password=conf.hp3par_password,
hp3par_san_ip=self.conf.hp3par_san_ip, hp3par_san_ip=conf.hp3par_san_ip,
ssh_conn_timeout=self.conf.ssh_conn_timeout)]) 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()]) self.mock_mediator.assert_has_calls([mock.call.do_setup()])
@ -114,20 +119,22 @@ class HP3ParDriverTestCase(test.TestCase):
self.assertRaises(exception.ShareBackendException, self.assertRaises(exception.ShareBackendException,
self.driver.do_setup, None) self.driver.do_setup, None)
conf = self.conf
self.mock_mediator_constructor.assert_has_calls([ self.mock_mediator_constructor.assert_has_calls([
mock.call(hp3par_san_ssh_port=self.conf.hp3par_san_ssh_port, mock.call(hp3par_san_ssh_port=conf.hp3par_san_ssh_port,
hp3par_san_password=self.conf.hp3par_san_password, hp3par_san_password=conf.hp3par_san_password,
hp3par_username=self.conf.hp3par_username, hp3par_username=conf.hp3par_username,
hp3par_san_login=self.conf.hp3par_san_login, hp3par_san_login=conf.hp3par_san_login,
hp3par_debug=self.conf.hp3par_debug, hp3par_debug=conf.hp3par_debug,
hp3par_api_url=self.conf.hp3par_api_url, hp3par_api_url=conf.hp3par_api_url,
hp3par_password=self.conf.hp3par_password, hp3par_password=conf.hp3par_password,
hp3par_san_ip=self.conf.hp3par_san_ip, hp3par_san_ip=conf.hp3par_san_ip,
ssh_conn_timeout=self.conf.ssh_conn_timeout)]) hp3par_fstore_per_share=conf.hp3par_fstore_per_share,
ssh_conn_timeout=conf.ssh_conn_timeout)])
self.mock_mediator.assert_has_calls([ self.mock_mediator.assert_has_calls([
mock.call.do_setup(), 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): def init_driver(self):
"""Simple driver setup for re-use with tests that need one.""" """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.fpg = constants.EXPECTED_FPG
self.driver.share_ip_address = self.conf.hp3par_share_ip_address 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.""" """Re-usable code for create share."""
context = None context = None
share_server = None share_server = None
share = { share = {
'project_id': expected_project_id,
'id': expected_share_id, 'id': expected_share_id,
'share_proto': protocol, 'share_proto': protocol,
'size': expected_size, 'size': expected_size,
@ -188,11 +197,13 @@ class HP3ParDriverTestCase(test.TestCase):
constants.EXPECTED_SHARE_NAME) constants.EXPECTED_SHARE_NAME)
location = self.do_create_share(constants.CIFS, location = self.do_create_share(constants.CIFS,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SIZE_2) constants.EXPECTED_SIZE_2)
self.assertEqual(expected_location, location) self.assertEqual(expected_location, location)
expected_calls = [mock.call.create_share( expected_calls = [mock.call.create_share(
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.CIFS, constants.CIFS,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
@ -210,12 +221,14 @@ class HP3ParDriverTestCase(test.TestCase):
constants.EXPECTED_SHARE_PATH) constants.EXPECTED_SHARE_PATH)
location = self.do_create_share(constants.NFS, location = self.do_create_share(constants.NFS,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SIZE_1) constants.EXPECTED_SIZE_1)
self.assertEqual(expected_location, location) self.assertEqual(expected_location, location)
expected_calls = [ 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.NFS,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS, constants.EXPECTED_VFS,
@ -242,7 +255,9 @@ class HP3ParDriverTestCase(test.TestCase):
expected_calls = [ expected_calls = [
mock.call.create_share_from_snapshot(constants.EXPECTED_SHARE_ID, mock.call.create_share_from_snapshot(constants.EXPECTED_SHARE_ID,
constants.CIFS, constants.CIFS,
constants.EXPECTED_FSTORE,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID, constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS)] constants.EXPECTED_VFS)]
@ -267,7 +282,9 @@ class HP3ParDriverTestCase(test.TestCase):
expected_calls = [ expected_calls = [
mock.call.create_share_from_snapshot(constants.EXPECTED_SHARE_ID, mock.call.create_share_from_snapshot(constants.EXPECTED_SHARE_ID,
constants.NFS, constants.NFS,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID, constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS)] constants.EXPECTED_VFS)]
@ -280,6 +297,7 @@ class HP3ParDriverTestCase(test.TestCase):
context = None context = None
share_server = None share_server = None
share = { share = {
'project_id': constants.EXPECTED_PROJECT_ID,
'id': constants.EXPECTED_SHARE_ID, 'id': constants.EXPECTED_SHARE_ID,
'share_proto': constants.CIFS, 'share_proto': constants.CIFS,
'size': constants.EXPECTED_SIZE_1, 'size': constants.EXPECTED_SIZE_1,
@ -288,7 +306,8 @@ class HP3ParDriverTestCase(test.TestCase):
self.driver.delete_share(context, share, share_server) self.driver.delete_share(context, share, share_server)
expected_calls = [ 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.CIFS,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS)] constants.EXPECTED_VFS)]
@ -305,7 +324,9 @@ class HP3ParDriverTestCase(test.TestCase):
share_server) share_server)
expected_calls = [ 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_SNAP_ID,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS)] constants.EXPECTED_VFS)]
@ -321,7 +342,9 @@ class HP3ParDriverTestCase(test.TestCase):
share_server) share_server)
expected_calls = [ 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_SNAP_ID,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
@ -337,7 +360,8 @@ class HP3ParDriverTestCase(test.TestCase):
constants.ACCESS_INFO) constants.ACCESS_INFO)
expected_calls = [ 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.NFS,
constants.IP, constants.IP,
constants.EXPECTED_IP_1234, constants.EXPECTED_IP_1234,
@ -355,7 +379,8 @@ class HP3ParDriverTestCase(test.TestCase):
constants.ACCESS_INFO) constants.ACCESS_INFO)
expected_calls = [ 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.NFS,
constants.IP, constants.IP,
constants.EXPECTED_IP_1234, constants.EXPECTED_IP_1234,

View File

@ -14,10 +14,10 @@
import sys import sys
import ddt
import mock import mock
if 'hp3parclient' not in sys.modules: if 'hp3parclient' not in sys.modules:
sys.modules['hp3parclient'] = mock.Mock() sys.modules['hp3parclient'] = mock.Mock()
import six
from manila import exception from manila import exception
from manila.share.drivers.hp import hp_3par_mediator as hp3parmediator 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 from oslo_utils import units
@ddt.ddt
class HP3ParMediatorTestCase(test.TestCase): class HP3ParMediatorTestCase(test.TestCase):
def setUp(self): def setUp(self):
@ -143,20 +144,23 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_fpg, expected_fpg,
expected_vfsname, expected_vfsname,
expected_protocol, expected_protocol,
expected_share_id, expected_project_id,
expected_size): expected_share_id):
size = six.text_type(expected_size) expected_sharedir = expected_share_id
expected_sharedir = None
if expected_protocol == constants.NFS_LOWER: if expected_protocol == constants.NFS_LOWER:
expected_calls = [ expected_calls = [
mock.call.createfstore(expected_vfsname, expected_share_id, mock.call.createfstore(expected_vfsname, expected_project_id,
comment='OpenStack Manila fstore', comment='OpenStack Manila fstore',
fpg=expected_fpg), fpg=expected_fpg),
mock.call.setfsquota(expected_vfsname, fpg=expected_fpg, mock.call.getfsquota(fpg=expected_fpg,
hcapacity=size, vfs=expected_vfsname,
scapacity=size, fstore=expected_project_id),
fstore=expected_share_id), mock.call.setfsquota(expected_vfsname,
fpg=expected_fpg,
hcapacity='2048',
scapacity='2048',
fstore=expected_project_id),
mock.call.createfshare(expected_protocol, expected_vfsname, mock.call.createfshare(expected_protocol, expected_vfsname,
expected_share_id, expected_share_id,
comment='OpenStack Manila fshare', comment='OpenStack Manila fshare',
@ -164,29 +168,33 @@ class HP3ParMediatorTestCase(test.TestCase):
sharedir=expected_sharedir, sharedir=expected_sharedir,
clientip='127.0.0.1', clientip='127.0.0.1',
options='rw,no_root_squash,insecure', options='rw,no_root_squash,insecure',
fstore=expected_share_id), fstore=expected_project_id),
mock.call.getfshare(expected_protocol, expected_share_id, mock.call.getfshare(expected_protocol, expected_share_id,
fpg=expected_fpg, vfs=expected_vfsname, fpg=expected_fpg, vfs=expected_vfsname,
fstore=expected_share_id)] fstore=expected_project_id)]
else: else:
expected_calls = [ expected_calls = [
mock.call.createfstore(expected_vfsname, expected_share_id, mock.call.createfstore(expected_vfsname, expected_project_id,
comment='OpenStack Manila fstore', comment='OpenStack Manila fstore',
fpg=expected_fpg), fpg=expected_fpg),
mock.call.setfsquota(expected_vfsname, fpg=expected_fpg, mock.call.getfsquota(fpg=expected_fpg,
hcapacity=size, vfs=expected_vfsname,
scapacity=size, fstore=expected_project_id),
fstore=expected_share_id), mock.call.setfsquota(expected_vfsname,
fpg=expected_fpg,
hcapacity='2048',
scapacity='2048',
fstore=expected_project_id),
mock.call.createfshare(expected_protocol, expected_vfsname, mock.call.createfshare(expected_protocol, expected_vfsname,
expected_share_id, expected_share_id,
comment='OpenStack Manila fshare', comment='OpenStack Manila fshare',
fpg=expected_fpg, fpg=expected_fpg,
sharedir=expected_sharedir, sharedir=expected_sharedir,
allowip='127.0.0.1', allowip='127.0.0.1',
fstore=expected_share_id), fstore=expected_project_id),
mock.call.getfshare(expected_protocol, expected_share_id, mock.call.getfshare(expected_protocol, expected_share_id,
fpg=expected_fpg, vfs=expected_vfsname, fpg=expected_fpg, vfs=expected_vfsname,
fstore=expected_share_id)] fstore=expected_project_id)]
return expected_calls return expected_calls
def test_mediator_create_cifs_share(self): def test_mediator_create_cifs_share(self):
@ -198,11 +206,18 @@ class HP3ParMediatorTestCase(test.TestCase):
'members': [{'shareName': constants.EXPECTED_SHARE_NAME}] '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.CIFS,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS, constants.EXPECTED_VFS,
size=constants.EXPECTED_SIZE_2) size=constants.EXPECTED_SIZE_1)
self.assertEqual(constants.EXPECTED_SHARE_NAME, location) self.assertEqual(constants.EXPECTED_SHARE_NAME, location)
@ -210,8 +225,8 @@ class HP3ParMediatorTestCase(test.TestCase):
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS, constants.EXPECTED_VFS,
constants.SMB_LOWER, constants.SMB_LOWER,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SIZE_2) constants.EXPECTED_SHARE_ID)
self.mock_client.assert_has_calls(expected_calls) self.mock_client.assert_has_calls(expected_calls)
@ -224,7 +239,14 @@ class HP3ParMediatorTestCase(test.TestCase):
'members': [{'sharePath': constants.EXPECTED_SHARE_PATH}] '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.NFS.lower(),
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS, constants.EXPECTED_VFS,
@ -233,10 +255,11 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertEqual(constants.EXPECTED_SHARE_PATH, location) self.assertEqual(constants.EXPECTED_SHARE_PATH, location)
expected_calls = self.get_expected_calls_for_create_share( 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.NFS.lower(),
constants.EXPECTED_SHARE_ID, constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SIZE_1) constants.EXPECTED_SHARE_ID)
self.mock_client.assert_has_calls(expected_calls) self.mock_client.assert_has_calls(expected_calls)
@ -246,13 +269,16 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mock_client.getfsnap.return_value = { self.mock_client.getfsnap.return_value = {
'message': None, 'message': None,
'total': 1, '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( location = self.mediator.create_share_from_snapshot(
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.CIFS, constants.CIFS,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID, constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
@ -264,21 +290,22 @@ class HP3ParMediatorTestCase(test.TestCase):
vfs=constants.EXPECTED_VFS, vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
pat=True, pat=True,
fstore=constants.EXPECTED_SHARE_ID), fstore=constants.EXPECTED_FSTORE),
mock.call.createfshare(constants.SMB_LOWER, mock.call.createfshare(constants.SMB_LOWER,
constants.EXPECTED_VFS, constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
comment=mock.ANY, comment=mock.ANY,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
sharedir='.snapshot/%s' % sharedir='.snapshot/%s/%s' % (
constants.EXPECTED_SNAP_ID, constants.EXPECTED_SNAP_ID,
fstore=constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID),
fstore=constants.EXPECTED_FSTORE,
allowip=constants.EXPECTED_IP_127), allowip=constants.EXPECTED_IP_127),
mock.call.getfshare(constants.SMB_LOWER, mock.call.getfshare(constants.SMB_LOWER,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS, vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID)] fstore=constants.EXPECTED_FSTORE)]
self.mock_client.assert_has_calls(expected_calls) self.mock_client.assert_has_calls(expected_calls)
@ -288,13 +315,16 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mock_client.getfsnap.return_value = { self.mock_client.getfsnap.return_value = {
'message': None, 'message': None,
'total': 1, '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( location = self.mediator.create_share_from_snapshot(
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.NFS, constants.NFS,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID, constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
@ -306,22 +336,23 @@ class HP3ParMediatorTestCase(test.TestCase):
vfs=constants.EXPECTED_VFS, vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
pat=True, pat=True,
fstore=constants.EXPECTED_SHARE_ID), fstore=constants.EXPECTED_FSTORE),
mock.call.createfshare(constants.NFS_LOWER, mock.call.createfshare(constants.NFS_LOWER,
constants.EXPECTED_VFS, constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
comment=mock.ANY, comment=mock.ANY,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
sharedir='.snapshot/%s' % sharedir='.snapshot/%s/%s' %
constants.EXPECTED_SNAP_ID, (constants.EXPECTED_SNAP_ID,
fstore=constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID),
fstore=constants.EXPECTED_FSTORE,
clientip=constants.EXPECTED_IP_127, clientip=constants.EXPECTED_IP_127,
options='ro,no_root_squash,insecure'), options='ro,no_root_squash,insecure'),
mock.call.getfshare(constants.NFS_LOWER, mock.call.getfshare(constants.NFS_LOWER,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS, vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID)] fstore=constants.EXPECTED_FSTORE)]
self.mock_client.assert_has_calls(expected_calls) self.mock_client.assert_has_calls(expected_calls)
@ -338,7 +369,9 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mediator.create_share_from_snapshot, self.mediator.create_share_from_snapshot,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.NFS, constants.NFS,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_ID, constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
@ -346,7 +379,12 @@ class HP3ParMediatorTestCase(test.TestCase):
def test_mediator_delete_share(self): def test_mediator_delete_share(self):
self.init_mediator() 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.CIFS,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
@ -356,10 +394,10 @@ class HP3ParMediatorTestCase(test.TestCase):
constants.EXPECTED_VFS, constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
fstore=constants.EXPECTED_FSTORE), fstore=constants.EXPECTED_SHARE_ID),
mock.call.removefstore(constants.EXPECTED_VFS, mock.call.removefstore(constants.EXPECTED_VFS,
constants.EXPECTED_FSTORE, constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG) fpg=constants.EXPECTED_FPG),
] ]
self.mock_client.assert_has_calls(expected_calls) self.mock_client.assert_has_calls(expected_calls)
@ -367,14 +405,16 @@ class HP3ParMediatorTestCase(test.TestCase):
def test_mediator_create_snapshot(self): def test_mediator_create_snapshot(self):
self.init_mediator() 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_SNAP_NAME,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
expected_calls = [ expected_calls = [
mock.call.createfsnap(constants.EXPECTED_VFS, mock.call.createfsnap(constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SNAP_NAME, constants.EXPECTED_SNAP_NAME,
fpg=constants.EXPECTED_FPG) fpg=constants.EXPECTED_FPG)
] ]
@ -389,7 +429,9 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertRaises(exception.ShareBackendException, self.assertRaises(exception.ShareBackendException,
self.mediator.create_snapshot, self.mediator.create_snapshot,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_NAME, constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
@ -401,7 +443,13 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mock_client.getfsnap.return_value = { self.mock_client.getfsnap.return_value = {
'total': 1, '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 = [ 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_SNAP_NAME,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
@ -426,17 +476,17 @@ class HP3ParMediatorTestCase(test.TestCase):
vfs=constants.EXPECTED_VFS, vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
pat=True, pat=True,
fstore=constants.EXPECTED_SHARE_ID), fstore=constants.EXPECTED_PROJECT_ID),
mock.call.getfshare(constants.NFS_LOWER, mock.call.getfshare(constants.NFS_LOWER,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS, vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID), fstore=constants.EXPECTED_PROJECT_ID),
mock.call.getfshare(constants.SMB_LOWER, mock.call.getfshare(constants.SMB_LOWER,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS, vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID), fstore=constants.EXPECTED_PROJECT_ID),
mock.call.removefsnap(constants.EXPECTED_VFS, mock.call.removefsnap(constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_PROJECT_ID,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
snapname=expected_name_from_array), snapname=expected_name_from_array),
mock.call.startfsnapclean(constants.EXPECTED_FPG, mock.call.startfsnapclean(constants.EXPECTED_FPG,
@ -452,7 +502,9 @@ class HP3ParMediatorTestCase(test.TestCase):
'members': [], '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_SNAP_NAME,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
@ -497,7 +549,9 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertRaises(exception.Invalid, self.assertRaises(exception.Invalid,
self.mediator.delete_snapshot, self.mediator.delete_snapshot,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_NAME, constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
@ -527,7 +581,9 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertRaises(exception.Invalid, self.assertRaises(exception.Invalid,
self.mediator.delete_snapshot, self.mediator.delete_snapshot,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_NAME, constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
@ -535,7 +591,9 @@ class HP3ParMediatorTestCase(test.TestCase):
def _assert_delete_snapshot_raises(self): def _assert_delete_snapshot_raises(self):
self.assertRaises(exception.ShareBackendException, self.assertRaises(exception.ShareBackendException,
self.mediator.delete_snapshot, self.mediator.delete_snapshot,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SNAP_NAME, constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
@ -551,7 +609,8 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mock_client.getfsnap.side_effect = None self.mock_client.getfsnap.side_effect = None
self.mock_client.getfsnap.return_value = { self.mock_client.getfsnap.return_value = {
'total': 1, 'total': 1,
'members': [{'snapName': constants.EXPECTED_SNAP_NAME}] 'members': [{'snapName': constants.EXPECTED_SNAP_NAME,
'fstoreName': constants.EXPECTED_FSTORE}]
} }
# getfshare exception # getfshare exception
@ -563,12 +622,14 @@ class HP3ParMediatorTestCase(test.TestCase):
if args[0] == constants.NFS_LOWER: if args[0] == constants.NFS_LOWER:
return { return {
'total': 1, 'total': 1,
'members': [{'sharePath': '/anyfpg/anyvfs/anyfstore'}] 'members': [{'sharePath': '/anyfpg/anyvfs/anyfstore',
'fstoreName': constants.EXPECTED_FSTORE}]
} }
else: else:
return { return {
'total': 1, 'total': 1,
'members': [{'shareDir': []}] 'members': [{'shareDir': [],
'fstoreName': constants.EXPECTED_FSTORE}]
} }
self.mock_client.getfshare.side_effect = mock_fshare self.mock_client.getfshare.side_effect = mock_fshare
@ -587,7 +648,9 @@ class HP3ParMediatorTestCase(test.TestCase):
'startfsnapclean fail.') 'startfsnapclean fail.')
mock_log = self.mock_object(hp3parmediator, 'LOG') 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_SNAP_NAME,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) constants.EXPECTED_VFS)
@ -597,17 +660,17 @@ class HP3ParMediatorTestCase(test.TestCase):
vfs=constants.EXPECTED_VFS, vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
pat=True, pat=True,
fstore=constants.EXPECTED_SHARE_ID), fstore=constants.EXPECTED_FSTORE),
mock.call.getfshare(constants.NFS_LOWER, mock.call.getfshare(constants.NFS_LOWER,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS, vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID), fstore=constants.EXPECTED_FSTORE),
mock.call.getfshare(constants.SMB_LOWER, mock.call.getfshare(constants.SMB_LOWER,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS, vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID), fstore=constants.EXPECTED_FSTORE),
mock.call.removefsnap(constants.EXPECTED_VFS, mock.call.removefsnap(constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_FSTORE,
fpg=constants.EXPECTED_FPG, fpg=constants.EXPECTED_FPG,
snapname=constants.EXPECTED_SNAP_NAME), snapname=constants.EXPECTED_SNAP_NAME),
mock.call.startfsnapclean(constants.EXPECTED_FPG, mock.call.startfsnapclean(constants.EXPECTED_FPG,
@ -651,7 +714,8 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_allowperm = '+%s:fullcontrol' % constants.USERNAME 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.CIFS,
constants.USER, constants.USER,
constants.USERNAME, constants.USERNAME,
@ -675,7 +739,8 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_denyperm = '-%s:fullcontrol' % constants.USERNAME 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.CIFS,
constants.USER, constants.USER,
constants.USERNAME, constants.USERNAME,
@ -699,7 +764,8 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_allowip = '+%s' % constants.EXPECTED_IP_1234 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.CIFS,
constants.IP, constants.IP,
constants.EXPECTED_IP_1234, constants.EXPECTED_IP_1234,
@ -722,7 +788,8 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_denyip = '-%s' % constants.EXPECTED_IP_1234 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.CIFS,
constants.IP, constants.IP,
constants.EXPECTED_IP_1234, constants.EXPECTED_IP_1234,
@ -745,7 +812,8 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_clientip = '+%s' % constants.EXPECTED_IP_1234 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.NFS,
constants.IP, constants.IP,
constants.EXPECTED_IP_1234, constants.EXPECTED_IP_1234,
@ -768,7 +836,8 @@ class HP3ParMediatorTestCase(test.TestCase):
expected_clientip = '-%s' % constants.EXPECTED_IP_1234 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.NFS,
constants.IP, constants.IP,
constants.EXPECTED_IP_1234, constants.EXPECTED_IP_1234,
@ -791,6 +860,7 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertRaises(exception.HP3ParInvalid, self.assertRaises(exception.HP3ParInvalid,
self.mediator.allow_access, self.mediator.allow_access,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.NFS, constants.NFS,
constants.USER, constants.USER,
@ -804,6 +874,7 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertRaises(exception.InvalidInput, self.assertRaises(exception.InvalidInput,
self.mediator.allow_access, self.mediator.allow_access,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
'unsupported_other_protocol', 'unsupported_other_protocol',
constants.USER, constants.USER,
@ -817,9 +888,241 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertRaises(exception.InvalidInput, self.assertRaises(exception.InvalidInput,
self.mediator.allow_access, self.mediator.allow_access,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
constants.CIFS, constants.CIFS,
'unsupported_other_type', 'unsupported_other_type',
constants.USERNAME, constants.USERNAME,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS) 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)