Add missing attribute in Power in RSD 2.2

Change-Id: I2bef7e18158430e1d272383ee7f123bb0eb0f7ca
This commit is contained in:
Lin Yang 2019-05-29 11:32:53 -07:00
parent aeacfae878
commit b72d928986
10 changed files with 486 additions and 13 deletions

View File

@ -0,0 +1,45 @@
# Copyright 2019 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 import utils
from rsd_lib.resources.v2_1.chassis import chassis
from rsd_lib.resources.v2_2.chassis import power
class Chassis(chassis.Chassis):
"""Chassis resource class
A Chassis represents the physical components for any system. This
resource represents the sheet-metal confined spaces and logical zones
like racks, enclosures, chassis and all other containers. Subsystems
(like sensors), which operate outside of a system's data plane (meaning
the resources are not accessible to software running on the system) are
linked either directly or indirectly through this resource.
"""
@property
@utils.cache_it
def power(self):
"""Property to provide reference to `Power` instance
It is calculated once when it is queried for the first time. On
refresh, this property is reset.
"""
return power.Power(
self._conn,
utils.get_sub_resource_path_by(self, "Power"),
redfish_version=self.redfish_version,
)

View File

@ -0,0 +1,61 @@
# Copyright 2019 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.resources.v2_1.chassis import power
from rsd_lib import utils as rsd_lib_utils
class IntelRackScaleField(base.CompositeField):
"""Power field
Extended Power resource.
"""
input_ac_power_watts = base.Field(
"InputACPowerWatts", adapter=rsd_lib_utils.num_or_none
)
"""The global power level on AC side in Watts."""
class OemField(base.CompositeField):
intel_rackscale = IntelRackScaleField("Intel_RackScale")
"""Intel Rack Scale Design specific properties."""
class PowerSupplyCollectionField(power.PowerSupplyCollectionField):
"""PowerSupply field
Details of a power supplies associated with this system or device
"""
indicator_led = base.Field("IndicatorLED")
"""The state of the indicator LED, used to identify the power supply."""
class Power(power.Power):
"""Power resource class
This is the schema definition for the Power Metrics. It represents the
properties for Power Consumption and Power Limiting.
"""
power_supplies = PowerSupplyCollectionField("PowerSupplies")
"""Details of the power supplies associated with this system or device"""
oem = OemField("Oem")
"""Oem specific properties."""

View File

