Redfish: Adds 'read_raid_configuration' API to get current raid config

This commit adds functionality to verify the success of raid create
or delete operation and gets the current raid configuration on
SmartStorageConfig redfish based iLO.

Co-Authored-By: Paresh Sao <paresh.sao@hpe.com>
Change-Id: I9f546e8ef87229f442dc3855042cbe3ac3a198f8
This commit is contained in:
Anshul Jain 2018-01-18 04:14:52 -06:00 committed by paresh-sao
parent 8bda342451
commit 72ba876a58
13 changed files with 581 additions and 8 deletions

View File

@ -48,6 +48,7 @@ SUPPORTED_RIS_METHODS = [
'inject_nmi',
'insert_virtual_media',
'press_pwr_btn',
'read_raid_configuration',
'reset_bios_to_default',
'reset_ilo_credential',
'reset_secure_boot_keys',
@ -96,6 +97,7 @@ SUPPORTED_REDFISH_METHODS = [
'set_one_time_boot',
'update_persistent_boot',
'set_pending_boot_mode',
'read_raid_configuration',
'reset_ilo_credential',
'reset_bios_to_default',
'get_secure_boot_mode',
@ -110,7 +112,7 @@ SUPPORTED_REDFISH_METHODS = [
'unset_iscsi_boot_info',
'unset_iscsi_info',
'get_iscsi_initiator_info',
'set_iscsi_initiator_info',
'set_iscsi_initiator_info'
]
LOG = log.get_logger(__name__)
@ -669,6 +671,24 @@ class IloClient(operations.IloOperations):
"""
return self._call_method('create_raid_configuration', raid_config)
def read_raid_configuration(self, raid_config=None):
"""Read the logical drives from the system.
:param raid_config: None in case of post-delete read or in case of
post-create a dictionary containing target raid
configuration data. This data stucture should be as
follows:
raid_config = {'logical_disks': [{'raid_level': 1,
'size_gb': 100, 'physical_disks': ['6I:1:5'],
'controller': 'HPE Smart Array P408i-a SR Gen10'},
<info-for-logical-disk-2>]}
:raises: IloError, on an error from iLO.
:raises: IloCommandNotSupportedError, if the command is not supported
on the server.
:returns: A dictionary containing list of logical disks
"""
return self._call_method('read_raid_configuration', raid_config)
def update_firmware(self, firmware_url, component_type):
"""Updates the given firmware on the server

View File

@ -446,6 +446,25 @@ class IloOperations(object):
"""
raise exception.IloCommandNotSupportedError(ERRMSG)
def read_raid_configuration(self, raid_config=None):
"""Read the logical drives from the system
Read raid configuration of the hardware.
:param raid_config: None in case of post-delete read or in case of
post-create a dictionary containing target raid
configuration data. This data stucture should be as
follows:
raid_config = {'logical_disks': [{'raid_level': 1,
'size_gb': 100, 'physical_disks': ['6I:1:5'],
'controller': 'HPE Smart Array P408i-a SR Gen10'},
<info-for-logical-disk-2>]}
:raises: IloError, on an error from iLO.
:raises: IloCommandNotSupportedError, if the command is not supported
on the server.
"""
raise exception.IloCommandNotSupportedError(ERRMSG)
def delete_raid_configuration(self):
"""Deletes the logical drives from the system

View File

@ -1209,6 +1209,24 @@ class RIBCLOperations(operations.IloOperations):
"""
self._raise_command_not_supported("get_host_post_state")
def read_raid_configuration(self, raid_config=None):
"""Read the logical drives from the system
Read raid configuration of the hardware.
:param raid_config: None in case of post-delete read or in case of
post-create a dictionary containing target raid
configuration data. This data stucture should be as
follows:
raid_config = {'logical_disks': [{'raid_level': 1,
'size_gb': 100, 'physical_disks': ['6I:1:5'],
'controller': 'HPE Smart Array P408i-a SR Gen10'},
<info-for-logical-disk-2>]}
:raises: IloCommandNotSupportedError, if the command is not supported
on the server.
"""
self._raise_command_not_supported("read_raid_configuration")
def delete_raid_configuration(self):
"""Delete the raid configuration on the hardware.

View File

@ -1981,6 +1981,24 @@ class RISOperations(rest.RestConnectorBase, operations.IloOperations):
{'method': method, 'platform': platform})
raise (exception.IloCommandNotSupportedError(msg))
def read_raid_configuration(self, raid_config=None):
"""Read the logical drives from the system
Read raid configuration of the hardware.
:param raid_config: None in case of post-delete read or in case of
post-create a dictionary containing target raid
configuration data. This data stucture should be as
follows:
raid_config = {'logical_disks': [{'raid_level': 1,
'size_gb': 100, 'physical_disks': ['6I:1:5'],
'controller': 'HPE Smart Array P408i-a SR Gen10'},
<info-for-logical-disk-2>]}
:raises: IloCommandNotSupportedError, if the command is not supported
on the server.
"""
self._raise_command_not_supported("read_raid_configuration")
def delete_raid_configuration(self):
"""Delete the raid configuration on the hardware.

View File

@ -1052,6 +1052,23 @@ class RedfishOperations(operations.IloOperations):
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
return GET_POST_STATE_MAP.get(sushy_system.post_state)
def read_raid_configuration(self, raid_config=None):
"""Read the logical drives from the system
:param raid_config: None in case of post-delete read or in case of
post-create a dictionary containing target raid
configuration data. This data stucture should be as
follows:
raid_config = {'logical_disks': [{'raid_level': 1,
'size_gb': 100, 'physical_disks': ['6I:1:5'],
'controller': 'HPE Smart Array P408i-a SR Gen10'},
<info-for-logical-disk-2>]}
:raises: IloError, on an error from iLO.
:returns: A dictionary containing list of logical disks
"""
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
return sushy_system.read_raid(raid_config=raid_config)
def delete_raid_configuration(self):
"""Delete the raid configuration on the hardware."""
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)

View File

@ -33,13 +33,89 @@ class HPESmartStorageConfig(base.ResourceBase):
controller_id = base.Field("Id")
smart_storage_config_message = base.Field(['@Redfish.Settings',
'Messages'])
logical_drives = LogicalDriveListField("LogicalDrives", default=[])
location = base.Field("Location")
physical_drives = base.Field("PhysicalDrives", adapter=list, default=None)
settings_uri = base.Field(["@Redfish.Settings",
"SettingsObject", "@odata.id"])
def _generic_format(self, raid_config, controller=None):
"""Convert redfish data of current raid config to generic format.
:param raid_config: Raid configuration dictionary
:param controller: Array controller model in post_create read else
None
:returns: current raid config.
"""
logical_drives = raid_config["LogicalDrives"]
logical_disks = []
controller = controller
for ld in logical_drives:
prop = {'size_gb': ld['CapacityGiB'],
'raid_level': ld['Raid'].strip('Raid'),
'root_device_hint': {
'wwn': '0x' + ld['VolumeUniqueIdentifier']},
'controller': controller,
'physical_disks': ld['DataDrives'],
'volume_name': ld['LogicalDriveName']}
logical_disks.append(prop)
return logical_disks
def _check_smart_storage_message(self):
"""Check for smart storage message.
:returns: result, raid_message
"""
ssc_mesg = self.smart_storage_config_message
result = True
raid_message = ""
for element in ssc_mesg:
if "Success" not in element['MessageId']:
result = False
raid_message = element['MessageId']
return result, raid_message
def read_raid(self, controller=None):
"""Get the current RAID configuration from the system.
:param controller: If controller model its post-create read else
post-delete
:returns: current raid config.
"""
if controller:
if not self.logical_drives:
msg = ('No logical drives found on the controller')
LOG.debug(msg)
raise exception.IloLogicalDriveNotFoundError(msg)
raid_op = 'create_raid'
else:
raid_op = 'delete_raid'
result, raid_message = self._check_smart_storage_message()
if result:
configured_raid_settings = self._conn.get(self.settings_uri)
raid_data = {
'logical_disks': self._generic_format(
configured_raid_settings.json(), controller=controller)}
return raid_data
else:
if self.physical_drives is None or not raid_message:
# This controller is not configured or controller
# not used in raid operation
return
else:
msg = ('Failed to perform the %(opr)s operation '
'successfully. Error - %(error)s'
% {'opr': raid_op, 'error': str(raid_message)})
raise exception.IloError(msg)
def delete_raid(self):
"""Clears the RAID configuration from the system.

View File

@ -344,10 +344,11 @@ class HPESystem(system.System):
"""
ac = self.smart_storage.array_controllers.array_controller_by_model(
controller_model)
for ssc_id in self.smart_storage_config_identities:
ssc_obj = self.get_smart_storage_config(ssc_id)
if ac.location == ssc_obj.location:
return ssc_obj
if ac:
for ssc_id in self.smart_storage_config_identities:
ssc_obj = self.get_smart_storage_config(ssc_id)
if ac.location == ssc_obj.location:
return ssc_obj
def check_smart_storage_config_ids(self):
"""Check SmartStorageConfig controllers is there in hardware.
@ -454,3 +455,96 @@ class HPESystem(system.System):
'raid configuration for one or more controllers with '
'Error: %(error)s' % {'error': str(any_exceptions)})
raise exception.IloError(msg)
def _post_create_read_raid(self, raid_config):
"""Read the logical drives from the system after post-create raid
:param raid_config: A dictionary containing target raid configuration
data. This data stucture should be as follows:
raid_config = {'logical_disks': [{'raid_level': 1,
'size_gb': 100, 'physical_disks': ['6I:1:5'],
'controller': 'HPE Smart Array P408i-a SR Gen10'},
<info-for-logical-disk-2>]}
:raises: IloLogicalDriveNotFoundError, if no controllers are configured
:raises: IloError, if any error form iLO
:returns: A dictionary containing list of logical disks
"""
controllers = self._parse_raid_config_data(raid_config)
ld_exc_count = 0
any_exceptions = []
config = {'logical_disks': []}
for controller in controllers:
try:
ssc_obj = (
self._get_smart_storage_config_by_controller_model(
controller))
if ssc_obj:
result = ssc_obj.read_raid(controller=controller)
config['logical_disks'].extend(result['logical_disks'])
except exception.IloLogicalDriveNotFoundError as e:
ld_exc_count += 1
except sushy.exceptions.SushyError as e:
any_exceptions.append((controller, str(e)))
if ld_exc_count == len(controllers):
msg = 'No logical drives are found in any controllers.'
raise exception.IloLogicalDriveNotFoundError(msg)
if any_exceptions:
msg = ('The Redfish controller failed to read the '
'raid configuration in one or more controllers with '
'Error: %(error)s' % {'error': str(any_exceptions)})
raise exception.IloError(msg)
return config
def _post_delete_read_raid(self):
"""Read the logical drives from the system after post-delete raid
:raises: IloError, if any error form iLO
:returns: Empty dictionary with format: {'logical_disks': []}
"""
any_exceptions = []
ssc_ids = self.smart_storage_config_identities
config = {'logical_disks': []}
for ssc_id in ssc_ids:
try:
ssc_obj = self.get_smart_storage_config(ssc_id)
ac_obj = (
self.smart_storage.array_controllers.
array_controller_by_location(ssc_obj.location))
if ac_obj:
model = ac_obj.model
result = ssc_obj.read_raid()
if result:
config['logical_disks'].extend(result['logical_disks'])
except sushy.exceptions.SushyError as e:
any_exceptions.append((model, str(e)))
if any_exceptions:
msg = ('The Redfish controller failed to read the '
'raid configuration in one or more controllers with '
'Error: %(error)s' % {'error': str(any_exceptions)})
raise exception.IloError(msg)
return config
def read_raid(self, raid_config=None):
"""Read the logical drives from the system
:param raid_config: None or a dictionary containing target raid
configuration data. This data stucture should be as
follows:
raid_config = {'logical_disks': [{'raid_level': 1,
'size_gb': 100, 'physical_disks': ['6I:1:5'],
'controller': 'HPE Smart Array P408i-a SR Gen10'},
<info-for-logical-disk-2>]}
:returns: A dictionary containing list of logical disks
"""
self.check_smart_storage_config_ids()
if raid_config:
# When read called after create raid, user can pass raid config
# as a input
result = self._post_create_read_raid(raid_config=raid_config)
else:
# When read called after delete raid, there will be no input
# passed by user then
result = self._post_delete_read_raid()
return result

