Fix HNAS driver inconsistent exceptions

Fix following scenarios:

- Driver raises ProcessExecutionError
- Driver serializes the exception and passes to LOG.exception
- Driver does not handle several commands possible failure
- Driver does not log some error situations

Also, slightly improvements with regards to affected tests:

- Improved coverage
- Improved resource names passed to exception messages

Change-Id: I7fd9945d4cd6953e6fb33020d44f2d4472da27c7
Closes-bug: #1660952
This commit is contained in:
Rodrigo Barbieri 2017-02-01 10:07:18 -02:00
parent 6b4171bff2
commit c6c022fa8e
4 changed files with 256 additions and 85 deletions

View File

@ -23,7 +23,7 @@ import six
from manila.common import constants
from manila import exception
from manila.i18n import _, _LE, _LI, _LW
from manila.i18n import _, _LI, _LW
from manila.share import driver
from manila.share import utils
@ -833,12 +833,10 @@ class HitachiHNASDriver(driver.ShareDriver):
self.hnas.cifs_share_add(share_id, snapshot_id=snapshot_id)
LOG.debug("CIFS share created to %(shr)s.",
{'shr': share_id})
except exception.HNASBackendException as e:
except exception.HNASBackendException:
with excutils.save_and_reraise_exception():
if snapshot_id is None:
self.hnas.vvol_delete(share_id)
msg = six.text_type(e)
LOG.exception(msg)
def _check_fs_mounted(self):
mounted = self.hnas.check_fs_mounted()
@ -1061,10 +1059,6 @@ class HitachiHNASDriver(driver.ShareDriver):
self.hnas.cifs_share_add(share['id'])
except exception.HNASBackendException:
with excutils.save_and_reraise_exception():
msg = _LE('Failed to create share %(share_id)s from snapshot '
'%(snap)s.')
LOG.exception(msg, {'share_id': share['id'],
'snap': hnas_snapshot_id})
self.hnas.vvol_delete(share['id'])
return self._get_export_locations(

View File

@ -55,7 +55,13 @@ class HNASSSHBackend(object):
dedupe = True if dedupe is enabled on filesystem.
"""
command = ['df', '-a', '-f', self.fs_name]
output, err = self._execute(command)
try:
output, err = self._execute(command)
except processutils.ProcessExecutionError:
msg = _("Could not get HNAS backend stats.")
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
line = output.split('\n')
fs = Filesystem(line[3])
@ -74,7 +80,7 @@ class HNASSSHBackend(object):
try:
self._execute(command)
except processutils.ProcessExecutionError:
msg = _("Could not create NFS export %s.") % share_id
msg = _("Could not create NFS export %s.") % name
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
@ -95,7 +101,7 @@ class HNASSSHBackend(object):
LOG.warning(_LW("Export %s does not exist on "
"backend anymore."), name)
else:
msg = six.text_type(e)
msg = _("Could not delete NFS export %s.") % name
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
@ -111,7 +117,7 @@ class HNASSSHBackend(object):
try:
self._execute(command)
except processutils.ProcessExecutionError:
msg = _("Could not create CIFS share %s.") % share_id
msg = _("Could not create CIFS share %s.") % name
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
@ -125,7 +131,7 @@ class HNASSSHBackend(object):
LOG.warning(_LW("CIFS share %s does not exist on "
"backend anymore."), name)
else:
msg = six.text_type(e)
msg = _("Could not delete CIFS share %s.") % name
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
@ -156,7 +162,12 @@ class HNASSSHBackend(object):
command.append(string_command)
command.append(name)
self._execute(command)
try:
self._execute(command)
except processutils.ProcessExecutionError:
msg = _("Could not update access rules for NFS export %s.") % name
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
def cifs_allow_access(self, name, user, permission, is_snapshot=False):
command = ['cifs-saa', 'add', '--target-label', self.fs_name,
@ -168,26 +179,43 @@ class HNASSSHBackend(object):
if 'already listed as a user' in e.stderr:
if is_snapshot:
LOG.debug('User %(user)s already allowed to access '
'snapshot %(snapshot)s.',
{'user': user, 'snapshot': name})
'snapshot %(snapshot)s.', {
'user': user,
'snapshot': name,
})
else:
self._update_cifs_rule(name, user, permission)
else:
msg = six.text_type(e)
entity_type = "share"
if is_snapshot:
entity_type = "snapshot"
msg = _("Could not add access of user %(user)s to "
"%(entity_type)s %(name)s.") % {
'user': user,
'name': name,
'entity_type': entity_type,
}
LOG.exception(msg)
raise exception.InvalidShareAccess(reason=msg)
raise exception.HNASBackendException(msg=msg)
def _update_cifs_rule(self, name, user, permission):
LOG.debug('User %(user)s already allowed to access '
'share %(share)s. Updating access level...',
{'user': user, 'share': name})
'share %(share)s. Updating access level...', {
'user': user,
'share': name,
})
command = ['cifs-saa', 'change', '--target-label', self.fs_name,
name, user, permission]
try:
self._execute(command)
except processutils.ProcessExecutionError:
msg = _("Could not update CIFS rule access for user %s.") % user
msg = _("Could not update access of user %(user)s to "
"share %(share)s.") % {
'user': user,
'share': name,
}
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
@ -205,11 +233,18 @@ class HNASSSHBackend(object):
if ('not listed as a user' in e.stderr or
'Could not delete user/group' in e.stderr):
LOG.warning(_LW('User %(user)s already not allowed to access '
'%(entity_type)s %(share)s.'),
{'entity_type': entity_type, 'user': user,
'share': name})
'%(entity_type)s %(name)s.'), {
'entity_type': entity_type,
'user': user,
'name': name
})
else:
msg = six.text_type(e)
msg = _("Could not delete access of user %(user)s to "
"%(entity_type)s %(name)s.") % {
'user': user,
'name': name,
'entity_type': entity_type,
}
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
@ -224,7 +259,7 @@ class HNASSSHBackend(object):
'added.', {'share': hnas_share_id})
return []
else:
msg = six.text_type(e)
msg = _("Could not list access of share %s.") % hnas_share_id
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
@ -240,10 +275,12 @@ class HNASSSHBackend(object):
except processutils.ProcessExecutionError as e:
if ('Cannot find any clonable files in the source directory' in
e.stderr):
msg = _("Source path %s is empty") % src_path
msg = _("Source path %s is empty.") % src_path
LOG.debug(msg)
raise exception.HNASNothingToCloneException(msg=msg)
else:
msg = six.text_type(e)
msg = _("Could not submit tree clone job to clone from %(src)s"
" to %(dest)s.") % {'src': src_path, 'dest': dest_path}
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
@ -277,8 +314,8 @@ class HNASSSHBackend(object):
self._execute(command)
LOG.error(_LE("Timeout in snapshot creation from "
"source path %s.") % src_path)
msg = (_("Share snapshot of source path %s "
"was not created.") % src_path)
msg = _("Share snapshot of source path %s "
"was not created.") % src_path
raise exception.HNASBackendException(msg=msg)
else:
time.sleep(job_rechecks ** 2)
@ -297,8 +334,8 @@ class HNASSSHBackend(object):
else:
LOG.error(_LE('Error creating snapshot of source path %s.'),
src_path)
msg = (_('Snapshot of source path %s was not created.') %
src_path)
msg = _('Snapshot of source path %s was not '
'created.') % src_path
raise exception.HNASBackendException(msg=msg)
def tree_delete(self, path):
@ -311,9 +348,10 @@ class HNASSSHBackend(object):
LOG.warning(_LW("Attempted to delete path %s "
"but it does not exist."), path)
else:
msg = six.text_type(e)
msg = _("Could not submit tree delete job to delete path "
"%s.") % path
LOG.exception(msg)
raise
raise exception.HNASBackendException(msg=msg)
def create_directory(self, dest_path):
self._locked_selectfs('create', dest_path)
@ -338,15 +376,18 @@ class HNASSSHBackend(object):
{'path': path, 'out': e.stdout})
return False
else:
raise
msg = _("Could not check if path %s exists.") % path
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
return True
def check_fs_mounted(self):
command = ['df', '-a', '-f', self.fs_name]
output, err = self._execute(command)
if "not found" in output:
msg = (_("Filesystem %s does not exist or it is not available "
"in the current EVS context.") % self.fs_name)
msg = _("Filesystem %s does not exist or it is not available "
"in the current EVS context.") % self.fs_name
LOG.error(msg)
raise exception.HNASItemNotFoundException(msg=msg)
else:
line = output.split('\n')
@ -359,16 +400,21 @@ class HNASSSHBackend(object):
self._execute(command)
except processutils.ProcessExecutionError as e:
if 'file system is already mounted' not in e.stderr:
msg = six.text_type(e)
msg = _("Failed to mount filesystem %s.") % self.fs_name
LOG.exception(msg)
raise
raise exception.HNASBackendException(msg=msg)
def vvol_create(self, vvol_name):
# create a virtual-volume inside directory
path = '/shares/' + vvol_name
command = ['virtual-volume', 'add', '--ensure', self.fs_name,
vvol_name, path]
self._execute(command)
try:
self._execute(command)
except processutils.ProcessExecutionError:
msg = _("Failed to create vvol %s.") % vvol_name
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
def vvol_delete(self, vvol_name):
path = '/shares/' + vvol_name
@ -379,43 +425,61 @@ class HNASSSHBackend(object):
self._execute(command)
except processutils.ProcessExecutionError as e:
if 'Source path: Cannot access' in e.stderr:
LOG.debug("Share %(shr)s does not exist.",
{'shr': vvol_name})
LOG.warning(_LW("Share %s does not exist."), vvol_name)
else:
msg = six.text_type(e)
msg = _("Failed to delete vvol %s.") % vvol_name
LOG.exception(msg)
raise e
raise exception.HNASBackendException(msg=msg)
def quota_add(self, vvol_name, vvol_quota):
str_quota = six.text_type(vvol_quota) + 'G'
command = ['quota', 'add', '--usage-limit',
str_quota, '--usage-hard-limit',
'yes', self.fs_name, vvol_name]
self._execute(command)
try:
self._execute(command)
except processutils.ProcessExecutionError:
msg = _("Failed to add %(quota)s quota to vvol "
"%(vvol)s.") % {'quota': str_quota, 'vvol': vvol_name}
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
def modify_quota(self, vvol_name, new_size):
str_quota = six.text_type(new_size) + 'G'
command = ['quota', 'mod', '--usage-limit', str_quota,
self.fs_name, vvol_name]
self._execute(command)
try:
self._execute(command)
except processutils.ProcessExecutionError:
msg = _("Failed to update quota of vvol %(vvol)s to "
"%(quota)s.") % {'quota': str_quota, 'vvol': vvol_name}
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
def check_vvol(self, vvol_name):
command = ['virtual-volume', 'list', '--verbose', self.fs_name,
vvol_name]
try:
self._execute(command)
except processutils.ProcessExecutionError as e:
msg = six.text_type(e)
except processutils.ProcessExecutionError:
msg = _("Virtual volume %s does not exist.") % vvol_name
LOG.exception(msg)
msg = (_("Virtual volume %s does not exist.") % vvol_name)
raise exception.HNASItemNotFoundException(msg=msg)
def check_quota(self, vvol_name):
command = ['quota', 'list', '--verbose', self.fs_name, vvol_name]
output, err = self._execute(command)
try:
output, err = self._execute(command)
except processutils.ProcessExecutionError:
msg = _("Could not check quota of vvol %s.") % vvol_name
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
if 'No quotas matching specified filter criteria' in output:
msg = (_("Virtual volume %s does not have any quota.") % vvol_name)
msg = _("Virtual volume %s does not have any"
" quota.") % vvol_name
LOG.error(msg)
raise exception.HNASItemNotFoundException(msg=msg)
def check_export(self, vvol_name, is_snapshot=False):
@ -425,6 +489,7 @@ class HNASSSHBackend(object):
return
else:
msg = _("Export %s does not exist.") % export[0].export_name
LOG.error(msg)
raise exception.HNASItemNotFoundException(msg=msg)
def check_cifs(self, vvol_name):
@ -437,6 +502,7 @@ class HNASSSHBackend(object):
"configured filesystem "
"%(fs)s.") % {'share': vvol_name,
'fs': self.fs_name}
LOG.error(msg)
raise exception.HNASItemNotFoundException(msg=msg)
def is_cifs_in_use(self, vvol_name):
@ -455,9 +521,13 @@ class HNASSSHBackend(object):
msg = _("CIFS share %(share)s was not found in EVS "
"%(evs_id)s") % {'share': vvol_name,
'evs_id': self.evs_id}
LOG.exception(msg)
raise exception.HNASItemNotFoundException(msg=msg)
else:
raise
msg = _("Could not list CIFS shares by vvol name "
"%s.") % vvol_name
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
return output
@ -475,8 +545,9 @@ class HNASSSHBackend(object):
elif quota.limit_unit == 'GB':
return quota.limit
else:
msg = (_("Share %s does not support quota values "
"below 1G.") % share_id)
msg = _("Share %s does not support quota values "
"below 1G.") % share_id
LOG.error(msg)
raise exception.HNASBackendException(msg=msg)
def get_share_usage(self, share_id):
@ -486,7 +557,8 @@ class HNASSSHBackend(object):
quota = Quota(output)
if quota.usage is None:
msg = (_("Virtual volume %s does not have any quota.") % share_id)
msg = _("Virtual volume %s does not have any quota.") % share_id
LOG.error(msg)
raise exception.HNASItemNotFoundException(msg=msg)
else:
bytes_usage = strutils.string_to_bytes(six.text_type(quota.usage) +
@ -506,11 +578,16 @@ class HNASSSHBackend(object):
except processutils.ProcessExecutionError as e:
if 'does not exist' in e.stderr:
msg = _("Export %(name)s was not found in EVS "
"%(evs_id)s.") % {'name': name,
'evs_id': self.evs_id}
"%(evs_id)s.") % {
'name': name,
'evs_id': self.evs_id,
}
LOG.exception(msg)
raise exception.HNASItemNotFoundException(msg=msg)
else:
raise
msg = _("Could not list NFS exports by name %s.") % name
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
items = output.split('Export name')
if items[0][0] == '\n':
@ -526,7 +603,7 @@ class HNASSSHBackend(object):
if self.admin_ip0 is not None:
command = ['ssc', '--smuauth', self.admin_ip0]
command = command + ['console-context', '--evs', self.evs_id]
command += ['console-context', '--evs', self.evs_id]
commands = command + commands
mutils.check_ssh_injection(commands)
@ -545,22 +622,26 @@ class HNASSSHBackend(object):
out, err = processutils.ssh_execute(ssh, commands,
check_exit_code=True)
LOG.debug("Command %(cmd)s result: out = %(out)s - err = "
"%(err)s.", {'cmd': commands,
'out': out, 'err': err})
"%(err)s.", {
'cmd': commands,
'out': out,
'err': err,
})
return out, err
except processutils.ProcessExecutionError as e:
if 'Failed to establish SSC connection' in e.stderr:
LOG.debug("SSC connection error!")
msg = _("Failed to establish SSC connection.")
LOG.debug(msg)
raise exception.HNASConnException(msg=msg)
else:
LOG.debug("Command %(cmd)s result: out = %(out)s - err = "
"%(err)s - exit = %(exit)s.", {'cmd': e.cmd,
'out': e.stdout,
'err': e.stderr,
'exit':
e.exit_code})
LOG.error(_LE("Error running SSH command."))
LOG.debug("Error running SSH command. "
"Command %(cmd)s result: out = %(out)s - err = "
"%(err)s - exit = %(exit)s.", {
'cmd': e.cmd,
'out': e.stdout,
'err': e.stderr,
'exit': e.exit_code,
})
raise
@mutils.synchronized("hitachi_hnas_select_fs", external=True)
@ -569,7 +650,12 @@ class HNASSSHBackend(object):
command = ['selectfs', self.fs_name, '\n',
'ssc', '127.0.0.1', 'console-context', '--evs',
self.evs_id, 'mkdir', '-p', path]
self._execute(command)
try:
self._execute(command)
except processutils.ProcessExecutionError:
msg = _("Failed to create directory %s.") % path
LOG.exception(msg)
raise exception.HNASBackendException(msg=msg)
if op == 'delete':
command = ['selectfs', self.fs_name, '\n',
@ -585,9 +671,9 @@ class HNASSSHBackend(object):
LOG.warning(_LW("Attempted to delete path %s but it does "
"not exist."), path)
else:
msg = six.text_type(e)
msg = _("Failed to delete directory %s.") % path
LOG.exception(msg)
raise
raise exception.HNASBackendException(msg=msg)
class Export(object):

View File

@ -455,7 +455,6 @@ class HitachiHNASTestCase(test.TestCase):
self.assertRaises(exception.HNASBackendException,
self._driver.create_share, 'context', share_nfs)
self.assertTrue(self.mock_log.debug.called)
self.assertTrue(self.mock_log.exception.called)
ssh.HNASSSHBackend.vvol_create.assert_called_once_with(share_nfs['id'])
ssh.HNASSSHBackend.quota_add.assert_called_once_with(share_nfs['id'],
share_nfs['size'])

View File

@ -539,6 +539,18 @@ class HNASSSHTestCase(test.TestCase):
self.assertEqual(5120.0, free)
self.assertTrue(dedupe)
def test_get_stats_error(self):
fake_list_command = ['df', '-a', '-f', self.fs_name]
self.mock_object(ssh.HNASSSHBackend, '_execute',
mock.Mock(side_effect=putils.ProcessExecutionError))
self.assertRaises(exception.HNASBackendException,
self._driver_ssh.get_stats)
ssh.HNASSSHBackend._execute.assert_called_with(fake_list_command)
@ddt.data(True, False)
def test_nfs_export_add(self, is_snapshot):
if is_snapshot:
@ -694,11 +706,24 @@ class HNASSSHTestCase(test.TestCase):
self._driver_ssh._execute.assert_called_with(fake_export_command)
def test_update_nfs_access_rule_exception(self):
def test_update_nfs_access_rule_exception_no_share_provided(self):
self.assertRaises(exception.HNASBackendException,
self._driver_ssh.update_nfs_access_rule,
['127.0.0.1'])
def test_update_nfs_access_rule_exception_error(self):
fake_export_command = ['nfs-export', 'mod', '-c',
u'"127.0.0.1,127.0.0.2"', '/shares/fake_id']
self.mock_object(ssh.HNASSSHBackend, "_execute", mock.Mock(
side_effect=putils.ProcessExecutionError))
self.assertRaises(exception.HNASBackendException,
self._driver_ssh.update_nfs_access_rule,
['127.0.0.1', '127.0.0.2'], share_id="fake_id")
self._driver_ssh._execute.assert_called_with(fake_export_command)
def test_cifs_allow_access(self):
fake_cifs_allow_command = ['cifs-saa', 'add', '--target-label',
self.fs_name, 'vvol_test',
@ -738,7 +763,7 @@ class HNASSSHTestCase(test.TestCase):
stderr='Could not add user/group fake_user to '
'share \'vvol_test\'')]))
self.assertRaises(exception.InvalidShareAccess,
self.assertRaises(exception.HNASBackendException,
self._driver_ssh.cifs_allow_access, 'vvol_test',
'fake_user', 'acr')
@ -931,7 +956,7 @@ class HNASSSHTestCase(test.TestCase):
stderr='')]
))
self.assertRaises(putils.ProcessExecutionError,
self.assertRaises(exception.HNASBackendException,
self._driver_ssh.tree_delete, "/path")
self.assertTrue(self.mock_log.exception.called)
self._driver_ssh._execute.assert_called_with(fake_tree_delete_command)
@ -1009,7 +1034,7 @@ class HNASSSHTestCase(test.TestCase):
mock.Mock(side_effect=putils.ProcessExecutionError(
stdout="Internal Server Error.")))
self.assertRaises(putils.ProcessExecutionError,
self.assertRaises(exception.HNASBackendException,
self._driver_ssh.check_snapshot, path)
self._driver_ssh._execute.assert_called_with(check_snap_args)
@ -1040,7 +1065,9 @@ class HNASSSHTestCase(test.TestCase):
self.mock_object(ssh.HNASSSHBackend, "_execute", mock.Mock(
side_effect=putils.ProcessExecutionError(stderr='')))
self.assertRaises(putils.ProcessExecutionError, self._driver_ssh.mount)
self.assertRaises(
exception.HNASBackendException, self._driver_ssh.mount)
self._driver_ssh._execute.assert_called_with(fake_mount_command)
def test_vvol_create(self):
@ -1052,6 +1079,17 @@ class HNASSSHTestCase(test.TestCase):
self._driver_ssh._execute.assert_called_with(fake_vvol_create_command)
def test_vvol_create_error(self):
fake_vvol_create_command = ['virtual-volume', 'add', '--ensure',
self.fs_name, 'vvol', '/shares/vvol']
self.mock_object(ssh.HNASSSHBackend, "_execute",
mock.Mock(side_effect=putils.ProcessExecutionError))
self.assertRaises(exception.HNASBackendException,
self._driver_ssh.vvol_create, "vvol")
self._driver_ssh._execute.assert_called_with(fake_vvol_create_command)
def test_vvol_delete_vvol_does_not_exist(self):
fake_vvol_delete_command = ['tree-delete-job-submit', '--confirm',
'-f', self.fs_name, '/shares/vvol']
@ -1073,7 +1111,7 @@ class HNASSSHTestCase(test.TestCase):
stderr='')]
))
self.assertRaises(putils.ProcessExecutionError,
self.assertRaises(exception.HNASBackendException,
self._driver_ssh.vvol_delete, "vvol")
self.assertTrue(self.mock_log.exception.called)
self._driver_ssh._execute.assert_called_with(fake_vvol_delete_command)
@ -1097,6 +1135,29 @@ class HNASSSHTestCase(test.TestCase):
self._driver_ssh._execute.assert_called_with(fake_modify_quota_command)
def test_quota_add_error(self):
fake_add_quota_command = ['quota', 'add', '--usage-limit', '1G',
'--usage-hard-limit', 'yes',
self.fs_name, 'vvol']
self.mock_object(ssh.HNASSSHBackend, "_execute",
mock.Mock(side_effect=putils.ProcessExecutionError))
self.assertRaises(exception.HNASBackendException,
self._driver_ssh.quota_add, 'vvol', 1)
self._driver_ssh._execute.assert_called_with(fake_add_quota_command)
def test_modify_quota_error(self):
fake_modify_quota_command = ['quota', 'mod', '--usage-limit', '1G',
self.fs_name, 'vvol']
self.mock_object(ssh.HNASSSHBackend, "_execute",
mock.Mock(side_effect=putils.ProcessExecutionError))
self.assertRaises(exception.HNASBackendException,
self._driver_ssh.modify_quota, 'vvol', 1)
self._driver_ssh._execute.assert_called_with(fake_modify_quota_command)
def test_check_vvol(self):
fake_check_vvol_command = ['virtual-volume', 'list', '--verbose',
self.fs_name, 'vvol']
@ -1117,6 +1178,16 @@ class HNASSSHTestCase(test.TestCase):
self._driver_ssh.check_quota, 'vvol')
self._driver_ssh._execute.assert_called_with(fake_check_quota_command)
def test_check_quota_error(self):
fake_check_quota_command = ['quota', 'list', '--verbose',
self.fs_name, 'vvol']
self.mock_object(ssh.HNASSSHBackend, "_execute", mock.Mock(
side_effect=putils.ProcessExecutionError))
self.assertRaises(exception.HNASBackendException,
self._driver_ssh.check_quota, 'vvol')
self._driver_ssh._execute.assert_called_with(fake_check_quota_command)
@ddt.data(True, False)
def test_check_export(self, is_snapshot):
self.mock_object(ssh.HNASSSHBackend, "_get_export", mock.Mock(
@ -1159,7 +1230,7 @@ class HNASSSHTestCase(test.TestCase):
self.mock_object(ssh.HNASSSHBackend, '_execute', mock.Mock(
side_effect=[putils.ProcessExecutionError(stderr='Error.')]))
self.assertRaises(putils.ProcessExecutionError,
self.assertRaises(exception.HNASBackendException,
self._driver_ssh.check_cifs, 'wrong_vvol')
self._driver_ssh._execute.assert_called_with(check_cifs_share_command)
@ -1288,7 +1359,7 @@ class HNASSSHTestCase(test.TestCase):
side_effect=putils.ProcessExecutionError(stderr="Some error.")
))
self.assertRaises(putils.ProcessExecutionError,
self.assertRaises(exception.HNASBackendException,
self._driver_ssh._get_export, 'fake_id')
def test__execute(self):
@ -1336,7 +1407,6 @@ class HNASSSHTestCase(test.TestCase):
check_exit_code=True)
self.assertTrue(self.mock_log.debug.called)
self.assertTrue(self.mock_log.error.called)
def test__locked_selectfs_create_operation(self):
exec_command = ['selectfs', self.fs_name, '\n', 'ssc', '127.0.0.1',
@ -1348,7 +1418,19 @@ class HNASSSHTestCase(test.TestCase):
self._driver_ssh._execute.assert_called_with(exec_command)
def test__locked_selectfs_delete_operation_successfull(self):
def test__locked_selectfs_create_operation_error(self):
exec_command = ['selectfs', self.fs_name, '\n', 'ssc', '127.0.0.1',
'console-context', '--evs', six.text_type(self.evs_id),
'mkdir', '-p', '/path']
self.mock_object(ssh.HNASSSHBackend, '_execute',
mock.Mock(side_effect=putils.ProcessExecutionError))
self.assertRaises(exception.HNASBackendException,
self._driver_ssh._locked_selectfs, 'create', '/path')
self._driver_ssh._execute.assert_called_with(exec_command)
def test__locked_selectfs_delete_operation_successful(self):
exec_command = ['selectfs', self.fs_name, '\n', 'ssc', '127.0.0.1',
'console-context', '--evs', six.text_type(self.evs_id),
'rmdir', '/path']
@ -1369,11 +1451,21 @@ class HNASSSHTestCase(test.TestCase):
self.assertTrue(self.mock_log.debug.called)
def test__locked_selectfs_delete_exception(self):
msg = 'rmdir: cannot remove \'/path\''
msg = "rmdir: cannot remove '/path'"
self.mock_object(ssh.HNASSSHBackend, '_execute', mock.Mock(
side_effect=[putils.ProcessExecutionError(stderr=msg)]))
self.assertRaises(putils.ProcessExecutionError,
self.assertRaises(exception.HNASBackendException,
self._driver_ssh._locked_selectfs, 'delete', 'path')
self.assertTrue(self.mock_log.exception.called)
def test__locked_selectfs_delete_not_found(self):
msg = "rmdir: NotFound '/path'"
self.mock_object(ssh.HNASSSHBackend, '_execute', mock.Mock(
side_effect=[putils.ProcessExecutionError(stderr=msg)]))
self._driver_ssh._locked_selectfs('delete', 'path')
self.assertTrue(self.mock_log.warning.called)