@ -0,0 +1,118 @@
{
"@odata.context": "/redfish/v1/$metadata#Chassis/Members/$entity",
"@odata.id": "/redfish/v1/Chassis/1",
"@odata.type": "#Chassis.v1_3_0.Chassis",
"Id": "1",
"ChassisType": "RackMount",
"Name": "name-as-string",
"Description": "description-as-string",
"Manufacturer": "Intel Corporation",
"Model": "model-as-string",
"SKU": "sku-as-string",
"SerialNumber": "serial-number-as-string",
"PartNumber": "part-number-as-string",
"AssetTag": "FlexChassis1",
"IndicatorLED": "Unknown",
"PowerState": "On",
"PhysicalSecurity": {
"IntrusionSensorNumber": 1,
"IntrusionSensor": 2,
"IntrusionSensorReArm": 3
},
"Status": {
"State": "Enabled",
"Health": "OK"
},
"Oem": {
"Intel_RackScale": {
"@odata.type": "#Intel.Oem.RackChassis",
"Location": {
"Id": "Rack1",
"ParentId": "Pod1"
},
"RMMPresent": true,
"RackSupportsDisaggregatedPowerCooling": true,
"UUID": "Unique ID",
"GeoTag": "54.348103, 18.645172"
}
},
"ThermalZones": {
"@odata.id": "/redfish/v1/Chassis/Rack1/ThermalZones"
},
"PowerZones": {
"@odata.id": "/redfish/v1/Chassis/Rack1/PowerZones"
},
"Thermal": {
"@odata.id": "/redfish/v1/Chassis/Rack1/Thermal"
},
"Power": {
"@odata.id": "/redfish/v1/Chassis/Rack1/Power"
},
"Links": {
"@odata.type": "#Chassis.v1_2_0.Links",
"Contains": [
{
"@odata.id": "/redfish/v1/Chassis/Drawer1"
}
],
"ContainedBy": null,
"ComputerSystems": [
{
"@odata.id": "/redfish/v1/Systems/system1"
},
{
"@odata.id": "/redfish/v1/Systems/system2"
},
{
"@odata.id": "/redfish/v1/Systems/system3"
},
{
"@odata.id": "/redfish/v1/Systems/system4"
}
],
"Drives": [
{
"@odata.id": "/redfish/v1/Drives/1"
}
],
"Storage": [
{
"@odata.id": "/redfish/v1/Storage/1"
}
],
"CooledBy": [
{
"@odata.id": "/redfish/v1/Cool/1"
}
],
"PoweredBy": [
{
"@odata.id": "/redfish/v1/Power/1"
}
],
"ManagedBy": [
{
"@odata.id": "/redfish/v1/Managers/RMM"
}
],
"ManagersInChassis": [
{
"@odata.id": "/redfish/v1/Managers/RMM"
}
],
"Oem": {
"Intel_RackScale": {
"@odata.type": "#Intel.Oem.ChassisLinks",
"Switches": []
}
},
"PCIeDevices": [
{
"@data.id": "/redfish/v1/Chassis/1/PCIeDevices/Device1"
},
{
"@data.id": "/redfish/v1/Chassis/1/PCIeDevices/Device2"
}
]
}
}

View File

@ -0,0 +1,133 @@
{
"@odata.context": "/redfish/v1/$metadata#Power.Power",
"@odata.id": "/redfish/v1/Chassis/Rack1/Power",
"@odata.type": "#Power.v1_1_0.Power",
"Id": "Power",
"Name": "PowerName",
"Description": "PowerSubsystem",
"PowerControl": [
{
"@odata.id": "/redfish/v1/Chassis/Rack1/Power#/PowerControl/0",
"MemberId": "0",
"Name": "System Power Control",
"PowerConsumedWatts": 8000,
"PowerRequestedWatts": 8500,
"PowerAvailableWatts": 8500,
"PowerCapacityWatts": 10000,
"PowerAllocatedWatts": 8500,
"PowerMetrics": {
"IntervalInMin": 30,
"MinConsumedWatts": 7500,
"MaxConsumedWatts": 8200,
"AverageConsumedWatts": 8000
},
"PowerLimit": {
"LimitInWatts": 9000,
"LimitException": "LogEventOnly",
"CorrectionInMs": 42
},
"RelatedItem": [
{"@odata.id": "/redfish/v1/Chassis/Drawer1"},
{"@odata.id": "/redfish/v1/Systems/System1"}
],
"Status": {
"State": "Enabled",
"Health": "OK",
"HealthRollup": "OK"
},
"Oem": {}
}
],
"Voltages": [
{
"@odata.id": "/redfish/v1/Chassis/Rack1/Power#/Voltages/0",
"MemberId": "0",
"Name": "VRM1 Voltage",
"SensorNumber": 11,
"Status": {
"State": "Enabled",
"Health": "OK"
},
"ReadingVolts": 12,
"UpperThresholdNonCritical": 100.5,
"UpperThresholdCritical": 13,
"UpperThresholdFatal": 15,
"LowerThresholdNonCritical": 11.5,
"LowerThresholdCritical": 11,
"LowerThresholdFatal": 10,
"MinReadingRange": 0,
"MaxReadingRange": 20,
"PhysicalContext": "VoltageRegulator",
"RelatedItem": [
{"@odata.id": "/redfish/v1/Systems/System1" }
]
}
],
"PowerSupplies": [
{
"@odata.id": "/redfish/v1/Chassis/Rack1/Power#/PowerSupplies/0",
"MemberId": "0",
"Name": "Power Supply Bay 1",
"Status": {
"State": "Enabled",
"Health": "Warning"
},
"Oem": {},
"PowerSupplyType": "DC",
"LineInputVoltageType": "DCNeg48V",
"LineInputVoltage": -48,
"PowerCapacityWatts": 400,
"LastPowerOutputWatts": 192,
"Model": "499253-B21",
"Manufacturer": "ManufacturerName",
"FirmwareVersion": "1.00",
"SerialNumber": "1z0000001",
"PartNumber": "1z0000001A3a",
"SparePartNumber": "0000001A3a",
"IndicatorLED": "Off",
"InputRanges": [
{
"InputType": "DC",
"MinimumVoltage": -47,
"MaximumVoltage": -49,
"OutputWattage": 400,
"MinimumFrequencyHz": 50,
"MaximumFrequencyHz": 60,
"Oem": {}
}
],
"RelatedItem": [
{"@odata.id": "/redfish/v1/Chassis/Rack1"}
],
"Redundancy": [
{
"@odata.id": "/redfish/v1/Chassis/1/Power#/Redundancy/0",
"MemberId": "0",
"Name": "PowerSupply Redundancy Group 2"
}
]
}
],
"Redundancy": [
{
"@odata.id": "/redfish/v1/Chassis/Rack1/Power#/Redundancy/0",
"MemberId": "0",
"Name": "PowerSupply Redundancy Group 1",
"Mode": "Failover",
"MaxNumSupported": 2,
"MinNumNeeded": 1,
"RedundancySet": [
{"@odata.id": "/redfish/v1/Chassis/1/Power#/PowerSupplies/0"}
],
"Status": {
"State": "Offline",
"Health": "OK"
}
}
],
"Oem": {
"Intel_RackScale": {
"InputACPowerWatts": 245
}
}
}