View File

@ -811,6 +811,38 @@ class IloClientTestCase(testtools.TestCase):
self.client.create_raid_configuration,
raid_config)
@mock.patch.object(client.IloClient, '_call_method')
def test_read_raid_configuration(self, call_mock):
ld1 = {"size_gb": 150, "raid_level": '0', "is_root_volume": True}
raid_config = {"logical_disks": [ld1]}
self.client.read_raid_configuration(raid_config)
call_mock.assert_called_once_with('read_raid_configuration',
raid_config)
@mock.patch.object(ris.RISOperations, 'get_product_name')
def test_read_raid_configuration_gen9(self, get_product_mock):
self.client.model = 'Gen9'
ld1 = {"size_gb": 150, "raid_level": '0', "is_root_volume": True}
raid_config = {"logical_disks": [ld1]}
get_product_mock.return_value = 'ProLiant BL460c Gen9'
self.assertRaisesRegexp(exception.IloCommandNotSupportedError,
'`read_raid_configuration` is not supported '
'on ProLiant BL460c Gen9',
self.client.read_raid_configuration,
raid_config)
@mock.patch.object(ribcl.RIBCLOperations, 'get_product_name')
def test_read_raid_configuration_gen8(self, get_product_mock):
self.client.model = 'Gen8'
ld1 = {"size_gb": 150, "raid_level": '0', "is_root_volume": True}
raid_config = {"logical_disks": [ld1]}
get_product_mock.return_value = 'ProLiant DL380 G8'
self.assertRaisesRegexp(exception.IloCommandNotSupportedError,
'`read_raid_configuration` is not supported '
'on ProLiant DL380 G8',
self.client.read_raid_configuration,
raid_config)
@mock.patch.object(ris.RISOperations, 'eject_virtual_media')
def test_eject_virtual_media_gen9(self, eject_virtual_media_mock):
self.client.model = 'Gen9'

