Merge "Redfish: Add the Storage and its related URIs for local_gb discovery"
This commit is contained in:
commit
55bd626431
|
@ -0,0 +1,35 @@
|
|||
# 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.
|
||||
|
||||
# There is no explicit collection for Drives. That said, a URI link as
|
||||
# "/redfish/v1/Systems/1/Storage/1/Drives" will be an invalid URI.
|
||||
|
||||
|
||||
from sushy.resources import base
|
||||
|
||||
|
||||
class Drive(base.ResourceBase):
|
||||
|
||||
capacity_bytes = base.Field('CapacityBytes', adapter=int)
|
||||
"""The size in bytes of this Drive"""
|
||||
|
||||
media_type = base.Field('MediaType')
|
||||
"""The type of media contained in this drive"""
|
||||
|
||||
protocol = base.Field('Protocol')
|
||||
"""The protocol this drive is using to communicate to the storage
|
||||
controller."""
|
||||
|
||||
rotation_speed_rpm = base.Field('RotationSpeedRPM', adapter=int)
|
||||
"""The rotation speed of this Drive in Revolutions per Minute (RPM)."""
|
|
@ -0,0 +1,123 @@
|
|||
# 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 drive as sys_drives
|
||||
from proliantutils.redfish.resources.system.storage \
|
||||
import volume as sys_volumes
|
||||
from proliantutils.redfish import utils
|
||||
from sushy.resources import base
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Storage(base.ResourceBase):
|
||||
|
||||
identity = base.Field('Id', required=True)
|
||||
"""The Storage identity string"""
|
||||
|
||||
name = base.Field('Name')
|
||||
"""The name of the resource or array element"""
|
||||
|
||||
description = base.Field('Description')
|
||||
"""Description"""
|
||||
|
||||
storage_controllers = base.Field('StorageControllers')
|
||||
"""The set of storage controllers"""
|
||||
|
||||
drives = base.Field('Drives')
|
||||
"""The set of drives attached to the storage controllers"""
|
||||
|
||||
_volumes = None
|
||||
_drives_maximum_size_bytes = None
|
||||
|
||||
@property
|
||||
def volumes(self):
|
||||
"""This property prepares the list of volumes
|
||||
|
||||
:return a list of volumes.
|
||||
"""
|
||||
if self._volumes is None:
|
||||
self._volumes = sys_volumes.VolumeCollection(
|
||||
self._conn, utils.get_subresource_path_by(self, 'Volumes'),
|
||||
redfish_version=self.redfish_version)
|
||||
return self._volumes
|
||||
|
||||
def _drives_list(self):
|
||||
"""This property prepares the list of drives
|
||||
|
||||
:return a list of drives.
|
||||
"""
|
||||
drives_list = []
|
||||
for member in self.drives:
|
||||
drives_list.append(sys_drives.Drive(
|
||||
self._conn, member.get('@odata.id'), self.redfish_version))
|
||||
return drives_list
|
||||
|
||||
@property
|
||||
def drives_maximum_size_bytes(self):
|
||||
"""Gets the biggest disk
|
||||
|
||||
:returns the size in MiB.
|
||||
"""
|
||||
if self._drives_maximum_size_bytes is None:
|
||||
self._drives_maximum_size_bytes = (
|
||||
max([member.capacity_bytes
|
||||
for member in self._drives_list()]))
|
||||
return self._drives_maximum_size_bytes
|
||||
|
||||
def refresh(self):
|
||||
super(Storage, self).refresh()
|
||||
self._drives_maximum_size_bytes = None
|
||||
self._volumes = None
|
||||
|
||||
|
||||
class StorageCollection(base.ResourceCollectionBase):
|
||||
|
||||
_volumes_maximum_size_bytes = None
|
||||
_drives_maximum_size_bytes = None
|
||||
|
||||
@property
|
||||
def _resource_type(self):
|
||||
return Storage
|
||||
|
||||
@property
|
||||
def volumes_maximum_size_bytes(self):
|
||||
"""Gets the biggest logical drive
|
||||
|
||||
:returns the size in MiB.
|
||||
"""
|
||||
if self._volumes_maximum_size_bytes is None:
|
||||
self._volumes_maximum_size_bytes = (
|
||||
max([member.volumes.maximum_size_bytes
|
||||
for member in self.get_members()]))
|
||||
return self._volumes_maximum_size_bytes
|
||||
|
||||
@property
|
||||
def drives_maximum_size_bytes(self):
|
||||
"""Gets the biggest disk
|
||||
|
||||
:returns the size in MiB.
|
||||
"""
|
||||
if self._drives_maximum_size_bytes is None:
|
||||
self._drives_maximum_size_bytes = (
|
||||
max([member.drives_maximum_size_bytes
|
||||
for member in self.get_members()]))
|
||||
return self._drives_maximum_size_bytes
|
||||
|
||||
def refresh(self):
|
||||
super(StorageCollection, self).refresh()
|
||||
self._volumes_maximum_size_bytes = None
|
||||
self._drives_maximum_size_bytes = None
|
|
@ -0,0 +1,52 @@
|
|||
# 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.
|
||||
|
||||
|
||||
from sushy.resources import base
|
||||
|
||||
|
||||
class Volume(base.ResourceBase):
|
||||
|
||||
identity = base.Field('Id', required=True)
|
||||
"""The processor identity string"""
|
||||
|
||||
capacity_bytes = base.Field('CapacityBytes', adapter=int)
|
||||
"""The size in bytes of this Volume"""
|
||||
|
||||
volume_type = base.Field('VolumeType')
|
||||
"""The type of this volume."""
|
||||
|
||||
|
||||
class VolumeCollection(base.ResourceCollectionBase):
|
||||
|
||||
_maximum_size_bytes = None
|
||||
|
||||
@property
|
||||
def _resource_type(self):
|
||||
return Volume
|
||||
|
||||
@property
|
||||
def maximum_size_bytes(self):
|
||||
"""Gets the biggest volume
|
||||
|
||||
:returns size in bytes.
|
||||
"""
|
||||
if self._maximum_size_bytes is None:
|
||||
self._maximum_size_bytes = (
|
||||
max([member.capacity_bytes for member in self.get_members()]))
|
||||
return self._maximum_size_bytes
|
||||
|
||||
def refresh(self):
|
||||
super(VolumeCollection, self).refresh()
|
||||
self._maximum_size_bytes = None
|
|
@ -28,6 +28,7 @@ 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.resources.system.storage import storage
|
||||
from proliantutils.redfish import utils
|
||||
|
||||
|
||||
|
@ -76,7 +77,7 @@ class HPESystem(system.System):
|
|||
_secure_boot = None # ref to SecureBoot instance
|
||||
|
||||
_smart_storage = None
|
||||
|
||||
_storages = None
|
||||
_pci_devices = None
|
||||
_ethernet_interfaces = None
|
||||
|
||||
|
@ -197,6 +198,7 @@ class HPESystem(system.System):
|
|||
self._secure_boot = None
|
||||
self._ethernet_interfaces = None
|
||||
self._smart_storage = None
|
||||
self._storages = None
|
||||
|
||||
def _get_hpe_sub_resource_collection_path(self, sub_res):
|
||||
path = None
|
||||
|
@ -234,3 +236,16 @@ class HPESystem(system.System):
|
|||
self, ['Oem', 'Hpe', 'Links', 'SmartStorage']),
|
||||
redfish_version=self.redfish_version)
|
||||
return self._smart_storage
|
||||
|
||||
@property
|
||||
def storages(self):
|
||||
"""This property gets the list of instances for Storages
|
||||
|
||||
This property gets the list of instances for Storages
|
||||
:returns: a list of instances of Storages
|
||||
"""
|
||||
if self._storages is None:
|
||||
self._storages = storage.StorageCollection(
|
||||
self._conn, utils.get_subresource_path_by(self, 'Storage'),
|
||||
redfish_version=self.redfish_version)
|
||||
return self._storages
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"drive1":{
|
||||
"@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": 15000,
|
||||
"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"
|
||||
},
|
||||
"drive2": {
|
||||
"@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": "3F5A8C54207B7233"
|
||||
}],
|
||||
"HotspareType": "None",
|
||||
"EncryptionAbility": "SelfEncryptingDrive",
|
||||
"EncryptionStatus": "Unlocked",
|
||||
"RotationSpeedRPM": 15000,
|
||||
"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/3F5A8C54207B7233/Actions/Drive.SecureErase"
|
||||
}
|
||||
},
|
||||
"@odata.context": "/redfish/v1/$metadata#Drive.Drive",
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Drives/3F5A8C54207B7233"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"@odata.type": "#Storage.v1_1_0.Storage",
|
||||
"Id": "1",
|
||||
"Name": "Local Storage Controller",
|
||||
"Description": "Integrated RAID Controller",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK",
|
||||
"HealthRollup": "OK"
|
||||
},
|
||||
"StorageControllers": [{
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1#/StorageControllers/0",
|
||||
"@odata.type": "#Storage.v1_0_0.StorageController",
|
||||
"Id": "0",
|
||||
"Name": "Contoso Integrated RAID",
|
||||
"Description": "Contoso Integrated RAID",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK"
|
||||
},
|
||||
"Identifiers": [{
|
||||
"DurableNameFormat": "NAA",
|
||||
"DurableName": "345C59DBD970859C"
|
||||
}],
|
||||
"Manufacturer": "Contoso",
|
||||
"Model": "12Gbs Integrated RAID",
|
||||
"SerialNumber": "2M220100SL",
|
||||
"PartNumber": "CT18754",
|
||||
"SpeedGbps": 12,
|
||||
"FirmwareVersion": "1.0.0.7",
|
||||
"SupportedControllerProtocols": [
|
||||
"PCIe"
|
||||
],
|
||||
"SupportedDeviceProtocols": [
|
||||
"SAS",
|
||||
"SATA"
|
||||
]
|
||||
}],
|
||||
"Drives": [{
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Drives/35D38F11ACEF7BD3"
|
||||
}, {
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Drives/3F5A8C54207B7233"
|
||||
}],
|
||||
"Volumes": {
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes"
|
||||
},
|
||||
"Links": {},
|
||||
"Actions": {
|
||||
"#Storage.SetEncryptionKey": {
|
||||
"Target": "/redfish/v1/Systems/437XR1138R2/Storage/1/Actions/Storage.SetEncryptionKey"
|
||||
}
|
||||
},
|
||||
"@odata.context": "/redfish/v1/$metadata#Storage.Storage",
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1"
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"@odata.type": "#StorageCollection.StorageCollection",
|
||||
"Name": "Storage Collection",
|
||||
"Members@odata.count": 1,
|
||||
"Members": [{
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1"
|
||||
}],
|
||||
"@odata.context": "/redfish/v1/$metadata#StorageCollection.StorageCollection",
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage"
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"@odata.type": "#Volume.v1_0_0.Volume",
|
||||
"Id": "1",
|
||||
"Name": "Virtual Disk 1",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK"
|
||||
},
|
||||
"Encrypted": false,
|
||||
"VolumeType": "Mirrored",
|
||||
"CapacityBytes": 899527000000,
|
||||
"Identifiers": [{
|
||||
"DurableNameFormat": "VPD83type3",
|
||||
"DurableName": "690b11c02547001d96f0fbe6c1cb31"
|
||||
}, {
|
||||
"DurableNameFormat": "UUID",
|
||||
"DurableName": "38f1818b-111e-463a-aa19-fa54f792e468"
|
||||
}],
|
||||
"Links": {
|
||||
"Drives": [{
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Drives/3F5A8C54207B7233"
|
||||
}, {
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Drives/35D38F11ACEF7BD3"
|
||||
}]
|
||||
},
|
||||
"Actions": {
|
||||
"#Volume.Initialize": {
|
||||
"Target": "/redfish/v1/Systems/3/Storage/RAIDIntegrated/Volumes/1/Actions/Volume.Initialize",
|
||||
"InitializeType@Redfish.AllowableValues": [
|
||||
"Fast",
|
||||
"Slow"
|
||||
]
|
||||
}
|
||||
},
|
||||
"@odata.context": "/redfish/v1/$metadata#Volume.Volume",
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes/1"
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#VolumeCollection.VolumeCollection",
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes",
|
||||
"@odata.type": "#VolumeCollection.VolumeCollection",
|
||||
"Name": "Storage Volume Collection",
|
||||
"Description": "Storage Volume Collection",
|
||||
"Members@odata.count": 1,
|
||||
"Members": [{
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes/1"
|
||||
}],
|
||||
"Oem": {}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
# 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 drive
|
||||
|
||||
|
||||
class DriveTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(DriveTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
drive_file = 'proliantutils/tests/redfish/json_samples/drive.json'
|
||||
with open(drive_file, 'r') as f:
|
||||
dr_json = json.loads(f.read())
|
||||
self.conn.get.return_value.json.return_value = dr_json['drive1']
|
||||
|
||||
drive_path = ("/redfish/v1/Systems/437XR1138R2/Storage/1/"
|
||||
"Drives/35D38F11ACEF7BD3")
|
||||
self.sys_drive = drive.Drive(
|
||||
self.conn, drive_path, redfish_version='1.0.2')
|
||||
|
||||
def test__parse_attributes(self):
|
||||
self.sys_drive._parse_attributes()
|
||||
self.assertEqual('1.0.2', self.sys_drive.redfish_version)
|
|
@ -0,0 +1,172 @@
|
|||
# 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 storage
|
||||
|
||||
|
||||
class StorageTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(StorageTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
storage_file = 'proliantutils/tests/redfish/json_samples/storage.json'
|
||||
with open(storage_file, 'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
self.stor_json = self.conn.get.return_value.json.return_value
|
||||
|
||||
path = ("/redfish/v1/Systems/437XR1138R2/Storage/1")
|
||||
self.sys_stor = storage.Storage(
|
||||
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)
|
||||
self.assertEqual('1', self.sys_stor.identity)
|
||||
self.assertEqual('Local Storage Controller', self.sys_stor.name)
|
||||
self.assertEqual('Integrated RAID Controller',
|
||||
self.sys_stor.description)
|
||||
self.assertEqual(self.stor_json.get('StorageControllers'),
|
||||
self.sys_stor.storage_controllers)
|
||||
self.assertEqual(self.stor_json.get('Drives'),
|
||||
self.sys_stor.drives)
|
||||
|
||||
def test_volumes(self):
|
||||
log_coll = None
|
||||
log_dr = None
|
||||
self.assertIsNone(self.sys_stor._volumes)
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
with open('proliantutils/tests/redfish/'
|
||||
'json_samples/volume_collection.json') as f:
|
||||
log_coll = json.loads(f.read())
|
||||
with open('proliantutils/tests/redfish/'
|
||||
'json_samples/volume.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.volumes
|
||||
self.assertIs(actual_log_dr,
|
||||
self.sys_stor.volumes)
|
||||
self.sys_stor.refresh()
|
||||
self.assertIsNone(self.sys_stor._volumes)
|
||||
|
||||
def test_drives_list(self):
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
with open('proliantutils/tests/redfish/'
|
||||
'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']]
|
||||
actual_dr = self.sys_stor._drives_list()
|
||||
self.assertIsInstance(actual_dr, list)
|
||||
|
||||
def test_drives_maximum_size_bytes(self):
|
||||
self.assertIsNone(self.sys_stor._drives_maximum_size_bytes)
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
val = []
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'drive.json')
|
||||
with open(path, 'r') as f:
|
||||
dr_json = json.loads(f.read())
|
||||
val.append(dr_json['drive1'])
|
||||
val.append(dr_json['drive2'])
|
||||
self.conn.get.return_value.json.side_effect = val
|
||||
expected = 899527000000
|
||||
actual = self.sys_stor.drives_maximum_size_bytes
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
|
||||
class StorageCollectionTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(StorageCollectionTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('proliantutils/tests/redfish/json_samples/'
|
||||
'storage_collection.json', 'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
self.sys_stor_col = storage.StorageCollection(
|
||||
self.conn, '/redfish/v1/Systems/437XR1138R2/Storage',
|
||||
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('Storage Collection',
|
||||
self.sys_stor_col.name)
|
||||
path = ('/redfish/v1/Systems/437XR1138R2/Storage/1',)
|
||||
self.assertEqual(path, self.sys_stor_col.members_identities)
|
||||
|
||||
@mock.patch.object(storage, 'Storage', autospec=True)
|
||||
def test_get_member(self, mock_eth):
|
||||
self.sys_stor_col.get_member(
|
||||
'/redfish/v1/Systems/437XR1138R2/Storage/1')
|
||||
mock_eth.assert_called_once_with(
|
||||
self.sys_stor_col._conn,
|
||||
('/redfish/v1/Systems/437XR1138R2/Storage/1'),
|
||||
redfish_version=self.sys_stor_col.redfish_version)
|
||||
|
||||
@mock.patch.object(storage, 'Storage', autospec=True)
|
||||
def test_get_members(self, mock_eth):
|
||||
members = self.sys_stor_col.get_members()
|
||||
path = ("/redfish/v1/Systems/437XR1138R2/Storage/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_volumes_maximum_size_bytes(self):
|
||||
self.assertIsNone(self.sys_stor_col._volumes_maximum_size_bytes)
|
||||
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/'
|
||||
'volume_collection.json')
|
||||
with open(path, 'r') as f:
|
||||
val.append(json.loads(f.read()))
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'volume.json')
|
||||
with open(path, 'r') as f:
|
||||
val.append(json.loads(f.read()))
|
||||
self.conn.get.return_value.json.side_effect = val
|
||||
expected = 899527000000
|
||||
actual = self.sys_stor_col.volumes_maximum_size_bytes
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_drives_maximum_size_bytes(self):
|
||||
self.assertIsNone(self.sys_stor_col._drives_maximum_size_bytes)
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
val = []
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'storage.json')
|
||||
with open(path, 'r') as f:
|
||||
val.append(json.loads(f.read()))
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'drive.json')
|
||||
with open(path, 'r') as f:
|
||||
dr_json = json.loads(f.read())
|
||||
val.append(dr_json['drive1'])
|
||||
val.append(dr_json['drive2'])
|
||||
self.conn.get.return_value.json.side_effect = val
|
||||
expected = 899527000000
|
||||
actual = self.sys_stor_col.drives_maximum_size_bytes
|
||||
self.assertEqual(expected, actual)
|
|
@ -0,0 +1,94 @@
|
|||
# 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 volume
|
||||
|
||||
|
||||
class VolumeTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(VolumeTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
vol_file = 'proliantutils/tests/redfish/json_samples/volume.json'
|
||||
with open(vol_file, 'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
|
||||
vol_path = ("/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes/1")
|
||||
self.sys_vol = volume.Volume(
|
||||
self.conn, vol_path, redfish_version='1.0.2')
|
||||
|
||||
def test__parse_attributes(self):
|
||||
self.sys_vol._parse_attributes()
|
||||
self.assertEqual('1.0.2', self.sys_vol.redfish_version)
|
||||
self.assertEqual('1', self.sys_vol.identity)
|
||||
self.assertEqual('Mirrored', self.sys_vol.volume_type)
|
||||
self.assertEqual(899527000000, self.sys_vol.capacity_bytes)
|
||||
|
||||
|
||||
class VolumeCollectionTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(VolumeCollectionTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('proliantutils/tests/redfish/json_samples/'
|
||||
'volume_collection.json', 'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
self.sys_vol_col = volume.VolumeCollection(
|
||||
self.conn, '/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes',
|
||||
redfish_version='1.0.2')
|
||||
|
||||
def test__parse_attributes(self):
|
||||
self.sys_vol_col._parse_attributes()
|
||||
self.assertEqual('1.0.2', self.sys_vol_col.redfish_version)
|
||||
self.assertEqual('Storage Volume Collection',
|
||||
self.sys_vol_col.name)
|
||||
vol_path = ('/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes/1',)
|
||||
self.assertEqual(vol_path, self.sys_vol_col.members_identities)
|
||||
|
||||
@mock.patch.object(volume, 'Volume', autospec=True)
|
||||
def test_get_member(self, mock_vol):
|
||||
self.sys_vol_col.get_member(
|
||||
'/redfish/v1/Systems/437XR1138R2/Volumes/1')
|
||||
mock_vol.assert_called_once_with(
|
||||
self.sys_vol_col._conn,
|
||||
('/redfish/v1/Systems/437XR1138R2/Volumes/1'),
|
||||
redfish_version=self.sys_vol_col.redfish_version)
|
||||
|
||||
@mock.patch.object(volume, 'Volume', autospec=True)
|
||||
def test_get_members(self, mock_vol):
|
||||
members = self.sys_vol_col.get_members()
|
||||
vol_path = ("/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes/1")
|
||||
calls = [
|
||||
mock.call(self.sys_vol_col._conn, vol_path,
|
||||
redfish_version=self.sys_vol_col.redfish_version),
|
||||
]
|
||||
mock_vol.assert_has_calls(calls)
|
||||
self.assertIsInstance(members, list)
|
||||
self.assertEqual(1, len(members))
|
||||
|
||||
def test_maximum_size_bytes(self):
|
||||
self.assertIsNone(self.sys_vol_col._maximum_size_bytes)
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'volume.json')
|
||||
with open(path, 'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
expected = 899527000000
|
||||
actual = self.sys_vol_col.maximum_size_bytes
|
||||
self.assertEqual(expected, actual)
|
|
@ -25,6 +25,7 @@ from proliantutils.redfish.resources.system import constants as sys_cons
|
|||
from proliantutils.redfish.resources.system import ethernet_interface
|
||||
from proliantutils.redfish.resources.system import secure_boot
|
||||
from proliantutils.redfish.resources.system.storage import smart_storage
|
||||
from proliantutils.redfish.resources.system.storage import storage
|
||||
from proliantutils.redfish.resources.system import system
|
||||
from proliantutils.redfish import utils
|
||||
from sushy.resources.system import system as sushy_system
|
||||
|
@ -358,3 +359,20 @@ class HPESystemTestCase(testtools.TestCase):
|
|||
self.sys_inst.smart_storage
|
||||
self.assertIsInstance(self.sys_inst._smart_storage,
|
||||
smart_storage.HPESmartStorage)
|
||||
|
||||
def test_storages(self):
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
coll = None
|
||||
value = None
|
||||
path = ('proliantutils/tests/redfish/json_samples/'
|
||||
'storage_collection.json')
|
||||
with open(path, 'r') as f:
|
||||
coll = json.loads(f.read())
|
||||
with open('proliantutils/tests/redfish/json_samples/'
|
||||
'storage.json', 'r') as f:
|
||||
value = (json.loads(f.read()))
|
||||
self.conn.get.return_value.json.side_effect = [coll, value]
|
||||
self.assertIsNone(self.sys_inst._storages)
|
||||
self.sys_inst.storages
|
||||
self.assertIsInstance(self.sys_inst._storages,
|
||||
storage.StorageCollection)
|
||||
|
|
Loading…
Reference in New Issue