View File

@ -167,7 +167,7 @@ class TestChassis(base.TestCase):
# On refreshing the chassis instance...
with open(
"rsd_lib/tests/unit/json_samples/v2_1/" "chassis.json", "r"
"rsd_lib/tests/unit/json_samples/v2_1/chassis.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
@ -190,7 +190,7 @@ class TestChassis(base.TestCase):
# | GIVEN |
self.conn.get.return_value.json.reset_mock()
with open(
"rsd_lib/tests/unit/json_samples/v2_1/" "power.json", "r"
"rsd_lib/tests/unit/json_samples/v2_1/power.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN |
@ -209,7 +209,7 @@ class TestChassis(base.TestCase):
def test_power_on_refresh(self):
# | GIVEN |
with open(
"rsd_lib/tests/unit/json_samples/v2_1/" "power.json", "r"
"rsd_lib/tests/unit/json_samples/v2_1/power.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN |
@ -217,7 +217,7 @@ class TestChassis(base.TestCase):
# On refreshing the chassis instance...
with open(
"rsd_lib/tests/unit/json_samples/v2_1/" "chassis.json", "r"
"rsd_lib/tests/unit/json_samples/v2_1/chassis.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
@ -226,7 +226,7 @@ class TestChassis(base.TestCase):
# | GIVEN |
with open(
"rsd_lib/tests/unit/json_samples/v2_1/" "power.json", "r"
"rsd_lib/tests/unit/json_samples/v2_1/power.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN |
@ -271,7 +271,7 @@ class TestChassis(base.TestCase):
# On refreshing the chassis instance...
with open(
"rsd_lib/tests/unit/json_samples/v2_1/" "chassis.json", "r"
"rsd_lib/tests/unit/json_samples/v2_1/chassis.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
@ -294,7 +294,7 @@ class TestChassis(base.TestCase):
# | GIVEN |
self.conn.get.return_value.json.reset_mock()
with open(
"rsd_lib/tests/unit/json_samples/v2_1/" "thermal.json", "r"
"rsd_lib/tests/unit/json_samples/v2_1/thermal.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN |
@ -313,7 +313,7 @@ class TestChassis(base.TestCase):
def test_thermal_on_refresh(self):
# | GIVEN |
with open(
"rsd_lib/tests/unit/json_samples/v2_1/" "thermal.json", "r"
"rsd_lib/tests/unit/json_samples/v2_1/thermal.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN |
@ -321,7 +321,7 @@ class TestChassis(base.TestCase):
# On refreshing the chassis instance...
with open(
"rsd_lib/tests/unit/json_samples/v2_1/" "chassis.json", "r"
"rsd_lib/tests/unit/json_samples/v2_1/chassis.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
@ -330,7 +330,7 @@ class TestChassis(base.TestCase):
# | GIVEN |
with open(
"rsd_lib/tests/unit/json_samples/v2_1/" "thermal.json", "r"
"rsd_lib/tests/unit/json_samples/v2_1/thermal.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN |

View File

@ -24,9 +24,7 @@ class PowerTestCase(testtools.TestCase):
def setUp(self):
super(PowerTestCase, self).setUp()
self.conn = mock.Mock()
with open(
"rsd_lib/tests/unit/json_samples/v2_1/" "power.json", "r"
) as f:
with open("rsd_lib/tests/unit/json_samples/v2_1/power.json", "r") as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.power_inst = power.Power(

View File

@ -0,0 +1,75 @@
# Copyright 2019 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.
import json
import mock
import testtools
from rsd_lib.resources.v2_2.chassis import chassis
from rsd_lib.resources.v2_2.chassis import power
class ChassisTestCase(testtools.TestCase):
def setUp(self):
super(ChassisTestCase, self).setUp()
self.conn = mock.Mock()
with open(
"rsd_lib/tests/unit/json_samples/v2_2/chassis.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.chassis_inst = chassis.Chassis(
self.conn, "/redfish/v1/Chassis/chassis1", redfish_version="1.0.2"
)
def test_power(self):
# | GIVEN |
self.conn.get.return_value.json.reset_mock()
with open("rsd_lib/tests/unit/json_samples/v2_2/power.json", "r") as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN |
actual_power = self.chassis_inst.power
# | THEN |
self.assertIsInstance(actual_power, power.Power)
self.conn.get.return_value.json.assert_called_once_with()
# reset mock
self.conn.get.return_value.json.reset_mock()
# | WHEN & THEN |
# tests for same object on invoking subsequently
self.assertIs(actual_power, self.chassis_inst.power)
self.conn.get.return_value.json.assert_not_called()
def test_power_on_refresh(self):
# | GIVEN |
with open("rsd_lib/tests/unit/json_samples/v2_2/power.json", "r") as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN |
self.assertIsInstance(self.chassis_inst.power, power.Power)
# On refreshing the chassis instance...
with open(
"rsd_lib/tests/unit/json_samples/v2_2/chassis.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.chassis_inst.invalidate()
self.chassis_inst.refresh(force=False)
# | GIVEN |
with open("rsd_lib/tests/unit/json_samples/v2_2/power.json", "r") as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN |
self.assertIsInstance(self.chassis_inst.power, power.Power)

View File

@ -0,0 +1,43 @@
# Copyright 2019 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.
import json
import mock
import testtools
from rsd_lib.resources.v2_2.chassis import power
class PowerTestCase(testtools.TestCase):
def setUp(self):
super(PowerTestCase, self).setUp()
self.conn = mock.Mock()
with open("rsd_lib/tests/unit/json_samples/v2_2/power.json", "r") as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.power_inst = power.Power(
self.conn,
"/redfish/v1/Chassis/Rack1/Power",
redfish_version="1.1.0",
)
def test__parse_attributes(self):
self.power_inst._parse_attributes()
self.assertEqual(
"Off", self.power_inst.power_supplies[0].indicator_led
)
self.assertEqual(
245, self.power_inst.oem.intel_rackscale.input_ac_power_watts
)