View File

@ -1055,6 +1055,16 @@ class IloRibclTestCaseBeforeRisSupport(unittest.TestCase):
'ProLiant DL380 G7',
self.ilo.get_host_post_state)
@mock.patch.object(ribcl.RIBCLOperations, 'get_product_name')
def test_read_raid_configuration(self, product_name_mock):
ld1 = {"size_gb": 150, "raid_level": '0', "is_root_volume": True}
raid_config = {"logical_disks": [ld1]}
product_name_mock.return_value = constants.GET_PRODUCT_NAME
self.assertRaisesRegexp(exception.IloCommandNotSupportedError,
'ProLiant DL380 G7',
self.ilo.read_raid_configuration,
raid_config)
@mock.patch.object(ribcl.RIBCLOperations, 'get_product_name')
def test_delete_raid_configuration(self, product_name_mock):
product_name_mock.return_value = constants.GET_PRODUCT_NAME

View File

@ -2552,6 +2552,16 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
self.assertEqual(ret, expt_ret)
get_array_mock.assert_called_once_with()
@mock.patch.object(ris.RISOperations, 'get_product_name')
def test_read_raid_configuration(self, product_name_mock):
ld1 = {"size_gb": 150, "raid_level": '0', "is_root_volume": True}
raid_config = {"logical_disks": [ld1]}
product_name_mock.return_value = 'ProLiant BL460c Gen9'
self.assertRaisesRegexp(exception.IloCommandNotSupportedError,
'ProLiant BL460c Gen9',
self.client.read_raid_configuration,
raid_config)
@mock.patch.object(ris.RISOperations, 'get_product_name')
def test_delete_raid_configuration(self, product_name_mock):
product_name_mock.return_value = 'ProLiant BL460c Gen9'

