|
- # Copyright (c) 2014 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.
-
- """ GlusterFS volume mapped share layout testcases.
- """
-
- import re
- import shutil
- import tempfile
- from unittest import mock
-
- import ddt
- from oslo_config import cfg
-
- from manila.common import constants
- from manila import context
- from manila import exception
- from manila.share import configuration as config
- from manila.share.drivers.glusterfs import common
- from manila.share.drivers.glusterfs import layout_volume
- from manila import test
- from manila.tests import fake_utils
-
-
- CONF = cfg.CONF
-
-
- def new_share(**kwargs):
- share = {
- 'id': 'fakeid',
- 'name': 'fakename',
- 'size': 1,
- 'share_proto': 'glusterfs',
- }
- share.update(kwargs)
- return share
-
-
- def glusterXMLOut(**kwargs):
-
- template = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <cliOutput>
- <opRet>%(ret)d</opRet>
- <opErrno>%(errno)d</opErrno>
- <opErrstr>fake error</opErrstr>
- </cliOutput>"""
-
- return template % kwargs, ''
-
-
- FAKE_UUID1 = '11111111-1111-1111-1111-111111111111'
- FAKE_UUID2 = '22222222-2222-2222-2222-222222222222'
-
-
- @ddt.ddt
- class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
- """Tests GlusterfsVolumeMappedLayout."""
-
- def setUp(self):
- super(GlusterfsVolumeMappedLayoutTestCase, self).setUp()
- fake_utils.stub_out_utils_execute(self)
- self._execute = fake_utils.fake_execute
- self._context = context.get_admin_context()
-
- self.glusterfs_target1 = 'root@host1:/gv1'
- self.glusterfs_target2 = 'root@host2:/gv2'
- self.glusterfs_server1 = 'root@host1'
- self.glusterfs_server2 = 'root@host2'
- self.glusterfs_server1_volumes = 'manila-share-1-1G\nshare1'
- self.glusterfs_server2_volumes = 'manila-share-2-2G\nshare2'
- self.share1 = new_share(
- export_location=self.glusterfs_target1,
- status=constants.STATUS_AVAILABLE)
- self.share2 = new_share(
- export_location=self.glusterfs_target2,
- status=constants.STATUS_AVAILABLE)
- gmgr = common.GlusterManager
- self.gmgr1 = gmgr(self.glusterfs_server1, self._execute, None, None,
- requires={'volume': False})
- self.gmgr2 = gmgr(self.glusterfs_server2, self._execute, None, None,
- requires={'volume': False})
- self.glusterfs_volumes_dict = (
- {'root@host1:/manila-share-1-1G': {'size': 1},
- 'root@host2:/manila-share-2-2G': {'size': 2}})
- self.glusterfs_used_vols = set([
- 'root@host1:/manila-share-1-1G',
- 'root@host2:/manila-share-2-2G'])
-
- CONF.set_default('glusterfs_servers',
- [self.glusterfs_server1, self.glusterfs_server2])
- CONF.set_default('glusterfs_server_password',
- 'fake_password')
- CONF.set_default('glusterfs_path_to_private_key',
- '/fakepath/to/privatekey')
- CONF.set_default('glusterfs_volume_pattern',
- r'manila-share-\d+-#{size}G$')
- CONF.set_default('driver_handles_share_servers', False)
-
- self.fake_driver = mock.Mock()
- self.mock_object(self.fake_driver, '_execute',
- self._execute)
- self.fake_driver.GLUSTERFS_VERSION_MIN = (3, 6)
-
- self.fake_conf = config.Configuration(None)
- self.mock_object(tempfile, 'mkdtemp',
- mock.Mock(return_value='/tmp/tmpKGHKJ'))
- self.mock_object(common.GlusterManager, 'make_gluster_call')
-
- self.fake_private_storage = mock.Mock()
-
- with mock.patch.object(layout_volume.GlusterfsVolumeMappedLayout,
- '_glustermanager',
- side_effect=[self.gmgr1, self.gmgr2]):
- self._layout = layout_volume.GlusterfsVolumeMappedLayout(
- self.fake_driver, configuration=self.fake_conf,
- private_storage=self.fake_private_storage)
- self._layout.glusterfs_versions = {self.glusterfs_server1: ('3', '6'),
- self.glusterfs_server2: ('3', '7')}
- self.addCleanup(fake_utils.fake_execute_set_repliers, [])
- self.addCleanup(fake_utils.fake_execute_clear_log)
-
- @ddt.data({"test_kwargs": {}, "requires": {"volume": True}},
- {"test_kwargs": {'req_volume': False},
- "requires": {"volume": False}})
- @ddt.unpack
- def test_glustermanager(self, test_kwargs, requires):
- fake_obj = mock.Mock()
- self.mock_object(common, 'GlusterManager',
- mock.Mock(return_value=fake_obj))
-
- ret = self._layout._glustermanager(self.glusterfs_target1,
- **test_kwargs)
-
- common.GlusterManager.assert_called_once_with(
- self.glusterfs_target1, self._execute,
- self._layout.configuration.glusterfs_path_to_private_key,
- self._layout.configuration.glusterfs_server_password,
- requires=requires)
- self.assertEqual(fake_obj, ret)
-
- def test_compile_volume_pattern(self):
- volume_pattern = r'manila-share-\d+-(?P<size>\d+)G$'
-
- ret = self._layout._compile_volume_pattern()
-
- self.assertEqual(re.compile(volume_pattern), ret)
-
- @ddt.data({'root@host1:/manila-share-1-1G': 'NONE',
- 'root@host2:/manila-share-2-2G': None},
- {'root@host1:/manila-share-1-1G': FAKE_UUID1,
- 'root@host2:/manila-share-2-2G': None},
- {'root@host1:/manila-share-1-1G': 'foobarbaz',
- 'root@host2:/manila-share-2-2G': FAKE_UUID2},
- {'root@host1:/manila-share-1-1G': FAKE_UUID1,
- 'root@host2:/manila-share-2-2G': FAKE_UUID2})
- def test_fetch_gluster_volumes(self, sharemark):
- vol1_qualified = 'root@host1:/manila-share-1-1G'
- gmgr_vol1 = common.GlusterManager(vol1_qualified)
- gmgr_vol1.get_vol_option = mock.Mock(
- return_value=sharemark[vol1_qualified])
- vol2_qualified = 'root@host2:/manila-share-2-2G'
- gmgr_vol2 = common.GlusterManager(vol2_qualified)
- gmgr_vol2.get_vol_option = mock.Mock(
- return_value=sharemark[vol2_qualified])
- self.mock_object(
- self.gmgr1, 'gluster_call',
- mock.Mock(return_value=(self.glusterfs_server1_volumes, '')))
- self.mock_object(
- self.gmgr2, 'gluster_call',
- mock.Mock(return_value=(self.glusterfs_server2_volumes, '')))
- _glustermanager_calls = (self.gmgr1, gmgr_vol1, self.gmgr2, gmgr_vol2)
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(side_effect=_glustermanager_calls))
- expected_output = {}
- for q, d in self.glusterfs_volumes_dict.items():
- if sharemark[q] not in (FAKE_UUID1, FAKE_UUID2):
- expected_output[q] = d
-
- ret = self._layout._fetch_gluster_volumes()
-
- test_args = ('volume', 'list')
- self.gmgr1.gluster_call.assert_called_once_with(*test_args,
- log=mock.ANY)
- self.gmgr2.gluster_call.assert_called_once_with(*test_args,
- log=mock.ANY)
- gmgr_vol1.get_vol_option.assert_called_once_with(
- 'user.manila-share')
- gmgr_vol2.get_vol_option.assert_called_once_with(
- 'user.manila-share')
- self.assertEqual(expected_output, ret)
-
- def test_fetch_gluster_volumes_no_filter_used(self):
- vol1_qualified = 'root@host1:/manila-share-1-1G'
- gmgr_vol1 = common.GlusterManager(vol1_qualified)
- gmgr_vol1.get_vol_option = mock.Mock()
- vol2_qualified = 'root@host2:/manila-share-2-2G'
- gmgr_vol2 = common.GlusterManager(vol2_qualified)
- gmgr_vol2.get_vol_option = mock.Mock()
- self.mock_object(
- self.gmgr1, 'gluster_call',
- mock.Mock(return_value=(self.glusterfs_server1_volumes, '')))
- self.mock_object(
- self.gmgr2, 'gluster_call',
- mock.Mock(return_value=(self.glusterfs_server2_volumes, '')))
- _glustermanager_calls = (self.gmgr1, gmgr_vol1, self.gmgr2, gmgr_vol2)
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(side_effect=_glustermanager_calls))
- expected_output = self.glusterfs_volumes_dict
-
- ret = self._layout._fetch_gluster_volumes(filter_used=False)
-
- test_args = ('volume', 'list')
- self.gmgr1.gluster_call.assert_called_once_with(*test_args,
- log=mock.ANY)
- self.gmgr2.gluster_call.assert_called_once_with(*test_args,
- log=mock.ANY)
- self.assertFalse(gmgr_vol1.get_vol_option.called)
- self.assertFalse(gmgr_vol2.get_vol_option.called)
- self.assertEqual(expected_output, ret)
-
- def test_fetch_gluster_volumes_no_keymatch(self):
- vol1_qualified = 'root@host1:/manila-share-1'
- gmgr_vol1 = common.GlusterManager(vol1_qualified)
- gmgr_vol1.get_vol_option = mock.Mock(return_value=None)
- self._layout.configuration.glusterfs_servers = [self.glusterfs_server1]
- self.mock_object(
- self.gmgr1, 'gluster_call',
- mock.Mock(return_value=('manila-share-1', '')))
- _glustermanager_calls = (self.gmgr1, gmgr_vol1)
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(side_effect=_glustermanager_calls))
- self.mock_object(self._layout, 'volume_pattern',
- re.compile(r'manila-share-\d+(-(?P<size>\d+)G)?$'))
- expected_output = {'root@host1:/manila-share-1': {'size': None}}
-
- ret = self._layout._fetch_gluster_volumes()
-
- test_args = ('volume', 'list')
- self.gmgr1.gluster_call.assert_called_once_with(*test_args,
- log=mock.ANY)
- self.assertEqual(expected_output, ret)
-
- def test_fetch_gluster_volumes_error(self):
- test_args = ('volume', 'list')
-
- def raise_exception(*args, **kwargs):
- if(args == test_args):
- raise exception.GlusterfsException()
-
- self._layout.configuration.glusterfs_servers = [self.glusterfs_server1]
- self.mock_object(self.gmgr1, 'gluster_call',
- mock.Mock(side_effect=raise_exception))
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=self.gmgr1))
- self.mock_object(layout_volume.LOG, 'error')
-
- self.assertRaises(exception.GlusterfsException,
- self._layout._fetch_gluster_volumes)
-
- self.gmgr1.gluster_call.assert_called_once_with(*test_args,
- log=mock.ANY)
-
- def test_do_setup(self):
- self._layout.configuration.glusterfs_servers = [self.glusterfs_server1]
- self.mock_object(self.gmgr1, 'get_gluster_version',
- mock.Mock(return_value=('3', '6')))
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=self.gmgr1))
- self.mock_object(self._layout, '_fetch_gluster_volumes',
- mock.Mock(return_value=self.glusterfs_volumes_dict))
- self.mock_object(self._layout, '_check_mount_glusterfs')
- self._layout.gluster_used_vols = self.glusterfs_used_vols
- self.mock_object(layout_volume.LOG, 'warning')
-
- self._layout.do_setup(self._context)
-
- self._layout._fetch_gluster_volumes.assert_called_once_with(
- filter_used=False)
- self._layout._check_mount_glusterfs.assert_called_once_with()
- self.gmgr1.get_gluster_version.assert_called_once_with()
-
- def test_do_setup_unsupported_glusterfs_version(self):
- self._layout.configuration.glusterfs_servers = [self.glusterfs_server1]
- self.mock_object(self.gmgr1, 'get_gluster_version',
- mock.Mock(return_value=('3', '5')))
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=self.gmgr1))
-
- self.assertRaises(exception.GlusterfsException,
- self._layout.do_setup, self._context)
-
- self.gmgr1.get_gluster_version.assert_called_once_with()
-
- @ddt.data(exception.GlusterfsException, RuntimeError)
- def test_do_setup_get_gluster_version_fails(self, exc):
- def raise_exception(*args, **kwargs):
- raise exc
-
- self._layout.configuration.glusterfs_servers = [self.glusterfs_server1]
- self.mock_object(self.gmgr1, 'get_gluster_version',
- mock.Mock(side_effect=raise_exception))
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=self.gmgr1))
-
- self.assertRaises(exc, self._layout.do_setup, self._context)
-
- self.gmgr1.get_gluster_version.assert_called_once_with()
-
- def test_do_setup_glusterfs_no_volumes_provided_by_backend(self):
- self._layout.configuration.glusterfs_servers = [self.glusterfs_server1]
- self.mock_object(self.gmgr1, 'get_gluster_version',
- mock.Mock(return_value=('3', '6')))
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=self.gmgr1))
- self.mock_object(self._layout, '_fetch_gluster_volumes',
- mock.Mock(return_value={}))
-
- self.assertRaises(exception.GlusterfsException,
- self._layout.do_setup, self._context)
-
- self._layout._fetch_gluster_volumes.assert_called_once_with(
- filter_used=False)
-
- def test_share_manager(self):
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=self.gmgr1))
- self.mock_object(self._layout.private_storage,
- 'get', mock.Mock(return_value='host1:/gv1'))
-
- ret = self._layout._share_manager(self.share1)
-
- self._layout.private_storage.get.assert_called_once_with(
- self.share1['id'], 'volume')
- self._layout._glustermanager.assert_called_once_with('host1:/gv1')
- self.assertEqual(self.gmgr1, ret)
-
- def test_share_manager_no_privdata(self):
- self.mock_object(self._layout.private_storage,
- 'get', mock.Mock(return_value=None))
-
- ret = self._layout._share_manager(self.share1)
-
- self._layout.private_storage.get.assert_called_once_with(
- self.share1['id'], 'volume')
- self.assertIsNone(ret)
-
- def test_ensure_share(self):
- share = self.share1
- gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
- None, None)
- gmgr1.set_vol_option = mock.Mock()
- self.mock_object(self._layout, '_share_manager',
- mock.Mock(return_value=gmgr1))
-
- self._layout.ensure_share(self._context, share)
-
- self._layout._share_manager.assert_called_once_with(share)
- self.assertIn(self.glusterfs_target1, self._layout.gluster_used_vols)
- gmgr1.set_vol_option.assert_called_once_with(
- 'user.manila-share', share['id'])
-
- @ddt.data({"voldict": {"host:/share2G": {"size": 2}}, "used_vols": set(),
- "size": 1, "expected": "host:/share2G"},
- {"voldict": {"host:/share2G": {"size": 2}}, "used_vols": set(),
- "size": 2, "expected": "host:/share2G"},
- {"voldict": {"host:/share2G": {"size": 2}}, "used_vols": set(),
- "size": None, "expected": "host:/share2G"},
- {"voldict": {"host:/share2G": {"size": 2},
- "host:/share": {"size": None}},
- "used_vols": set(["host:/share2G"]), "size": 1,
- "expected": "host:/share"},
- {"voldict": {"host:/share2G": {"size": 2},
- "host:/share": {"size": None}},
- "used_vols": set(["host:/share2G"]), "size": 2,
- "expected": "host:/share"},
- {"voldict": {"host:/share2G": {"size": 2},
- "host:/share": {"size": None}},
- "used_vols": set(["host:/share2G"]), "size": 3,
- "expected": "host:/share"},
- {"voldict": {"host:/share2G": {"size": 2},
- "host:/share": {"size": None}},
- "used_vols": set(["host:/share2G"]), "size": None,
- "expected": "host:/share"},
- {"voldict": {"host:/share": {}}, "used_vols": set(), "size": 1,
- "expected": "host:/share"},
- {"voldict": {"host:/share": {}}, "used_vols": set(),
- "size": None, "expected": "host:/share"})
- @ddt.unpack
- def test_pop_gluster_vol(self, voldict, used_vols, size, expected):
- gmgr = common.GlusterManager
- gmgr1 = gmgr(expected, self._execute, None, None)
- self._layout._fetch_gluster_volumes = mock.Mock(return_value=voldict)
- self._layout.gluster_used_vols = used_vols
- self._layout._glustermanager = mock.Mock(return_value=gmgr1)
- self._layout.volume_pattern_keys = list(voldict.values())[0].keys()
-
- result = self._layout._pop_gluster_vol(size=size)
-
- self.assertEqual(expected, result)
- self.assertIn(result, used_vols)
- self._layout._fetch_gluster_volumes.assert_called_once_with()
- self._layout._glustermanager.assert_called_once_with(result)
-
- @ddt.data({"voldict": {"share2G": {"size": 2}},
- "used_vols": set(), "size": 3},
- {"voldict": {"share2G": {"size": 2}},
- "used_vols": set(["share2G"]), "size": None})
- @ddt.unpack
- def test_pop_gluster_vol_excp(self, voldict, used_vols, size):
- self._layout._fetch_gluster_volumes = mock.Mock(return_value=voldict)
- self._layout.gluster_used_vols = used_vols
- self._layout.volume_pattern_keys = list(voldict.values())[0].keys()
-
- self.assertRaises(exception.GlusterfsException,
- self._layout._pop_gluster_vol, size=size)
-
- self._layout._fetch_gluster_volumes.assert_called_once_with()
- self.assertFalse(
- self.fake_driver._setup_via_manager.called)
-
- def test_push_gluster_vol(self):
- self._layout.gluster_used_vols = set([
- self.glusterfs_target1, self.glusterfs_target2])
-
- self._layout._push_gluster_vol(self.glusterfs_target2)
-
- self.assertEqual(1, len(self._layout.gluster_used_vols))
- self.assertFalse(
- self.glusterfs_target2 in self._layout.gluster_used_vols)
-
- def test_push_gluster_vol_excp(self):
- self._layout.gluster_used_vols = set([self.glusterfs_target1])
- self._layout.gluster_unused_vols_dict = {}
-
- self.assertRaises(exception.GlusterfsException,
- self._layout._push_gluster_vol,
- self.glusterfs_target2)
-
- @ddt.data({'vers_minor': '6',
- 'cmd': ['find', '/tmp/tmpKGHKJ', '-mindepth', '1',
- '-delete']},
- {'vers_minor': '7',
- 'cmd': ['find', '/tmp/tmpKGHKJ', '-mindepth', '1', '!',
- '-path', '/tmp/tmpKGHKJ/.trashcan', '!', '-path',
- '/tmp/tmpKGHKJ/.trashcan/internal_op', '-delete']})
- @ddt.unpack
- def test_wipe_gluster_vol(self, vers_minor, cmd):
- tmpdir = '/tmp/tmpKGHKJ'
- gmgr = common.GlusterManager
- gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
- self._layout.glusterfs_versions = {
- self.glusterfs_server1: ('3', vers_minor)}
-
- self.mock_object(tempfile, 'mkdtemp',
- mock.Mock(return_value=tmpdir))
- self.mock_object(self.fake_driver, '_execute', mock.Mock())
- self.mock_object(common, '_mount_gluster_vol', mock.Mock())
- self.mock_object(common, '_umount_gluster_vol', mock.Mock())
- self.mock_object(shutil, 'rmtree', mock.Mock())
-
- self._layout._wipe_gluster_vol(gmgr1)
-
- tempfile.mkdtemp.assert_called_once_with()
- common._mount_gluster_vol.assert_called_once_with(
- self.fake_driver._execute, gmgr1.export,
- tmpdir)
- kwargs = {'run_as_root': True}
- self.fake_driver._execute.assert_called_once_with(
- *cmd, **kwargs)
- common._umount_gluster_vol.assert_called_once_with(
- self.fake_driver._execute, tmpdir)
- kwargs = {'ignore_errors': True}
- shutil.rmtree.assert_called_once_with(tmpdir,
- **kwargs)
-
- def test_wipe_gluster_vol_mount_fail(self):
- tmpdir = '/tmp/tmpKGHKJ'
- gmgr = common.GlusterManager
- gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
- self._layout.glusterfs_versions = {
- self.glusterfs_server1: ('3', '6')}
- self.mock_object(tempfile, 'mkdtemp',
- mock.Mock(return_value=tmpdir))
- self.mock_object(self.fake_driver, '_execute', mock.Mock())
- self.mock_object(common, '_mount_gluster_vol',
- mock.Mock(side_effect=exception.GlusterfsException))
- self.mock_object(common, '_umount_gluster_vol', mock.Mock())
- self.mock_object(shutil, 'rmtree', mock.Mock())
-
- self.assertRaises(exception.GlusterfsException,
- self._layout._wipe_gluster_vol,
- gmgr1)
-
- tempfile.mkdtemp.assert_called_once_with()
- common._mount_gluster_vol.assert_called_once_with(
- self.fake_driver._execute, gmgr1.export,
- tmpdir)
- self.assertFalse(self.fake_driver._execute.called)
- self.assertFalse(common._umount_gluster_vol.called)
- kwargs = {'ignore_errors': True}
- shutil.rmtree.assert_called_once_with(tmpdir,
- **kwargs)
-
- def test_wipe_gluster_vol_error_wiping_gluster_vol(self):
- tmpdir = '/tmp/tmpKGHKJ'
- gmgr = common.GlusterManager
- gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
- self._layout.glusterfs_versions = {
- self.glusterfs_server1: ('3', '6')}
- cmd = ['find', '/tmp/tmpKGHKJ', '-mindepth', '1', '-delete']
- self.mock_object(tempfile, 'mkdtemp',
- mock.Mock(return_value=tmpdir))
- self.mock_object(
- self.fake_driver, '_execute',
- mock.Mock(side_effect=exception.ProcessExecutionError))
- self.mock_object(common, '_mount_gluster_vol', mock.Mock())
- self.mock_object(common, '_umount_gluster_vol', mock.Mock())
- self.mock_object(shutil, 'rmtree', mock.Mock())
-
- self.assertRaises(exception.GlusterfsException,
- self._layout._wipe_gluster_vol,
- gmgr1)
-
- tempfile.mkdtemp.assert_called_once_with()
- common._mount_gluster_vol.assert_called_once_with(
- self.fake_driver._execute, gmgr1.export,
- tmpdir)
- kwargs = {'run_as_root': True}
- self.fake_driver._execute.assert_called_once_with(
- *cmd, **kwargs)
- common._umount_gluster_vol.assert_called_once_with(
- self.fake_driver._execute, tmpdir)
- kwargs = {'ignore_errors': True}
- shutil.rmtree.assert_called_once_with(tmpdir,
- **kwargs)
-
- def test_create_share(self):
- self._layout._pop_gluster_vol = mock.Mock(
- return_value=self.glusterfs_target1)
- gmgr1 = common.GlusterManager(self.glusterfs_target1)
- gmgr1.set_vol_option = mock.Mock()
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=gmgr1))
- self.mock_object(self.fake_driver, '_setup_via_manager',
- mock.Mock(return_value='host1:/gv1'))
-
- share = new_share()
- exp_locn = self._layout.create_share(self._context, share)
-
- self._layout._pop_gluster_vol.assert_called_once_with(share['size'])
- self.fake_driver._setup_via_manager.assert_called_once_with(
- {'manager': gmgr1, 'share': share})
- self._layout.private_storage.update.assert_called_once_with(
- share['id'], {'volume': self.glusterfs_target1})
- gmgr1.set_vol_option.assert_called_once_with(
- 'user.manila-share', share['id'])
- self.assertEqual('host1:/gv1', exp_locn)
-
- def test_create_share_error(self):
- self._layout._pop_gluster_vol = mock.Mock(
- side_effect=exception.GlusterfsException)
-
- share = new_share()
- self.assertRaises(exception.GlusterfsException,
- self._layout.create_share, self._context, share)
-
- self._layout._pop_gluster_vol.assert_called_once_with(
- share['size'])
-
- @ddt.data(None, '', 'Eeyore')
- def test_delete_share(self, clone_of):
- self._layout._push_gluster_vol = mock.Mock()
- self._layout._wipe_gluster_vol = mock.Mock()
- gmgr = common.GlusterManager
- gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
- gmgr1.set_vol_option = mock.Mock()
- gmgr1.get_vol_option = mock.Mock(return_value=clone_of)
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=gmgr1))
- self._layout.gluster_used_vols = set([self.glusterfs_target1])
-
- self._layout.delete_share(self._context, self.share1)
-
- gmgr1.get_vol_option.assert_called_once_with(
- 'user.manila-cloned-from')
- self._layout._wipe_gluster_vol.assert_called_once_with(gmgr1)
- self._layout._push_gluster_vol.assert_called_once_with(
- self.glusterfs_target1)
- self._layout.private_storage.delete.assert_called_once_with(
- self.share1['id'])
- gmgr1.set_vol_option.assert_has_calls([
- mock.call('user.manila-share', 'NONE'),
- mock.call('nfs.disable', 'on')
- ])
-
- def test_delete_share_clone(self):
- self._layout._push_gluster_vol = mock.Mock()
- self._layout._wipe_gluster_vol = mock.Mock()
- gmgr = common.GlusterManager
- gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
- gmgr1.gluster_call = mock.Mock()
- gmgr1.get_vol_option = mock.Mock(return_value=FAKE_UUID1)
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=gmgr1))
- self._layout.gluster_used_vols = set([self.glusterfs_target1])
-
- self._layout.delete_share(self._context, self.share1)
-
- gmgr1.get_vol_option.assert_called_once_with(
- 'user.manila-cloned-from')
- self.assertFalse(self._layout._wipe_gluster_vol.called)
- self._layout._push_gluster_vol.assert_called_once_with(
- self.glusterfs_target1)
- self._layout.private_storage.delete.assert_called_once_with(
- self.share1['id'])
- gmgr1.gluster_call.assert_called_once_with(
- 'volume', 'delete', 'gv1')
-
- def test_delete_share_error(self):
- self._layout._wipe_gluster_vol = mock.Mock()
- self._layout._wipe_gluster_vol.side_effect = (
- exception.GlusterfsException)
- self._layout._push_gluster_vol = mock.Mock()
- gmgr = common.GlusterManager
- gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
- gmgr1.get_vol_option = mock.Mock(return_value=None)
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=gmgr1))
- self._layout.gluster_used_vols = set([self.glusterfs_target1])
-
- self.assertRaises(exception.GlusterfsException,
- self._layout.delete_share, self._context,
- self.share1)
-
- self._layout._wipe_gluster_vol.assert_called_once_with(gmgr1)
- self.assertFalse(self._layout._push_gluster_vol.called)
-
- def test_delete_share_missing_record(self):
- self.mock_object(self._layout, '_share_manager',
- mock.Mock(return_value=None))
-
- self._layout.delete_share(self._context, self.share1)
-
- self._layout._share_manager.assert_called_once_with(self.share1)
-
- def test_create_snapshot(self):
- self._layout.gluster_nosnap_vols_dict = {}
- self._layout.glusterfs_versions = {self.glusterfs_server1: ('3', '6')}
- gmgr = common.GlusterManager
- gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
- self._layout.gluster_used_vols = set([self.glusterfs_target1])
- self.mock_object(gmgr1, 'gluster_call',
- mock.Mock(
- side_effect=(glusterXMLOut(ret=0, errno=0),)))
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=gmgr1))
-
- snapshot = {
- 'id': 'fake_snap_id',
- 'share_id': self.share1['id'],
- 'share': self.share1
- }
- ret = self._layout.create_snapshot(self._context, snapshot)
-
- self.assertIsNone(ret)
- args = ('--xml', 'snapshot', 'create', 'manila-fake_snap_id',
- gmgr1.volume)
- gmgr1.gluster_call.assert_called_once_with(*args, log=mock.ANY)
-
- @ddt.data({'side_effect': (glusterXMLOut(ret=-1, errno=2),),
- '_exception': exception.GlusterfsException},
- {'side_effect': (('', ''),),
- '_exception': exception.GlusterfsException})
- @ddt.unpack
- def test_create_snapshot_error(self, side_effect, _exception):
- self._layout.gluster_nosnap_vols_dict = {}
- self._layout.glusterfs_versions = {self.glusterfs_server1: ('3', '6')}
- gmgr = common.GlusterManager
- gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
- self._layout.gluster_used_vols = set([self.glusterfs_target1])
- self.mock_object(gmgr1, 'gluster_call',
- mock.Mock(side_effect=side_effect))
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=gmgr1))
-
- snapshot = {
- 'id': 'fake_snap_id',
- 'share_id': self.share1['id'],
- 'share': self.share1
- }
- self.assertRaises(_exception, self._layout.create_snapshot,
- self._context, snapshot)
-
- args = ('--xml', 'snapshot', 'create', 'manila-fake_snap_id',
- gmgr1.volume)
- gmgr1.gluster_call.assert_called_once_with(*args, log=mock.ANY)
-
- @ddt.data({"vers_minor": '6', "exctype": exception.GlusterfsException},
- {"vers_minor": '7',
- "exctype": exception.ShareSnapshotNotSupported})
- @ddt.unpack
- def test_create_snapshot_no_snap(self, vers_minor, exctype):
- self._layout.gluster_nosnap_vols_dict = {}
- self._layout.glusterfs_versions = {
- self.glusterfs_server1: ('3', vers_minor)}
- gmgr = common.GlusterManager
- gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
- self._layout.gluster_used_vols = set([self.glusterfs_target1])
- self.mock_object(gmgr1, 'gluster_call',
- mock.Mock(
- side_effect=(glusterXMLOut(ret=-1, errno=0),)))
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=gmgr1))
-
- snapshot = {
- 'id': 'fake_snap_id',
- 'share_id': self.share1['id'],
- 'share': self.share1
- }
- self.assertRaises(exctype, self._layout.create_snapshot, self._context,
- snapshot)
-
- args = ('--xml', 'snapshot', 'create', 'manila-fake_snap_id',
- gmgr1.volume)
- gmgr1.gluster_call.assert_called_once_with(*args, log=mock.ANY)
-
- @ddt.data({"vers_minor": '6', "exctype": exception.GlusterfsException},
- {"vers_minor": '7',
- "exctype": exception.ShareSnapshotNotSupported})
- @ddt.unpack
- def test_create_snapshot_no_snap_cached(self, vers_minor, exctype):
- self._layout.gluster_nosnap_vols_dict = {
- self.glusterfs_target1: 'fake error'}
- self._layout.glusterfs_versions = {
- self.glusterfs_server1: ('3', vers_minor)}
- self._layout.gluster_used_vols = set([self.glusterfs_target1])
- gmgr = common.GlusterManager
- gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
- self.mock_object(self._layout, '_share_manager',
- mock.Mock(return_value=gmgr1))
-
- snapshot = {
- 'id': 'fake_snap_id',
- 'share_id': self.share1['id'],
- 'share': self.share1
- }
- self.assertRaises(exctype, self._layout.create_snapshot, self._context,
- snapshot)
-
- def test_find_actual_backend_snapshot_name(self):
- 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', '')))
-
- snapshot = {
- 'id': 'fake_snap_id',
- 'share_id': self.share1['id'],
- 'share': self.share1
- }
- ret = self._layout._find_actual_backend_snapshot_name(gmgr1, snapshot)
-
- args = ('snapshot', 'list', gmgr1.volume, '--mode=script')
- gmgr1.gluster_call.assert_called_once_with(*args, log=mock.ANY)
- self.assertEqual('fake_snap_id_xyz', ret)
-
- @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 = common.GlusterManager
- gmgr1 = gmgr(self.share1['export_location'], self._execute, None, None)
- self.mock_object(gmgr1, 'gluster_call',
- mock.Mock(return_value=(snaplist, '')))
-
- snapshot = {
- 'id': 'fake_snap_id',
- 'share_id': self.share1['id'],
- 'share': self.share1
- }
- self.assertRaises(exception.GlusterfsException,
- self._layout._find_actual_backend_snapshot_name,
- gmgr1, snapshot)
-
- args = ('snapshot', 'list', gmgr1.volume, '--mode=script')
- gmgr1.gluster_call.assert_called_once_with(*args, log=mock.ANY)
-
- @ddt.data({'glusterfs_target': 'root@host1:/gv1',
- 'glusterfs_server': 'root@host1'},
- {'glusterfs_target': 'host1:/gv1',
- 'glusterfs_server': 'host1'})
- @ddt.unpack
- def test_create_share_from_snapshot(self, glusterfs_target,
- glusterfs_server):
- share = new_share()
- snapshot = {
- 'id': 'fake_snap_id',
- 'share_instance': new_share(export_location=glusterfs_target),
- 'share_id': 'fake_share_id',
- }
- volume = ''.join(['manila-', share['id']])
- new_vol_addr = ':/'.join([glusterfs_server, volume])
- gmgr = common.GlusterManager
- old_gmgr = gmgr(glusterfs_target, self._execute, None, None)
- new_gmgr = gmgr(new_vol_addr, self._execute, None, None)
- self._layout.gluster_used_vols = set([glusterfs_target])
- self._layout.glusterfs_versions = {glusterfs_server: ('3', '7')}
- self.mock_object(old_gmgr, 'gluster_call',
- mock.Mock(side_effect=[('', ''), ('', '')]))
- self.mock_object(new_gmgr, 'gluster_call',
- mock.Mock(side_effect=[('', ''), ('', ''), ('', '')]))
- self.mock_object(new_gmgr, 'get_vol_option',
- mock.Mock())
- new_gmgr.get_vol_option.return_value = (
- 'glusterfs-server-1,client')
- self.mock_object(self._layout, '_find_actual_backend_snapshot_name',
- mock.Mock(return_value='fake_snap_id_xyz'))
- self.mock_object(self._layout, '_share_manager',
- mock.Mock(return_value=old_gmgr))
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=new_gmgr))
- self.mock_object(self.fake_driver, '_setup_via_manager',
- mock.Mock(return_value='host1:/gv1'))
-
- ret = self._layout.create_share_from_snapshot(
- self._context, share, snapshot, None)
-
- (self._layout._find_actual_backend_snapshot_name.
- assert_called_once_with(old_gmgr, snapshot))
- args = (('snapshot', 'activate', 'fake_snap_id_xyz',
- 'force', '--mode=script'),
- ('snapshot', 'clone', volume, 'fake_snap_id_xyz'))
- old_gmgr.gluster_call.assert_has_calls(
- [mock.call(*a, log=mock.ANY) for a in args])
- args = (('volume', 'start', volume),
- ('volume', 'set', volume, 'user.manila-share', share['id']),
- ('volume', 'set', volume, 'user.manila-cloned-from',
- snapshot['share_id']))
- new_gmgr.gluster_call.assert_has_calls(
- [mock.call(*a, log=mock.ANY) for a in args], any_order=True)
- self._layout._share_manager.assert_called_once_with(
- snapshot['share_instance'])
- self._layout._glustermanager.assert_called_once_with(
- gmgr.parse(new_vol_addr))
- self._layout.driver._setup_via_manager.assert_called_once_with(
- {'manager': new_gmgr, 'share': share},
- {'manager': old_gmgr, 'share': snapshot['share_instance']})
- self._layout.private_storage.update.assert_called_once_with(
- share['id'], {'volume': new_vol_addr})
- self.assertIn(
- new_vol_addr,
- self._layout.gluster_used_vols)
- self.assertEqual('host1:/gv1', ret)
-
- def test_create_share_from_snapshot_error_unsupported_gluster_version(
- self):
- glusterfs_target = 'root@host1:/gv1'
- glusterfs_server = 'root@host1'
- share = new_share()
- volume = ''.join(['manila-', share['id']])
- new_vol_addr = ':/'.join([glusterfs_server, volume])
- gmgr = common.GlusterManager
- old_gmgr = gmgr(glusterfs_target, self._execute, None, None)
- new_gmgr = gmgr(new_vol_addr, self._execute, None, None)
- self._layout.gluster_used_vols_dict = {glusterfs_target: old_gmgr}
- self._layout.glusterfs_versions = {glusterfs_server: ('3', '6')}
- self.mock_object(
- old_gmgr, 'gluster_call',
- mock.Mock(side_effect=[('', ''), ('', '')]))
- self.mock_object(new_gmgr, 'get_vol_option',
- mock.Mock())
- new_gmgr.get_vol_option.return_value = (
- 'glusterfs-server-1,client')
- self.mock_object(self._layout, '_find_actual_backend_snapshot_name',
- mock.Mock(return_value='fake_snap_id_xyz'))
- self.mock_object(self._layout, '_share_manager',
- mock.Mock(return_value=old_gmgr))
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=new_gmgr))
-
- snapshot = {
- 'id': 'fake_snap_id',
- 'share_instance': new_share(export_location=glusterfs_target)
- }
- self.assertRaises(exception.GlusterfsException,
- self._layout.create_share_from_snapshot,
- self._context, share, snapshot)
-
- self.assertFalse(
- self._layout._find_actual_backend_snapshot_name.called)
- self.assertFalse(old_gmgr.gluster_call.called)
- self._layout._share_manager.assert_called_once_with(
- snapshot['share_instance'])
- self.assertFalse(self._layout._glustermanager.called)
- self.assertFalse(new_gmgr.get_vol_option.called)
- self.assertFalse(new_gmgr.gluster_call.called)
- self.assertNotIn(new_vol_addr,
- self._layout.glusterfs_versions.keys())
-
- def test_delete_snapshot(self):
- self._layout.gluster_nosnap_vols_dict = {}
- gmgr = common.GlusterManager
- gmgr1 = gmgr(self.share1['export_location'], self._execute, None, None)
- self._layout.gluster_used_vols = set([self.glusterfs_target1])
- self.mock_object(self._layout, '_find_actual_backend_snapshot_name',
- mock.Mock(return_value='fake_snap_id_xyz'))
- self.mock_object(
- gmgr1, 'gluster_call',
- mock.Mock(return_value=glusterXMLOut(ret=0, errno=0)))
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=gmgr1))
- snapshot = {
- 'id': 'fake_snap_id',
- 'share_id': self.share1['id'],
- 'share': self.share1
- }
- ret = self._layout.delete_snapshot(self._context, snapshot)
-
- self.assertIsNone(ret)
- args = ('--xml', 'snapshot', 'delete', 'fake_snap_id_xyz',
- '--mode=script')
- gmgr1.gluster_call.assert_called_once_with(*args, log=mock.ANY)
- (self._layout._find_actual_backend_snapshot_name.
- assert_called_once_with(gmgr1, snapshot))
-
- @ddt.data({'side_effect': (glusterXMLOut(ret=-1, errno=0),),
- '_exception': exception.GlusterfsException},
- {'side_effect': (('', ''),),
- '_exception': exception.GlusterfsException})
- @ddt.unpack
- def test_delete_snapshot_error(self, side_effect, _exception):
- self._layout.gluster_nosnap_vols_dict = {}
- gmgr = common.GlusterManager
- gmgr1 = gmgr(self.share1['export_location'], self._execute, None, None)
- self._layout.gluster_used_vols = set([self.glusterfs_target1])
- self.mock_object(self._layout, '_find_actual_backend_snapshot_name',
- mock.Mock(return_value='fake_snap_id_xyz'))
- args = ('--xml', 'snapshot', 'delete', 'fake_snap_id_xyz',
- '--mode=script')
- self.mock_object(
- gmgr1, 'gluster_call',
- mock.Mock(side_effect=side_effect))
- self.mock_object(self._layout, '_glustermanager',
- mock.Mock(return_value=gmgr1))
-
- snapshot = {
- 'id': 'fake_snap_id',
- 'share_id': self.share1['id'],
- 'share': self.share1
- }
- self.assertRaises(_exception, self._layout.delete_snapshot,
- self._context, snapshot)
-
- gmgr1.gluster_call.assert_called_once_with(*args, log=mock.ANY)
- (self._layout._find_actual_backend_snapshot_name.
- assert_called_once_with(gmgr1, snapshot))
-
- @ddt.data(
- ('manage_existing', ('share', 'driver_options'), {}),
- ('unmanage', ('share',), {}),
- ('extend_share', ('share', 'new_size'), {'share_server': None}),
- ('shrink_share', ('share', 'new_size'), {'share_server': None}))
- def test_nonimplemented_methods(self, method_invocation):
- method, args, kwargs = method_invocation
- self.assertRaises(NotImplementedError, getattr(self._layout, method),
- *args, **kwargs)
|