Redfish: Adds SmartStorage and its related URIs for local_gb discovery
Change-Id: Iff415e0ed83c546469d70e25318d48c361c765a8
This commit is contained in:
parent
f885f47e2d
commit
ede50237fd
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
@ -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"
|
||||
}
|
42
proliantutils/tests/redfish/json_samples/disk_drive.json
Normal file
42
proliantutils/tests/redfish/json_samples/disk_drive.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
@ -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"
|
||||
}
|
29
proliantutils/tests/redfish/json_samples/logical_drive.json
Normal file
29
proliantutils/tests/redfish/json_samples/logical_drive.json
Normal file
@ -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"
|
||||
}
|
@ -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"
|
||||
}
|
20
proliantutils/tests/redfish/json_samples/smart_storage.json
Normal file
20
proliantutils/tests/redfish/json_samples/smart_storage.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
@ -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)
|
@ -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)
|
@ -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)
|
@ -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)
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user