View File

@ -38,8 +38,12 @@ class HPESmartStorageConfigTestCase(testtools.TestCase):
redfish_version='1.0.2')
def test_attributes(self):
physical_drive = [{'LegacyBootPriority': 'None',
'Location': '1I:1:2',
'LocationFormat': 'ControllerPort:Box:Bay'}]
self.assertEqual('smartstorageconfig', self.ssc_inst.controller_id)
self.assertEqual('Slot 0', self.ssc_inst.location)
self.assertEqual(physical_drive, self.ssc_inst.physical_drives)
self.assertEqual(
'600508B1001C045A9BAAC9F4F49498AE',
self.ssc_inst.logical_drives[0].volume_unique_identifier)
@ -102,3 +106,95 @@ class HPESmartStorageConfigTestCase(testtools.TestCase):
validate_mock.assert_called_once_with(raid_config)
self.ssc_inst._conn.put.assert_called_once_with(settings_uri,
data=data)
def test__generic_format_delete_scenario(self):
expected_data = []
raid_config = {"LogicalDrives": []}
self.assertEqual(expected_data,
self.ssc_inst._generic_format(raid_config))
def test__generic_format_create_scenario(self):
expected_data = [{'controller': 'HPE Smart Array P408i-p SR Gen10',
'physical_disks': [u'2I:1:2', u'2I:1:1'],
'raid_level': u'0',
'root_device_hint': {
'wwn': u'0x600508B1001C045A9BAAC9F4F49498AE'},
'size_gb': 2235,
'volume_name': u'01A27294PFJHD0ARCA218H 63E0'}]
result = self.ssc_inst._generic_format(
self.ssc_inst.json, controller='HPE Smart Array P408i-p SR Gen10')
self.assertEqual(expected_data, result)
def test__check_smart_storage_message(self):
result, mesg = self.ssc_inst._check_smart_storage_message()
self.assertEqual(True, result)
self.assertEqual("", mesg)
@mock.patch.object(smart_storage_config.HPESmartStorageConfig,
'_check_smart_storage_message', autospec=True)
@mock.patch.object(smart_storage_config.HPESmartStorageConfig,
'_generic_format', autospec=True)
def test_read_raid_post_create(self, format_mock, message_mock):
message_mock.return_value = True, 'Success'
ld1 = {"size_gb": 150, "raid_level": '0', "is_root_volume": True}
type(self.ssc_inst).logical_drives = mock.PropertyMock(
return_value=[ld1])
ld1['controller'] = 'HPE Smart Array P408i-p SR Gen10'
format_mock.return_value = [ld1]
expected = {'logical_disks': [ld1]}
self.assertEqual(
expected, self.ssc_inst.read_raid(controller=ld1['controller']))
self.assertTrue(message_mock.called)
self.assertTrue(format_mock.called)
@mock.patch.object(smart_storage_config.HPESmartStorageConfig,
'_check_smart_storage_message', autospec=True)
@mock.patch.object(smart_storage_config.HPESmartStorageConfig,
'_generic_format', autospec=True)
def test_read_raid_post_delete(self, format_mock, message_mock):
message_mock.return_value = True, 'Success'
format_mock.return_value = []
type(self.ssc_inst).logical_drives = mock.PropertyMock(
return_value=[])
expected = {'logical_disks': []}
self.assertEqual(expected, self.ssc_inst.read_raid())
self.assertTrue(message_mock.called)
self.assertTrue(format_mock.called)
@mock.patch.object(smart_storage_config.HPESmartStorageConfig,
'_check_smart_storage_message', autospec=True)
def test_read_raid_failed(self, message_mock):
ld1 = {"size_gb": 150, "raid_level": '0', "is_root_volume": True}
type(self.ssc_inst).logical_drives = mock.PropertyMock(
return_value=[ld1])
ld1['controller'] = 'HPE Smart Array P408i-p SR Gen10'
physical_drive = [{'LegacyBootPriority': 'None',
'Location': '1I:1:2',
'LocationFormat': 'ControllerPort:Box:Bay'}]
type(self.ssc_inst).physical_drives = mock.PropertyMock(
return_value=physical_drive)
message_mock.return_value = False, 'err_mesg'
self.assertRaisesRegexp(
exception.IloError,
'Failed to perform the create_raid operation successfully',
self.ssc_inst.read_raid, ld1['controller'])
def test_read_raid_logical_drive_not_found(self):
type(self.ssc_inst).logical_drives = mock.PropertyMock(
return_value=[])
model = 'HPE Smart Array P408i-p SR Gen10'
self.assertRaises(exception.IloLogicalDriveNotFoundError,
self.ssc_inst.read_raid, model)
@mock.patch.object(smart_storage_config.HPESmartStorageConfig,
'_check_smart_storage_message', autospec=True)
@mock.patch.object(smart_storage_config.HPESmartStorageConfig,
'_generic_format', autospec=True)
def test_read_raid_controller_not_configured_post_delete(
self, format_mock, message_mock):
message_mock.return_value = False, ''
type(self.ssc_inst).physical_drives = mock.PropertyMock(
return_value=None)
self.ssc_inst.read_raid()
self.assertTrue(message_mock.called)
self.assertFalse(format_mock.called)

