glusterfs*: factor out common parts

GlusterManager and a few standalone
management routines have been moved
to the newly created glusterfs/common.py;
both glusterfs and glusterfs_native drivers
import these from there. The obnoxious
import of glusterfs to glusterfs_native
has been eliminated.

Partially implements bp modular-glusterfs-share-layouts

Change-Id: I6a94f1056bd45187c0268d75fa854b127b2b562d
This commit is contained in:
Csaba Henk 2015-08-19 06:28:42 +02:00
parent d172f86df2
commit 6849f9e386
7 changed files with 788 additions and 739 deletions

View File

@ -28,7 +28,6 @@ import errno
import os
import re
import sys
import xml.etree.cElementTree as etree
from oslo_config import cfg
from oslo_log import log
@ -37,10 +36,10 @@ import six
from manila import exception
from manila.i18n import _
from manila.i18n import _LE
from manila.i18n import _LW
from manila.share import driver
from manila.share.drivers import ganesha
from manila.share.drivers.ganesha import utils as ganesha_utils
from manila.share.drivers.glusterfs import common
LOG = log.getLogger(__name__)
@ -89,142 +88,6 @@ NFS_EXPORT_VOL = 'nfs.export-volumes'
GLUSTERFS_VERSION_MIN = (3, 5)
class GlusterManager(object):
"""Interface with a GlusterFS volume."""
scheme = re.compile('\A(?:(?P<user>[^:@/]+)@)?'
'(?P<host>[^:@/]+)'
'(?::/(?P<vol>.+))?')
def __init__(self, address, execf, path_to_private_key=None,
remote_server_password=None, has_volume=True):
"""Initialize a GlusterManager instance.
:param address: the Gluster URI (in [<user>@]<host>:/<vol> format).
:param execf: executor function for management commands.
:param path_to_private_key: path to private ssh key of remote server.
:param remote_server_password: ssh password for remote server.
:param has_volume: instruction to uri parser regarding how to deal
with the optional volume part (True: require its
presence, False: require its absence, None: don't
require anything about volume).
"""
m = self.scheme.search(address)
if m:
self.volume = m.group('vol')
if (has_volume is True and not self.volume) or (
has_volume is False and self.volume):
m = None
if not m:
raise exception.GlusterfsException(
_('Invalid gluster address %s.') % address)
self.remote_user = m.group('user')
self.host = m.group('host')
self.management_address = '@'.join(
filter(None, (self.remote_user, self.host)))
self.qualified = address
if self.volume:
self.export = ':/'.join([self.host, self.volume])
else:
self.export = None
self.path_to_private_key = path_to_private_key
self.remote_server_password = remote_server_password
self.gluster_call = self.make_gluster_call(execf)
def make_gluster_call(self, execf):
"""Execute a Gluster command locally or remotely."""
if self.remote_user:
gluster_execf = ganesha_utils.SSHExecutor(
self.host, 22, None, self.remote_user,
password=self.remote_server_password,
privatekey=self.path_to_private_key)
else:
gluster_execf = ganesha_utils.RootExecutor(execf)
return lambda *args, **kwargs: gluster_execf(*(('gluster',) + args),
**kwargs)
def get_gluster_vol_option(self, option):
"""Get the value of an option set on a GlusterFS volume."""
args = ('--xml', 'volume', 'info', self.volume)
try:
out, err = self.gluster_call(*args)
except exception.ProcessExecutionError as exc:
LOG.error(_LE("Error retrieving volume info: %s"), exc.stderr)
raise exception.GlusterfsException("gluster %s failed" %
' '.join(args))
if not out:
raise exception.GlusterfsException(
'gluster volume info %s: no data received' %
self.volume
)
vix = etree.fromstring(out)
if int(vix.find('./volInfo/volumes/count').text) != 1:
raise exception.InvalidShare('Volume name ambiguity')
for e in vix.findall(".//option"):
o, v = (e.find(a).text for a in ('name', 'value'))
if o == option:
return v
def get_gluster_version(self):
"""Retrieve GlusterFS version.
:returns: version (as tuple of strings, example: ('3', '6', '0beta2'))
"""
try:
out, err = self.gluster_call('--version')
except exception.ProcessExecutionError as exc:
raise exception.GlusterfsException(
_("'gluster version' failed on server "
"%(server)s: %(message)s") %
{'server': self.host, 'message': six.text_type(exc)})
try:
owords = out.split()
if owords[0] != 'glusterfs':
raise RuntimeError
vers = owords[1].split('.')
# provoke an exception if vers does not start with two numerals
int(vers[0])
int(vers[1])
except Exception:
raise exception.GlusterfsException(
_("Cannot parse version info obtained from server "
"%(server)s, version info: %(info)s") %
{'server': self.host, 'info': out})
return vers
def check_gluster_version(self, minvers):
"""Retrieve and check GlusterFS version.
:param minvers: minimum version to require
(given as tuple of integers, example: (3, 6))
"""
vers = self.get_gluster_version()
if self.numreduct(vers) < minvers:
raise exception.GlusterfsException(_(
"Unsupported GlusterFS version %(version)s on server "
"%(server)s, minimum requirement: %(minvers)s") % {
'server': self.host,
'version': '.'.join(vers),
'minvers': '.'.join(six.text_type(c) for c in minvers)})
@staticmethod
def numreduct(vers):
"""The numeric reduct of a tuple of strings.
That is, applying an integer conversion map on the longest
initial segment of vers which consists of numerals.
"""
numvers = []
for c in vers:
try:
numvers.append(int(c))
except ValueError:
break
return tuple(numvers)
class GlusterfsShareDriver(driver.ExecuteMixin, driver.GaneshaMixin,
driver.ShareDriver,):
"""Execute commands relating to Shares."""
@ -244,7 +107,7 @@ class GlusterfsShareDriver(driver.ExecuteMixin, driver.GaneshaMixin,
raise exception.GlusterfsException(
_('glusterfs_target configuration that specifies the GlusterFS'
' volume to be mounted on the Manila host is not set.'))
self.gluster_manager = GlusterManager(
self.gluster_manager = common.GlusterManager(
self.configuration.glusterfs_target,
self._execute,
self.configuration.glusterfs_path_to_private_key,
@ -296,35 +159,13 @@ class GlusterfsShareDriver(driver.ExecuteMixin, driver.GaneshaMixin,
return os.path.join(self.configuration.glusterfs_mount_point_base,
self.gluster_manager.volume)
def _do_mount(self, cmd, ensure):
"""Execute the mount command based on 'ensure' parameter.
:param cmd: command to do the actual mount
:param ensure: boolean to allow remounting a volume with a warning
"""
try:
self._execute(*cmd, run_as_root=True)
except exception.ProcessExecutionError as exc:
if ensure and 'already mounted' in exc.stderr:
LOG.warn(_LW("%s is already mounted"),
self.gluster_manager.export)
else:
raise exception.GlusterfsException(
'Unable to mount Gluster volume'
)
def _mount_gluster_vol(self, mount_path, ensure=False):
"""Mount GlusterFS volume at the specified mount path."""
self._execute('mkdir', '-p', mount_path)
command = ['mount', '-t', 'glusterfs', self.gluster_manager.export,
mount_path]
self._do_mount(command, ensure)
def _ensure_gluster_vol_mounted(self):
"""Ensure GlusterFS volume is native-mounted on Manila host."""
mount_path = self._get_mount_point_for_gluster_vol()
try:
self._mount_gluster_vol(mount_path, ensure=True)
common._mount_gluster_vol(self._execute,
self.gluster_manager.export, mount_path,
ensure=True)
except exception.GlusterfsException:
LOG.error(_LE('Could not mount the Gluster volume %s'),
self.gluster_manager.volume)
@ -555,7 +396,7 @@ class GaneshaNFSHelper(ganesha.GaneshaNASHelper):
def _default_config_hook(self):
"""Callback to provide default export block."""
dconf = super(GaneshaNFSHelper, self)._default_config_hook()
conf_dir = ganesha_utils.path_from(__file__, "glusterfs", "conf")
conf_dir = ganesha_utils.path_from(__file__, "conf")
ganesha_utils.patch(dconf, self._load_conf_dir(conf_dir))
return dconf

View File

@ -0,0 +1,238 @@
# Copyright (c) 2015 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Common GlussterFS routines."""
import re
import xml.etree.cElementTree as etree
from oslo_log import log
import six
from manila import exception
from manila.i18n import _
from manila.i18n import _LE
from manila.i18n import _LW
from manila.share.drivers.ganesha import utils as ganesha_utils
LOG = log.getLogger(__name__)
class GlusterManager(object):
"""Interface with a GlusterFS volume."""
scheme = re.compile('\A(?:(?P<user>[^:@/]+)@)?'
'(?P<host>[^:@/]+)'
'(?::/(?P<vol>.+))?')
def __init__(self, address, execf, path_to_private_key=None,
remote_server_password=None, has_volume=True):
"""Initialize a GlusterManager instance.
:param address: the Gluster URI (in [<user>@]<host>:/<vol> format).
:param execf: executor function for management commands.
:param path_to_private_key: path to private ssh key of remote server.
:param remote_server_password: ssh password for remote server.
:param has_volume: instruction to uri parser regarding how to deal
with the optional volume part (True: require its
presence, False: require its absence, None: don't
require anything about volume).
"""
m = self.scheme.search(address)
if m:
self.volume = m.group('vol')
if (has_volume is True and not self.volume) or (
has_volume is False and self.volume):
m = None
if not m:
raise exception.GlusterfsException(
_('Invalid gluster address %s.') % address)
self.remote_user = m.group('user')
self.host = m.group('host')
self.management_address = '@'.join(
filter(None, (self.remote_user, self.host)))
self.qualified = address
if self.volume:
self.export = ':/'.join([self.host, self.volume])
else:
self.export = None
self.path_to_private_key = path_to_private_key
self.remote_server_password = remote_server_password
self.gluster_call = self.make_gluster_call(execf)
def make_gluster_call(self, execf):
"""Execute a Gluster command locally or remotely."""
if self.remote_user:
gluster_execf = ganesha_utils.SSHExecutor(
self.host, 22, None, self.remote_user,
password=self.remote_server_password,
privatekey=self.path_to_private_key)
else:
gluster_execf = ganesha_utils.RootExecutor(execf)
return lambda *args, **kwargs: gluster_execf(*(('gluster',) + args),
**kwargs)
def get_gluster_vol_option(self, option):
"""Get the value of an option set on a GlusterFS volume."""
args = ('--xml', 'volume', 'info', self.volume)
try:
out, err = self.gluster_call(*args)
except exception.ProcessExecutionError as exc:
LOG.error(_LE("Error retrieving volume info: %s"), exc.stderr)
raise exception.GlusterfsException("gluster %s failed" %
' '.join(args))
if not out:
raise exception.GlusterfsException(
'gluster volume info %s: no data received' %
self.volume
)
vix = etree.fromstring(out)
if int(vix.find('./volInfo/volumes/count').text) != 1:
raise exception.InvalidShare('Volume name ambiguity')
for e in vix.findall(".//option"):
o, v = (e.find(a).text for a in ('name', 'value'))
if o == option:
return v
def get_gluster_version(self):
"""Retrieve GlusterFS version.
:returns: version (as tuple of strings, example: ('3', '6', '0beta2'))
"""
try:
out, err = self.gluster_call('--version')
except exception.ProcessExecutionError as exc:
raise exception.GlusterfsException(
_("'gluster version' failed on server "
"%(server)s: %(message)s") %
{'server': self.host, 'message': six.text_type(exc)})
try:
owords = out.split()
if owords[0] != 'glusterfs':
raise RuntimeError
vers = owords[1].split('.')
# provoke an exception if vers does not start with two numerals
int(vers[0])
int(vers[1])
except Exception:
raise exception.GlusterfsException(
_("Cannot parse version info obtained from server "
"%(server)s, version info: %(info)s") %
{'server': self.host, 'info': out})
return vers
def check_gluster_version(self, minvers):
"""Retrieve and check GlusterFS version.
:param minvers: minimum version to require
(given as tuple of integers, example: (3, 6))
"""
vers = self.get_gluster_version()
if self.numreduct(vers) < minvers:
raise exception.GlusterfsException(_(
"Unsupported GlusterFS version %(version)s on server "
"%(server)s, minimum requirement: %(minvers)s") % {
'server': self.host,
'version': '.'.join(vers),
'minvers': '.'.join(six.text_type(c) for c in minvers)})
@staticmethod
def numreduct(vers):
"""The numeric reduct of a tuple of strings.
That is, applying an integer conversion map on the longest
initial segment of vers which consists of numerals.
"""
numvers = []
for c in vers:
try:
numvers.append(int(c))
except ValueError:
break
return tuple(numvers)
def _mount_gluster_vol(execute, gluster_export, mount_path, ensure=False):
"""Mount a GlusterFS volume at the specified mount path.
:param execute: command exectution function
:param gluster_export: GlusterFS export to mount
:param mount_path: path to mount at
:param ensure: boolean to allow remounting a volume with a warning
"""
execute('mkdir', '-p', mount_path)
command = ['mount', '-t', 'glusterfs', gluster_export, mount_path]
try:
execute(*command, run_as_root=True)
except exception.ProcessExecutionError as exc:
if ensure and 'already mounted' in exc.stderr:
LOG.warn(_LW("%s is already mounted"), gluster_export)
else:
raise exception.GlusterfsException(
'Unable to mount Gluster volume'
)
def _umount_gluster_vol(execute, mount_path):
"""Unmount a GlusterFS volume at the specified mount path.
:param execute: command exectution function
:param mount_path: path where volume is mounted
"""
try:
execute('umount', mount_path, run_as_root=True)
except exception.ProcessExecutionError as exc:
msg = (_("Unable to unmount gluster volume. "
"mount_dir: %(mount_path)s, Error: %(error)s") %
{'mount_path': mount_path, 'error': exc.stderr})
LOG.error(msg)
raise exception.GlusterfsException(msg)
def _restart_gluster_vol(gluster_mgr):
"""Restart a GlusterFS volume through its manager.
:param gluster_mgr: GlusterManager instance
"""
try:
# TODO(csaba): '--mode=script' ensures that the Gluster CLI runs in
# script mode. This seems unnecessary as the Gluster CLI is
# expected to run in non-interactive mode when the stdin is not
# a terminal, as is the case below. But on testing, found the
# behaviour of Gluster-CLI to be the contrary. Need to investigate
# this odd-behaviour of Gluster-CLI.
gluster_mgr.gluster_call(
'volume', 'stop', gluster_mgr.volume, '--mode=script')
except exception.ProcessExecutionError as exc:
msg = (_("Error stopping gluster volume. "
"Volume: %(volname)s, Error: %(error)s") %
{'volname': gluster_mgr.volume, 'error': exc.stderr})
LOG.error(msg)
raise exception.GlusterfsException(msg)
try:
gluster_mgr.gluster_call(
'volume', 'start', gluster_mgr.volume)
except exception.ProcessExecutionError as exc:
msg = (_("Error starting gluster volume. "
"Volume: %(volname)s, Error: %(error)s") %
{'volname': gluster_mgr.volume, 'error': exc.stderr})
LOG.error(msg)
raise exception.GlusterfsException(msg)

View File

@ -44,7 +44,7 @@ from manila.i18n import _LE
from manila.i18n import _LI
from manila.i18n import _LW
from manila.share import driver
from manila.share.drivers import glusterfs
from manila.share.drivers.glusterfs import common
from manila import utils
LOG = log.getLogger(__name__)
@ -177,7 +177,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
','.join(exceptions.keys())))
notsupp_servers = []
for srvaddr, vers in six.iteritems(glusterfs_versions):
if glusterfs.GlusterManager.numreduct(
if common.GlusterManager.numreduct(
vers) < GLUSTERFS_VERSION_MIN:
notsupp_servers.append(srvaddr)
if notsupp_servers:
@ -225,7 +225,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
def _glustermanager(self, gluster_address, has_volume=True):
"""Create GlusterManager object for gluster_address."""
return glusterfs.GlusterManager(
return common.GlusterManager(
gluster_address, self._execute,
self.configuration.glusterfs_native_path_to_private_key,
self.configuration.glusterfs_native_server_password,
@ -308,37 +308,9 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
# TODO(deepakcs) Remove this once ssl options can be
# set dynamically.
self._restart_gluster_vol(gluster_mgr)
common._restart_gluster_vol(gluster_mgr)
return gluster_mgr
@staticmethod
def _restart_gluster_vol(gluster_mgr):
try:
# TODO(csaba): '--mode=script' ensures that the Gluster CLI runs in
# script mode. This seems unnecessary as the Gluster CLI is
# expected to run in non-interactive mode when the stdin is not
# a terminal, as is the case below. But on testing, found the
# behaviour of Gluster-CLI to be the contrary. Need to investigate
# this odd-behaviour of Gluster-CLI.
gluster_mgr.gluster_call(
'volume', 'stop', gluster_mgr.volume, '--mode=script')
except exception.ProcessExecutionError as exc:
msg = (_("Error stopping gluster volume. "
"Volume: %(volname)s, Error: %(error)s") %
{'volname': gluster_mgr.volume, 'error': exc.stderr})
LOG.error(msg)
raise exception.GlusterfsException(msg)
try:
gluster_mgr.gluster_call(
'volume', 'start', gluster_mgr.volume)
except exception.ProcessExecutionError as exc:
msg = (_("Error starting gluster volume. "
"Volume: %(volname)s, Error: %(error)s") %
{'volname': gluster_mgr.volume, 'error': exc.stderr})
LOG.error(msg)
raise exception.GlusterfsException(msg)
@utils.synchronized("glusterfs_native", external=False)
def _pop_gluster_vol(self, size=None):
"""Pick an unbound volume.
@ -444,30 +416,6 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
LOG.error(msg)
raise exception.GlusterfsException(msg)
def _do_mount(self, gluster_export, mntdir):
cmd = ['mount', '-t', 'glusterfs', gluster_export, mntdir]
try:
self._execute(*cmd, run_as_root=True)
except exception.ProcessExecutionError as exc:
msg = (_("Unable to mount gluster volume. "
"gluster_export: %(export)s, Error: %(error)s") %
{'export': gluster_export, 'error': exc.stderr})
LOG.error(msg)
raise exception.GlusterfsException(msg)
def _do_umount(self, mntdir):
cmd = ['umount', mntdir]
try:
self._execute(*cmd, run_as_root=True)
except exception.ProcessExecutionError as exc:
msg = (_("Unable to unmount gluster volume. "
"mount_dir: %(mntdir)s, Error: %(error)s") %
{'mntdir': mntdir, 'error': exc.stderr})
LOG.error(msg)
raise exception.GlusterfsException(msg)
def _wipe_gluster_vol(self, gluster_mgr):
# Reset the SSL options.
@ -497,13 +445,13 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
LOG.error(msg)
raise exception.GlusterfsException(msg)
self._restart_gluster_vol(gluster_mgr)
common._restart_gluster_vol(gluster_mgr)
# Create a temporary mount.
gluster_export = gluster_mgr.export
tmpdir = tempfile.mkdtemp()
try:
self._do_mount(gluster_export, tmpdir)
common._mount_gluster_vol(self._execute, gluster_export, tmpdir)
except exception.GlusterfsException:
shutil.rmtree(tmpdir, ignore_errors=True)
raise
@ -517,8 +465,8 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
# delete the paths of the two directories, but delete their contents
# along with the rest of the contents of the volume.
srvaddr = gluster_mgr.management_address
if glusterfs.GlusterManager.numreduct(self.glusterfs_versions[srvaddr]
) < (3, 7):
if common.GlusterManager.numreduct(self.glusterfs_versions[srvaddr]
) < (3, 7):
cmd = ['find', tmpdir, '-mindepth', '1', '-delete']
else:
ignored_dirs = map(lambda x: os.path.join(tmpdir, *x),
@ -537,7 +485,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
raise exception.GlusterfsException(msg)
finally:
# Unmount.
self._do_umount(tmpdir)
common._umount_gluster_vol(self._execute, tmpdir)
shutil.rmtree(tmpdir, ignore_errors=True)
# Set the SSL options.
@ -567,7 +515,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
LOG.error(msg)
raise exception.GlusterfsException(msg)
self._restart_gluster_vol(gluster_mgr)
common._restart_gluster_vol(gluster_mgr)
def get_network_allocations_number(self):
return 0
@ -652,7 +600,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
# a version check.
vers = self.glusterfs_versions[old_gmgr.management_address]
minvers = (3, 7)
if glusterfs.GlusterManager.numreduct(vers) < minvers:
if common.GlusterManager.numreduct(vers) < minvers:
minvers_str = '.'.join(six.text_type(c) for c in minvers)
vers_str = '.'.join(vers)
msg = (_("GlusterFS version %(version)s on server %(server)s does "
@ -748,7 +696,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
if opret == -1:
vers = self.glusterfs_versions[gluster_mgr.management_address]
if glusterfs.GlusterManager.numreduct(vers) > (3, 6):
if common.GlusterManager.numreduct(vers) > (3, 6):
# This logic has not yet been implemented in GlusterFS 3.6
if operrno == 0:
self.gluster_nosnap_vols_dict[vol] = operrstr
@ -846,7 +794,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
# TODO(deepakcs) Remove this once ssl options can be
# set dynamically.
self._restart_gluster_vol(gluster_mgr)
common._restart_gluster_vol(gluster_mgr)
@utils.synchronized("glusterfs_native_access", external=False)
def deny_access(self, context, share, access, share_server=None):
@ -891,7 +839,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin, driver.ShareDriver):
# TODO(deepakcs) Remove this once ssl options can be
# set dynamically.
self._restart_gluster_vol(gluster_mgr)
common._restart_gluster_vol(gluster_mgr)
def _update_share_stats(self):
"""Send stats info for the GlusterFS volume."""

View File

@ -0,0 +1,408 @@
# Copyright (c) 2015 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Test cases for GlusterFS common routines."""
import ddt
import mock
from oslo_config import cfg
from manila import exception
from manila.share.drivers.glusterfs import common
from manila import test
from manila.tests import fake_utils
CONF = cfg.CONF
fake_gluster_manager_attrs = {
'export': '127.0.0.1:/testvol',
'host': '127.0.0.1',
'qualified': 'testuser@127.0.0.1:/testvol',
'remote_user': 'testuser',
'volume': 'testvol',
'path_to_private_key': '/fakepath/to/privatekey',
'remote_server_password': 'fakepassword',
}
fake_args = ('foo', 'bar')
fake_kwargs = {'key1': 'value1', 'key2': 'value2'}
fake_path_to_private_key = '/fakepath/to/privatekey'
fake_remote_server_password = 'fakepassword'
NFS_EXPORT_DIR = 'nfs.export-dir'
fakehost = 'example.com'
fakevol = 'testvol'
fakeexport = ':/'.join((fakehost, fakevol))
fakemnt = '/mnt/glusterfs'
@ddt.ddt
class GlusterManagerTestCase(test.TestCase):
"""Tests GlusterManager."""
def setUp(self):
super(GlusterManagerTestCase, self).setUp()
self.fake_execf = mock.Mock()
self.fake_executor = mock.Mock(return_value=('', ''))
with mock.patch.object(common.GlusterManager, 'make_gluster_call',
return_value=self.fake_executor):
self._gluster_manager = common.GlusterManager(
'testuser@127.0.0.1:/testvol', self.fake_execf,
fake_path_to_private_key, fake_remote_server_password)
def test_gluster_manager_init(self):
self.assertEqual(fake_gluster_manager_attrs['remote_user'],
self._gluster_manager.remote_user)
self.assertEqual(fake_gluster_manager_attrs['host'],
self._gluster_manager.host)
self.assertEqual(fake_gluster_manager_attrs['volume'],
self._gluster_manager.volume)
self.assertEqual(fake_gluster_manager_attrs['qualified'],
self._gluster_manager.qualified)
self.assertEqual(fake_gluster_manager_attrs['export'],
self._gluster_manager.export)
self.assertEqual(fake_gluster_manager_attrs['path_to_private_key'],
self._gluster_manager.path_to_private_key)
self.assertEqual(fake_gluster_manager_attrs['remote_server_password'],
self._gluster_manager.remote_server_password)
self.assertEqual(self.fake_executor,
self._gluster_manager.gluster_call)
@ddt.data(None, True)
def test_gluster_manager_init_has_vol(self, has_volume):
test_gluster_manager = common.GlusterManager(
'testuser@127.0.0.1:/testvol', self.fake_execf,
has_volume=has_volume)
self.assertEqual('testvol', test_gluster_manager.volume)
@ddt.data(None, False)
def test_gluster_manager_init_no_vol(self, has_volume):
test_gluster_manager = common.GlusterManager(
'testuser@127.0.0.1', self.fake_execf, has_volume=has_volume)
self.assertIsNone(test_gluster_manager.volume)
def test_gluster_manager_init_has_shouldnt_have_vol(self):
self.assertRaises(exception.GlusterfsException,
common.GlusterManager,
'testuser@127.0.0.1:/testvol',
self.fake_execf, has_volume=False)
def test_gluster_manager_hasnt_should_have_vol(self):
self.assertRaises(exception.GlusterfsException,
common.GlusterManager, 'testuser@127.0.0.1',
self.fake_execf, has_volume=True)
def test_gluster_manager_invalid(self):
self.assertRaises(exception.GlusterfsException,
common.GlusterManager, '127.0.0.1:vol',
'self.fake_execf')
def test_gluster_manager_make_gluster_call_local(self):
fake_obj = mock.Mock()
fake_execute = mock.Mock()
with mock.patch.object(common.ganesha_utils, 'RootExecutor',
mock.Mock(return_value=fake_obj)):
gluster_manager = common.GlusterManager(
'127.0.0.1:/testvol', self.fake_execf)
gluster_manager.make_gluster_call(fake_execute)(*fake_args,
**fake_kwargs)
common.ganesha_utils.RootExecutor.assert_called_with(
fake_execute)
fake_obj.assert_called_once_with(
*(('gluster',) + fake_args), **fake_kwargs)
def test_gluster_manager_make_gluster_call_remote(self):
fake_obj = mock.Mock()
fake_execute = mock.Mock()
with mock.patch.object(common.ganesha_utils, 'SSHExecutor',
mock.Mock(return_value=fake_obj)):
gluster_manager = common.GlusterManager(
'testuser@127.0.0.1:/testvol', self.fake_execf,
fake_path_to_private_key, fake_remote_server_password)
gluster_manager.make_gluster_call(fake_execute)(*fake_args,
**fake_kwargs)
common.ganesha_utils.SSHExecutor.assert_called_with(
gluster_manager.host, 22, None, gluster_manager.remote_user,
password=gluster_manager.remote_server_password,
privatekey=gluster_manager.path_to_private_key)
fake_obj.assert_called_once_with(
*(('gluster',) + fake_args), **fake_kwargs)
def test_get_gluster_vol_option_empty_volinfo(self):
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(return_value=('', {})))
self.assertRaises(exception.GlusterfsException,
self._gluster_manager.get_gluster_vol_option,
NFS_EXPORT_DIR)
self._gluster_manager.gluster_call.assert_called_once_with(
*args)
def test_get_gluster_vol_option_failing_volinfo(self):
def raise_exception(*ignore_args, **ignore_kwargs):
raise RuntimeError('fake error')
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=raise_exception))
self.assertRaises(RuntimeError,
self._gluster_manager.get_gluster_vol_option,
NFS_EXPORT_DIR)
self._gluster_manager.gluster_call.assert_called_once_with(
*args)
def test_get_gluster_vol_option_ambiguous_volinfo(self):
def xml_output(*ignore_args, **ignore_kwargs):
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cliOutput>
<volInfo>
<volumes>
<count>0</count>
</volumes>
</volInfo>
</cliOutput>""", ''
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=xml_output))
self.assertRaises(exception.InvalidShare,
self._gluster_manager.get_gluster_vol_option,
NFS_EXPORT_DIR)
self._gluster_manager.gluster_call.assert_called_once_with(*args)
def test_get_gluster_vol_option_trivial_volinfo(self):
def xml_output(*ignore_args, **ignore_kwargs):
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cliOutput>
<volInfo>
<volumes>
<volume>
</volume>
<count>1</count>
</volumes>
</volInfo>
</cliOutput>""", ''
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=xml_output))
ret = self._gluster_manager.get_gluster_vol_option(NFS_EXPORT_DIR)
self.assertIsNone(ret)
self._gluster_manager.gluster_call.assert_called_once_with(*args)
def test_get_gluster_vol_option(self):
def xml_output(*ignore_args, **ignore_kwargs):
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cliOutput>
<volInfo>
<volumes>
<volume>
<options>
<option>
<name>nfs.export-dir</name>
<value>/foo(10.0.0.1|10.0.0.2),/bar(10.0.0.1)</value>
</option>
</options>
</volume>
<count>1</count>
</volumes>
</volInfo>
</cliOutput>""", ''
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=xml_output))
ret = self._gluster_manager.get_gluster_vol_option(NFS_EXPORT_DIR)
self.assertEqual('/foo(10.0.0.1|10.0.0.2),/bar(10.0.0.1)', ret)
self._gluster_manager.gluster_call.assert_called_once_with(*args)
def test_get_gluster_version(self):
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(return_value=('glusterfs 3.6.2beta3', '')))
ret = self._gluster_manager.get_gluster_version()
self.assertEqual(['3', '6', '2beta3'], ret)
self._gluster_manager.gluster_call.assert_called_once_with(
'--version')
@ddt.data("foo 1.1.1", "glusterfs 3-6", "glusterfs 3.6beta3")
def test_get_gluster_version_exception(self, versinfo):
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(return_value=(versinfo, '')))
self.assertRaises(exception.GlusterfsException,
self._gluster_manager.get_gluster_version)
self._gluster_manager.gluster_call.assert_called_once_with(
'--version')
def test_get_gluster_version_process_error(self):
def raise_exception(*args, **kwargs):
raise exception.ProcessExecutionError()
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=raise_exception))
self.assertRaises(exception.GlusterfsException,
self._gluster_manager.get_gluster_version)
self._gluster_manager.gluster_call.assert_called_once_with(
'--version')
def test_check_gluster_version(self):
self.mock_object(self._gluster_manager, 'get_gluster_version',
mock.Mock(return_value=('3', '6')))
ret = self._gluster_manager.check_gluster_version((3, 5, 2))
self.assertIsNone(ret)
self._gluster_manager.get_gluster_version.assert_called_once_with()
def test_check_gluster_version_unmet(self):
self.mock_object(self._gluster_manager, 'get_gluster_version',
mock.Mock(return_value=('3', '5', '2')))
self.assertRaises(exception.GlusterfsException,
self._gluster_manager.check_gluster_version, (3, 6))
self._gluster_manager.get_gluster_version.assert_called_once_with()
@ddt.data(('3', '6'),
('3', '6', '2beta'),
('3', '6', '2beta', '4'))
def test_numreduct(self, vers):
ret = common.GlusterManager.numreduct(vers)
self.assertEqual((3, 6), ret)
@ddt.ddt
class GlusterFSCommonTestCase(test.TestCase):
"""Tests common GlusterFS utility functions."""
def setUp(self):
super(GlusterFSCommonTestCase, self).setUp()
fake_utils.stub_out_utils_execute(self)
self._execute = fake_utils.fake_execute
self.addCleanup(fake_utils.fake_execute_set_repliers, [])
self.addCleanup(fake_utils.fake_execute_clear_log)
self.mock_object(common.GlusterManager, 'make_gluster_call')
@staticmethod
def _mount_exec(vol, mnt):
return ['mkdir -p %s' % mnt,
'mount -t glusterfs %(exp)s %(mnt)s' % {'exp': vol,
'mnt': mnt}]
def test_mount_gluster_vol(self):
expected_exec = self._mount_exec(fakeexport, fakemnt)
ret = common._mount_gluster_vol(self._execute, fakeexport, fakemnt,
False)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
self.assertIsNone(ret)
def test_mount_gluster_vol_mounted_noensure(self):
def exec_runner(*ignore_args, **ignore_kwargs):
raise exception.ProcessExecutionError(stderr='already mounted')
expected_exec = self._mount_exec(fakeexport, fakemnt)
fake_utils.fake_execute_set_repliers([('mount', exec_runner)])
self.assertRaises(exception.GlusterfsException,
common._mount_gluster_vol,
self._execute, fakeexport, fakemnt, False)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
def test_mount_gluster_vol_mounted_ensure(self):
def exec_runner(*ignore_args, **ignore_kwargs):
raise exception.ProcessExecutionError(stderr='already mounted')
expected_exec = self._mount_exec(fakeexport, fakemnt)
common.LOG.warn = mock.Mock()
fake_utils.fake_execute_set_repliers([('mount', exec_runner)])
ret = common._mount_gluster_vol(self._execute, fakeexport, fakemnt,
True)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
self.assertIsNone(ret)
common.LOG.warn.assert_called_with(
"%s is already mounted", fakeexport)
@ddt.data(True, False)
def test_mount_gluster_vol_fail(self, ensure):
def exec_runner(*ignore_args, **ignore_kwargs):
raise RuntimeError('fake error')
expected_exec = self._mount_exec(fakeexport, fakemnt)
fake_utils.fake_execute_set_repliers([('mount', exec_runner)])
self.assertRaises(RuntimeError, common._mount_gluster_vol,
self._execute, fakeexport, fakemnt, ensure)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
def test_umount_gluster_vol(self):
expected_exec = ['umount %s' % fakemnt]
ret = common._umount_gluster_vol(self._execute, fakemnt)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
self.assertIsNone(ret)
@ddt.data({'in_exc': exception.ProcessExecutionError,
'out_exc': exception.GlusterfsException},
{'in_exc': RuntimeError, 'out_exc': RuntimeError})
@ddt.unpack
def test_umount_gluster_vol_fail(self, in_exc, out_exc):
def exec_runner(*ignore_args, **ignore_kwargs):
raise in_exc('fake error')
expected_exec = ['umount %s' % fakemnt]
fake_utils.fake_execute_set_repliers([('umount', exec_runner)])
self.assertRaises(out_exc, common._umount_gluster_vol,
self._execute, fakemnt)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
def test_restart_gluster_vol(self):
gmgr = common.GlusterManager(fakeexport, self._execute, None, None)
test_args = [('volume', 'stop', fakevol, '--mode=script'),
('volume', 'start', fakevol)]
common._restart_gluster_vol(gmgr)
self.assertEqual(
[mock.call(*test_args[0]), mock.call(*test_args[1])],
gmgr.gluster_call.call_args_list)
def test_restart_gluster_vol_excp1(self):
gmgr = common.GlusterManager(fakeexport, self._execute, None, None)
test_args = ('volume', 'stop', fakevol, '--mode=script')
def raise_exception(*args, **kwargs):
if(args == test_args):
raise exception.ProcessExecutionError()
self.mock_object(gmgr, 'gluster_call',
mock.Mock(side_effect=raise_exception))
self.assertRaises(exception.GlusterfsException,
common._restart_gluster_vol, gmgr)
self.assertEqual(
[mock.call(*test_args)],
gmgr.gluster_call.call_args_list)
def test_restart_gluster_vol_excp2(self):
gmgr = common.GlusterManager(fakeexport, self._execute, None, None)
test_args = [('volume', 'stop', fakevol, '--mode=script'),
('volume', 'start', fakevol)]
def raise_exception(*args, **kwargs):
if(args == test_args[1]):
raise exception.ProcessExecutionError()
self.mock_object(gmgr, 'gluster_call',
mock.Mock(side_effect=raise_exception))
self.assertRaises(exception.GlusterfsException,
common._restart_gluster_vol, gmgr)
self.assertEqual(
[mock.call(*test_args[0]), mock.call(*test_args[1])],
gmgr.gluster_call.call_args_list)

View File

@ -17,7 +17,6 @@ import copy
import errno
import os
import ddt
import mock
from oslo_config import cfg
@ -25,6 +24,7 @@ from manila import context
from manila import exception
from manila.share import configuration as config
from manila.share.drivers import glusterfs
from manila.share.drivers.glusterfs import common
from manila import test
from manila.tests import fake_share
from manila.tests import fake_utils
@ -45,8 +45,6 @@ fake_gluster_manager_attrs = {
fake_local_share_path = '/mnt/nfs/testvol/fakename'
fake_args = ('foo', 'bar')
fake_kwargs = {'key1': 'value1', 'key2': 'value2'}
fake_path_to_private_key = '/fakepath/to/privatekey'
fake_remote_server_password = 'fakepassword'
fake_share_name = 'fakename'
@ -54,242 +52,6 @@ NFS_EXPORT_DIR = 'nfs.export-dir'
NFS_EXPORT_VOL = 'nfs.export-volumes'
@ddt.ddt
class GlusterManagerTestCase(test.TestCase):
"""Tests GlusterManager."""
def setUp(self):
super(GlusterManagerTestCase, self).setUp()
self.fake_execf = mock.Mock()
self.fake_executor = mock.Mock(return_value=('', ''))
with mock.patch.object(glusterfs.GlusterManager, 'make_gluster_call',
return_value=self.fake_executor):
self._gluster_manager = glusterfs.GlusterManager(
'testuser@127.0.0.1:/testvol', self.fake_execf,
fake_path_to_private_key, fake_remote_server_password)
def test_gluster_manager_init(self):
self.assertEqual(fake_gluster_manager_attrs['remote_user'],
self._gluster_manager.remote_user)
self.assertEqual(fake_gluster_manager_attrs['host'],
self._gluster_manager.host)
self.assertEqual(fake_gluster_manager_attrs['volume'],
self._gluster_manager.volume)
self.assertEqual(fake_gluster_manager_attrs['qualified'],
self._gluster_manager.qualified)
self.assertEqual(fake_gluster_manager_attrs['export'],
self._gluster_manager.export)
self.assertEqual(fake_gluster_manager_attrs['path_to_private_key'],
self._gluster_manager.path_to_private_key)
self.assertEqual(fake_gluster_manager_attrs['remote_server_password'],
self._gluster_manager.remote_server_password)
self.assertEqual(self.fake_executor,
self._gluster_manager.gluster_call)
@ddt.data(None, True)
def test_gluster_manager_init_has_vol(self, has_volume):
test_gluster_manager = glusterfs.GlusterManager(
'testuser@127.0.0.1:/testvol', self.fake_execf,
has_volume=has_volume)
self.assertEqual('testvol', test_gluster_manager.volume)
@ddt.data(None, False)
def test_gluster_manager_init_no_vol(self, has_volume):
test_gluster_manager = glusterfs.GlusterManager(
'testuser@127.0.0.1', self.fake_execf, has_volume=has_volume)
self.assertIsNone(test_gluster_manager.volume)
def test_gluster_manager_init_has_shouldnt_have_vol(self):
self.assertRaises(exception.GlusterfsException,
glusterfs.GlusterManager,
'testuser@127.0.0.1:/testvol',
self.fake_execf, has_volume=False)
def test_gluster_manager_hasnt_should_have_vol(self):
self.assertRaises(exception.GlusterfsException,
glusterfs.GlusterManager, 'testuser@127.0.0.1',
self.fake_execf, has_volume=True)
def test_gluster_manager_invalid(self):
self.assertRaises(exception.GlusterfsException,
glusterfs.GlusterManager, '127.0.0.1:vol',
'self.fake_execf')
def test_gluster_manager_make_gluster_call_local(self):
fake_obj = mock.Mock()
fake_execute = mock.Mock()
with mock.patch.object(glusterfs.ganesha_utils, 'RootExecutor',
mock.Mock(return_value=fake_obj)):
gluster_manager = glusterfs.GlusterManager(
'127.0.0.1:/testvol', self.fake_execf)
gluster_manager.make_gluster_call(fake_execute)(*fake_args,
**fake_kwargs)
glusterfs.ganesha_utils.RootExecutor.assert_called_with(
fake_execute)
fake_obj.assert_called_once_with(
*(('gluster',) + fake_args), **fake_kwargs)
def test_gluster_manager_make_gluster_call_remote(self):
fake_obj = mock.Mock()
fake_execute = mock.Mock()
with mock.patch.object(glusterfs.ganesha_utils, 'SSHExecutor',
mock.Mock(return_value=fake_obj)):
gluster_manager = glusterfs.GlusterManager(
'testuser@127.0.0.1:/testvol', self.fake_execf,
fake_path_to_private_key, fake_remote_server_password)
gluster_manager.make_gluster_call(fake_execute)(*fake_args,
**fake_kwargs)
glusterfs.ganesha_utils.SSHExecutor.assert_called_with(
gluster_manager.host, 22, None, gluster_manager.remote_user,
password=gluster_manager.remote_server_password,
privatekey=gluster_manager.path_to_private_key)
fake_obj.assert_called_once_with(
*(('gluster',) + fake_args), **fake_kwargs)
def test_get_gluster_vol_option_empty_volinfo(self):
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(return_value=('', {})))
self.assertRaises(exception.GlusterfsException,
self._gluster_manager.get_gluster_vol_option,
NFS_EXPORT_DIR)
self._gluster_manager.gluster_call.assert_called_once_with(
*args)
def test_get_gluster_vol_option_failing_volinfo(self):
def raise_exception(*ignore_args, **ignore_kwargs):
raise RuntimeError('fake error')
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=raise_exception))
self.assertRaises(RuntimeError,
self._gluster_manager.get_gluster_vol_option,
NFS_EXPORT_DIR)
self._gluster_manager.gluster_call.assert_called_once_with(
*args)
def test_get_gluster_vol_option_ambiguous_volinfo(self):
def xml_output(*ignore_args, **ignore_kwargs):
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cliOutput>
<volInfo>
<volumes>
<count>0</count>
</volumes>
</volInfo>
</cliOutput>""", ''
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=xml_output))
self.assertRaises(exception.InvalidShare,
self._gluster_manager.get_gluster_vol_option,
NFS_EXPORT_DIR)
self._gluster_manager.gluster_call.assert_called_once_with(*args)
def test_get_gluster_vol_option_trivial_volinfo(self):
def xml_output(*ignore_args, **ignore_kwargs):
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cliOutput>
<volInfo>
<volumes>
<volume>
</volume>
<count>1</count>
</volumes>
</volInfo>
</cliOutput>""", ''
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=xml_output))
ret = self._gluster_manager.get_gluster_vol_option(NFS_EXPORT_DIR)
self.assertIsNone(ret)
self._gluster_manager.gluster_call.assert_called_once_with(*args)
def test_get_gluster_vol_option(self):
def xml_output(*ignore_args, **ignore_kwargs):
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cliOutput>
<volInfo>
<volumes>
<volume>
<options>
<option>
<name>nfs.export-dir</name>
<value>/foo(10.0.0.1|10.0.0.2),/bar(10.0.0.1)</value>
</option>
</options>
</volume>
<count>1</count>
</volumes>
</volInfo>
</cliOutput>""", ''
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=xml_output))
ret = self._gluster_manager.get_gluster_vol_option(NFS_EXPORT_DIR)
self.assertEqual('/foo(10.0.0.1|10.0.0.2),/bar(10.0.0.1)', ret)
self._gluster_manager.gluster_call.assert_called_once_with(*args)
def test_get_gluster_version(self):
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(return_value=('glusterfs 3.6.2beta3', '')))
ret = self._gluster_manager.get_gluster_version()
self.assertEqual(['3', '6', '2beta3'], ret)
self._gluster_manager.gluster_call.assert_called_once_with(
'--version')
@ddt.data("foo 1.1.1", "glusterfs 3-6", "glusterfs 3.6beta3")
def test_get_gluster_version_exception(self, versinfo):
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(return_value=(versinfo, '')))
self.assertRaises(exception.GlusterfsException,
self._gluster_manager.get_gluster_version)
self._gluster_manager.gluster_call.assert_called_once_with(
'--version')
def test_get_gluster_version_process_error(self):
def raise_exception(*args, **kwargs):
raise exception.ProcessExecutionError()
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=raise_exception))
self.assertRaises(exception.GlusterfsException,
self._gluster_manager.get_gluster_version)
self._gluster_manager.gluster_call.assert_called_once_with(
'--version')
def test_check_gluster_version(self):
self.mock_object(self._gluster_manager, 'get_gluster_version',
mock.Mock(return_value=('3', '6')))
ret = self._gluster_manager.check_gluster_version((3, 5, 2))
self.assertIsNone(ret)
self._gluster_manager.get_gluster_version.assert_called_once_with()
def test_check_gluster_version_unmet(self):
self.mock_object(self._gluster_manager, 'get_gluster_version',
mock.Mock(return_value=('3', '5', '2')))
self.assertRaises(exception.GlusterfsException,
self._gluster_manager.check_gluster_version, (3, 6))
self._gluster_manager.get_gluster_version.assert_called_once_with()
@ddt.data(('3', '6'),
('3', '6', '2beta'),
('3', '6', '2beta', '4'))
def test_numreduct(self, vers):
ret = glusterfs.GlusterManager.numreduct(vers)
self.assertEqual((3, 6), ret)
class GlusterfsShareDriverTestCase(test.TestCase):
"""Tests GlusterfsShareDriver."""
@ -325,7 +87,7 @@ class GlusterfsShareDriverTestCase(test.TestCase):
methods = ('_ensure_gluster_vol_mounted', '_setup_helpers')
for method in methods:
self.mock_object(self._driver, method)
self.mock_object(glusterfs, 'GlusterManager',
self.mock_object(common, 'GlusterManager',
mock.Mock(return_value=fake_gluster_manager))
expected_exec = ['mount.glusterfs']
exec_cmd1 = 'mount.glusterfs'
@ -333,7 +95,7 @@ class GlusterfsShareDriverTestCase(test.TestCase):
args = ('volume', 'quota', 'testvol', 'enable')
self._driver.do_setup(self._context)
self.assertEqual(fake_gluster_manager, self._driver.gluster_manager)
glusterfs.GlusterManager.assert_called_once_with(
common.GlusterManager.assert_called_once_with(
self._driver.configuration.glusterfs_target, self._execute,
self._driver.configuration.glusterfs_path_to_private_key,
self._driver.configuration.glusterfs_server_password)
@ -368,7 +130,7 @@ class GlusterfsShareDriverTestCase(test.TestCase):
methods = ('_ensure_gluster_vol_mounted', '_setup_helpers')
for method in methods:
self.mock_object(self._driver, method)
self.mock_object(glusterfs, 'GlusterManager',
self.mock_object(common, 'GlusterManager',
mock.Mock(return_value=fake_gluster_manager))
expected_exec = ['mount.glusterfs']
exec_cmd1 = 'mount.glusterfs'
@ -377,7 +139,7 @@ class GlusterfsShareDriverTestCase(test.TestCase):
self.assertRaises(exception.GlusterfsException, self._driver.do_setup,
self._context)
self.assertEqual(fake_gluster_manager, self._driver.gluster_manager)
glusterfs.GlusterManager.assert_called_once_with(
common.GlusterManager.assert_called_once_with(
self._driver.configuration.glusterfs_target, self._execute,
self._driver.configuration.glusterfs_path_to_private_key,
self._driver.configuration.glusterfs_server_password)
@ -399,7 +161,7 @@ class GlusterfsShareDriverTestCase(test.TestCase):
methods = ('_ensure_gluster_vol_mounted', '_setup_helpers')
for method in methods:
self.mock_object(self._driver, method)
self.mock_object(glusterfs, 'GlusterManager',
self.mock_object(common, 'GlusterManager',
mock.Mock(return_value=fake_gluster_manager))
expected_exec = ['mount.glusterfs']
exec_cmd1 = 'mount.glusterfs'
@ -407,7 +169,7 @@ class GlusterfsShareDriverTestCase(test.TestCase):
args = ('volume', 'quota', 'testvol', 'enable')
self._driver.do_setup(self._context)
self.assertEqual(fake_gluster_manager, self._driver.gluster_manager)
glusterfs.GlusterManager.assert_called_once_with(
common.GlusterManager.assert_called_once_with(
self._driver.configuration.glusterfs_target, self._execute,
self._driver.configuration.glusterfs_path_to_private_key,
self._driver.configuration.glusterfs_server_password)
@ -431,69 +193,13 @@ class GlusterfsShareDriverTestCase(test.TestCase):
self.assertEqual(self._helper_nfs, self._driver._helpers['NFS'])
self._driver._helpers['NFS'].init_helper.assert_called_once_with()
def test_do_mount(self):
expected_exec = ['true']
ret = self._driver._do_mount(expected_exec, False)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
self.assertIsNone(ret)
def test_do_mount_mounted_noensure(self):
def exec_runner(*ignore_args, **ignore_kwargs):
raise exception.ProcessExecutionError(stderr='already mounted')
expected_exec = ['true']
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
self.assertRaises(exception.GlusterfsException, self._driver._do_mount,
expected_exec, False)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
def test_do_mount_mounted_ensure(self):
def exec_runner(*ignore_args, **ignore_kwargs):
raise exception.ProcessExecutionError(stderr='already mounted')
expected_exec = ['true']
glusterfs.LOG.warn = mock.Mock()
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
ret = self._driver._do_mount(expected_exec, True)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
self.assertIsNone(ret)
glusterfs.LOG.warn.assert_called_with(
"%s is already mounted", self._driver.gluster_manager.export)
def test_do_mount_fail_noensure(self):
def exec_runner(*ignore_args, **ignore_kwargs):
raise RuntimeError('fake error')
expected_exec = ['true']
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
self.assertRaises(RuntimeError, self._driver._do_mount,
expected_exec, False)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
def test_do_mount_fail_ensure(self):
def exec_runner(*ignore_args, **ignore_kwargs):
raise RuntimeError('fake error')
expected_exec = ['true']
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
self.assertRaises(RuntimeError, self._driver._do_mount,
expected_exec, True)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
def test_mount_gluster_vol(self):
mount_path = '/mnt/nfs/testvol'
self._driver._do_mount = mock.Mock()
cmd = ['mount', '-t', 'glusterfs',
fake_gluster_manager_attrs['export'], mount_path]
expected_exec = ['mkdir -p %s' % (mount_path)]
self._driver._mount_gluster_vol(mount_path)
self._driver._do_mount.assert_called_with(cmd, False)
self.assertEqual(fake_utils.fake_execute_get_log(), expected_exec)
def test_ensure_gluster_vol_mounted(self):
self._driver._mount_gluster_vol = mock.Mock()
common._mount_gluster_vol = mock.Mock()
self._driver._ensure_gluster_vol_mounted()
self.assertTrue(self._driver._mount_gluster_vol.called)
self.assertTrue(common._mount_gluster_vol.called)
def test_ensure_gluster_vol_mounted_error(self):
self._driver._mount_gluster_vol =\
common._mount_gluster_vol =\
mock.Mock(side_effect=exception.GlusterfsException)
self.assertRaises(exception.GlusterfsException,
self._driver._ensure_gluster_vol_mounted)
@ -987,7 +693,7 @@ class GaneshaNFSHelperTestCase(test.TestCase):
glusterfs.ganesha.GaneshaNASHelper._default_config_hook.\
assert_called_once_with()
glusterfs.ganesha_utils.path_from.assert_called_once_with(
glusterfs.__file__, 'glusterfs', 'conf')
glusterfs.__file__, 'conf')
self._helper._load_conf_dir.assert_called_once_with(
'/fakedir/glusterfs/conf')
glusterfs.ganesha_utils.patch.assert_called_once_with(

View File

@ -30,7 +30,7 @@ from manila.common import constants
from manila import context
from manila import exception
from manila.share import configuration as config
from manila.share.drivers import glusterfs
from manila.share.drivers.glusterfs import common
from manila.share.drivers import glusterfs_native
from manila import test
from manila.tests import fake_utils
@ -88,7 +88,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.share2 = new_share(
export_location=self.glusterfs_target2,
status=constants.STATUS_AVAILABLE)
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
self.gmgr1 = gmgr(self.glusterfs_server1, self._execute, None, None,
has_volume=False)
self.gmgr2 = gmgr(self.glusterfs_server2, self._execute, None, None,
@ -110,7 +110,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.fake_conf = config.Configuration(None)
self.mock_object(tempfile, 'mkdtemp',
mock.Mock(return_value='/tmp/tmpKGHKJ'))
self.mock_object(glusterfs.GlusterManager, 'make_gluster_call')
self.mock_object(common.GlusterManager, 'make_gluster_call')
with mock.patch.object(glusterfs_native.GlusterfsNativeShareDriver,
'_glustermanager',
@ -128,11 +128,11 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
@ddt.unpack
def test_glustermanager(self, test_kwargs, has_volume):
fake_obj = mock.Mock()
self.mock_object(glusterfs, 'GlusterManager',
self.mock_object(common, 'GlusterManager',
mock.Mock(return_value=fake_obj))
ret = self._driver._glustermanager(self.glusterfs_target1,
**test_kwargs)
glusterfs.GlusterManager.assert_called_once_with(
common.GlusterManager.assert_called_once_with(
self.glusterfs_target1, self._execute,
self._driver.configuration.glusterfs_native_path_to_private_key,
self._driver.configuration.glusterfs_native_server_password,
@ -238,9 +238,9 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
('volume', 'set', 'gv1', 'nfs.export-volumes', 'off'),
('volume', 'set', 'gv1', 'client.ssl', 'on'),
('volume', 'set', 'gv1', 'server.ssl', 'on')]
self._driver._restart_gluster_vol = mock.Mock()
common._restart_gluster_vol = mock.Mock()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self._driver._glustermanager = mock.Mock(return_value=gmgr1)
self.mock_object(gmgr1, 'get_gluster_vol_option',
@ -253,7 +253,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
mock.call(*test_args[1]),
mock.call(*test_args[2]))
self.assertEqual(gmgr1, ret)
self.assertTrue(self._driver._restart_gluster_vol.called)
self.assertTrue(common._restart_gluster_vol.called)
@ddt.data(0, 1, 2)
def test_setup_gluster_vols_excp(self, idx):
@ -266,9 +266,9 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
if(args == test_args[idx]):
raise exception.ProcessExecutionError()
self._driver._restart_gluster_vol = mock.Mock()
common._restart_gluster_vol = mock.Mock()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self._driver._glustermanager = mock.Mock(return_value=gmgr1)
self.mock_object(gmgr1, 'get_gluster_vol_option',
@ -281,12 +281,12 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
self.assertTrue(
mock.call(*test_args[idx]) in gmgr1.gluster_call.call_args_list)
self.assertFalse(self._driver._restart_gluster_vol.called)
self.assertFalse(common._restart_gluster_vol.called)
def test_setup_gluster_vol_no_ssl_allow(self):
self._driver._restart_gluster_vol = mock.Mock()
common._restart_gluster_vol = mock.Mock()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self._driver._glustermanager = mock.Mock(return_value=gmgr1)
self.mock_object(gmgr1, 'get_gluster_vol_option',
@ -296,55 +296,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver._setup_gluster_vol, gmgr1.volume)
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
self.assertFalse(gmgr1.gluster_call.called)
self.assertFalse(self._driver._restart_gluster_vol.called)
def test_restart_gluster_vol(self):
gmgr = glusterfs.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
test_args = [('volume', 'stop', 'gv1', '--mode=script'),
('volume', 'start', 'gv1')]
self._driver._restart_gluster_vol(gmgr1)
self.assertEqual(
[mock.call(*test_args[0]), mock.call(*test_args[1])],
gmgr1.gluster_call.call_args_list)
def test_restart_gluster_vol_excp1(self):
gmgr = glusterfs.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
test_args = ('volume', 'stop', 'gv1', '--mode=script')
def raise_exception(*args, **kwargs):
if(args == test_args):
raise exception.ProcessExecutionError()
self.mock_object(gmgr1, 'gluster_call',
mock.Mock(side_effect=raise_exception))
self.assertRaises(exception.GlusterfsException,
self._driver._restart_gluster_vol, gmgr1)
self.assertEqual(
[mock.call(*test_args)],
gmgr1.gluster_call.call_args_list)
def test_restart_gluster_vol_excp2(self):
gmgr = glusterfs.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
test_args = [('volume', 'stop', 'gv1', '--mode=script'),
('volume', 'start', 'gv1')]
def raise_exception(*args, **kwargs):
if(args == test_args[1]):
raise exception.ProcessExecutionError()
self.mock_object(gmgr1, 'gluster_call',
mock.Mock(side_effect=raise_exception))
self.assertRaises(exception.GlusterfsException,
self._driver._restart_gluster_vol, gmgr1)
self.assertEqual(
[mock.call(*test_args[0]), mock.call(*test_args[1])],
gmgr1.gluster_call.call_args_list)
self.assertFalse(common._restart_gluster_vol.called)
@ddt.data({"voldict": {"host:/share2G": {"size": 2}}, "used_vols": {},
"size": 1, "expected": "host:/share2G"},
@ -374,7 +326,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
"expected": "host:/share"})
@ddt.unpack
def test_pop_gluster_vol(self, voldict, used_vols, size, expected):
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(expected, self._execute, None, None)
self._driver._fetch_gluster_volumes = mock.Mock(return_value=voldict)
self._driver.gluster_used_vols_dict = used_vols
@ -403,7 +355,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.assertFalse(self._driver._setup_gluster_vol.called)
def test_push_gluster_vol(self):
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
gmgr2 = gmgr(self.glusterfs_target2, self._execute, None, None)
@ -417,7 +369,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.glusterfs_target2 in self._driver.gluster_used_vols_dict)
def test_push_gluster_vol_excp(self):
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
@ -427,50 +379,6 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver._push_gluster_vol,
self.glusterfs_target2)
def test_do_mount(self):
gmgr = glusterfs.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
tmpdir = '/tmp/tmpKGHKJ'
expected_exec = ['mount -t glusterfs host1:/gv1 /tmp/tmpKGHKJ']
self._driver._do_mount(gmgr1.export, tmpdir)
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
def test_do_mount_excp(self):
def exec_runner(*ignore_args, **ignore_kwargs):
raise exception.ProcessExecutionError
gmgr = glusterfs.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
tmpdir = '/tmp/tmpKGHKJ'
expected_exec = ['mount -t glusterfs host1:/gv1 /tmp/tmpKGHKJ']
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
self.assertRaises(exception.GlusterfsException,
self._driver._do_mount, gmgr1.export, tmpdir)
def test_do_umount(self):
tmpdir = '/tmp/tmpKGHKJ'
expected_exec = ['umount /tmp/tmpKGHKJ']
self._driver._do_umount(tmpdir)
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
def test_do_umount_excp(self):
def exec_runner(*ignore_args, **ignore_kwargs):
raise exception.ProcessExecutionError
tmpdir = '/tmp/tmpKGHKJ'
expected_exec = ['umount /tmp/tmpKGHKJ']
fake_utils.fake_execute_set_repliers([(expected_exec[0], exec_runner)])
self.assertRaises(exception.GlusterfsException,
self._driver._do_umount, tmpdir)
@ddt.data({'vers_minor': '6',
'cmd': 'find /tmp/tmpKGHKJ -mindepth 1 -delete'},
{'vers_minor': '7',
@ -479,9 +387,9 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
'/tmp/tmpKGHKJ/.trashcan/internal_op -delete'})
@ddt.unpack
def test_wipe_gluster_vol(self, vers_minor, cmd):
self._driver._restart_gluster_vol = mock.Mock()
self._driver._do_mount = mock.Mock()
self._driver._do_umount = mock.Mock()
common._restart_gluster_vol = mock.Mock()
common._mount_gluster_vol = mock.Mock()
common._umount_gluster_vol = mock.Mock()
shutil.rmtree = mock.Mock()
test_args = [
('volume', 'set', 'gv1', 'client.ssl', 'off'),
@ -489,7 +397,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
('volume', 'set', 'gv1', 'client.ssl', 'on'),
('volume', 'set', 'gv1', 'server.ssl', 'on')]
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self._driver.glusterfs_versions = {
self.glusterfs_server1: ('3', vers_minor)}
@ -497,21 +405,21 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver._wipe_gluster_vol(gmgr1)
self.assertEqual(2, self._driver._restart_gluster_vol.call_count)
self.assertEqual(2, common._restart_gluster_vol.call_count)
self.assertEqual(
[mock.call(*test_args[0]), mock.call(*test_args[1]),
mock.call(*test_args[2]), mock.call(*test_args[3])],
gmgr1.gluster_call.call_args_list)
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
self.assertTrue(tempfile.mkdtemp.called)
self.assertTrue(self._driver._do_mount.called)
self.assertTrue(self._driver._do_umount.called)
self.assertTrue(common._mount_gluster_vol.called)
self.assertTrue(common._umount_gluster_vol.called)
self.assertTrue(shutil.rmtree.called)
def test_wipe_gluster_vol_excp1(self):
self._driver._restart_gluster_vol = mock.Mock()
self._driver._do_mount = mock.Mock()
self._driver._do_umount = mock.Mock()
common._restart_gluster_vol = mock.Mock()
common._mount_gluster_vol = mock.Mock()
common._umount_gluster_vol = mock.Mock()
shutil.rmtree = mock.Mock()
test_args = ('volume', 'set', 'gv1', 'client.ssl', 'off')
@ -519,7 +427,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
if(args == test_args):
raise exception.ProcessExecutionError()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self.mock_object(gmgr1, 'gluster_call',
mock.Mock(side_effect=raise_exception))
@ -528,16 +436,16 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver._wipe_gluster_vol, gmgr1)
self.assertEqual(
[mock.call(*test_args)], gmgr1.gluster_call.call_args_list)
self.assertFalse(self._driver._restart_gluster_vol.called)
self.assertFalse(common._restart_gluster_vol.called)
self.assertFalse(tempfile.mkdtemp.called)
self.assertFalse(self._driver._do_mount.called)
self.assertFalse(self._driver._do_umount.called)
self.assertFalse(common._mount_gluster_vol.called)
self.assertFalse(common._umount_gluster_vol.called)
self.assertFalse(shutil.rmtree.called)
def test_wipe_gluster_vol_excp2(self):
self._driver._restart_gluster_vol = mock.Mock()
self._driver._do_mount = mock.Mock()
self._driver._do_umount = mock.Mock()
common._restart_gluster_vol = mock.Mock()
common._mount_gluster_vol = mock.Mock()
common._umount_gluster_vol = mock.Mock()
shutil.rmtree = mock.Mock()
test_args = [
('volume', 'set', 'gv1', 'client.ssl', 'off'),
@ -547,7 +455,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
if(args == test_args[1]):
raise exception.ProcessExecutionError()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self.mock_object(gmgr1, 'gluster_call',
mock.Mock(side_effect=raise_exception))
@ -557,16 +465,16 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.assertEqual(
[mock.call(*test_args[0]), mock.call(*test_args[1])],
gmgr1.gluster_call.call_args_list)
self.assertFalse(self._driver._restart_gluster_vol.called)
self.assertFalse(common._restart_gluster_vol.called)
self.assertFalse(tempfile.mkdtemp.called)
self.assertFalse(self._driver._do_mount.called)
self.assertFalse(self._driver._do_umount.called)
self.assertFalse(common._mount_gluster_vol.called)
self.assertFalse(common._umount_gluster_vol.called)
self.assertFalse(shutil.rmtree.called)
def test_wipe_gluster_vol_excp3(self):
self._driver._restart_gluster_vol = mock.Mock()
self._driver._do_mount = mock.Mock()
self._driver._do_umount = mock.Mock()
common._restart_gluster_vol = mock.Mock()
common._mount_gluster_vol = mock.Mock()
common._umount_gluster_vol = mock.Mock()
shutil.rmtree = mock.Mock()
test_args = [
('volume', 'set', 'gv1', 'client.ssl', 'off'),
@ -577,7 +485,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
if(args == test_args[2]):
raise exception.ProcessExecutionError()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self.mock_object(gmgr1, 'gluster_call',
mock.Mock(side_effect=raise_exception))
@ -591,16 +499,16 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
mock.call(*test_args[2])],
gmgr1.gluster_call.call_args_list)
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
self.assertTrue(self._driver._restart_gluster_vol.called)
self.assertTrue(common._restart_gluster_vol.called)
self.assertTrue(tempfile.mkdtemp.called)
self.assertTrue(self._driver._do_mount.called)
self.assertTrue(self._driver._do_umount.called)
self.assertTrue(common._mount_gluster_vol.called)
self.assertTrue(common._umount_gluster_vol.called)
self.assertTrue(shutil.rmtree.called)
def test_wipe_gluster_vol_excp4(self):
self._driver._restart_gluster_vol = mock.Mock()
self._driver._do_mount = mock.Mock()
self._driver._do_umount = mock.Mock()
common._restart_gluster_vol = mock.Mock()
common._mount_gluster_vol = mock.Mock()
common._umount_gluster_vol = mock.Mock()
shutil.rmtree = mock.Mock()
test_args = [
('volume', 'set', 'gv1', 'client.ssl', 'off'),
@ -612,7 +520,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
if(args == test_args[3]):
raise exception.ProcessExecutionError()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self.mock_object(gmgr1, 'gluster_call',
mock.Mock(side_effect=raise_exception))
@ -626,19 +534,19 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
mock.call(*test_args[2]), mock.call(*test_args[3])],
gmgr1.gluster_call.call_args_list)
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
self.assertTrue(self._driver._restart_gluster_vol.called)
self.assertTrue(common._restart_gluster_vol.called)
self.assertTrue(tempfile.mkdtemp.called)
self.assertTrue(self._driver._do_mount.called)
self.assertTrue(self._driver._do_umount.called)
self.assertTrue(common._mount_gluster_vol.called)
self.assertTrue(common._umount_gluster_vol.called)
self.assertTrue(shutil.rmtree.called)
def test_wipe_gluster_vol_excp5(self):
self._driver._restart_gluster_vol = mock.Mock()
self._driver._do_mount = mock.Mock()
self._driver._do_umount = mock.Mock()
common._restart_gluster_vol = mock.Mock()
common._mount_gluster_vol = mock.Mock()
common._umount_gluster_vol = mock.Mock()
shutil.rmtree = mock.Mock()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
test_args = [
@ -658,20 +566,20 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.assertEqual(
[mock.call(*test_args[0]), mock.call(*test_args[1])],
gmgr1.gluster_call.call_args_list)
self.assertTrue(self._driver._restart_gluster_vol.called)
self.assertTrue(common._restart_gluster_vol.called)
self.assertTrue(tempfile.mkdtemp.called)
self.assertTrue(self._driver._do_mount.called)
self.assertTrue(self._driver._do_umount.called)
self.assertTrue(common._mount_gluster_vol.called)
self.assertTrue(common._umount_gluster_vol.called)
self.assertTrue(shutil.rmtree.called)
def test_wipe_gluster_vol_mount_fail(self):
self._driver._restart_gluster_vol = mock.Mock()
self._driver._do_mount = mock.Mock()
self._driver._do_mount.side_effect = exception.GlusterfsException
self._driver._do_umount = mock.Mock()
common._restart_gluster_vol = mock.Mock()
common._mount_gluster_vol = mock.Mock()
common._mount_gluster_vol.side_effect = exception.GlusterfsException
common._umount_gluster_vol = mock.Mock()
shutil.rmtree = mock.Mock()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
test_args = [
@ -683,20 +591,20 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.assertEqual(
[mock.call(*test_args[0]), mock.call(*test_args[1])],
gmgr1.gluster_call.call_args_list)
self.assertTrue(self._driver._restart_gluster_vol.called)
self.assertTrue(common._restart_gluster_vol.called)
self.assertTrue(tempfile.mkdtemp.called)
self.assertTrue(self._driver._do_mount.called)
self.assertFalse(self._driver._do_umount.called)
self.assertTrue(common._mount_gluster_vol.called)
self.assertFalse(common._umount_gluster_vol.called)
self.assertTrue(shutil.rmtree.called)
def test_wipe_gluster_vol_umount_fail(self):
self._driver._restart_gluster_vol = mock.Mock()
self._driver._do_mount = mock.Mock()
self._driver._do_umount = mock.Mock()
self._driver._do_umount.side_effect = exception.GlusterfsException
common._restart_gluster_vol = mock.Mock()
common._mount_gluster_vol = mock.Mock()
common._umount_gluster_vol = mock.Mock()
common._umount_gluster_vol.side_effect = exception.GlusterfsException
shutil.rmtree = mock.Mock()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
test_args = [
@ -711,10 +619,10 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
[mock.call(*test_args[0]), mock.call(*test_args[1])],
gmgr1.gluster_call.call_args_list)
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
self.assertTrue(self._driver._restart_gluster_vol.called)
self.assertTrue(common._restart_gluster_vol.called)
self.assertTrue(tempfile.mkdtemp.called)
self.assertTrue(self._driver._do_mount.called)
self.assertTrue(self._driver._do_umount.called)
self.assertTrue(common._mount_gluster_vol.called)
self.assertTrue(common._umount_gluster_vol.called)
self.assertFalse(shutil.rmtree.called)
def test_create_share(self):
@ -742,7 +650,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
def test_delete_share(self):
self._driver._push_gluster_vol = mock.Mock()
self._driver._wipe_gluster_vol = mock.Mock()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
self._driver.delete_share(self._context, self.share1)
@ -765,7 +673,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver._wipe_gluster_vol.side_effect = (
exception.GlusterfsException)
self._driver._push_gluster_vol = mock.Mock()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
self.assertRaises(exception.GlusterfsException,
@ -778,7 +686,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver.gluster_nosnap_vols_dict = {}
self._driver.glusterfs_versions = {self.glusterfs_server1: ('3', '6')}
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
@ -800,7 +708,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver.gluster_nosnap_vols_dict = {}
self._driver.glusterfs_versions = {self.glusterfs_server1: ('3', '6')}
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
@ -828,7 +736,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver.glusterfs_versions = {
self.glusterfs_server1: ('3', vers_minor)}
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
@ -856,7 +764,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver.glusterfs_versions = {
self.glusterfs_server1: ('3', vers_minor)}
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
@ -870,7 +778,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
snapshot)
def test_find_actual_backend_snapshot_name(self):
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.share1['export_location'], self._execute, None, None)
self.mock_object(gmgr1, 'gluster_call',
mock.Mock(return_value=('fake_snap_id_xyz', '')))
@ -886,7 +794,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
@ddt.data('this is too bad', 'fake_snap_id_xyx\nfake_snap_id_pqr')
def test_find_actual_backend_snapshot_name_bad_snap_list(self, snaplist):
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.share1['export_location'], self._execute, None, None)
self.mock_object(gmgr1, 'gluster_call',
mock.Mock(return_value=(snaplist, '')))
@ -915,7 +823,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
}
volume = ''.join(['manila-', share['id']])
new_export_location = ':/'.join([glusterfs_server, volume])
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
old_gmgr = gmgr(glusterfs_target, self._execute, None, None)
new_gmgr = gmgr(new_export_location, self._execute, None, None)
self._driver.gluster_used_vols_dict = {glusterfs_target: old_gmgr}
@ -966,7 +874,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
}
volume = ''.join(['manila-', share['id']])
new_export_location = ':/'.join([glusterfs_server, volume])
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
old_gmgr = gmgr(glusterfs_target, self._execute, None, None)
new_gmgr = gmgr(new_export_location, self._execute, None, None)
self._driver.gluster_used_vols_dict = {glusterfs_target: old_gmgr}
@ -1011,7 +919,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
}
volume = ''.join(['manila-', share['id']])
new_export_location = ':/'.join([glusterfs_server, volume])
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
old_gmgr = gmgr(glusterfs_target, self._execute, None, None)
new_gmgr = gmgr(new_export_location, self._execute, None, None)
self._driver.gluster_used_vols_dict = {glusterfs_target: old_gmgr}
@ -1065,7 +973,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
}
volume = ''.join(['manila-', share['id']])
new_export_location = ':/'.join([glusterfs_server, volume])
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
old_gmgr = gmgr(glusterfs_target, self._execute, None, None)
new_gmgr = gmgr(new_export_location, self._execute, None, None)
self._driver.gluster_used_vols_dict = {glusterfs_target: old_gmgr}
@ -1102,7 +1010,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
def test_delete_snapshot(self):
self._driver.gluster_nosnap_vols_dict = {}
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.share1['export_location'], self._execute, None, None)
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
@ -1128,7 +1036,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
def test_delete_snapshot_error(self, badxmloutput):
self._driver.gluster_nosnap_vols_dict = {}
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.share1['export_location'], self._execute, None, None)
self._driver.gluster_used_vols_dict = {self.glusterfs_target1: gmgr1}
@ -1152,9 +1060,9 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
assert_called_once_with(gmgr1, snapshot))
def test_allow_access(self):
self._driver._restart_gluster_vol = mock.Mock()
common._restart_gluster_vol = mock.Mock()
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self.mock_object(gmgr1, 'get_gluster_vol_option',
mock.Mock(return_value='some.common.name'))
@ -1166,12 +1074,12 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver.allow_access(self._context, self.share1, access)
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
gmgr1.gluster_call.assert_called_once_with(*test_args)
self._driver._restart_gluster_vol.assert_called_once_with(gmgr1)
common._restart_gluster_vol.assert_called_once_with(gmgr1)
def test_allow_access_with_share_having_access(self):
self._driver._restart_gluster_vol = mock.Mock()
common._restart_gluster_vol = mock.Mock()
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self.mock_object(
gmgr1, 'get_gluster_vol_option',
@ -1182,17 +1090,17 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver.allow_access(self._context, self.share1, access)
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
self.assertFalse(gmgr1.gluster_call.called)
self.assertFalse(self._driver._restart_gluster_vol.called)
self.assertFalse(common._restart_gluster_vol.called)
def test_allow_access_invalid_access_type(self):
self._driver._restart_gluster_vol = mock.Mock()
common._restart_gluster_vol = mock.Mock()
access = {'access_type': 'invalid', 'access_to': 'client.example.com'}
expected_exec = []
self.assertRaises(exception.InvalidShareAccess,
self._driver.allow_access,
self._context, self.share1, access)
self.assertFalse(self._driver._restart_gluster_vol.called)
self.assertFalse(common._restart_gluster_vol.called)
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
def test_allow_access_excp(self):
@ -1204,9 +1112,9 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
if (args == test_args):
raise exception.ProcessExecutionError()
self._driver._restart_gluster_vol = mock.Mock()
common._restart_gluster_vol = mock.Mock()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self.mock_object(gmgr1, 'get_gluster_vol_option',
mock.Mock(return_value='some.common.name'))
@ -1220,12 +1128,12 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._context, self.share1, access)
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
gmgr1.gluster_call.assert_called_once_with(*test_args)
self.assertFalse(self._driver._restart_gluster_vol.called)
self.assertFalse(common._restart_gluster_vol.called)
def test_deny_access(self):
self._driver._restart_gluster_vol = mock.Mock()
common._restart_gluster_vol = mock.Mock()
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self.mock_object(
gmgr1, 'get_gluster_vol_option',
@ -1238,12 +1146,12 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver.deny_access(self._context, self.share1, access)
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
gmgr1.gluster_call.assert_called_once_with(*test_args)
self._driver._restart_gluster_vol.assert_called_once_with(gmgr1)
common._restart_gluster_vol.assert_called_once_with(gmgr1)
def test_deny_access_with_share_having_no_access(self):
self._driver._restart_gluster_vol = mock.Mock()
common._restart_gluster_vol = mock.Mock()
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self.mock_object(gmgr1, 'get_gluster_vol_option',
mock.Mock(return_value='some.common.name'))
@ -1253,16 +1161,16 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver.deny_access(self._context, self.share1, access)
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
self.assertFalse(gmgr1.gluster_call.called)
self.assertFalse(self._driver._restart_gluster_vol.called)
self.assertFalse(common._restart_gluster_vol.called)
def test_deny_access_invalid_access_type(self):
self._driver._restart_gluster_vol = mock.Mock()
common._restart_gluster_vol = mock.Mock()
access = {'access_type': 'invalid', 'access_to': 'NotApplicable'}
self.assertRaises(exception.InvalidShareAccess,
self._driver.deny_access,
self._context, self.share1, access)
self.assertFalse(self._driver._restart_gluster_vol.called)
self.assertFalse(common._restart_gluster_vol.called)
def test_deny_access_excp(self):
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
@ -1273,9 +1181,9 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
if (args == test_args):
raise exception.ProcessExecutionError()
self._driver._restart_gluster_vol = mock.Mock()
common._restart_gluster_vol = mock.Mock()
gmgr = glusterfs.GlusterManager
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
self.mock_object(
gmgr1, 'get_gluster_vol_option',
@ -1290,7 +1198,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._context, self.share1, access)
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
gmgr1.gluster_call.assert_called_once_with(*test_args)
self.assertFalse(self._driver._restart_gluster_vol.called)
self.assertFalse(common._restart_gluster_vol.called)
def test_get_share_stats_refresh_false(self):
self._driver._stats = mock.Mock()