Redfish: Add has_rotational attribute to server capabilities
Change-Id: Ic57375b319901d37f32c1cc81b1f47387ec41fcc
This commit is contained in:
parent
aad05fdb11
commit
45191de2e1
|
@ -681,6 +681,8 @@ class RedfishOperations(operations.IloOperations):
|
|||
members_identities) > 0),
|
||||
('has_ssd',
|
||||
common_storage.has_ssd(sushy_system)),
|
||||
('has_rotational',
|
||||
common_storage.has_rotational(sushy_system)),
|
||||
) if value})
|
||||
|
||||
memory_data = sushy_system.memory.details()
|
||||
|
|
|
@ -73,6 +73,7 @@ class HPEArrayControllerCollection(base.ResourceCollectionBase):
|
|||
_logical_drives_maximum_size_mib = None
|
||||
_physical_drives_maximum_size_mib = None
|
||||
_has_ssd = None
|
||||
_has_rotational = None
|
||||
|
||||
@property
|
||||
def _resource_type(self):
|
||||
|
@ -114,8 +115,21 @@ class HPEArrayControllerCollection(base.ResourceCollectionBase):
|
|||
break
|
||||
return self._has_ssd
|
||||
|
||||
@property
|
||||
def has_rotational(self):
|
||||
"""Return true if any of the drive under ArrayControllers is ssd"""
|
||||
|
||||
if self._has_rotational is None:
|
||||
self._has_rotational = False
|
||||
for member in self.get_members():
|
||||
if member.physical_drives.has_rotational:
|
||||
self._has_rotational = True
|
||||
break
|
||||
return self._has_rotational
|
||||
|
||||
def refresh(self):
|
||||
super(HPEArrayControllerCollection, self).refresh()
|
||||
self._logical_drives_maximum_size_mib = None
|
||||
self._physical_drives_maximum_size_mib = None
|
||||
self._has_ssd = None
|
||||
self._has_rotational = None
|
||||
|
|
|
@ -135,3 +135,29 @@ def has_ssd(system_obj):
|
|||
storage_value = _get_attribute_value_of(
|
||||
storage_resource, 'has_ssd', default=False)
|
||||
return storage_value
|
||||
|
||||
|
||||
def has_rotational(system_obj):
|
||||
"""Gets if the system has any drive as HDD drive
|
||||
|
||||
:param system_obj: The HPESystem object.
|
||||
:returns True if system has HDD drives.
|
||||
"""
|
||||
smart_value = False
|
||||
storage_value = False
|
||||
smart_resource = _get_attribute_value_of(system_obj, 'smart_storage')
|
||||
if smart_resource is not None:
|
||||
smart_value = _get_attribute_value_of(
|
||||
smart_resource, 'has_rotational', default=False)
|
||||
|
||||
if smart_value:
|
||||
return smart_value
|
||||
|
||||
# Its returned before just to avoid hitting BMC if we have
|
||||
# already got the HDD device above.
|
||||
storage_resource = _get_attribute_value_of(system_obj, 'storages')
|
||||
if storage_resource is not None:
|
||||
storage_value = _get_attribute_value_of(
|
||||
storage_resource, 'has_rotational', default=False)
|
||||
|
||||
return storage_value
|
||||
|
|
|
@ -41,6 +41,7 @@ class HPEPhysicalDriveCollection(base.ResourceCollectionBase):
|
|||
|
||||
_maximum_size_mib = None
|
||||
_has_ssd = None
|
||||
_has_rotational = None
|
||||
|
||||
@property
|
||||
def _resource_type(self):
|
||||
|
@ -70,7 +71,20 @@ class HPEPhysicalDriveCollection(base.ResourceCollectionBase):
|
|||
break
|
||||
return self._has_ssd
|
||||
|
||||
@property
|
||||
def has_rotational(self):
|
||||
"""Return true if the drive is HDD"""
|
||||
|
||||
if self._has_rotational is None:
|
||||
self._has_rotational = False
|
||||
for member in self.get_members():
|
||||
if member.media_type == constants.MEDIA_TYPE_HDD:
|
||||
self._has_rotational = True
|
||||
break
|
||||
return self._has_rotational
|
||||
|
||||
def refresh(self):
|
||||
super(HPEPhysicalDriveCollection, self).refresh()
|
||||
self._maximum_size_mib = None
|
||||
self._has_ssd = None
|
||||
self._has_rotational = None
|
||||
|
|
|
@ -34,6 +34,7 @@ class HPESmartStorage(base.ResourceBase):
|
|||
_logical_drives_maximum_size_mib = None
|
||||
_physical_drives_maximum_size_mib = None
|
||||
_has_ssd = None
|
||||
_has_rotational = None
|
||||
|
||||
@property
|
||||
def array_controllers(self):
|
||||
|
@ -88,9 +89,22 @@ class HPESmartStorage(base.ResourceBase):
|
|||
break
|
||||
return self._has_ssd
|
||||
|
||||
@property
|
||||
def has_rotational(self):
|
||||
"""Return true if any of the drive under ArrayControllers is HDD"""
|
||||
|
||||
if self._has_rotational is None:
|
||||
self._has_rotational = False
|
||||
for member in self.array_controllers.get_members():
|
||||
if member.physical_drives.has_rotational:
|
||||
self._has_rotational = True
|
||||
break
|
||||
return self._has_rotational
|
||||
|
||||
def refresh(self):
|
||||
super(HPESmartStorage, self).refresh()
|
||||
self._logical_drives_maximum_size_mib = None
|
||||
self._physical_drives_maximum_size_mib = None
|
||||
self._array_controllers = None
|
||||
self._has_ssd = None
|
||||
self._has_rotational = None
|
||||
|
|
|
@ -42,6 +42,7 @@ class Storage(base.ResourceBase):
|
|||
_volumes = None
|
||||
_drives_maximum_size_bytes = None
|
||||
_has_ssd = None
|
||||
_has_rotational = None
|
||||
|
||||
@property
|
||||
def volumes(self):
|
||||
|
@ -90,11 +91,24 @@ class Storage(base.ResourceBase):
|
|||
break
|
||||
return self._has_ssd
|
||||
|
||||
@property
|
||||
def has_rotational(self):
|
||||
"""Return true if any of the drive is HDD"""
|
||||
|
||||
if self._has_rotational is None:
|
||||
self._has_rotational = False
|
||||
for member in self._drives_list():
|
||||
if member.media_type == constants.MEDIA_TYPE_HDD:
|
||||
self._has_rotational = True
|
||||
break
|
||||
return self._has_rotational
|
||||
|
||||
def refresh(self):
|
||||
super(Storage, self).refresh()
|
||||
self._drives_maximum_size_bytes = None
|
||||
self._volumes = None
|
||||
self._has_ssd = None
|
||||
self._has_rotational = None
|
||||
|
||||
|
||||
class StorageCollection(base.ResourceCollectionBase):
|
||||
|
@ -103,6 +117,7 @@ class StorageCollection(base.ResourceCollectionBase):
|
|||
_volumes_maximum_size_bytes = None
|
||||
_drives_maximum_size_bytes = None
|
||||
_has_ssd = None
|
||||
_has_rotational = None
|
||||
|
||||
@property
|
||||
def _resource_type(self):
|
||||
|
@ -144,8 +159,21 @@ class StorageCollection(base.ResourceCollectionBase):
|
|||
break
|
||||
return self._has_ssd
|
||||
|
||||
@property
|
||||
def has_rotational(self):
|
||||
"""Return true if Storage has any drive as HDD"""
|
||||
|
||||
if self._has_rotational is None:
|
||||
self._has_rotational = False
|
||||
for member in self.get_members():
|
||||
if member.has_rotational:
|
||||
self._has_rotational = True
|
||||
break
|
||||
return self._has_rotational
|
||||
|
||||
def refresh(self):
|
||||
super(StorageCollection, self).refresh()
|
||||
self._volumes_maximum_size_bytes = None
|
||||
self._drives_maximum_size_bytes = None
|
||||
self._has_ssd = None
|
||||
self._has_rotational = None
|
||||
|
|
|
@ -181,3 +181,24 @@ class HPEArrayControllerCollectionTestCase(testtools.TestCase):
|
|||
val.append(dr_json['drive2'])
|
||||
self.conn.get.return_value.json.side_effect = val
|
||||
self.assertTrue(self.sys_stor_col.has_ssd)
|
||||
|
||||
def test_has_rotational(self):
|
||||
self.assertIsNone(self.sys_stor_col._has_rotational)
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
val = []
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'array_controller.json')
|
||||
with open(path, 'r') as f:
|
||||
val.append(json.loads(f.read()))
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'disk_drive_collection.json')
|
||||
with open(path, 'r') as f:
|
||||
val.append(json.loads(f.read()))
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'disk_drive.json')
|
||||
with open(path, 'r') as f:
|
||||
dr_json = json.loads(f.read())
|
||||
val.append(dr_json['drive1'])
|
||||
val.append(dr_json['drive2'])
|
||||
self.conn.get.return_value.json.side_effect = val
|
||||
self.assertTrue(self.sys_stor_col.has_rotational)
|
||||
|
|
|
@ -109,3 +109,18 @@ class CommonMethodsTestCase(testtools.TestCase):
|
|||
self._mock_property(storage_value))
|
||||
actual = common.has_ssd(system_obj)
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
@ddt.data((True, False, True),
|
||||
(True, True, True),
|
||||
(False, True, True),
|
||||
(False, False, False))
|
||||
@ddt.unpack
|
||||
def test_has_rotational(self, smart_value, storage_value,
|
||||
expected):
|
||||
system_obj = self.system_obj
|
||||
type(system_obj.smart_storage).has_rotational = (
|
||||
self._mock_property(smart_value))
|
||||
type(system_obj.storages).has_rotational = (
|
||||
self._mock_property(storage_value))
|
||||
actual = common.has_rotational(system_obj)
|
||||
self.assertEqual(expected, actual)
|
||||
|
|
|
@ -117,3 +117,14 @@ class HPEPhysicalDriveCollectionTestCase(testtools.TestCase):
|
|||
self.conn.get.return_value.json.side_effect = val
|
||||
actual = self.sys_stor_col.has_ssd
|
||||
self.assertTrue(actual)
|
||||
|
||||
def test_has_rotational(self):
|
||||
self.assertIsNone(self.sys_stor_col._has_rotational)
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'disk_drive.json')
|
||||
with open(path, 'r') as f:
|
||||
dr_json = json.loads(f.read())
|
||||
val = [dr_json['drive1'], dr_json['drive2']]
|
||||
self.conn.get.return_value.json.side_effect = val
|
||||
self.assertTrue(self.sys_stor_col.has_rotational)
|
||||
|
|
|
@ -132,3 +132,28 @@ class HPESmartStorageTestCase(testtools.TestCase):
|
|||
val.append(dr_json['drive2'])
|
||||
self.conn.get.return_value.json.side_effect = val
|
||||
self.assertTrue(self.sys_stor.has_ssd)
|
||||
|
||||
def test_has_rotaional(self):
|
||||
self.assertIsNone(self.sys_stor._has_rotational)
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
val = []
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'array_controller_collection.json')
|
||||
with open(path, 'r') as f:
|
||||
val.append(json.loads(f.read()))
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'array_controller.json')
|
||||
with open(path, 'r') as f:
|
||||
val.append(json.loads(f.read()))
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'disk_drive_collection.json')
|
||||
with open(path, 'r') as f:
|
||||
val.append(json.loads(f.read()))
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'disk_drive.json')
|
||||
with open(path, 'r') as f:
|
||||
dr_json = json.loads(f.read())
|
||||
val.append(dr_json['drive1'])
|
||||
val.append(dr_json['drive2'])
|
||||
self.conn.get.return_value.json.side_effect = val
|
||||
self.assertTrue(self.sys_stor.has_rotational)
|
||||
|
|
|
@ -100,6 +100,19 @@ class StorageTestCase(testtools.TestCase):
|
|||
self.conn.get.return_value.json.side_effect = val
|
||||
self.assertTrue(self.sys_stor.has_ssd)
|
||||
|
||||
def test_has_rotational(self):
|
||||
self.assertIsNone(self.sys_stor._has_rotational)
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
val = []
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'drive.json')
|
||||
with open(path, 'r') as f:
|
||||
dr_json = json.loads(f.read())
|
||||
val.append(dr_json['drive1'])
|
||||
val.append(dr_json['drive2'])
|
||||
self.conn.get.return_value.json.side_effect = val
|
||||
self.assertTrue(self.sys_stor.has_rotational)
|
||||
|
||||
|
||||
class StorageCollectionTestCase(testtools.TestCase):
|
||||
|
||||
|
@ -198,3 +211,20 @@ class StorageCollectionTestCase(testtools.TestCase):
|
|||
val.append(dr_json['drive2'])
|
||||
self.conn.get.return_value.json.side_effect = val
|
||||
self.assertTrue(self.sys_stor_col.has_ssd)
|
||||
|
||||
def test_has_rotational(self):
|
||||
self.assertIsNone(self.sys_stor_col._has_rotational)
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
val = []
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'storage.json')
|
||||
with open(path, 'r') as f:
|
||||
val.append(json.loads(f.read()))
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'drive.json')
|
||||
with open(path, 'r') as f:
|
||||
dr_json = json.loads(f.read())
|
||||
val.append(dr_json['drive1'])
|
||||
val.append(dr_json['drive2'])
|
||||
self.conn.get.return_value.json.side_effect = val
|
||||
self.assertTrue(self.sys_stor_col.has_rotational)
|
||||
|
|
|
@ -684,11 +684,12 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
|||
'The Redfish controller failed to get the supported boot modes.',
|
||||
self.rf_client.get_supported_boot_mode)
|
||||
|
||||
@mock.patch.object(common_storage, 'has_rotational')
|
||||
@mock.patch.object(common_storage, 'has_ssd')
|
||||
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
|
||||
def test_get_server_capabilities(self, get_manager_mock, get_system_mock,
|
||||
ssd_mock):
|
||||
ssd_mock, rotational_mock):
|
||||
type(get_system_mock.return_value.pci_devices).gpu_devices = (
|
||||
[mock.MagicMock(spec=pci_device.PCIDevice)])
|
||||
type(get_system_mock.return_value.bios_settings).sriov = (
|
||||
|
@ -726,6 +727,7 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
|||
memory_mock.details = mock.MagicMock(return_value=mem)
|
||||
get_system_mock.return_value.memory = memory_mock
|
||||
ssd_mock.return_value = True
|
||||
rotational_mock.return_value = True
|
||||
actual = self.rf_client.get_server_capabilities()
|
||||
expected = {'pci_gpu_devices': 1, 'sriov_enabled': 'true',
|
||||
'secure_boot': 'true', 'cpu_vt': 'true',
|
||||
|
@ -740,14 +742,17 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
|||
'persistent_memory': 'true',
|
||||
'nvdimm_n': 'true',
|
||||
'logical_nvdimm_n': 'false',
|
||||
'has_ssd': 'true'}
|
||||
'has_ssd': 'true',
|
||||
'has_rotational': 'true'}
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
@mock.patch.object(common_storage, 'has_rotational')
|
||||
@mock.patch.object(common_storage, 'has_ssd')
|
||||
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
|
||||
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
|
||||
def test_get_server_capabilities_optional_capabilities_absent(
|
||||
self, get_manager_mock, get_system_mock, ssd_mock):
|
||||
self, get_manager_mock, get_system_mock, ssd_mock,
|
||||
rotational_mock):
|
||||
type(get_system_mock.return_value.pci_devices).gpu_devices = (
|
||||
[mock.MagicMock(spec=pci_device.PCIDevice)])
|
||||
type(get_system_mock.return_value.bios_settings).sriov = (
|
||||
|
@ -786,6 +791,7 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
|||
get_system_mock.return_value.memory = memory_mock
|
||||
memory_mock.details = mock.MagicMock(return_value=mem)
|
||||
ssd_mock.return_value = False
|
||||
rotational_mock.return_value = False
|
||||
actual = self.rf_client.get_server_capabilities()
|
||||
expected = {'pci_gpu_devices': 1,
|
||||
'rom_firmware_version': 'U31 v1.00 (03/11/2017)',
|
||||
|
|
Loading…
Reference in New Issue