View File

@ -616,6 +616,105 @@ class HPESystemTestCase(testtools.TestCase):
"configuration for one or more controllers with",
self.sys_inst.create_raid, raid_config)
@mock.patch.object(array_controller.HPEArrayControllerCollection,
'array_controller_by_location')
@mock.patch.object(system.HPESystem, 'get_smart_storage_config')
def test__post_delete_read_raid(
self, get_smart_storage_config_mock,
array_controller_by_location_mock):
config_id = ['/redfish/v1/systems/1/smartstorageconfig/']
with open('proliantutils/tests/redfish/'
'json_samples/smart_storage.json', 'r') as f:
ss_json = json.loads(f.read())
with open('proliantutils/tests/redfish/'
'json_samples/array_controller_collection.json', 'r') as f:
acc_json = json.loads(f.read())
self.conn.get.return_value.json.reset_mock()
self.conn.get.return_value.json.side_effect = [ss_json, acc_json]
type(get_smart_storage_config_mock.return_value).location = 'Slot 0'
model = 'HPE Smart Array P408i-a SR Gen10'
type(array_controller_by_location_mock.return_value).model = model
type(self.sys_inst).smart_storage_config_identities = (
mock.PropertyMock(return_value=config_id))
result = {'logical_disks': []}
(get_smart_storage_config_mock.
return_value.read_raid.return_value) = result
self.assertEqual(result, self.sys_inst._post_delete_read_raid())
get_smart_storage_config_mock.assert_called_once_with(config_id[0])
@mock.patch.object(system.HPESystem, '_parse_raid_config_data')
@mock.patch.object(system.HPESystem,
'_get_smart_storage_config_by_controller_model')
def test__post_create_read_raid(
self, get_ssc_by_controller_model_mock,
parse_raid_config_data_mock):
ld1 = {'raid_level': '0', 'is_root_volume': True,
'size_gb': 150,
'controller': 'HPE Smart Array P408i-p SR Gen10'}
raid_config = {'logical_disks': [ld1]}
parse_data = {'HPE Smart Array P408i-p SR Gen10': [ld1]}
parse_raid_config_data_mock.return_value = parse_data
result_ld1 = [{'size_gb': 149,
'physical_disks': [u'2I:1:1'],
'raid_level': u'0',
'controller': 'HPE Smart Array P408i-p SR Gen10',
'root_device_hint': {'wwn': u'0x600508B'},
'volume_name': u'01E6E63APFJHD'}]
result = {'logical_disks': result_ld1}
(get_ssc_by_controller_model_mock.
return_value.read_raid.return_value) = result
self.assertEqual(
result,
self.sys_inst._post_create_read_raid(raid_config=raid_config))
get_ssc_by_controller_model_mock.assert_called_once_with(
ld1['controller'])
@mock.patch.object(system.HPESystem, '_parse_raid_config_data')
@mock.patch.object(system.HPESystem,
'_get_smart_storage_config_by_controller_model')
def test__post_create_read_raid_logical_drive_not_found(
self, get_ssc_by_controller_model_mock,
parse_raid_config_data_mock):
ld1 = {'raid_level': '0', 'is_root_volume': True,
'size_gb': 150,
'controller': 'HPE Smart Array P408i-p SR Gen10'}
raid_config = {'logical_disks': [ld1]}
parse_data = {'HPE Smart Array P408i-p SR Gen10': [ld1]}
parse_raid_config_data_mock.return_value = parse_data
get_ssc_by_controller_model_mock.return_value.read_raid.side_effect = (
exception.IloLogicalDriveNotFoundError('No logical drive found'))
self.assertRaisesRegex(
exception.IloError,
"No logical drives are found in any controllers.",
self.sys_inst._post_create_read_raid, raid_config)
@mock.patch.object(array_controller.HPEArrayControllerCollection,
'array_controller_by_location')
@mock.patch.object(system.HPESystem, 'get_smart_storage_config')
def test__post_delete_read_raid_failed(
self, get_smart_storage_config_mock,
array_controller_by_location_mock):
config_id = ['/redfish/v1/systems/1/smartstorageconfig/']
with open('proliantutils/tests/redfish/'
'json_samples/smart_storage.json', 'r') as f:
ss_json = json.loads(f.read())
with open('proliantutils/tests/redfish/'
'json_samples/array_controller_collection.json', 'r') as f:
acc_json = json.loads(f.read())
self.conn.get.return_value.json.reset_mock()
self.conn.get.return_value.json.side_effect = [ss_json, acc_json]
model = 'HPE Smart Array P408i-a SR Gen10'
type(array_controller_by_location_mock.return_value).model = model
type(self.sys_inst).smart_storage_config_identities = (
mock.PropertyMock(return_value=config_id))
get_smart_storage_config_mock.return_value.read_raid.side_effect = (
sushy.exceptions.SushyError)
self.assertRaisesRegexp(
exception.IloError,
"The Redfish controller failed to read the "
"raid configuration in one or more controllers with Error:",
self.sys_inst._post_delete_read_raid)
@mock.patch.object(system.HPESystem, 'check_smart_storage_config_ids')
@mock.patch.object(system.HPESystem, '_parse_raid_config_data')
@mock.patch.object(system.HPESystem,
@ -678,9 +777,60 @@ class HPESystemTestCase(testtools.TestCase):
self.conn.get.return_value.json.reset_mock()
self.conn.get.return_value.json.side_effect = [ss_json, acc_json]
type(array_controller_by_model_mock.return_value).location = 'Slot 0'
ssc_obj_mock = mock.Mock(location='Slot 0')
get_smart_storage_config_mock.return_value = ssc_obj_mock
type(get_smart_storage_config_mock.return_value).location = 'Slot 0'
self.assertEqual(
ssc_obj_mock.location,
'Slot 0',
self.sys_inst._get_smart_storage_config_by_controller_model(
'HPE Smart Array P408i-a SR Gen10').location)
@mock.patch.object(system.HPESystem, '_parse_raid_config_data')
@mock.patch.object(system.HPESystem,
'_get_smart_storage_config_by_controller_model')
def test__post_create_read_raid_failed_with_raid_config(
self, get_ssc_by_controller_model_mock,
parse_raid_config_data_mock):
ld1 = {'raid_level': '0', 'is_root_volume': True,
'size_gb': 150,
'controller': 'HPE Smart Array P408i-p SR Gen10'}
raid_config = {'logical_disks': [ld1]}
parse_data = {'HPE Smart Array P408i-p SR Gen10': [ld1]}
parse_raid_config_data_mock.return_value = parse_data
(get_ssc_by_controller_model_mock.
return_value.read_raid.side_effect) = sushy.exceptions.SushyError
self.assertRaisesRegexp(
exception.IloError,
"The Redfish controller failed to read the "
"raid configuration in one or more controllers with Error:",
self.sys_inst._post_create_read_raid, raid_config=raid_config)
@mock.patch.object(system.HPESystem, '_post_create_read_raid')
@mock.patch.object(system.HPESystem, 'check_smart_storage_config_ids')
def test_read_raid_post_create(
self, check_smart_storage_config_ids_mock,
post_create_read_raid_mock):
check_smart_storage_config_ids_mock.return_value = None
ld1 = {'raid_level': '0', 'is_root_volume': True,
'size_gb': 150,
'controller': 'HPE Smart Array P408i-p SR Gen10'}
raid_config = {'logical_disks': [ld1]}
result_ld1 = [{'size_gb': 149,
'physical_disks': [u'2I:1:1'],
'raid_level': u'0',
'controller': 'HPE Smart Array P408i-p SR Gen10',
'root_device_hint': {'wwn': u'0x600508B'},
'volume_name': u'01E6E63APFJHD'}]
result = {'logical_disks': result_ld1}
post_create_read_raid_mock.return_value = result
self.assertEqual(
result, self.sys_inst.read_raid(raid_config=raid_config))
@mock.patch.object(system.HPESystem, '_post_delete_read_raid')
@mock.patch.object(system.HPESystem, 'check_smart_storage_config_ids')
def test_read_raid_post_delete(
self, check_smart_storage_config_ids_mock,
post_delete_read_raid_mock):
check_smart_storage_config_ids_mock.return_value = None
result = {'logical_disks': []}
post_delete_read_raid_mock.return_value = result
self.assertEqual(
result, self.sys_inst.read_raid())

View File

@ -1683,3 +1683,16 @@ class RedfishOperationsTestCase(testtools.TestCase):
self.rf_client.create_raid_configuration(raid_config)
get_system_mock.return_value.create_raid.assert_called_once_with(
raid_config)
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
def test_read_raid_configuration(self, get_system_mock):
result_ld1 = [{'size_gb': 149,
'physical_disks': [u'2I:1:1'],
'raid_level': u'0',
'root_device_hint': {'wwn': u'0x600508B'},
'controller': u'Smart Storage Controller in Slot 1',
'volume_name': u'01E6E63APFJHD'}]
config = {'logical_disks': result_ld1}
expected = [('HPE Smart Array P408i-p SR Gen10', config)]
get_system_mock.return_value.read_raid.return_value = expected
self.assertEqual(expected, self.rf_client.read_raid_configuration())