Merge "Fix volume deletion on newer iDRACs"

This commit is contained in:
Zuul 2023-01-04 21:41:51 +00:00 committed by Gerrit Code Review
commit 3f6f693ee8
3 changed files with 99 additions and 2 deletions

View File

@ -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.

View File

@ -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):

View File

@ -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):