Merge "HP 3PAR driver fix for delete snapshot"

This commit is contained in:
Jenkins 2015-02-25 21:21:27 +00:00 committed by Gerrit Code Review
commit 8d6e27318c
3 changed files with 224 additions and 6 deletions

View File

@ -403,11 +403,14 @@ class HP3ParMediator(object):
path = share['sharePath'][1:].split('/')
dot_snapshot_index = 3
else:
path = share['shareDir'].split('/')
if share['shareDir']:
path = share['shareDir'].split('/')
else:
path = None
dot_snapshot_index = 0
snapshot_index = dot_snapshot_index
if len(path) > snapshot_index + 1:
snapshot_index = dot_snapshot_index + 1
if path and len(path) > snapshot_index:
if (path[dot_snapshot_index] == '.snapshot' and
path[snapshot_index].endswith(snapshot_tag)):
msg = (_('Cannot delete snapshot because it has a '

View File

@ -31,7 +31,7 @@ EXPECTED_IP_1234 = '1.2.3.4'
EXPECTED_IP_127 = '127.0.0.1'
EXPECTED_SHARE_ID = 'osf-share-id'
EXPECTED_SHARE_NAME = 'share-name'
EXPECTED_SHARE_PATH = '/share/path'
EXPECTED_SHARE_PATH = '/anyfpg/anyvfs/anyfstore'
EXPECTED_SIZE_1 = 1
EXPECTED_SIZE_2 = 2
EXPECTED_SNAP_NAME = 'osf-snap-name'

View File

@ -325,6 +325,24 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mock_client.assert_has_calls(expected_calls)
def test_mediator_create_share_from_snap_not_found(self):
self.init_mediator()
self.mock_client.getfsnap.return_value = {
'message': None,
'total': 0,
'members': []
}
self.assertRaises(exception.ShareBackendException,
self.mediator.create_share_from_snapshot,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SNAP_ID,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
def test_mediator_delete_share(self):
self.init_mediator()
@ -362,6 +380,20 @@ class HP3ParMediatorTestCase(test.TestCase):
]
self.mock_client.assert_has_calls(expected_calls)
def test_mediator_create_snapshot_backend_exception(self):
self.init_mediator()
# createfsnap exception
self.mock_client.createfsnap.side_effect = Exception(
'createfsnap fail.')
self.assertRaises(exception.ShareBackendException,
self.mediator.create_snapshot,
constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
def test_mediator_delete_snapshot(self):
self.init_mediator()
@ -369,10 +401,21 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mock_client.getfsnap.return_value = {
'total': 1,
'members': [{'snapName': expected_name_from_array}],
'message': None
'members': [{'snapName': expected_name_from_array}]
}
self.mock_client.getfshare.side_effect = [
# some typical independent NFS share (path) and SMB share (dir)
{
'total': 1,
'members': [{'sharePath': '/anyfpg/anyvfs/anyfstore'}]
},
{
'total': 1,
'members': [{'shareDir': []}],
}
]
self.mediator.delete_snapshot(constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
@ -401,6 +444,178 @@ class HP3ParMediatorTestCase(test.TestCase):
]
self.mock_client.assert_has_calls(expected_calls)
def test_mediator_delete_snapshot_not_found(self):
self.init_mediator()
self.mock_client.getfsnap.return_value = {
'total': 0,
'members': [],
}
self.mediator.delete_snapshot(constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call.getfsnap('*_%s' % constants.EXPECTED_SNAP_NAME,
vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG,
pat=True,
fstore=constants.EXPECTED_SHARE_ID),
]
# Code coverage for early exit when nothing to delete.
self.mock_client.assert_has_calls(expected_calls)
self.assertFalse(self.mock_client.getfshare.called)
self.assertFalse(self.mock_client.removefsnap.called)
self.assertFalse(self.mock_client.startfsnapclean.called)
def test_mediator_delete_snapshot_shared_nfs(self):
self.init_mediator()
# Mock a share under this snapshot for NFS
snapshot_dir = '.snapshot/DT_%s' % constants.EXPECTED_SNAP_NAME
snapshot_path = '%s/%s' % (constants.EXPECTED_SHARE_PATH, snapshot_dir)
self.mock_client.getfsnap.return_value = {
'total': 1,
'members': [{'snapName': constants.EXPECTED_SNAP_NAME}]
}
self.mock_client.getfshare.side_effect = [
# some typical independent NFS share (path) and SMB share (dir)
{
'total': 1,
'members': [{'sharePath': snapshot_path}],
},
{
'total': 0,
'members': [],
}
]
self.assertRaises(exception.Invalid,
self.mediator.delete_snapshot,
constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
def test_mediator_delete_snapshot_shared_smb(self):
self.init_mediator()
# Mock a share under this snapshot for SMB
snapshot_dir = '.snapshot/DT_%s' % constants.EXPECTED_SNAP_NAME
self.mock_client.getfsnap.return_value = {
'total': 1,
'members': [{'snapName': constants.EXPECTED_SNAP_NAME}]
}
self.mock_client.getfshare.side_effect = [
# some typical independent NFS share (path) and SMB share (dir)
{
'total': 1,
'members': [{'sharePath': constants.EXPECTED_SHARE_PATH}],
},
{
'total': 1,
'members': [{'shareDir': snapshot_dir}],
}
]
self.assertRaises(exception.Invalid,
self.mediator.delete_snapshot,
constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
def _assert_delete_snapshot_raises(self):
self.assertRaises(exception.ShareBackendException,
self.mediator.delete_snapshot,
constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
def test_mediator_delete_snapshot_backend_exceptions(self):
self.init_mediator()
# getfsnap exception
self.mock_client.getfsnap.side_effect = Exception('getfsnap fail.')
self._assert_delete_snapshot_raises()
# getfsnap OK
self.mock_client.getfsnap.side_effect = None
self.mock_client.getfsnap.return_value = {
'total': 1,
'members': [{'snapName': constants.EXPECTED_SNAP_NAME}]
}
# getfshare exception
self.mock_client.getfshare.side_effect = Exception('getfshare fail.')
self._assert_delete_snapshot_raises()
# getfshare OK
def mock_fshare(*args, **kwargs):
if args[0] == constants.NFS_LOWER:
return {
'total': 1,
'members': [{'sharePath': '/anyfpg/anyvfs/anyfstore'}]
}
else:
return {
'total': 1,
'members': [{'shareDir': []}]
}
self.mock_client.getfshare.side_effect = mock_fshare
# removefsnap exception
self.mock_client.removefsnap.side_effect = Exception(
'removefsnap fail.')
self._assert_delete_snapshot_raises()
# removefsnap OK
self.mock_client.removefsnap.side_effect = None
self.mock_client.removefsnap.return_value = []
# startfsnapclean exception (logged, not raised)
self.mock_client.startfsnapclean.side_effect = Exception(
'startfsnapclean fail.')
mock_log = self.mock_object(hp3parmediator, 'LOG')
self.mediator.delete_snapshot(constants.EXPECTED_SHARE_ID,
constants.EXPECTED_SNAP_NAME,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call.getfsnap('*_%s' % constants.EXPECTED_SNAP_NAME,
vfs=constants.EXPECTED_VFS,
fpg=constants.EXPECTED_FPG,
pat=True,
fstore=constants.EXPECTED_SHARE_ID),
mock.call.getfshare(constants.NFS_LOWER,
fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID),
mock.call.getfshare(constants.SMB_LOWER,
fpg=constants.EXPECTED_FPG,
vfs=constants.EXPECTED_VFS,
fstore=constants.EXPECTED_SHARE_ID),
mock.call.removefsnap(constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_ID,
fpg=constants.EXPECTED_FPG,
snapname=constants.EXPECTED_SNAP_NAME),
mock.call.startfsnapclean(constants.EXPECTED_FPG,
reclaimStrategy='maxspeed'),
]
self.mock_client.assert_has_calls(expected_calls)
mock_log.assert_has_calls(mock.call.exception(mock.ANY))
def test_mediator_get_capacity(self):
"""Mediator converts client stats to capacity result."""
expected_capacity = constants.EXPECTED_SIZE_2