From 9a7735aea25c97f1d52159cef07170a232b48656 Mon Sep 17 00:00:00 2001 From: Nisha Agarwal Date: Fri, 4 Aug 2017 00:40:22 -0700 Subject: [PATCH] Redfish: Adds drive_rotational__rpm attribute to server capabilities Change-Id: Id99d2b232ab8c915855c3aafe966d77fd162f1cc --- proliantutils/redfish/redfish.py | 5 ++ .../system/storage/array_controller.py | 13 +++++ .../resources/system/storage/common.py | 18 +++++++ .../system/storage/physical_drive.py | 14 ++++++ .../resources/system/storage/smart_storage.py | 13 +++++ .../resources/system/storage/storage.py | 27 +++++++++++ .../tests/redfish/json_samples/drive.json | 41 ++++++++++++++++ .../tests/redfish/json_samples/storage.json | 2 + .../system/storage/test_array_controller.py | 23 +++++++++ .../resources/system/storage/test_common.py | 15 ++++++ .../system/storage/test_physical_drive.py | 13 +++++ .../system/storage/test_smart_storage.py | 27 +++++++++++ .../resources/system/storage/test_storage.py | 47 ++++++++++++++++++- proliantutils/tests/redfish/test_redfish.py | 12 +++-- 14 files changed, 266 insertions(+), 4 deletions(-) diff --git a/proliantutils/redfish/redfish.py b/proliantutils/redfish/redfish.py index 8b3f8cbb..5769dd56 100644 --- a/proliantutils/redfish/redfish.py +++ b/proliantutils/redfish/redfish.py @@ -688,6 +688,11 @@ class RedfishOperations(operations.IloOperations): [('logical_raid_level_' + x, True) for x in sushy_system.smart_storage.logical_raid_levels]) + all_key_to_value_expression_tuples += ( + [('drive_rotational_' + str(x) + '_rpm', True) + for x in + common_storage.get_drive_rotational_speed_rpm(sushy_system)]) + capabilities.update( {key: 'true' for (key, value) in all_key_to_value_expression_tuples diff --git a/proliantutils/redfish/resources/system/storage/array_controller.py b/proliantutils/redfish/resources/system/storage/array_controller.py index 5e208b91..65b8b17d 100644 --- a/proliantutils/redfish/resources/system/storage/array_controller.py +++ b/proliantutils/redfish/resources/system/storage/array_controller.py @@ -75,6 +75,7 @@ class HPEArrayControllerCollection(base.ResourceCollectionBase): _has_ssd = None _has_rotational = None _logical_raid_levels = None + _drive_rotational_speed_rpm = None @property def _resource_type(self): @@ -141,6 +142,17 @@ class HPEArrayControllerCollection(base.ResourceCollectionBase): member.logical_drives.logical_raid_levels) return self._logical_raid_levels + @property + def drive_rotational_speed_rpm(self): + """Gets the set of rotational speed of the HDD drives""" + + if self._drive_rotational_speed_rpm is None: + self._drive_rotational_speed_rpm = set() + for member in self.get_members(): + self._drive_rotational_speed_rpm.update( + member.physical_drives.drive_rotational_speed_rpm) + return self._drive_rotational_speed_rpm + def refresh(self): super(HPEArrayControllerCollection, self).refresh() self._logical_drives_maximum_size_mib = None @@ -148,3 +160,4 @@ class HPEArrayControllerCollection(base.ResourceCollectionBase): self._has_ssd = None self._has_rotational = None self._logical_raid_levels = None + self._drive_rotational_speed_rpm = None diff --git a/proliantutils/redfish/resources/system/storage/common.py b/proliantutils/redfish/resources/system/storage/common.py index 49cd6ab9..56d5a989 100644 --- a/proliantutils/redfish/resources/system/storage/common.py +++ b/proliantutils/redfish/resources/system/storage/common.py @@ -175,3 +175,21 @@ def has_nvme_ssd(system_obj): storage_resource, 'has_nvme_ssd', default=False) return storage_value + + +def get_drive_rotational_speed_rpm(system_obj): + """Gets the set of rotational speed rpms of the disks. + + :param system_obj: The HPESystem object. + :returns the set of rotational speed rpms of the HDD devices. + """ + speed = set() + smart_resource = _get_attribute_value_of(system_obj, 'smart_storage') + if smart_resource is not None: + speed.update(_get_attribute_value_of( + smart_resource, 'drive_rotational_speed_rpm', default=set())) + storage_resource = _get_attribute_value_of(system_obj, 'storages') + if storage_resource is not None: + speed.update(_get_attribute_value_of( + storage_resource, 'drive_rotational_speed_rpm', default=set())) + return speed diff --git a/proliantutils/redfish/resources/system/storage/physical_drive.py b/proliantutils/redfish/resources/system/storage/physical_drive.py index 86a7d54b..612ec7dc 100644 --- a/proliantutils/redfish/resources/system/storage/physical_drive.py +++ b/proliantutils/redfish/resources/system/storage/physical_drive.py @@ -42,6 +42,7 @@ class HPEPhysicalDriveCollection(base.ResourceCollectionBase): _maximum_size_mib = None _has_ssd = None _has_rotational = None + _drive_rotational_speed_rpm = None @property def _resource_type(self): @@ -83,8 +84,21 @@ class HPEPhysicalDriveCollection(base.ResourceCollectionBase): break return self._has_rotational + @property + def drive_rotational_speed_rpm(self): + """Gets the set of rotational speed of the HDD drives""" + + if self._drive_rotational_speed_rpm is None: + self._drive_rotational_speed_rpm = set() + for member in self.get_members(): + if member.rotational_speed_rpm is not None: + self._drive_rotational_speed_rpm.add( + member.rotational_speed_rpm) + return self._drive_rotational_speed_rpm + def refresh(self): super(HPEPhysicalDriveCollection, self).refresh() self._maximum_size_mib = None self._has_ssd = None self._has_rotational = None + self._drive_rotational_speed_rpm = None diff --git a/proliantutils/redfish/resources/system/storage/smart_storage.py b/proliantutils/redfish/resources/system/storage/smart_storage.py index 13f52cd0..679fa6e4 100644 --- a/proliantutils/redfish/resources/system/storage/smart_storage.py +++ b/proliantutils/redfish/resources/system/storage/smart_storage.py @@ -36,6 +36,7 @@ class HPESmartStorage(base.ResourceBase): _has_ssd = None _has_rotational = None _logical_raid_levels = None + _drive_rotational_speed_rpm = None @property def array_controllers(self): @@ -115,6 +116,17 @@ class HPESmartStorage(base.ResourceBase): member.logical_drives.logical_raid_levels) return self._logical_raid_levels + @property + def drive_rotational_speed_rpm(self): + """Gets the list of rotational speed of the HDD drives""" + + if self._drive_rotational_speed_rpm is None: + self._drive_rotational_speed_rpm = set() + for member in self.array_controllers.get_members(): + self._drive_rotational_speed_rpm.update( + member.physical_drives.drive_rotational_speed_rpm) + return self._drive_rotational_speed_rpm + def refresh(self): super(HPESmartStorage, self).refresh() self._logical_drives_maximum_size_mib = None @@ -123,3 +135,4 @@ class HPESmartStorage(base.ResourceBase): self._has_ssd = None self._has_rotational = None self._logical_raid_levels = None + self._drive_rotational_speed_rpm = None diff --git a/proliantutils/redfish/resources/system/storage/storage.py b/proliantutils/redfish/resources/system/storage/storage.py index 591407aa..8e3d09a5 100644 --- a/proliantutils/redfish/resources/system/storage/storage.py +++ b/proliantutils/redfish/resources/system/storage/storage.py @@ -44,6 +44,7 @@ class Storage(base.ResourceBase): _has_ssd = None _has_rotational = None _has_nvme_ssd = None + _drive_rotational_speed_rpm = None @property def volumes(self): @@ -116,6 +117,18 @@ class Storage(base.ResourceBase): self._has_nvme_ssd = True return self._has_nvme_ssd + @property + def drive_rotational_speed_rpm(self): + """Gets set of rotational speed of the disks""" + + if self._drive_rotational_speed_rpm is None: + self._drive_rotational_speed_rpm = set() + for member in self._drives_list(): + if member.rotation_speed_rpm is not None: + self._drive_rotational_speed_rpm.add( + member.rotation_speed_rpm) + return self._drive_rotational_speed_rpm + def refresh(self): super(Storage, self).refresh() self._drives_maximum_size_bytes = None @@ -123,6 +136,7 @@ class Storage(base.ResourceBase): self._has_ssd = None self._has_rotational = None self._has_nvme_ssd = None + self._drive_rotational_speed_rpm = None class StorageCollection(base.ResourceCollectionBase): @@ -133,6 +147,7 @@ class StorageCollection(base.ResourceCollectionBase): _has_ssd = None _has_rotational = None _has_nvme_ssd = None + _drive_rotational_speed_rpm = None @property def _resource_type(self): @@ -198,6 +213,17 @@ class StorageCollection(base.ResourceCollectionBase): break return self._has_nvme_ssd + @property + def drive_rotational_speed_rpm(self): + """Gets set of rotational speed of the disks""" + + if self._drive_rotational_speed_rpm is None: + self._drive_rotational_speed_rpm = set() + for member in self.get_members(): + self._drive_rotational_speed_rpm.update( + member.drive_rotational_speed_rpm) + return self._drive_rotational_speed_rpm + def refresh(self): super(StorageCollection, self).refresh() self._volumes_maximum_size_bytes = None @@ -205,3 +231,4 @@ class StorageCollection(base.ResourceCollectionBase): self._has_ssd = None self._has_rotational = None self._has_nvme_ssd = None + self._drive_rotational_speed_rpm = None diff --git a/proliantutils/tests/redfish/json_samples/drive.json b/proliantutils/tests/redfish/json_samples/drive.json index 61d4cd84..38a37c40 100644 --- a/proliantutils/tests/redfish/json_samples/drive.json +++ b/proliantutils/tests/redfish/json_samples/drive.json @@ -77,5 +77,46 @@ }, "@odata.context": "/redfish/v1/$metadata#Drive.Drive", "@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Drives/3F5A8C54207B7233" + }, + "drive3": { + "@odata.type": "#Drive.v1_1_0.Drive", + "IndicatorLED": "Lit", + "Model": "C123", + "Revision": "100A", + "Status": { + "State": "Enabled", + "Health": "OK" + }, + "CapacityBytes": 899527000000, + "FailurePredicted": false, + "Protocol": "SAS", + "MediaType": "HDD", + "Manufacturer": "Contoso", + "SerialNumber": "1234567", + "PartNumber": "C123-1111", + "Identifiers": [{ + "DurableNameFormat": "NAA", + "DurableName": "35D38F11ACEF7BD3" + }], + "HotspareType": "None", + "EncryptionAbility": "SelfEncryptingDrive", + "EncryptionStatus": "Unlocked", + "RotationSpeedRPM": 10000, + "BlockSizeBytes": 512, + "CapableSpeedGbs": 12, + "NegotiatedSpeedGbs": 12, + "Links": { + "Volumes": [{ + "@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes/1" + }] + }, + "Actions": { + "#Drive.SecureErase": { + "Target": "/redfish/v1/Systems/437XR1138R2/Storage/1/Drives/35D38F11ACEF7BD3/Actions/Drive.SecureErase" + } + }, + "@odata.context": "/redfish/v1/$metadata#Drive.Drive", + "@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Drives/35D38F11ACEF7BD3" + } } diff --git a/proliantutils/tests/redfish/json_samples/storage.json b/proliantutils/tests/redfish/json_samples/storage.json index 6fb28236..bcd7741a 100644 --- a/proliantutils/tests/redfish/json_samples/storage.json +++ b/proliantutils/tests/redfish/json_samples/storage.json @@ -40,6 +40,8 @@ "@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Drives/35D38F11ACEF7BD3" }, { "@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Drives/3F5A8C54207B7233" + }, { + "@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Drives/3F5A8C54207B7234" }], "Volumes": { "@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes" diff --git a/proliantutils/tests/redfish/resources/system/storage/test_array_controller.py b/proliantutils/tests/redfish/resources/system/storage/test_array_controller.py index c8a0da71..e4bc21ad 100644 --- a/proliantutils/tests/redfish/resources/system/storage/test_array_controller.py +++ b/proliantutils/tests/redfish/resources/system/storage/test_array_controller.py @@ -223,3 +223,26 @@ 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_rotational) + + def test_drive_rotational_speed_rpm(self): + self.assertIsNone(self.sys_stor_col._drive_rotational_speed_rpm) + 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 + expected = set([10000]) + self.assertEqual(expected, + self.sys_stor_col.drive_rotational_speed_rpm) diff --git a/proliantutils/tests/redfish/resources/system/storage/test_common.py b/proliantutils/tests/redfish/resources/system/storage/test_common.py index 96e90dc5..6edb86a7 100644 --- a/proliantutils/tests/redfish/resources/system/storage/test_common.py +++ b/proliantutils/tests/redfish/resources/system/storage/test_common.py @@ -134,3 +134,18 @@ class CommonMethodsTestCase(testtools.TestCase): self._mock_property(storage_value)) actual = common.has_nvme_ssd(system_obj) self.assertEqual(expected, actual) + + @ddt.data((set([10000]), set([15000]), set([10000, 15000])), + (set([10000]), set(), set([10000])), + (set(), set([15000]), set([15000])), + (set(), set(), set())) + @ddt.unpack + def test_get_drive_rotational_speed_rpm(self, smart_value, + storage_value, expected): + system_obj = self.system_obj + type(system_obj.smart_storage).drive_rotational_speed_rpm = ( + self._mock_property(smart_value)) + type(system_obj.storages).drive_rotational_speed_rpm = ( + self._mock_property(storage_value)) + actual = common.get_drive_rotational_speed_rpm(system_obj) + self.assertEqual(expected, actual) diff --git a/proliantutils/tests/redfish/resources/system/storage/test_physical_drive.py b/proliantutils/tests/redfish/resources/system/storage/test_physical_drive.py index 9112bab7..7d4a7570 100644 --- a/proliantutils/tests/redfish/resources/system/storage/test_physical_drive.py +++ b/proliantutils/tests/redfish/resources/system/storage/test_physical_drive.py @@ -128,3 +128,16 @@ class HPEPhysicalDriveCollectionTestCase(testtools.TestCase): val = [dr_json['drive1'], dr_json['drive2']] self.conn.get.return_value.json.side_effect = val self.assertTrue(self.sys_stor_col.has_rotational) + + def test_drive_rotational_speed_rpm(self): + self.assertIsNone(self.sys_stor_col._drive_rotational_speed_rpm) + 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 + expected = set([10000]) + self.assertEqual(expected, + self.sys_stor_col.drive_rotational_speed_rpm) diff --git a/proliantutils/tests/redfish/resources/system/storage/test_smart_storage.py b/proliantutils/tests/redfish/resources/system/storage/test_smart_storage.py index cd15f12f..0e98d04d 100644 --- a/proliantutils/tests/redfish/resources/system/storage/test_smart_storage.py +++ b/proliantutils/tests/redfish/resources/system/storage/test_smart_storage.py @@ -182,3 +182,30 @@ class HPESmartStorageTestCase(testtools.TestCase): val.append(dr_json['drive2']) self.conn.get.return_value.json.side_effect = val self.assertTrue(self.sys_stor.has_rotational) + + def test_drive_rotational_speed_rpm(self): + self.assertIsNone(self.sys_stor._drive_rotational_speed_rpm) + 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 + expected = set([10000]) + self.assertEqual(expected, + self.sys_stor.drive_rotational_speed_rpm) diff --git a/proliantutils/tests/redfish/resources/system/storage/test_storage.py b/proliantutils/tests/redfish/resources/system/storage/test_storage.py index 06367a1e..ff9000b3 100644 --- a/proliantutils/tests/redfish/resources/system/storage/test_storage.py +++ b/proliantutils/tests/redfish/resources/system/storage/test_storage.py @@ -68,7 +68,8 @@ class StorageTestCase(testtools.TestCase): 'json_samples/drive.json') as f: dr_json = json.loads(f.read()) self.conn.get.return_value.json.side_effect = [dr_json['drive1'], - dr_json['drive2']] + dr_json['drive2'], + dr_json['drive3']] actual_dr = self.sys_stor._drives_list() self.assertIsInstance(actual_dr, list) @@ -82,6 +83,7 @@ class StorageTestCase(testtools.TestCase): dr_json = json.loads(f.read()) val.append(dr_json['drive1']) val.append(dr_json['drive2']) + val.append(dr_json['drive3']) self.conn.get.return_value.json.side_effect = val expected = 899527000000 actual = self.sys_stor.drives_maximum_size_bytes @@ -97,6 +99,7 @@ class StorageTestCase(testtools.TestCase): dr_json = json.loads(f.read()) val.append(dr_json['drive1']) val.append(dr_json['drive2']) + val.append(dr_json['drive3']) self.conn.get.return_value.json.side_effect = val self.assertTrue(self.sys_stor.has_ssd) @@ -110,6 +113,7 @@ class StorageTestCase(testtools.TestCase): dr_json = json.loads(f.read()) val.append(dr_json['drive1']) val.append(dr_json['drive2']) + val.append(dr_json['drive3']) self.conn.get.return_value.json.side_effect = val self.assertTrue(self.sys_stor.has_rotational) @@ -123,9 +127,26 @@ class StorageTestCase(testtools.TestCase): dr_json = json.loads(f.read()) val.append(dr_json['drive1']) val.append(dr_json['drive2']) + val.append(dr_json['drive3']) self.conn.get.return_value.json.side_effect = val self.assertTrue(self.sys_stor.has_nvme_ssd) + def test_drive_rotational_speed_rpm(self): + self.assertIsNone(self.sys_stor._drive_rotational_speed_rpm) + 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']) + val.append(dr_json['drive3']) + self.conn.get.return_value.json.side_effect = val + expected = set([15000, 10000]) + self.assertEqual(expected, + self.sys_stor.drive_rotational_speed_rpm) + class StorageCollectionTestCase(testtools.TestCase): @@ -203,6 +224,7 @@ class StorageCollectionTestCase(testtools.TestCase): dr_json = json.loads(f.read()) val.append(dr_json['drive1']) val.append(dr_json['drive2']) + val.append(dr_json['drive3']) self.conn.get.return_value.json.side_effect = val expected = 899527000000 actual = self.sys_stor_col.drives_maximum_size_bytes @@ -222,6 +244,7 @@ class StorageCollectionTestCase(testtools.TestCase): dr_json = json.loads(f.read()) val.append(dr_json['drive1']) val.append(dr_json['drive2']) + val.append(dr_json['drive3']) self.conn.get.return_value.json.side_effect = val self.assertTrue(self.sys_stor_col.has_ssd) @@ -239,6 +262,7 @@ class StorageCollectionTestCase(testtools.TestCase): dr_json = json.loads(f.read()) val.append(dr_json['drive1']) val.append(dr_json['drive2']) + val.append(dr_json['drive3']) self.conn.get.return_value.json.side_effect = val self.assertTrue(self.sys_stor_col.has_rotational) @@ -256,5 +280,26 @@ class StorageCollectionTestCase(testtools.TestCase): dr_json = json.loads(f.read()) val.append(dr_json['drive1']) val.append(dr_json['drive2']) + val.append(dr_json['drive3']) self.conn.get.return_value.json.side_effect = val self.assertTrue(self.sys_stor_col.has_nvme_ssd) + + def test_drive_rotational_speed_rpm(self): + self.assertIsNone(self.sys_stor_col._drive_rotational_speed_rpm) + 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']) + val.append(dr_json['drive3']) + self.conn.get.return_value.json.side_effect = val + expected = set([15000, 10000]) + self.assertEqual(expected, + self.sys_stor_col.drive_rotational_speed_rpm) diff --git a/proliantutils/tests/redfish/test_redfish.py b/proliantutils/tests/redfish/test_redfish.py index 057b3b63..017dbe2f 100644 --- a/proliantutils/tests/redfish/test_redfish.py +++ b/proliantutils/tests/redfish/test_redfish.py @@ -684,6 +684,7 @@ 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, 'get_drive_rotational_speed_rpm') @mock.patch.object(common_storage, 'has_nvme_ssd') @mock.patch.object(common_storage, 'has_rotational') @mock.patch.object(common_storage, 'has_ssd') @@ -691,7 +692,7 @@ class RedfishOperationsTestCase(testtools.TestCase): @mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager') def test_get_server_capabilities(self, get_manager_mock, get_system_mock, ssd_mock, rotational_mock, - nvme_mock): + nvme_mock, speed_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 = ( @@ -734,6 +735,7 @@ class RedfishOperationsTestCase(testtools.TestCase): raid_mock = mock.PropertyMock(return_value=set(['0', '1'])) type(get_system_mock.return_value. smart_storage).logical_raid_levels = (raid_mock) + speed_mock.return_value = set(['10000', '15000']) actual = self.rf_client.get_server_capabilities() expected = {'pci_gpu_devices': 1, 'sriov_enabled': 'true', 'secure_boot': 'true', 'cpu_vt': 'true', @@ -752,9 +754,12 @@ class RedfishOperationsTestCase(testtools.TestCase): 'has_rotational': 'true', 'has_nvme_ssd': 'true', 'logical_raid_level_0': 'true', - 'logical_raid_level_1': 'true'} + 'logical_raid_level_1': 'true', + 'drive_rotational_10000_rpm': 'true', + 'drive_rotational_15000_rpm': 'true'} self.assertEqual(expected, actual) + @mock.patch.object(common_storage, 'get_drive_rotational_speed_rpm') @mock.patch.object(common_storage, 'has_nvme_ssd') @mock.patch.object(common_storage, 'has_rotational') @mock.patch.object(common_storage, 'has_ssd') @@ -762,7 +767,7 @@ class RedfishOperationsTestCase(testtools.TestCase): @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, - rotational_mock, nvme_mock): + rotational_mock, nvme_mock, speed_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 = ( @@ -806,6 +811,7 @@ class RedfishOperationsTestCase(testtools.TestCase): raid_mock = mock.PropertyMock(return_value=set()) type(get_system_mock.return_value. smart_storage).logical_raid_levels = (raid_mock) + speed_mock.return_value = set() actual = self.rf_client.get_server_capabilities() expected = {'pci_gpu_devices': 1, 'rom_firmware_version': 'U31 v1.00 (03/11/2017)',