From ede50237fd095304b2b6683f8423d6ea2195f148 Mon Sep 17 00:00:00 2001 From: Nisha Agarwal Date: Wed, 12 Jul 2017 23:58:31 +0000 Subject: [PATCH] Redfish: Adds SmartStorage and its related URIs for local_gb discovery Change-Id: Iff415e0ed83c546469d70e25318d48c361c765a8 --- .../resources/system/storage/__init__.py | 0 .../system/storage/array_controller.py | 101 +++++++++++ .../resources/system/storage/logical_drive.py | 56 ++++++ .../system/storage/physical_drive.py | 58 +++++++ .../resources/system/storage/smart_storage.py | 79 +++++++++ .../redfish/resources/system/system.py | 21 +++ .../json_samples/array_controller.json | 49 ++++++ .../array_controller_collection.json | 14 ++ .../redfish/json_samples/disk_drive.json | 42 +++++ .../json_samples/disk_drive_collection.json | 14 ++ .../redfish/json_samples/logical_drive.json | 29 ++++ .../logical_drive_collection.json | 14 ++ .../redfish/json_samples/smart_storage.json | 20 +++ .../resources/system/storage/__init__.py | 0 .../system/storage/test_array_controller.py | 160 ++++++++++++++++++ .../system/storage/test_logical_drive.py | 98 +++++++++++ .../system/storage/test_physical_drive.py | 98 +++++++++++ .../system/storage/test_smart_storage.py | 107 ++++++++++++ .../redfish/resources/system/test_system.py | 13 ++ 19 files changed, 973 insertions(+) create mode 100644 proliantutils/redfish/resources/system/storage/__init__.py create mode 100644 proliantutils/redfish/resources/system/storage/array_controller.py create mode 100644 proliantutils/redfish/resources/system/storage/logical_drive.py create mode 100644 proliantutils/redfish/resources/system/storage/physical_drive.py create mode 100644 proliantutils/redfish/resources/system/storage/smart_storage.py create mode 100644 proliantutils/tests/redfish/json_samples/array_controller.json create mode 100644 proliantutils/tests/redfish/json_samples/array_controller_collection.json create mode 100644 proliantutils/tests/redfish/json_samples/disk_drive.json create mode 100644 proliantutils/tests/redfish/json_samples/disk_drive_collection.json create mode 100644 proliantutils/tests/redfish/json_samples/logical_drive.json create mode 100644 proliantutils/tests/redfish/json_samples/logical_drive_collection.json create mode 100644 proliantutils/tests/redfish/json_samples/smart_storage.json create mode 100644 proliantutils/tests/redfish/resources/system/storage/__init__.py create mode 100644 proliantutils/tests/redfish/resources/system/storage/test_array_controller.py create mode 100644 proliantutils/tests/redfish/resources/system/storage/test_logical_drive.py create mode 100644 proliantutils/tests/redfish/resources/system/storage/test_physical_drive.py create mode 100644 proliantutils/tests/redfish/resources/system/storage/test_smart_storage.py diff --git a/proliantutils/redfish/resources/system/storage/__init__.py b/proliantutils/redfish/resources/system/storage/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/proliantutils/redfish/resources/system/storage/array_controller.py b/proliantutils/redfish/resources/system/storage/array_controller.py new file mode 100644 index 00000000..1f5f2d17 --- /dev/null +++ b/proliantutils/redfish/resources/system/storage/array_controller.py @@ -0,0 +1,101 @@ +# Copyright 2017 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. + +import logging + +from proliantutils.redfish.resources.system.storage import logical_drive +from proliantutils.redfish.resources.system.storage import physical_drive +from proliantutils.redfish import utils +from sushy.resources import base + +LOG = logging.getLogger(__name__) + + +class HPEArrayController(base.ResourceBase): + + identity = base.Field('Id') + """The identity string""" + + name = base.Field('Name') + """The name of the resource or array element""" + + description = base.Field('Description') + """Description""" + + _logical_drives = None + _physical_drives = None + + @property + def logical_drives(self): + if self._logical_drives is None: + self._logical_drives = ( + logical_drive.HPELogicalDriveCollection( + self._conn, utils.get_subresource_path_by( + self, ['Links', 'LogicalDrives']), + redfish_version=self.redfish_version)) + return self._logical_drives + + @property + def physical_drives(self): + if self._physical_drives is None: + self._physical_drives = ( + physical_drive.HPEPhysicalDriveCollection( + self._conn, utils.get_subresource_path_by( + self, ['Links', 'PhysicalDrives']), + redfish_version=self.redfish_version)) + return self._physical_drives + + def refresh(self): + super(HPEArrayController, self).refresh() + self._physical_drives = None + self._logical_drives = None + + +class HPEArrayControllerCollection(base.ResourceCollectionBase): + + _logical_drives_maximum_size_mib = None + _physical_drives_maximum_size_mib = None + + @property + def _resource_type(self): + return HPEArrayController + + @property + def logical_drives_maximum_size_mib(self): + """Gets the biggest logical drive + + :returns the size in MiB. + """ + if self._logical_drives_maximum_size_mib is None: + self._logical_drives_maximum_size_mib = ( + max([member.logical_drives.maximum_size_mib + for member in self.get_members()])) + return self._logical_drives_maximum_size_mib + + @property + def physical_drives_maximum_size_mib(self): + """Gets the biggest disk + + :returns the size in MiB. + """ + if self._physical_drives_maximum_size_mib is None: + self._physical_drives_maximum_size_mib = ( + max([member.physical_drives.maximum_size_mib + for member in self.get_members()])) + return self._physical_drives_maximum_size_mib + + def refresh(self): + super(HPEArrayControllerCollection, self).refresh() + self._logical_drives_maximum_size_mib = None + self._physical_drives_maximum_size_mib = None diff --git a/proliantutils/redfish/resources/system/storage/logical_drive.py b/proliantutils/redfish/resources/system/storage/logical_drive.py new file mode 100644 index 00000000..d2b6069e --- /dev/null +++ b/proliantutils/redfish/resources/system/storage/logical_drive.py @@ -0,0 +1,56 @@ +# Copyright 2017 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. + +import logging + +from sushy.resources import base + +LOG = logging.getLogger(__name__) + + +class HPELogicalDrive(base.ResourceBase): + + identity = base.Field('Id') + + name = base.Field('Name') + + description = base.Field('Description') + + capacity_mib = base.Field('CapacityMiB', adapter=int) + + raid = base.Field('Raid') + + +class HPELogicalDriveCollection(base.ResourceCollectionBase): + + _maximum_size_mib = None + + @property + def _resource_type(self): + return HPELogicalDrive + + @property + def maximum_size_mib(self): + """Gets the biggest logical drive + + :returns size in MiB. + """ + if self._maximum_size_mib is None: + self._maximum_size_mib = ( + max([member.capacity_mib for member in self.get_members()])) + return self._maximum_size_mib + + def refresh(self): + super(HPELogicalDriveCollection, self).refresh() + self._maximum_size_mib = None diff --git a/proliantutils/redfish/resources/system/storage/physical_drive.py b/proliantutils/redfish/resources/system/storage/physical_drive.py new file mode 100644 index 00000000..7b743c6d --- /dev/null +++ b/proliantutils/redfish/resources/system/storage/physical_drive.py @@ -0,0 +1,58 @@ +# Copyright 2017 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. + +import logging + +from sushy.resources import base + +LOG = logging.getLogger(__name__) + + +class HPEPhysicalDrive(base.ResourceBase): + + identity = base.Field('Id', required=True) + + name = base.Field('Name') + + description = base.Field('Description') + + capacity_mib = base.Field('CapacityMiB', adapter=int) + + media_type = base.Field('MediaType') + + rotational_speed_rpm = base.Field('RotationalSpeedRpm', adapter=int) + + +class HPEPhysicalDriveCollection(base.ResourceCollectionBase): + + _maximum_size_mib = None + + @property + def _resource_type(self): + return HPEPhysicalDrive + + @property + def maximum_size_mib(self): + """Gets the biggest physical drive + + :returns size in MiB. + """ + if self._maximum_size_mib is None: + self._maximum_size_mib = ( + max([member.capacity_mib for member in self.get_members()])) + return self._maximum_size_mib + + def refresh(self): + super(HPEPhysicalDriveCollection, self).refresh() + self._maximum_size_mib = None diff --git a/proliantutils/redfish/resources/system/storage/smart_storage.py b/proliantutils/redfish/resources/system/storage/smart_storage.py new file mode 100644 index 00000000..b21112f5 --- /dev/null +++ b/proliantutils/redfish/resources/system/storage/smart_storage.py @@ -0,0 +1,79 @@ +# Copyright 2017 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. + +import logging + +from proliantutils.redfish.resources.system.storage import array_controller +from proliantutils.redfish import utils +from sushy.resources import base + +LOG = logging.getLogger(__name__) + + +class HPESmartStorage(base.ResourceBase): + + name = base.Field('Name') + """The name of the resource or array element""" + + description = base.Field('Description') + """Description""" + + _array_controllers = None + _logical_drives_maximum_size_mib = None + _physical_drives_maximum_size_mib = None + + @property + def array_controllers(self): + """This property gets the list of instances for array controllers + + This property gets the list of instances for array controllers + :returns: a list of instances of array controllers. + """ + if self._array_controllers is None: + self._array_controllers = ( + array_controller.HPEArrayControllerCollection( + self._conn, utils.get_subresource_path_by( + self, ['Links', 'ArrayControllers']), + redfish_version=self.redfish_version)) + return self._array_controllers + + @property + def logical_drives_maximum_size_mib(self): + """Gets the biggest logical drive + + :Returns the size in MiB. + """ + if self._logical_drives_maximum_size_mib is None: + self._logical_drives_maximum_size_mib = ( + max([member.logical_drives.maximum_size_mib + for member in self.array_controllers.get_members()])) + return self._logical_drives_maximum_size_mib + + @property + def physical_drives_maximum_size_mib(self): + """Gets the biggest disk drive + + :Returns the size in MiB. + """ + if self._physical_drives_maximum_size_mib is None: + self._physical_drives_maximum_size_mib = ( + max([member.physical_drives.maximum_size_mib + for member in self.array_controllers.get_members()])) + return self._physical_drives_maximum_size_mib + + 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 diff --git a/proliantutils/redfish/resources/system/system.py b/proliantutils/redfish/resources/system/system.py index 0e950d92..44102c7c 100644 --- a/proliantutils/redfish/resources/system/system.py +++ b/proliantutils/redfish/resources/system/system.py @@ -26,6 +26,8 @@ from proliantutils.redfish.resources.system import ethernet_interface from proliantutils.redfish.resources.system import mappings from proliantutils.redfish.resources.system import pci_device from proliantutils.redfish.resources.system import secure_boot +from proliantutils.redfish.resources.system.storage import \ + smart_storage as hpe_smart_storage from proliantutils.redfish import utils @@ -72,6 +74,9 @@ class HPESystem(system.System): _bios_settings = None # ref to BIOSSettings instance _secure_boot = None # ref to SecureBoot instance + + _smart_storage = None + _pci_devices = None _ethernet_interfaces = None @@ -191,6 +196,7 @@ class HPESystem(system.System): self._pci_devices = None self._secure_boot = None self._ethernet_interfaces = None + self._smart_storage = None def _get_hpe_sub_resource_collection_path(self, sub_res): path = None @@ -213,3 +219,18 @@ class HPESystem(system.System): redfish_version=self.redfish_version)) return self._ethernet_interfaces + + @property + def smart_storage(self): + """This property gets the object for smart storage. + + This property gets the object for smart storage. + There is no collection for smart storages. + :returns: an instance of smart storage + """ + if self._smart_storage is None: + self._smart_storage = hpe_smart_storage.HPESmartStorage( + self._conn, utils.get_subresource_path_by( + self, ['Oem', 'Hpe', 'Links', 'SmartStorage']), + redfish_version=self.redfish_version) + return self._smart_storage diff --git a/proliantutils/tests/redfish/json_samples/array_controller.json b/proliantutils/tests/redfish/json_samples/array_controller.json new file mode 100644 index 00000000..38c827c1 --- /dev/null +++ b/proliantutils/tests/redfish/json_samples/array_controller.json @@ -0,0 +1,49 @@ +{ + "@odata.context": "/redfish/v1/$metadata#Systems/Members/1/SmartStorage/ArrayControllers/Members/$entity", + "@odata.etag": "W/\"8DF69E2A\"", + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/", + "@odata.type": "#HpeSmartStorageArrayController.v2_0_0.HpeSmartStorageArrayController", + "AdapterType": "SmartArray", + "BackupPowerSourceStatus": "NotPresent", + "ControllerPartNumber": "836260-001", + "CurrentOperatingMode": "Mixed", + "Description": "HPE Smart Storage Array Controller View", + "EncryptionCryptoOfficerPasswordSet": false, + "EncryptionEnabled": false, + "EncryptionFwLocked": false, + "EncryptionHasLockedVolumesMissingBootPassword": false, + "EncryptionMixedVolumesEnabled": false, + "EncryptionStandaloneModeEnabled": false, + "ExternalPortCount": 0, + "FirmwareVersion": { + "Current": { + "VersionString": "0.01-808" + } + }, + "HardwareRevision": "B", + "Id": "0", + "InternalPortCount": 2, + "Links": { + "LogicalDrives": { + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/LogicalDrives/" + }, + "PhysicalDrives": { + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/DiskDrives/" + }, + "StorageEnclosures": { + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/StorageEnclosures/" + }, + "UnconfiguredDrives": { + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/UnconfiguredDrives/" + } + }, + "Location": "Slot 0", + "LocationFormat": "PCISlot", + "Model": "HPE Smart Array P408i-a SR Gen10", + "Name": "HpeSmartStorageArrayController", + "SerialNumber": "PEYHC0XRH400QI ", + "Status": { + "Health": "Warning", + "State": "Enabled" + } +} diff --git a/proliantutils/tests/redfish/json_samples/array_controller_collection.json b/proliantutils/tests/redfish/json_samples/array_controller_collection.json new file mode 100644 index 00000000..3940b823 --- /dev/null +++ b/proliantutils/tests/redfish/json_samples/array_controller_collection.json @@ -0,0 +1,14 @@ +{ + "@odata.context": "/redfish/v1/$metadata#Systems/Members/1/SmartStorage/ArrayControllers", + "@odata.etag": "W/\"E5B74C7A\"", + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/", + "@odata.type": "#HpeSmartStorageArrayControllerCollection.HpeSmartStorageArrayControllerCollection", + "Description": "HPE Smart Storage Array Controllers View", + "Members": [ + { + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/" + } + ], + "Members@odata.count": 1, + "Name": "HpeSmartStorageArrayControllers" +} diff --git a/proliantutils/tests/redfish/json_samples/disk_drive.json b/proliantutils/tests/redfish/json_samples/disk_drive.json new file mode 100644 index 00000000..7b0c59e6 --- /dev/null +++ b/proliantutils/tests/redfish/json_samples/disk_drive.json @@ -0,0 +1,42 @@ +{ + "@odata.context": "/redfish/v1/$metadata#Systems/Members/1/SmartStorage/ArrayControllers/Members/0/DiskDrives/Members/$entity", + "@odata.etag": "W/\"559F84DD\"", + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/DiskDrives/3/", + "@odata.type": "#HpeSmartStorageDiskDrive.v2_0_0.HpeSmartStorageDiskDrive", + "BlockSizeBytes": 512, + "CapacityGB": 600, + "CapacityLogicalBlocks": 1172123568, + "CapacityMiB": 572325, + "CarrierApplicationVersion": "0", + "CarrierAuthenticationStatus": "Fail", + "CurrentTemperatureCelsius": 29, + "Description": "HPE Smart Storage Disk Drive View", + "DiskDriveStatusReasons": [ + "NonAuthenticDrive" + ], + "DiskDriveUse": "Raw", + "EncryptedDrive": false, + "FirmwareVersion": { + "Current": { + "VersionString": "HPDC" + } + }, + "Id": "3", + "InterfaceSpeedMbps": 6000, + "InterfaceType": "SAS", + "LegacyBootPriority": "Primary", + "Location": "1I:0:1", + "LocationFormat": "ControllerPort:Box:Bay", + "MaximumTemperatureCelsius": 40, + "MediaType": "HDD", + "Model": "EG0600FBVFP", + "Name": "HpeSmartStorageDiskDrive", + "PowerOnHours": null, + "RotationalSpeedRpm": 10000, + "SSDEnduranceUtilizationPercentage": null, + "SerialNumber": "KWGER73R", + "Status": { + "Health": "Warning", + "State": "Enabled" + } +} diff --git a/proliantutils/tests/redfish/json_samples/disk_drive_collection.json b/proliantutils/tests/redfish/json_samples/disk_drive_collection.json new file mode 100644 index 00000000..5386b891 --- /dev/null +++ b/proliantutils/tests/redfish/json_samples/disk_drive_collection.json @@ -0,0 +1,14 @@ +{ + "@odata.context": "/redfish/v1/$metadata#Systems/Members/1/SmartStorage/ArrayControllers/Members/0/DiskDrives", + "@odata.etag": "W/\"E5B74C7A\"", + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/DiskDrives/", + "@odata.type": "#HpeSmartStorageDiskDriveCollection.HpeSmartStorageDiskDriveCollection", + "Description": "HPE Smart Storage Disk Drives View", + "Members": [ + { + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/DiskDrives/3/" + } + ], + "Members@odata.count": 1, + "Name": "HpeSmartStorageDiskDrives" +} diff --git a/proliantutils/tests/redfish/json_samples/logical_drive.json b/proliantutils/tests/redfish/json_samples/logical_drive.json new file mode 100644 index 00000000..61b94888 --- /dev/null +++ b/proliantutils/tests/redfish/json_samples/logical_drive.json @@ -0,0 +1,29 @@ +{ + "@odata.context": "/redfish/v1/$metadata#Systems/Members/1/SmartStorage/ArrayControllers/Members/0/LogicalDrives/Members/$entity", + "@odata.etag": "W/\"21D690E9\"", + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/LogicalDrives/1/", + "@odata.type": "#HpeSmartStorageLogicalDrive.v2_1_0.HpeSmartStorageLogicalDrive", + "CapacityMiB": 953837, + "Description": "HPE Smart Storage Logical Drive View", + "Id": "1", + "InterfaceType": "SATA", + "LegacyBootPriority": "None", + "Links": { + "DataDrives": { + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/LogicalDrives/1/DataDrives/" + } + }, + "LogicalDriveEncryption": false, + "LogicalDriveName": "019D4217PWDRE0XRH57093 7DA4", + "LogicalDriveNumber": 1, + "LogicalDriveType": "Data", + "MediaType": "HDD", + "Name": "HpeSmartStorageLogicalDrive", + "Raid": "0", + "Status": { + "Health": "OK", + "State": "Enabled" + }, + "StripeSizeBytes": 262144, + "VolumeUniqueIdentifier": "600508B1001CC8EF62AC74E1ABD407C1" +} diff --git a/proliantutils/tests/redfish/json_samples/logical_drive_collection.json b/proliantutils/tests/redfish/json_samples/logical_drive_collection.json new file mode 100644 index 00000000..6d401cf3 --- /dev/null +++ b/proliantutils/tests/redfish/json_samples/logical_drive_collection.json @@ -0,0 +1,14 @@ +{ + "@odata.context": "/redfish/v1/$metadata#Systems/Members/1/SmartStorage/ArrayControllers/Members/0/LogicalDrives", + "@odata.etag": "W/\"E5B74C7A\"", + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/LogicalDrives/", + "@odata.type": "#HpeSmartStorageLogicalDriveCollection.HpeSmartStorageLogicalDriveCollection", + "Description": "HPE Smart Storage Logical Drives View", + "Members": [ + { + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/LogicalDrives/1/" + } + ], + "Members@odata.count": 1, + "Name": "HpeSmartStorageLogicalDrives" +} diff --git a/proliantutils/tests/redfish/json_samples/smart_storage.json b/proliantutils/tests/redfish/json_samples/smart_storage.json new file mode 100644 index 00000000..edf9be86 --- /dev/null +++ b/proliantutils/tests/redfish/json_samples/smart_storage.json @@ -0,0 +1,20 @@ +{ + "@odata.context": "/redfish/v1/$metadata#Systems/Members/1/SmartStorage$entity", + "@odata.etag": "W/\"D9735974\"", + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/", + "@odata.type": "#HpeSmartStorage.v2_0_0.HpeSmartStorage", + "Description": "HPE Smart Storage", + "Id": "SmartStorage", + "Links": { + "ArrayControllers": { + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/" + }, + "HostBusAdapters": { + "@odata.id": "/redfish/v1/Systems/1/SmartStorage/HostBusAdapters/" + } + }, + "Name": "HpeSmartStorage", + "Status": { + "Health": "OK" + } +} diff --git a/proliantutils/tests/redfish/resources/system/storage/__init__.py b/proliantutils/tests/redfish/resources/system/storage/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/proliantutils/tests/redfish/resources/system/storage/test_array_controller.py b/proliantutils/tests/redfish/resources/system/storage/test_array_controller.py new file mode 100644 index 00000000..fb38e11d --- /dev/null +++ b/proliantutils/tests/redfish/resources/system/storage/test_array_controller.py @@ -0,0 +1,160 @@ +# Copyright 2017 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. + +import json + +import mock +import testtools + +from proliantutils.redfish.resources.system.storage import array_controller + + +class HPEArrayControllerTestCase(testtools.TestCase): + + def setUp(self): + super(HPEArrayControllerTestCase, self).setUp() + self.conn = mock.Mock() + array_controller_file = ('proliantutils/tests/redfish/json_samples/' + 'array_controller.json') + + with open(array_controller_file, 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + path = ("/redfish/v1/Systems/1/SmartStorage/ArrayControllers") + self.sys_stor = array_controller.HPEArrayController( + self.conn, path, redfish_version='1.0.2') + + def test__parse_attributes(self): + self.sys_stor._parse_attributes() + self.assertEqual('1.0.2', self.sys_stor.redfish_version) + + def test_logical_drives(self): + log_coll = None + log_dr = None + self.assertIsNone(self.sys_stor._logical_drives) + self.conn.get.return_value.json.reset_mock() + with open('proliantutils/tests/redfish/' + 'json_samples/logical_drive_collection.json') as f: + log_coll = json.loads(f.read()) + with open('proliantutils/tests/redfish/' + 'json_samples/logical_drive.json') as f: + log_dr = json.loads(f.read()) + self.conn.get.return_value.json.side_effect = [log_coll, log_dr] + actual_log_dr = self.sys_stor.logical_drives + self.conn.get.return_value.json.reset_mock() + self.assertIs(actual_log_dr, + self.sys_stor.logical_drives) + self.conn.get.return_value.json.assert_not_called() + + def test_physical_drives(self): + disk_coll = None + disk_dr = None + self.assertIsNone(self.sys_stor._physical_drives) + self.conn.get.return_value.json.reset_mock() + with open('proliantutils/tests/redfish/' + 'json_samples/disk_drive_collection.json') as f: + disk_coll = json.loads(f.read()) + with open('proliantutils/tests/redfish/' + 'json_samples/disk_drive.json') as f: + disk_dr = json.loads(f.read()) + self.conn.get.return_value.json.side_effect = [disk_coll, disk_dr] + actual_log_dr = self.sys_stor.physical_drives + self.conn.get.return_value.json.reset_mock() + self.assertIs(actual_log_dr, + self.sys_stor.physical_drives) + self.conn.get.return_value.json.assert_not_called() + + +class HPEArrayControllerCollectionTestCase(testtools.TestCase): + + def setUp(self): + super(HPEArrayControllerCollectionTestCase, self).setUp() + self.conn = mock.Mock() + with open('proliantutils/tests/redfish/json_samples/' + 'array_controller_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + self.sys_stor_col = array_controller.HPEArrayControllerCollection( + self.conn, '/redfish/v1/Systems/1/SmartStorage/ArrayControllers', + redfish_version='1.0.2') + + def test__parse_attributes(self): + self.sys_stor_col._parse_attributes() + self.assertEqual('1.0.2', self.sys_stor_col.redfish_version) + self.assertEqual('HpeSmartStorageArrayControllers', + self.sys_stor_col.name) + path = ('/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0',) + self.assertEqual(path, self.sys_stor_col.members_identities) + + @mock.patch.object(array_controller, 'HPEArrayController', autospec=True) + def test_get_member(self, mock_eth): + self.sys_stor_col.get_member( + '/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0') + mock_eth.assert_called_once_with( + self.sys_stor_col._conn, + '/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0', + redfish_version=self.sys_stor_col.redfish_version) + + @mock.patch.object(array_controller, 'HPEArrayController', autospec=True) + def test_get_members(self, mock_eth): + members = self.sys_stor_col.get_members() + path = ("/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0") + calls = [ + mock.call(self.sys_stor_col._conn, path, + redfish_version=self.sys_stor_col.redfish_version), + ] + mock_eth.assert_has_calls(calls) + self.assertIsInstance(members, list) + self.assertEqual(1, len(members)) + + def test_logical_drives_maximum_size_mib(self): + self.assertIsNone(self.sys_stor_col._logical_drives_maximum_size_mib) + 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/' + 'logical_drive_collection.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + path = ('proliantutils/tests/redfish/json_samples/' + 'logical_drive.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + self.conn.get.return_value.json.side_effect = val + expected = 953837 + actual = self.sys_stor_col.logical_drives_maximum_size_mib + self.assertEqual(expected, actual) + + def test_physical_drives_maximum_size_mib(self): + self.assertIsNone(self.sys_stor_col._physical_drives_maximum_size_mib) + 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: + val.append(json.loads(f.read())) + self.conn.get.return_value.json.side_effect = val + expected = 572325 + actual = self.sys_stor_col.physical_drives_maximum_size_mib + self.assertEqual(expected, actual) diff --git a/proliantutils/tests/redfish/resources/system/storage/test_logical_drive.py b/proliantutils/tests/redfish/resources/system/storage/test_logical_drive.py new file mode 100644 index 00000000..f67e7a89 --- /dev/null +++ b/proliantutils/tests/redfish/resources/system/storage/test_logical_drive.py @@ -0,0 +1,98 @@ +# Copyright 2017 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. + +import json + +import mock +import testtools + +from proliantutils.redfish.resources.system.storage import logical_drive + + +class HPELogicalDriveTestCase(testtools.TestCase): + + def setUp(self): + super(HPELogicalDriveTestCase, self).setUp() + self.conn = mock.Mock() + logical_file = ('proliantutils/tests/redfish/json_samples/' + 'logical_drive.json') + with open(logical_file, 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + path = ("/redfish/v1/Systems/1/SmartStorage/" + "ArrayControllers/0/LogicalDrives") + self.sys_stor = logical_drive.HPELogicalDrive( + self.conn, path, redfish_version='1.0.2') + + def test__parse_attributes(self): + self.sys_stor._parse_attributes() + self.assertEqual('1.0.2', self.sys_stor.redfish_version) + + +class HPELogicalDriveCollectionTestCase(testtools.TestCase): + + def setUp(self): + super(HPELogicalDriveCollectionTestCase, self).setUp() + self.conn = mock.Mock() + with open('proliantutils/tests/redfish/json_samples/' + 'logical_drive_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + self.sys_stor_col = logical_drive.HPELogicalDriveCollection( + self.conn, ('/redfish/v1/Systems/1/SmartStorage/' + 'ArrayControllers/0/LogicalDrives'), + redfish_version='1.0.2') + + def test__parse_attributes(self): + self.sys_stor_col._parse_attributes() + self.assertEqual('1.0.2', self.sys_stor_col.redfish_version) + self.assertEqual('HpeSmartStorageLogicalDrives', + self.sys_stor_col.name) + path = ('/redfish/v1/Systems/1/SmartStorage/' + 'ArrayControllers/0/LogicalDrives/1',) + self.assertEqual(path, self.sys_stor_col.members_identities) + + @mock.patch.object(logical_drive, 'HPELogicalDrive', autospec=True) + def test_get_member(self, mock_eth): + self.sys_stor_col.get_member( + ('/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/' + 'LogicalDrives/1')) + mock_eth.assert_called_once_with( + self.sys_stor_col._conn, + ('/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/' + 'LogicalDrives/1'), + redfish_version=self.sys_stor_col.redfish_version) + + @mock.patch.object(logical_drive, 'HPELogicalDrive', autospec=True) + def test_get_members(self, mock_eth): + members = self.sys_stor_col.get_members() + path = ("/redfish/v1/Systems/1/SmartStorage/ArrayControllers/" + "0/LogicalDrives/1") + calls = [ + mock.call(self.sys_stor_col._conn, path, + redfish_version=self.sys_stor_col.redfish_version), + ] + mock_eth.assert_has_calls(calls) + self.assertIsInstance(members, list) + self.assertEqual(1, len(members)) + + def test_maximum_size_mib(self): + self.assertIsNone(self.sys_stor_col._maximum_size_mib) + self.conn.get.return_value.json.reset_mock() + path = ('proliantutils/tests/redfish/json_samples/' + 'logical_drive.json') + with open(path, 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + expected = 953837 + actual = self.sys_stor_col.maximum_size_mib + 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 new file mode 100644 index 00000000..816670b8 --- /dev/null +++ b/proliantutils/tests/redfish/resources/system/storage/test_physical_drive.py @@ -0,0 +1,98 @@ +# Copyright 2017 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. + +import json + +import mock +import testtools + +from proliantutils.redfish.resources.system.storage import physical_drive + + +class HPEPhysicalDriveTestCase(testtools.TestCase): + + def setUp(self): + super(HPEPhysicalDriveTestCase, self).setUp() + self.conn = mock.Mock() + logical_file = ('proliantutils/tests/redfish/json_samples/' + 'disk_drive.json') + with open(logical_file, 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + path = ("/redfish/v1/Systems/1/SmartStorage/" + "ArrayControllers/0/DiskDrives") + self.sys_stor = physical_drive.HPEPhysicalDrive( + self.conn, path, redfish_version='1.0.2') + + def test__parse_attributes(self): + self.sys_stor._parse_attributes() + self.assertEqual('1.0.2', self.sys_stor.redfish_version) + + +class HPEPhysicalDriveCollectionTestCase(testtools.TestCase): + + def setUp(self): + super(HPEPhysicalDriveCollectionTestCase, self).setUp() + self.conn = mock.Mock() + with open('proliantutils/tests/redfish/json_samples/' + 'disk_drive_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + self.sys_stor_col = physical_drive.HPEPhysicalDriveCollection( + self.conn, ('/redfish/v1/Systems/1/SmartStorage/' + 'ArrayControllers/0/DiskDrives'), + redfish_version='1.0.2') + + def test__parse_attributes(self): + self.sys_stor_col._parse_attributes() + self.assertEqual('1.0.2', self.sys_stor_col.redfish_version) + self.assertEqual('HpeSmartStorageDiskDrives', + self.sys_stor_col.name) + path = ('/redfish/v1/Systems/1/SmartStorage/' + 'ArrayControllers/0/DiskDrives/3',) + self.assertEqual(path, self.sys_stor_col.members_identities) + + @mock.patch.object(physical_drive, 'HPEPhysicalDrive', autospec=True) + def test_get_member(self, mock_eth): + self.sys_stor_col.get_member( + ('/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/' + 'DiskDrives/3')) + mock_eth.assert_called_once_with( + self.sys_stor_col._conn, + ('/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/' + 'DiskDrives/3'), + redfish_version=self.sys_stor_col.redfish_version) + + @mock.patch.object(physical_drive, 'HPEPhysicalDrive', autospec=True) + def test_get_members(self, mock_eth): + members = self.sys_stor_col.get_members() + path = ("/redfish/v1/Systems/1/SmartStorage/ArrayControllers/" + "0/DiskDrives/3") + calls = [ + mock.call(self.sys_stor_col._conn, path, + redfish_version=self.sys_stor_col.redfish_version), + ] + mock_eth.assert_has_calls(calls) + self.assertIsInstance(members, list) + self.assertEqual(1, len(members)) + + def test_maximum_size_mib(self): + self.assertIsNone(self.sys_stor_col._maximum_size_mib) + self.conn.get.return_value.json.reset_mock() + path = ('proliantutils/tests/redfish/json_samples/' + 'disk_drive.json') + with open(path, 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + expected = 572325 + actual = self.sys_stor_col.maximum_size_mib + self.assertEqual(expected, actual) diff --git a/proliantutils/tests/redfish/resources/system/storage/test_smart_storage.py b/proliantutils/tests/redfish/resources/system/storage/test_smart_storage.py new file mode 100644 index 00000000..8e7a0aae --- /dev/null +++ b/proliantutils/tests/redfish/resources/system/storage/test_smart_storage.py @@ -0,0 +1,107 @@ +# Copyright 2017 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. + +import json + +import mock +import testtools + +from proliantutils.redfish.resources.system.storage import array_controller +from proliantutils.redfish.resources.system.storage import smart_storage + + +class HPESmartStorageTestCase(testtools.TestCase): + + def setUp(self): + super(HPESmartStorageTestCase, self).setUp() + self.conn = mock.Mock() + storage_file = ('proliantutils/tests/redfish/json_samples' + '/smart_storage.json') + with open(storage_file, 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + path = ("/redfish/v1/Systems/1/SmartStorage") + self.sys_stor = smart_storage.HPESmartStorage( + self.conn, path, redfish_version='1.0.2') + + def test__parse_attributes(self): + self.sys_stor._parse_attributes() + self.assertEqual('1.0.2', self.sys_stor.redfish_version) + + def test_array_controllers(self): + self.conn.get.return_value.json.reset_mock() + coll = None + value = None + path = ('proliantutils/tests/redfish/json_samples/' + 'array_controller_collection.json') + with open(path, 'r') as f: + coll = json.loads(f.read()) + with open('proliantutils/tests/redfish/json_samples/' + 'array_controller.json', 'r') as f: + value = (json.loads(f.read())) + self.conn.get.return_value.json.side_effect = [coll, value] + self.assertIsNone(self.sys_stor._array_controllers) + self.sys_stor.array_controllers + self.assertIsInstance(self.sys_stor._array_controllers, + array_controller.HPEArrayControllerCollection) + + def test_logical_drives_maximum_size_mib(self): + self.assertIsNone(self.sys_stor._logical_drives_maximum_size_mib) + 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/' + 'logical_drive_collection.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + path = ('proliantutils/tests/redfish/json_samples/' + 'logical_drive.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + self.conn.get.return_value.json.side_effect = val + expected = 953837 + actual = self.sys_stor.logical_drives_maximum_size_mib + self.assertEqual(expected, actual) + + def test_physical_drives_maximum_size_mib(self): + self.assertIsNone(self.sys_stor._physical_drives_maximum_size_mib) + 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: + val.append(json.loads(f.read())) + self.conn.get.return_value.json.side_effect = val + expected = 572325 + actual = self.sys_stor.physical_drives_maximum_size_mib + self.assertEqual(expected, actual) diff --git a/proliantutils/tests/redfish/resources/system/test_system.py b/proliantutils/tests/redfish/resources/system/test_system.py index e6b43015..ac49787e 100644 --- a/proliantutils/tests/redfish/resources/system/test_system.py +++ b/proliantutils/tests/redfish/resources/system/test_system.py @@ -24,6 +24,7 @@ from proliantutils.redfish.resources.system import bios from proliantutils.redfish.resources.system import constants as sys_cons from proliantutils.redfish.resources.system import ethernet_interface from proliantutils.redfish.resources.system import secure_boot +from proliantutils.redfish.resources.system.storage import smart_storage from proliantutils.redfish.resources.system import system from proliantutils.redfish import utils from sushy.resources.system import system as sushy_system @@ -345,3 +346,15 @@ class HPESystemTestCase(testtools.TestCase): actual_macs) self.assertIsInstance(self.sys_inst._ethernet_interfaces, ethernet_interface.EthernetInterfaceCollection) + + def test_smart_storage(self): + self.conn.get.return_value.json.reset_mock() + value = None + with open('proliantutils/tests/redfish/json_samples/' + 'smart_storage.json', 'r') as f: + value = (json.loads(f.read())) + self.conn.get.return_value.json.return_value = value + self.assertIsNone(self.sys_inst._smart_storage) + self.sys_inst.smart_storage + self.assertIsInstance(self.sys_inst._smart_storage, + smart_storage.HPESmartStorage)