Add PowerZone resource for RSD 2.1
Change-Id: I3d16f8a3b7424d3211e35f749711d9e694bf9800
This commit is contained in:
parent
d9c59bba76
commit
3764c4d8d0
146
rsd_lib/resources/v2_1/chassis/power_zone.py
Normal file
146
rsd_lib/resources/v2_1/chassis/power_zone.py
Normal file
@ -0,0 +1,146 @@
|
||||
# Copyright 2018 Intel, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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
|
||||
|
||||
from rsd_lib import utils as rsd_lib_utils
|
||||
|
||||
|
||||
class StatusField(base.CompositeField):
|
||||
state = base.Field('State')
|
||||
health = base.Field('Health')
|
||||
health_rollup = base.Field('HealthRollup')
|
||||
|
||||
|
||||
class RackLocationField(base.CompositeField):
|
||||
rack_units = base.Field('RackUnits')
|
||||
"""Indicates the rack unit type"""
|
||||
|
||||
xlocation = base.Field('XLocation', adapter=rsd_lib_utils.int_or_none)
|
||||
"""The horizontal location within uLocation, from left to right
|
||||
(1.. MAXIMUM) 0 indicate not available
|
||||
"""
|
||||
|
||||
ulocation = base.Field('ULocation', adapter=rsd_lib_utils.int_or_none)
|
||||
"""The index of the top-most U of the component, from top to bottom
|
||||
(1.. MAXIMUM) 0 indicate not available
|
||||
"""
|
||||
|
||||
uheight = base.Field('UHeight', adapter=rsd_lib_utils.int_or_none)
|
||||
"""The height of managed zone, e.g. 8 for 8U, 16 for 16U"""
|
||||
|
||||
|
||||
class PowerSuppliesField(base.ListField):
|
||||
name = base.Field('Name')
|
||||
"""The Power Supply name"""
|
||||
|
||||
power_capacity_watts = base.Field(
|
||||
'PowerCapacityWatts', adapter=rsd_lib_utils.int_or_none)
|
||||
"""The maximum capacity of this Power Supply"""
|
||||
|
||||
last_power_output_watts = base.Field(
|
||||
'LastPowerOutputWatts', adapter=rsd_lib_utils.int_or_none)
|
||||
"""The average power output of this Power Supply"""
|
||||
|
||||
manufacturer = base.Field('Manufacturer')
|
||||
"""The manufacturer of this Power Supply"""
|
||||
|
||||
model_number = base.Field('ModelNumber')
|
||||
"""The model number for this Power Supply"""
|
||||
|
||||
firmware_revision = base.Field('FirmwareRevision')
|
||||
"""The firmware version for this Power Supply"""
|
||||
|
||||
serial_number = base.Field('SerialNumber')
|
||||
"""The serial number for this Power Supply"""
|
||||
|
||||
part_number = base.Field('PartNumber')
|
||||
"""The part number for this Power Supply"""
|
||||
|
||||
status = StatusField('Status')
|
||||
"""The Power supply status"""
|
||||
|
||||
rack_location = RackLocationField('RackLocation')
|
||||
"""The PowerZone physical location"""
|
||||
|
||||
|
||||
class PowerZone(base.ResourceBase):
|
||||
identity = base.Field('Id', required=True)
|
||||
"""The PowerZone identity string"""
|
||||
|
||||
name = base.Field('Name')
|
||||
"""The PowerZone name"""
|
||||
|
||||
description = base.Field('Description')
|
||||
"""The PowerZone description"""
|
||||
|
||||
status = StatusField('Status')
|
||||
"""The PowerZone status"""
|
||||
|
||||
rack_location = RackLocationField('RackLocation')
|
||||
"""The PowerZone physical location"""
|
||||
|
||||
max_psus_supported = base.Field(
|
||||
'MaxPSUsSupported', adapter=rsd_lib_utils.int_or_none)
|
||||
"""The maximum number of Power Supply Units supported by PowerZone"""
|
||||
|
||||
presence = base.Field('Presence')
|
||||
"""Indicates the aggregated Power Supply Unit presence information
|
||||
Aggregated Power Supply Unit presence format: Length of string indicate
|
||||
total slot of Power Supply Units in PowerZone.
|
||||
|
||||
For each byte the string:
|
||||
"1" means present
|
||||
"0" means not present
|
||||
"""
|
||||
|
||||
number_of_psus_present = base.Field(
|
||||
'NumberOfPSUsPresent', adapter=rsd_lib_utils.int_or_none)
|
||||
"""Indicates the number of existing Power Supply Units in PowerZone"""
|
||||
|
||||
power_consumed_watts = base.Field(
|
||||
'PowerConsumedWatts', adapter=rsd_lib_utils.int_or_none)
|
||||
"""The total power consumption of PowerZone, sum of trays'
|
||||
power consumption
|
||||
"""
|
||||
|
||||
power_output_watts = base.Field(
|
||||
'PowerOutputWatts', adapter=rsd_lib_utils.int_or_none)
|
||||
"""The total power production of PowerZone, sum of PSUs' output"""
|
||||
|
||||
power_capacity_watts = base.Field(
|
||||
'PowerCapacityWatts', adapter=rsd_lib_utils.int_or_none)
|
||||
"""The maximum power capacity supported by PowerZone"""
|
||||
|
||||
power_supplies = PowerSuppliesField('PowerSupplies')
|
||||
"""Details of the power supplies associated with this system or device"""
|
||||
|
||||
|
||||
class PowerZoneCollection(base.ResourceCollectionBase):
|
||||
@property
|
||||
def _resource_type(self):
|
||||
return PowerZone
|
||||
|
||||
def __init__(self, connector, path, redfish_version=None):
|
||||
"""A class representing a PowerZone Collection
|
||||
|
||||
:param connector: A Connector instance
|
||||
:param path: The canonical path to the power zone collection resource
|
||||
:param redfish_version: The version of RedFish. Used to construct
|
||||
the object according to schema of the given version.
|
||||
"""
|
||||
super(PowerZoneCollection, self).__init__(connector,
|
||||
path,
|
||||
redfish_version)
|
50
rsd_lib/tests/unit/json_samples/v2_1/power_zone.json
Normal file
50
rsd_lib/tests/unit/json_samples/v2_1/power_zone.json
Normal file
@ -0,0 +1,50 @@
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#Chassis/Rack/PowerZones/Members/$entity",
|
||||
"@odata.id": "/redfish/v1/Chassis/Rack1/PowerZones/1",
|
||||
"@odata.type": "PowerZone.v1_0_0.PowerZone",
|
||||
"Id": "1",
|
||||
"Name": "power zone 1",
|
||||
"Description": "power zone 1 description",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK",
|
||||
"HealthRollup": "OK"
|
||||
},
|
||||
"RackLocation": {
|
||||
"RackUnits": "OU",
|
||||
"XLocation": 0,
|
||||
"ULocation": 1,
|
||||
"UHeight": 8
|
||||
},
|
||||
"MaxPSUsSupported": 6,
|
||||
"Presence": "111111",
|
||||
"NumberOfPSUsPresent": 6,
|
||||
"PowerConsumedWatts": 2000,
|
||||
"PowerOutputWatts": 2000,
|
||||
"PowerCapacityWatts": 3000,
|
||||
"PowerSupplies": [
|
||||
{
|
||||
"Name": "Power supply 1",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK",
|
||||
"HealthRollup": "OK"
|
||||
},
|
||||
"RackLocation": {
|
||||
"RackUnits": "OU",
|
||||
"XLocation": 0,
|
||||
"ULocation": 1,
|
||||
"UHeight": 8
|
||||
},
|
||||
"SerialNumber": "",
|
||||
"Manufacturer": "",
|
||||
"ModelNumber": "",
|
||||
"PartNumber": "",
|
||||
"FirmwareRevision": "",
|
||||
"PowerCapacityWatts": 300,
|
||||
"LastPowerOutputWatts": 48
|
||||
}
|
||||
],
|
||||
"Actions": {},
|
||||
"Links": {}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#PowerZoneCollection.PowerZoneCollection",
|
||||
"@odata.id": "/redfish/v1/Chassis/Rack1/PowerZones",
|
||||
"@odata.type": "#PowerZoneCollection.PowerZoneCollection",
|
||||
"Name": "Power Zones Collection",
|
||||
"Members@odata.count": 1,
|
||||
"Members": [
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Chassis/Rack1/PowerZones/Power1"
|
||||
}
|
||||
]
|
||||
}
|
128
rsd_lib/tests/unit/resources/v2_1/chassis/test_power_zone.py
Normal file
128
rsd_lib/tests/unit/resources/v2_1/chassis/test_power_zone.py
Normal file
@ -0,0 +1,128 @@
|
||||
# Copyright 2018 99cloud, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 rsd_lib.resources.v2_1.chassis import power_zone
|
||||
|
||||
|
||||
class PowerZoneTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(PowerZoneTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('rsd_lib/tests/unit/json_samples/v2_1/'
|
||||
'power_zone.json', 'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
|
||||
self.power_zone_inst = power_zone.PowerZone(
|
||||
self.conn, '/redfish/v1/Chassis/Rack1/PowerZones/1',
|
||||
redfish_version='1.1.0')
|
||||
|
||||
def test__parse_attributes(self):
|
||||
self.power_zone_inst._parse_attributes()
|
||||
self.assertEqual('1', self.power_zone_inst.identity)
|
||||
self.assertEqual('power zone 1', self.power_zone_inst.name)
|
||||
self.assertEqual('power zone 1 description',
|
||||
self.power_zone_inst.description)
|
||||
self.assertEqual('1', self.power_zone_inst.identity)
|
||||
self.assertEqual('Enabled', self.power_zone_inst.status.state)
|
||||
self.assertEqual('OK', self.power_zone_inst.status.health)
|
||||
self.assertEqual('OK', self.power_zone_inst.status.health_rollup)
|
||||
self.assertEqual('OU', self.power_zone_inst.rack_location.rack_units)
|
||||
self.assertEqual(0, self.power_zone_inst.rack_location.xlocation)
|
||||
self.assertEqual(1, self.power_zone_inst.rack_location.ulocation)
|
||||
self.assertEqual(8, self.power_zone_inst.rack_location.uheight)
|
||||
self.assertEqual(6, self.power_zone_inst.max_psus_supported)
|
||||
self.assertEqual('111111', self.power_zone_inst.presence)
|
||||
self.assertEqual(6, self.power_zone_inst.number_of_psus_present)
|
||||
self.assertEqual(2000, self.power_zone_inst.power_consumed_watts)
|
||||
self.assertEqual(2000, self.power_zone_inst.power_output_watts)
|
||||
self.assertEqual(3000, self.power_zone_inst.power_capacity_watts)
|
||||
self.assertEqual(
|
||||
'Power supply 1', self.power_zone_inst.power_supplies[0].name)
|
||||
self.assertEqual(
|
||||
300, self.power_zone_inst.power_supplies[0].power_capacity_watts)
|
||||
self.assertEqual(
|
||||
48, self.power_zone_inst.power_supplies[0].last_power_output_watts)
|
||||
self.assertEqual(
|
||||
'', self.power_zone_inst.power_supplies[0].manufacturer)
|
||||
self.assertEqual(
|
||||
'', self.power_zone_inst.power_supplies[0].model_number)
|
||||
self.assertEqual(
|
||||
'', self.power_zone_inst.power_supplies[0].firmware_revision)
|
||||
self.assertEqual(
|
||||
'', self.power_zone_inst.power_supplies[0].serial_number)
|
||||
self.assertEqual(
|
||||
'', self.power_zone_inst.power_supplies[0].part_number)
|
||||
self.assertEqual(
|
||||
'Enabled', self.power_zone_inst.power_supplies[0].status.state)
|
||||
self.assertEqual(
|
||||
'OK', self.power_zone_inst.power_supplies[0].status.health)
|
||||
self.assertEqual(
|
||||
'OK', self.power_zone_inst.power_supplies[0].status.health_rollup)
|
||||
self.assertEqual(
|
||||
'OU',
|
||||
self.power_zone_inst.power_supplies[0].rack_location.rack_units)
|
||||
self.assertEqual(
|
||||
0, self.power_zone_inst.power_supplies[0].rack_location.xlocation)
|
||||
self.assertEqual(
|
||||
1, self.power_zone_inst.power_supplies[0].rack_location.ulocation)
|
||||
self.assertEqual(
|
||||
8, self.power_zone_inst.power_supplies[0].rack_location.uheight)
|
||||
|
||||
|
||||
class PowerZoneCollectionTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(PowerZoneCollectionTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('rsd_lib/tests/unit/json_samples/v2_1/'
|
||||
'power_zone_collection.json', 'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
self.power_zone_col = power_zone.\
|
||||
PowerZoneCollection(
|
||||
self.conn, '/redfish/v1/Chassis/Rack1/PowerZones',
|
||||
redfish_version='1.1.0')
|
||||
|
||||
def test__parse_attributes(self):
|
||||
self.power_zone_col._parse_attributes()
|
||||
self.assertEqual('1.1.0', self.power_zone_col.redfish_version)
|
||||
self.assertEqual(('/redfish/v1/Chassis/Rack1/PowerZones/Power1',),
|
||||
self.power_zone_col.members_identities)
|
||||
|
||||
@mock.patch.object(power_zone, 'PowerZone', autospec=True)
|
||||
def test_get_member(self, mock_storage_subsystem):
|
||||
self.power_zone_col.get_member(
|
||||
'/redfish/v1/Chassis/Rack1/PowerZones/Power1')
|
||||
mock_storage_subsystem.assert_called_once_with(
|
||||
self.power_zone_col._conn,
|
||||
'/redfish/v1/Chassis/Rack1/PowerZones/Power1',
|
||||
redfish_version=self.power_zone_col.redfish_version)
|
||||
|
||||
@mock.patch.object(power_zone, 'PowerZone', autospec=True)
|
||||
def test_get_members(self, mock_storage_subsystem):
|
||||
members = self.power_zone_col.get_members()
|
||||
calls = [
|
||||
mock.call(self.power_zone_col._conn,
|
||||
'/redfish/v1/Chassis/Rack1/PowerZones/Power1',
|
||||
redfish_version=self.power_zone_col.
|
||||
redfish_version)
|
||||
]
|
||||
mock_storage_subsystem.assert_has_calls(calls)
|
||||
self.assertIsInstance(members, list)
|
||||
self.assertEqual(1, len(members))
|
Loading…
x
Reference in New Issue
Block a user