Merge "Fix volume deletion on newer iDRACs"
This commit is contained in:
commit
3f6f693ee8
|
@ -0,0 +1,4 @@
|
|||
fixes:
|
||||
- |
|
||||
Fixes 'Unsupported parameter name @Redfish.OperationApplyTime' error
|
||||
on iDRAC firmware version 6.00.02.00 or newer when deleting volumes.
|
|
@ -136,8 +136,22 @@ class Volume(base.ResourceBase):
|
|||
if (payload and payload.get(_OAT_PROP)
|
||||
== res_cons.ApplyTime.IMMEDIATE.value):
|
||||
blocking = True
|
||||
r = self._conn.delete(self._path, data=payload, blocking=blocking,
|
||||
timeout=timeout)
|
||||
try:
|
||||
r = self._conn.delete(self._path, data=payload,
|
||||
blocking=blocking, timeout=timeout)
|
||||
except exceptions.ServerSideError as exc:
|
||||
if (_OAT_PROP in str(exc.message)
|
||||
and 'SYS029' in str(exc.message)):
|
||||
LOG.debug('Retry volume delete without %(prop)s for %(path)s '
|
||||
'because got error: %(err)s',
|
||||
{'prop': _OAT_PROP,
|
||||
'path': self._path,
|
||||
'err': exc})
|
||||
payload.pop(_OAT_PROP)
|
||||
r = self._conn.delete(self._path, data=payload,
|
||||
blocking=blocking, timeout=timeout)
|
||||
else:
|
||||
raise exc
|
||||
return r
|
||||
|
||||
def delete(self, payload=None, apply_time=None, timeout=500):
|
||||
|
|
|
@ -16,6 +16,7 @@ from unittest import mock
|
|||
from dateutil import parser
|
||||
|
||||
import sushy
|
||||
from sushy import exceptions
|
||||
from sushy.resources import constants as res_cons
|
||||
from sushy.resources.system.storage import constants as store_cons
|
||||
from sushy.resources.system.storage import volume
|
||||
|
@ -106,6 +107,84 @@ class VolumeTestCase(base.TestCase):
|
|||
self.assertEqual(task_mon.task_monitor_uri,
|
||||
'/redfish/v1/taskmon/4608f7e6')
|
||||
|
||||
@mock.patch.object(volume.LOG, 'debug', autospec=True)
|
||||
def test_delete_retry_on_501_sys029_apply_time(self, mock_debug):
|
||||
payload = {}
|
||||
_OAT_PROP = '@Redfish.OperationApplyTime'
|
||||
payload[_OAT_PROP] = 'Immediate'
|
||||
target_uri = '/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes/1'
|
||||
response_info = {"error": {"@Message.ExtendedInfo": [
|
||||
{'Message': '@Redfish.OperationApplyTime.',
|
||||
'MessageId': 'IDRAC.2.7.SYS029'}]}}
|
||||
mock_error = mock.Mock()
|
||||
mock_error.status_code = 501
|
||||
mock_error.json.return_value = response_info
|
||||
mock_success = mock.Mock()
|
||||
mock_success.status_code = 201
|
||||
self.conn.delete.side_effect = [exceptions.ServerSideError(
|
||||
method='DELETE', url=target_uri, response=mock_error),
|
||||
mock_success]
|
||||
|
||||
resource = self.stor_volume.delete(
|
||||
payload=payload, apply_time=res_cons.ApplyTime.IMMEDIATE)
|
||||
|
||||
self.assertIsNone(resource)
|
||||
self.assertEqual(2, self.stor_volume._conn.delete.call_count)
|
||||
expected_calls = [
|
||||
mock.call(self.stor_volume._path, data=payload, blocking=True,
|
||||
timeout=500),
|
||||
mock.call(self.stor_volume._path, data={}, blocking=True,
|
||||
timeout=500)
|
||||
]
|
||||
self.stor_volume._conn.delete.assert_has_calls(expected_calls)
|
||||
mock_debug.assert_called_once()
|
||||
|
||||
@mock.patch.object(volume.LOG, 'debug', autospec=True)
|
||||
def test_delete_retry_on_501_sys029_other(self, mock_debug):
|
||||
payload = {}
|
||||
_OAT_PROP = '@Redfish.OperationApplyTime'
|
||||
payload[_OAT_PROP] = 'Immediate'
|
||||
target_uri = '/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes/1'
|
||||
response_info = {"error": {"@Message.ExtendedInfo": [
|
||||
{'Message': '@Redfish.SomethingElse.',
|
||||
'MessageId': 'IDRAC.2.7.SYS029'}]}}
|
||||
mock_error = mock.Mock()
|
||||
mock_error.status_code = 501
|
||||
mock_error.json.return_value = response_info
|
||||
mock_success = mock.Mock()
|
||||
mock_success.status_code = 201
|
||||
self.conn.delete.side_effect = [exceptions.ServerSideError(
|
||||
method='DELETE', url=target_uri, response=mock_error),
|
||||
mock_success]
|
||||
|
||||
self.assertRaises(exceptions.ServerSideError, self.stor_volume.delete,
|
||||
payload=payload,
|
||||
apply_time=res_cons.ApplyTime.IMMEDIATE)
|
||||
self.stor_volume._conn.delete.assert_called_once_with(
|
||||
self.stor_volume._path, data=payload, blocking=True, timeout=500)
|
||||
mock_debug.assert_not_called()
|
||||
|
||||
@mock.patch.object(volume.LOG, 'debug', autospec=True)
|
||||
def test_delete_raise_on_501_other(self, mock_debug):
|
||||
payload = {}
|
||||
_OAT_PROP = '@Redfish.OperationApplyTime'
|
||||
payload[_OAT_PROP] = 'Immediate'
|
||||
target_uri = '/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes/1'
|
||||
response_info = {"error": {"@Message.ExtendedInfo": [
|
||||
{'Message': 'Other message.'}]}}
|
||||
mock_error = mock.Mock()
|
||||
mock_error.status_code = 501
|
||||
mock_error.json.return_value = response_info
|
||||
self.conn.delete.side_effect = [exceptions.ServerSideError(
|
||||
method='DELETE', url=target_uri, response=mock_error)]
|
||||
|
||||
self.assertRaises(exceptions.ServerSideError, self.stor_volume.delete,
|
||||
payload=payload,
|
||||
apply_time=res_cons.ApplyTime.IMMEDIATE)
|
||||
self.stor_volume._conn.delete.assert_called_once_with(
|
||||
self.stor_volume._path, data=payload, blocking=True, timeout=500)
|
||||
mock_debug.assert_not_called()
|
||||
|
||||
|
||||
class VolumeCollectionTestCase(base.TestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue