Redfish: Adds 'delete_raid_configuration' API to clear raid
The commit adds functionality to delete logical drives in a SmartStorageConfig redfish systems. Co-Authored-By: Paresh Sao <paresh.sao@hpe.com> Change-Id: Id3a07ab0ca1c0ad8199a28ef2efb22aadc5edfd5
This commit is contained in:
parent
21549e746d
commit
2cf3a473c9
|
@ -80,6 +80,16 @@ class IloCommandNotSupportedInBiosError(IloCommandNotSupportedError):
|
|||
super(IloCommandNotSupportedInBiosError, self).__init__(message)
|
||||
|
||||
|
||||
class IloLogicalDriveNotFoundError(IloError):
|
||||
"""Logical drive not found error.
|
||||
|
||||
This exception is raised when iLO client library unable to find
|
||||
any logical drive on storage controller
|
||||
"""
|
||||
def __init__(self, message, errorcode=None):
|
||||
super(IloLogicalDriveNotFoundError, self).__init__(message)
|
||||
|
||||
|
||||
class IloLoginFailError(IloError):
|
||||
"""iLO Login Failed.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
# Copyright 2018 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -25,6 +25,7 @@ from proliantutils.redfish import redfish
|
|||
SUPPORTED_RIS_METHODS = [
|
||||
'activate_license',
|
||||
'clear_secure_boot_keys',
|
||||
'delete_raid_configuration',
|
||||
'eject_virtual_media',
|
||||
'get_current_bios_settings',
|
||||
'get_current_boot_mode',
|
||||
|
@ -68,6 +69,7 @@ SUPPORTED_RIS_METHODS = [
|
|||
]
|
||||
|
||||
SUPPORTED_REDFISH_METHODS = [
|
||||
'delete_raid_configuration',
|
||||
'get_product_name',
|
||||
'get_host_post_state',
|
||||
'get_host_power_status',
|
||||
|
@ -637,6 +639,15 @@ class IloClient(operations.IloOperations):
|
|||
"""
|
||||
return self._call_method('activate_license', key)
|
||||
|
||||
def delete_raid_configuration(self):
|
||||
"""Deletes the logical drives from the system
|
||||
|
||||
:raises: IloError, on an error from iLO.
|
||||
:raises: IloCommandNotSupportedError, if the command is not supported
|
||||
on the server.
|
||||
"""
|
||||
return self._call_method('delete_raid_configuration')
|
||||
|
||||
def update_firmware(self, firmware_url, component_type):
|
||||
"""Updates the given firmware on the server
|
||||
|
||||
|
|
|
@ -445,3 +445,12 @@ class IloOperations(object):
|
|||
on the server.
|
||||
"""
|
||||
raise exception.IloCommandNotSupportedError(ERRMSG)
|
||||
|
||||
def delete_raid_configuration(self):
|
||||
"""Deletes the logical drives from the system
|
||||
|
||||
:raises: IloError, on an error from iLO.
|
||||
:raises: IloCommandNotSupportedError, if the command is
|
||||
not supported on the server.
|
||||
"""
|
||||
raise exception.IloCommandNotSupportedError(ERRMSG)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
# Copyright 2018 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -1209,6 +1209,17 @@ class RIBCLOperations(operations.IloOperations):
|
|||
"""
|
||||
self._raise_command_not_supported("get_host_post_state")
|
||||
|
||||
def delete_raid_configuration(self):
|
||||
"""Delete the raid configuration on the hardware.
|
||||
|
||||
Loops through each SmartStorageConfig controller and clears the
|
||||
raid configuration.
|
||||
|
||||
:raises: IloError, on an error from iLO
|
||||
:raises: IloCommandNotSupportedError
|
||||
"""
|
||||
self._raise_command_not_supported("delete_raid_configuration")
|
||||
|
||||
|
||||
# The below block of code is there only for backward-compatibility
|
||||
# reasons (before commit 47608b6 for ris-support).
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2017 Hewlett Packard Enterprise Development Company, L.P.
|
||||
# Copyright 2018 Hewlett Packard Enterprise Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -1974,3 +1974,20 @@ class RISOperations(rest.RestConnectorBase, operations.IloOperations):
|
|||
return utils.apply_bios_properties_filter(
|
||||
default_settings, constants.SUPPORTED_BIOS_PROPERTIES)
|
||||
return default_settings
|
||||
|
||||
def _raise_command_not_supported(self, method):
|
||||
platform = self.get_product_name()
|
||||
msg = ("`%(method)s` is not supported on %(platform)s" %
|
||||
{'method': method, 'platform': platform})
|
||||
raise (exception.IloCommandNotSupportedError(msg))
|
||||
|
||||
def delete_raid_configuration(self):
|
||||
"""Delete the raid configuration on the hardware.
|
||||
|
||||
Loops through each SmartStorageConfig controller and clears the
|
||||
raid configuration.
|
||||
|
||||
:raises: IloError, on an error from iLO
|
||||
:raises: IloCommandNotSupportedError
|
||||
"""
|
||||
self._raise_command_not_supported("delete_raid_configuration")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2017 Hewlett Packard Enterprise Development LP
|
||||
# Copyright 2018 Hewlett Packard Enterprise Development LP
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -1050,3 +1050,8 @@ class RedfishOperations(operations.IloOperations):
|
|||
"""
|
||||
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
|
||||
return GET_POST_STATE_MAP.get(sushy_system.post_state)
|
||||
|
||||
def delete_raid_configuration(self):
|
||||
"""Delete the raid configuration on the hardware."""
|
||||
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
|
||||
sushy_system.delete_raid()
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
# Copyright 2018 Hewlett Packard Enterprise Development LP
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from proliantutils import exception
|
||||
from proliantutils import log
|
||||
from sushy.resources import base
|
||||
|
||||
|
||||
LOG = log.get_logger(__name__)
|
||||
|
||||
|
||||
class LogicalDriveListField(base.ListField):
|
||||
volume_unique_identifier = base.Field('VolumeUniqueIdentifier',
|
||||
required=True)
|
||||
|
||||
|
||||
class HPESmartStorageConfig(base.ResourceBase):
|
||||
"""Class that defines the functionality for SmartSorageConfig Resources."""
|
||||
|
||||
controller_id = base.Field("Id")
|
||||
|
||||
logical_drives = LogicalDriveListField("LogicalDrives", default=[])
|
||||
|
||||
settings_uri = base.Field(["@Redfish.Settings",
|
||||
"SettingsObject", "@odata.id"])
|
||||
|
||||
def delete_raid(self):
|
||||
"""Clears the RAID configuration from the system.
|
||||
|
||||
"""
|
||||
if not self.logical_drives:
|
||||
msg = ('No logical drives found on the controller '
|
||||
'%(controller)s' % {'controller': str(self.controller_id)})
|
||||
LOG.debug(msg)
|
||||
raise exception.IloLogicalDriveNotFoundError(msg)
|
||||
|
||||
lds = [{
|
||||
'Actions': [{"Action": "LogicalDriveDelete"}],
|
||||
'VolumeUniqueIdentifier':
|
||||
logical_drive.volume_unique_identifier}
|
||||
for logical_drive in self.logical_drives]
|
||||
|
||||
data = {'LogicalDrives': lds, 'DataGuard': 'Permissive'}
|
||||
self._conn.put(self.settings_uri, data=data)
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2017 Hewlett Packard Enterprise Development LP
|
||||
# Copyright 2018 Hewlett Packard Enterprise Development LP
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -17,6 +17,7 @@ __author__ = 'HPE'
|
|||
import sushy
|
||||
from sushy.resources import base
|
||||
from sushy.resources.system import system
|
||||
from sushy import utils as sushy_utils
|
||||
|
||||
from proliantutils import exception
|
||||
from proliantutils import log
|
||||
|
@ -27,6 +28,7 @@ from proliantutils.redfish.resources.system import mappings
|
|||
from proliantutils.redfish.resources.system import memory
|
||||
from proliantutils.redfish.resources.system import pci_device
|
||||
from proliantutils.redfish.resources.system import secure_boot
|
||||
from proliantutils.redfish.resources.system import smart_storage_config
|
||||
from proliantutils.redfish.resources.system.storage import simple_storage
|
||||
from proliantutils.redfish.resources.system.storage import \
|
||||
smart_storage as hpe_smart_storage
|
||||
|
@ -71,6 +73,11 @@ class HPESystem(system.System):
|
|||
'Boot',
|
||||
'UefiTargetBootSourceOverride@Redfish.AllowableValues'],
|
||||
adapter=list))
|
||||
|
||||
smart_storage_config_identities = base.Field(
|
||||
['Oem', 'Hpe', 'SmartStorageConfig'],
|
||||
adapter=sushy_utils.get_members_identities)
|
||||
|
||||
supported_boot_mode = base.MappedField(
|
||||
['Oem', 'Hpe', 'Bios', 'UefiClass'], mappings.SUPPORTED_BOOT_MODE,
|
||||
default=constants.SUPPORTED_LEGACY_BIOS_ONLY)
|
||||
|
@ -323,3 +330,51 @@ class HPESystem(system.System):
|
|||
|
||||
self._memory.refresh(force=False)
|
||||
return self._memory
|
||||
|
||||
def get_smart_storage_config(self, smart_storage_config_url):
|
||||
"""Returns a SmartStorageConfig Instance for each controller."""
|
||||
return (smart_storage_config.
|
||||
HPESmartStorageConfig(self._conn, smart_storage_config_url,
|
||||
redfish_version=self.redfish_version))
|
||||
|
||||
def check_smart_storage_config_ids(self):
|
||||
"""Check SmartStorageConfig controllers is there in hardware.
|
||||
|
||||
:raises: IloError, on an error from iLO.
|
||||
"""
|
||||
if self.smart_storage_config_identities is None:
|
||||
msg = ('The Redfish controller failed to get the '
|
||||
'SmartStorageConfig controller configurations.')
|
||||
LOG.debug(msg)
|
||||
raise exception.IloError(msg)
|
||||
|
||||
def delete_raid(self):
|
||||
"""Delete the raid configuration on the hardware.
|
||||
|
||||
Loops through each SmartStorageConfig controller and clears the
|
||||
raid configuration.
|
||||
|
||||
:raises: IloError, on an error from iLO.
|
||||
"""
|
||||
self.check_smart_storage_config_ids()
|
||||
any_exceptions = []
|
||||
ld_exc_count = 0
|
||||
for config_id in self.smart_storage_config_identities:
|
||||
try:
|
||||
ssc_obj = self.get_smart_storage_config(config_id)
|
||||
ssc_obj.delete_raid()
|
||||
except exception.IloLogicalDriveNotFoundError as e:
|
||||
ld_exc_count += 1
|
||||
except sushy.exceptions.SushyError as e:
|
||||
any_exceptions.append((config_id, str(e)))
|
||||
|
||||
if any_exceptions:
|
||||
msg = ('The Redfish controller failed to delete the '
|
||||
'raid configuration in one or more controllers with '
|
||||
'Error: %(error)s' % {'error': str(any_exceptions)})
|
||||
raise exception.IloError(msg)
|
||||
|
||||
if ld_exc_count == len(self.smart_storage_config_identities):
|
||||
msg = ('No logical drives are found in any controllers. Nothing '
|
||||
'to delete.')
|
||||
raise exception.IloLogicalDriveNotFoundError(msg)
|
||||
|
|
|
@ -756,6 +756,29 @@ class IloClientTestCase(testtools.TestCase):
|
|||
self.client.activate_license('fake-key')
|
||||
call_mock.assert_called_once_with('activate_license', 'fake-key')
|
||||
|
||||
@mock.patch.object(client.IloClient, '_call_method')
|
||||
def test_delete_raid_configuration(self, call_mock):
|
||||
self.client.delete_raid_configuration()
|
||||
call_mock.assert_called_once_with('delete_raid_configuration')
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'get_product_name')
|
||||
def test_delete_raid_configuration_gen9(self, get_product_mock):
|
||||
self.client.model = 'Gen9'
|
||||
get_product_mock.return_value = 'ProLiant BL460c Gen9'
|
||||
self.assertRaisesRegexp(exception.IloCommandNotSupportedError,
|
||||
'`delete_raid_configuration` is not supported '
|
||||
'on ProLiant BL460c Gen9',
|
||||
self.client.delete_raid_configuration)
|
||||
|
||||
@mock.patch.object(ribcl.RIBCLOperations, 'get_product_name')
|
||||
def test_delete_raid_configuration_gen8(self, get_product_mock):
|
||||
self.client.model = 'Gen8'
|
||||
get_product_mock.return_value = 'ProLiant DL380 G8'
|
||||
self.assertRaisesRegexp(exception.IloCommandNotSupportedError,
|
||||
'`delete_raid_configuration` is not supported '
|
||||
'on ProLiant DL380 G8',
|
||||
self.client.delete_raid_configuration)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'eject_virtual_media')
|
||||
def test_eject_virtual_media_gen9(self, eject_virtual_media_mock):
|
||||
self.client.model = 'Gen9'
|
||||
|
|
|
@ -1055,5 +1055,13 @@ class IloRibclTestCaseBeforeRisSupport(unittest.TestCase):
|
|||
'ProLiant DL380 G7',
|
||||
self.ilo.get_host_post_state)
|
||||
|
||||
@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
|
||||
self.assertRaisesRegexp(exception.IloCommandNotSupportedError,
|
||||
'ProLiant DL380 G7',
|
||||
self.ilo.delete_raid_configuration)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -2551,3 +2551,10 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
|
|||
ret = self.client._is_raid_supported()
|
||||
self.assertEqual(ret, expt_ret)
|
||||
get_array_mock.assert_called_once_with()
|
||||
|
||||
@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'
|
||||
self.assertRaisesRegexp(exception.IloCommandNotSupportedError,
|
||||
'ProLiant BL460c Gen9',
|
||||
self.client.delete_raid_configuration)
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
{
|
||||
"@Redfish.Settings": {
|
||||
"@odata.type": "#Settings.v1_0_0.Settings",
|
||||
"ETag": "78F92741",
|
||||
"Messages": [
|
||||
{
|
||||
"MessageId": "SmartStorageMessages.2.0.0.Success"
|
||||
}
|
||||
],
|
||||
"SettingsObject": {
|
||||
"@odata.id": "/redfish/v1/systems/1/smartstorageconfig/settings/"
|
||||
},
|
||||
"Time": "2017-10-31T12:12:35+00:00"
|
||||
},
|
||||
"@odata.context": "/redfish/v1/$metadata#SmartStorageConfig.SmartStorageConfig",
|
||||
"@odata.etag": "W/\"90107B96DAE4060606D29991827C7EF7\"",
|
||||
"@odata.id": "/redfish/v1/systems/1/smartstorageconfig/",
|
||||
"@odata.type": "#SmartStorageConfig.v2_0_0.SmartStorageConfig",
|
||||
"CurrentParallelSurfaceScanCount": null,
|
||||
"DataGuard": "Strict",
|
||||
"DegradedPerformanceOptimization": null,
|
||||
"DriveWriteCache": null,
|
||||
"ElevatorSort": null,
|
||||
"EncryptionConfiguration": "None",
|
||||
"EncryptionEULA": null,
|
||||
"ExpandPriority": null,
|
||||
"FlexibleLatencySchedulerSetting": null,
|
||||
"Id": "smartstorageconfig",
|
||||
"InconsistencyRepairPolicy": null,
|
||||
"Location": "Slot 0",
|
||||
"LocationFormat": "PCISlot",
|
||||
"LogicalDrives": [
|
||||
{
|
||||
"Accelerator": "ControllerCache",
|
||||
"BlockSizeBytes": 512,
|
||||
"CapacityBlocks": 4688319664,
|
||||
"CapacityGiB": 2235,
|
||||
"DataDrives": [
|
||||
"2I:1:2",
|
||||
"2I:1:1"
|
||||
],
|
||||
"DriveLocationFormat": "ControllerPort:Box:Bay",
|
||||
"LegacyBootPriority": "None",
|
||||
"LogicalDriveName": "01A27294PFJHD0ARCA218H 63E0",
|
||||
"LogicalDriveNumber": 1,
|
||||
"ParityGroupCount": 0,
|
||||
"Raid": "Raid0",
|
||||
"SpareDrives": [],
|
||||
"SpareRebuildMode": null,
|
||||
"StripSizeBytes": 262144,
|
||||
"StripeSizeBytes": 524288,
|
||||
"VolumeUniqueIdentifier": "600508B1001C045A9BAAC9F4F49498AE"
|
||||
}
|
||||
],
|
||||
"MonitorAndPerformanceAnalysisDelaySeconds": null,
|
||||
"NoBatteryWriteCache": null,
|
||||
"Oem": {
|
||||
"Hpe": {
|
||||
"@odata.type": "#HpeBiosExt.v2_0_0.HpeBiosExt",
|
||||
"SettingsObject": {
|
||||
"UnmodifiedETag": "W/\"1BBCED8C1E405050504A92724569294F\""
|
||||
}
|
||||
}
|
||||
},
|
||||
"PhysicalDrives": [
|
||||
{
|
||||
"LegacyBootPriority": "None",
|
||||
"Location": "1I:1:2",
|
||||
"LocationFormat": "ControllerPort:Box:Bay"
|
||||
}
|
||||
],
|
||||
"Ports": [
|
||||
{
|
||||
"OperatingModeAfterReboot": "Mixed",
|
||||
"PortIndex": 0
|
||||
}
|
||||
],
|
||||
"PowerModeAfterReboot": "MaxPerformance",
|
||||
"PredictiveSpareRebuild": null,
|
||||
"QueueDepth": null,
|
||||
"ReadCachePercent": null,
|
||||
"RebuildPriority": null,
|
||||
"SurfaceScanAnalysisDelaySeconds": null,
|
||||
"SurfaceScanAnalysisPriority": null,
|
||||
"SurvivalPowerMode": "Enabled",
|
||||
"WriteCacheBypassThresholdKiB": null
|
||||
}
|
|
@ -97,6 +97,11 @@
|
|||
"target": "/redfish/v1/Systems/1/Actions/Oem/Hpe/HpeComputerSystemExt.SystemReset/"
|
||||
}
|
||||
},
|
||||
"SmartStorageConfig": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/systems/1/smartstorageconfig/"
|
||||
}
|
||||
],
|
||||
"AggregateHealthStatus": {
|
||||
"AgentlessManagementService": "Unavailable",
|
||||
"BiosOrHardwareHealth": {
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
# Copyright 2017 Hewlett Packard Enterprise Development LP
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from proliantutils import exception
|
||||
from proliantutils.redfish.resources.system import smart_storage_config
|
||||
|
||||
|
||||
class HPESmartStorageConfigTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(HPESmartStorageConfigTestCase, self).setUp()
|
||||
self.conn = mock.MagicMock()
|
||||
with open('proliantutils/tests/redfish/'
|
||||
'json_samples/smart_storage_config.json', 'r') as f:
|
||||
self.conn.get.return_value.json.return_value = (
|
||||
json.load(f))
|
||||
|
||||
self.ssc_inst = smart_storage_config.HPESmartStorageConfig(
|
||||
self.conn, '/redfish/v1/Systems/1/smartstorageconfig',
|
||||
redfish_version='1.0.2')
|
||||
|
||||
def test_attributes(self):
|
||||
self.assertEqual('smartstorageconfig', self.ssc_inst.controller_id)
|
||||
self.assertEqual(
|
||||
'600508B1001C045A9BAAC9F4F49498AE',
|
||||
self.ssc_inst.logical_drives[0].volume_unique_identifier)
|
||||
self.assertEqual("/redfish/v1/systems/1/smartstorageconfig/settings/",
|
||||
self.ssc_inst.settings_uri)
|
||||
|
||||
def test_delete_raid(self):
|
||||
settings_uri = "/redfish/v1/systems/1/smartstorageconfig/settings/"
|
||||
data = {
|
||||
"LogicalDrives": [{
|
||||
"Actions": [{"Action": "LogicalDriveDelete"}],
|
||||
"VolumeUniqueIdentifier": "600508B1001C045A9BAAC9F4F49498AE"}],
|
||||
"DataGuard": "Permissive",
|
||||
}
|
||||
self.ssc_inst.delete_raid()
|
||||
self.ssc_inst._conn.put.assert_called_once_with(settings_uri,
|
||||
data=data)
|
||||
|
||||
def test_delete_raid_logical_drive_not_found(self):
|
||||
type(self.ssc_inst).logical_drives = mock.PropertyMock(
|
||||
return_value=[])
|
||||
self.assertRaises(exception.IloLogicalDriveNotFoundError,
|
||||
self.ssc_inst.delete_raid)
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2017 Hewlett Packard Enterprise Development LP
|
||||
# Copyright 2018 Hewlett Packard Enterprise Development LP
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -25,6 +25,7 @@ from proliantutils.redfish.resources.system import constants as sys_cons
|
|||
from proliantutils.redfish.resources.system import ethernet_interface
|
||||
from proliantutils.redfish.resources.system import memory
|
||||
from proliantutils.redfish.resources.system import secure_boot
|
||||
from proliantutils.redfish.resources.system import smart_storage_config
|
||||
from proliantutils.redfish.resources.system.storage import simple_storage
|
||||
from proliantutils.redfish.resources.system.storage import smart_storage
|
||||
from proliantutils.redfish.resources.system.storage import storage
|
||||
|
@ -497,3 +498,65 @@ class HPESystemTestCase(testtools.TestCase):
|
|||
def test_get_host_post_state(self):
|
||||
expected = sys_cons.POST_STATE_FINISHEDPOST
|
||||
self.assertEqual(expected, self.sys_inst.post_state)
|
||||
|
||||
@mock.patch.object(smart_storage_config, 'HPESmartStorageConfig',
|
||||
autospec=True)
|
||||
def test_get_smart_storage_config(self, mock_ssc):
|
||||
ssc_element = '/redfish/v1/systems/1/smartstorageconfig/'
|
||||
ssc_inst = self.sys_inst.get_smart_storage_config(ssc_element)
|
||||
self.assertIsInstance(ssc_inst,
|
||||
smart_storage_config.HPESmartStorageConfig.
|
||||
__class__)
|
||||
mock_ssc.assert_called_once_with(
|
||||
self.conn, "/redfish/v1/systems/1/smartstorageconfig/",
|
||||
redfish_version='1.0.2')
|
||||
|
||||
@mock.patch.object(system.HPESystem, 'get_smart_storage_config')
|
||||
def test_delete_raid(self, get_smart_storage_config_mock):
|
||||
config_id = ['/redfish/v1/systems/1/smartstorageconfig/']
|
||||
type(self.sys_inst).smart_storage_config_identities = (
|
||||
mock.PropertyMock(return_value=config_id))
|
||||
self.sys_inst.delete_raid()
|
||||
get_smart_storage_config_mock.assert_called_once_with(config_id[0])
|
||||
(get_smart_storage_config_mock.return_value.
|
||||
delete_raid.assert_called_once_with())
|
||||
|
||||
@mock.patch.object(system.HPESystem, 'get_smart_storage_config')
|
||||
def test_delete_raid_controller_failed(self,
|
||||
get_smart_storage_config_mock):
|
||||
config_id = ['/redfish/v1/systems/1/smartstorageconfig/',
|
||||
'/redfish/v1/systems/1/smartstorageconfig1/',
|
||||
'/redfish/v1/systems/1/smartstorageconfig2/']
|
||||
type(self.sys_inst).smart_storage_config_identities = (
|
||||
mock.PropertyMock(return_value=config_id))
|
||||
get_smart_storage_config_mock.return_value.delete_raid.side_effect = (
|
||||
[None, sushy.exceptions.SushyError, None])
|
||||
self.assertRaisesRegex(
|
||||
exception.IloError,
|
||||
"The Redfish controller failed to delete the "
|
||||
"raid configuration in one or more controllers with",
|
||||
self.sys_inst.delete_raid)
|
||||
|
||||
@mock.patch.object(system.HPESystem, 'get_smart_storage_config')
|
||||
def test_delete_raid_logical_drive_not_found(
|
||||
self, get_smart_storage_config_mock):
|
||||
config_id = ['/redfish/v1/systems/1/smartstorageconfig/',
|
||||
'/redfish/v1/systems/1/smartstorageconfig1/']
|
||||
type(self.sys_inst).smart_storage_config_identities = (
|
||||
mock.PropertyMock(return_value=config_id))
|
||||
get_smart_storage_config_mock.return_value.delete_raid.side_effect = (
|
||||
exception.IloLogicalDriveNotFoundError('No logical drive found'))
|
||||
self.assertRaisesRegex(
|
||||
exception.IloError,
|
||||
"No logical drives are found in any controllers. "
|
||||
"Nothing to delete.",
|
||||
self.sys_inst.delete_raid)
|
||||
|
||||
def test_check_smart_storage_config_ids(self):
|
||||
type(self.sys_inst).smart_storage_config_identities = (
|
||||
mock.PropertyMock(return_value=None))
|
||||
self.assertRaisesRegex(
|
||||
exception.IloError,
|
||||
"The Redfish controller failed to get the SmartStorageConfig "
|
||||
"controller configurations",
|
||||
self.sys_inst.check_smart_storage_config_ids)
|
||||
|
|
|
@ -1454,3 +1454,8 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
|||
type(get_system_mock.return_value).post_state = post_state
|
||||
result = self.rf_client.get_host_post_state()
|
||||
self.assertEqual('PowerOff', result)
|
||||
|
||||
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||
def test_delete_raid_configuration(self, get_system_mock):
|
||||
self.rf_client.delete_raid_configuration()
|
||||
get_system_mock.return_value.delete_raid.assert_called_once_with()
|
||||
|
|
Loading…
Reference in New Issue