Add all missing attributes of Chassis in RSD 2.1

Change-Id: I2e7e3c7d2142371b35bd98ff632a00a9d3bea75b
This commit is contained in:
Lin Yang
2019-03-21 22:08:15 -07:00
parent 53e49840eb
commit ad7026fd89
16 changed files with 1426 additions and 1346 deletions

View File

@@ -16,6 +16,7 @@
import copy import copy
from sushy.resources import base from sushy.resources import base
from sushy import utils
from rsd_lib import utils as rsd_lib_utils from rsd_lib import utils as rsd_lib_utils
@@ -46,7 +47,107 @@ class DynamicField(base.Field):
instance = copy.copy(self) instance = copy.copy(self)
for name, attr in value.items(): for name, attr in value.items():
setattr( setattr(
instance, rsd_lib_utils.camelcase_to_underscore_joined(name), instance,
attr) rsd_lib_utils.camelcase_to_underscore_joined(name),
attr,
)
return instance return instance
class StatusField(base.CompositeField):
"""This Field describes the status of a resource and its children."""
health = base.Field("Health")
"""Represents health of resource w/o considering its dependent resources"""
health_rollup = base.Field("HealthRollup")
"""Represents health state of resource and its dependent resources"""
state = base.Field("State")
"""Indicates the known state of the resource, such as if it is enabled."""
class LocationField(base.CompositeField):
info = base.Field("Info")
"""This indicates the location of the resource."""
info_format = base.Field("InfoFormat")
"""This represents the format of the Info property."""
class ReferenceableMemberField(base.ListField):
member_id = base.Field("MemberId")
"""This is the identifier for the member within the collection."""
class IdentifierField(base.CompositeField):
durable_name = base.Field("DurableName")
"""This indicates the world wide, persistent name of the resource."""
durable_name_format = base.Field("DurableNameFormat")
"""This represents the format of the DurableName property."""
class RedundancyCollectionField(ReferenceableMemberField):
"""Redundancy field
This is the redundancy definition to be used in other resource schemas.
"""
name = base.Field("Name")
"""The name of the resource or array element."""
mode = base.Field("Mode")
"""This is the redundancy mode of the group."""
max_num_supported = base.Field(
"MaxNumSupported", adapter=rsd_lib_utils.num_or_none
)
"""This is the maximum number of members allowable for this particular
redundancy group.
"""
min_num_needed = base.Field(
"MinNumNeeded", adapter=rsd_lib_utils.num_or_none
)
"""This is the minumum number of members needed for this group to be
redundant.
"""
status = StatusField("Status")
"""This indicates the known state of the resource, such as if it is
enabled.
"""
redundancy_set = base.Field(
"RedundancySet", adapter=utils.get_members_identities
)
"""Contains any ids that represent components of this redundancy set."""
redundancy_enabled = base.Field("RedundancyEnabled", adapter=bool)
"""This indicates whether redundancy is enabled."""
class ResourceBase(base.ResourceBase):
identity = base.Field("Id", required=True)
"""The resource identity string"""
name = base.Field("Name")
"""The resource name"""
description = base.Field("Description")
"""The resource description"""
class ResourceCollectionBase(base.ResourceCollectionBase):
name = base.Field("Name")
"""The resource collection name"""
description = base.Field("Description")
"""The resource collection description"""

View File

@@ -16,8 +16,8 @@
from sushy.resources import base from sushy.resources import base
from sushy import utils from sushy import utils
from rsd_lib import common as rsd_lib_common from rsd_lib import base as rsd_lib_base
from rsd_lib.resources.v2_1.chassis import log_services from rsd_lib.resources.v2_1.chassis import log_service
from rsd_lib.resources.v2_1.chassis import power from rsd_lib.resources.v2_1.chassis import power
from rsd_lib.resources.v2_1.chassis import power_zone from rsd_lib.resources.v2_1.chassis import power_zone
from rsd_lib.resources.v2_1.chassis import thermal from rsd_lib.resources.v2_1.chassis import thermal
@@ -25,226 +25,250 @@ from rsd_lib.resources.v2_1.chassis import thermal_zone
from rsd_lib import utils as rsd_lib_utils from rsd_lib import utils as rsd_lib_utils
class LinksField(base.CompositeField):
contains = base.Field('Contains', adapter=utils.get_members_identities)
"""Any other chassis that this chassis has in it"""
contained_by = base.Field('ContainedBy',
adapter=rsd_lib_utils.get_resource_identity)
"""The resource that represents the chassis that contains this chassis
and shall be of type Chassis
"""
computer_systems = base.Field('ComputerSystems',
adapter=utils.get_members_identities)
"""The computer systems contained in this chassis"""
managed_by = base.Field('ManagedBy', adapter=utils.get_members_identities)
"""The managers contained in this chassis"""
managers_in_chassis = base.Field('ManagersInChassis',
adapter=utils.get_members_identities)
"""The managers located in this chassis"""
switches = base.Field(['Oem', 'Intel_RackScale', 'Switches'],
adapter=utils.get_members_identities)
"""The Ethernet switches contained in this chassis"""
drives = base.Field("Drives", adapter=utils.get_members_identities)
""""An array of references to the disk drives located in this Chassis"""
storage = base.Field("Storage", adapter=utils.get_members_identities)
"""An array of references to the storage subsystems connected to or inside
this Chassis
"""
cooled_by = base.Field("CooledBy",
adapter=utils.get_members_identities)
"""An array of ID[s] of resources that cool this chassis"""
powered_by = base.Field("PoweredBy",
adapter=utils.get_members_identities)
"""An array of ID[s] of resources that power this chassis"""
class LocationField(base.CompositeField): class LocationField(base.CompositeField):
identity = base.Field('Id')
identity = base.Field("Id")
"""The location ID of the chassis""" """The location ID of the chassis"""
parent_id = base.Field('ParentId') parent_id = base.Field("ParentId")
"""The location ID of parent chassis""" """The location ID of parent chassis"""
class OemField(base.CompositeField): class LinksIntelRackScaleField(base.CompositeField):
location = LocationField('Location')
switches = base.Field("Switches", adapter=utils.get_members_identities)
"""An array of references to the ethernet switches located in this Chassis.
"""
class LinksOemField(base.CompositeField):
intel_rackscale = LinksIntelRackScaleField("Intel_RackScale")
"""Intel Rack Scale Design specific properties."""
class LinksField(base.CompositeField):
computer_systems = base.Field(
"ComputerSystems", adapter=utils.get_members_identities
)
"""An array of references to the computer systems contained in this
chassis. This will only reference ComputerSystems that are directly
and wholly contained in this chassis.
"""
managed_by = base.Field("ManagedBy", adapter=utils.get_members_identities)
"""An array of references to the Managers responsible for managing this
chassis.
"""
contained_by = base.Field(
"ContainedBy", adapter=rsd_lib_utils.get_resource_identity
)
"""A reference to the chassis that this chassis is contained by."""
contains = base.Field("Contains", adapter=utils.get_members_identities)
"""An array of references to any other chassis that this chassis has in it.
"""
powered_by = base.Field("PoweredBy", adapter=utils.get_members_identities)
"""An array of ID[s] of resources that power this chassis. Normally the ID
will be a chassis or a specific set of powerSupplies
"""
cooled_by = base.Field("CooledBy", adapter=utils.get_members_identities)
"""An array of ID[s] of resources that cool this chassis. Normally the ID
will be a chassis or a specific set of fans.
"""
managers_in_chassis = base.Field(
"ManagersInChassis", adapter=utils.get_members_identities
)
"""An array of references to the managers located in this Chassis."""
drives = base.Field("Drives", adapter=utils.get_members_identities)
"""An array of references to the disk drives located in this Chassis."""
storage = base.Field("Storage", adapter=utils.get_members_identities)
"""An array of references to the storage subsystems connected to or inside
this Chassis.
"""
oem = LinksOemField("Oem")
"""Oem specific properties."""
class PhysicalSecurityField(base.CompositeField):
intrusion_sensor_number = base.Field(
"IntrusionSensorNumber", adapter=rsd_lib_utils.num_or_none
)
"""A numerical identifier to represent the physical security sensor."""
intrusion_sensor = base.Field("IntrusionSensor")
"""This indicates the known state of the physical security sensor, such as
if it is hardware intrusion detected.
"""
intrusion_sensor_re_arm = base.Field("IntrusionSensorReArm")
"""This indicates how the Normal state to be restored."""
class IntelRackScaleField(base.CompositeField):
location = LocationField("Location")
"""Property that shows this chassis ID and its parent""" """Property that shows this chassis ID and its parent"""
rmm_present = base.Field('RMMPresent', adapter=bool) rmm_present = base.Field("RMMPresent", adapter=bool)
"""RMM presence in a rack""" """RMM presence in a rack"""
rack_supports_disaggregated_power_cooling = base.Field( rack_supports_disaggregated_power_cooling = base.Field(
'RackSupportsDisaggregatedPowerCooling', adapter=bool) "RackSupportsDisaggregatedPowerCooling", adapter=bool
)
"""Indicates if Rack support is disaggregated (shared) power and cooling """Indicates if Rack support is disaggregated (shared) power and cooling
capabilities capabilities
""" """
uuid = base.Field('UUID') uuid = base.Field("UUID")
"""Chassis unique ID""" """Chassis unique ID"""
geo_tag = base.Field('GeoTag') geo_tag = base.Field("GeoTag")
"""Provides info about the geographical location of this chassis""" """Provides info about the geographical location of this chassis"""
class PhysicalSecurityField(base.CompositeField): class OemField(base.CompositeField):
intrusion_sensor_number = base.Field("IntrusionSensorNumber",
adapter=rsd_lib_utils.num_or_none)
""""The physical security intrusion sensor number"""
intrusion_sensor = base.Field("IntrusionSensor") intel_rackscale = IntelRackScaleField("Intel_RackScale")
""""The physical security intrusion sensor""" """Intel Rack Scale Design specific properties."""
intrusion_sensor_rearm = base.Field("IntrusionSensorReArm")
""""The physical security intrusion sensor rearm"""
class Chassis(base.ResourceBase): class Chassis(rsd_lib_base.ResourceBase):
identity = base.Field('Id', required=True) """Chassis resource class
"""The chassis identity string"""
asset_tag = base.Field('AssetTag') A Chassis represents the physical components for any system. This
"""The chassis asset tag""" 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.
"""
description = base.Field('Description') chassis_type = base.Field("ChassisType")
"""The chassis description""" """This property indicates the type of physical form factor of this
resource.
"""
manufacturer = base.Field('Manufacturer') manufacturer = base.Field("Manufacturer")
"""The chassis manufacturer""" """This is the manufacturer of this chassis."""
name = base.Field('Name') model = base.Field("Model")
"""The chassis name""" """This is the model number for the chassis."""
model = base.Field('Model') sku = base.Field("SKU")
"""The chassis Model""" """This is the SKU for this chassis."""
indicator_led = base.Field('IndicatorLED') serial_number = base.Field("SerialNumber")
"""The state of the indicator LED, used to identify the chassis""" """The serial number for this chassis."""
part_number = base.Field('PartNumber') part_number = base.Field("PartNumber")
"""The chassis part number""" """The part number for this chassis."""
serial_number = base.Field('SerialNumber') asset_tag = base.Field("AssetTag")
"""The chassis serial number""" """The user assigned asset tag for this chassis."""
sku = base.Field('SKU') indicator_led = base.Field("IndicatorLED")
"""The chassis stock-keeping unit""" """The state of the indicator LED, used to identify the chassis."""
status = rsd_lib_common.StatusField('Status') links = LinksField("Links")
"""The chassis status""" """Contains references to other resources that are related to this
resource.
"""
chassis_type = base.Field('ChassisType') status = rsd_lib_base.StatusField("Status")
"""The chassis type""" """This indicates the known state of the resource, such as if it is
enabled.
oem = OemField(['Oem', 'Intel_RackScale']) """
"""The chassis oem object"""
links = LinksField('Links')
"""The link section of chassis"""
power_state = base.Field("PowerState") power_state = base.Field("PowerState")
"""The chassis power state""" """This is the current power state of the chassis."""
physical_security = PhysicalSecurityField("PhysicalSecurity") physical_security = PhysicalSecurityField("PhysicalSecurity")
"""The chassis physical security""" """The state of the physical security sensor."""
def __init__(self, connector, identity, redfish_version=None): location = rsd_lib_base.LocationField("Location")
"""A class representing a Chassis
:param connector: A Connector instance oem = OemField("Oem")
:param identity: The identity of the chassis resource """Oem specific properties."""
:param redfish_version: The version of RedFish. Used to construct
the object according to schema of the given version.
"""
super(Chassis, self).__init__(connector, identity, redfish_version)
def _get_power_zone_collection_path(self):
"""Helper function to find the PowerZoneCollection path"""
return utils.get_sub_resource_path_by(self, 'PowerZones')
@property @property
@utils.cache_it @utils.cache_it
def power_zones(self): def log_services(self):
"""Property to provide reference to `PowerZoneCollection` instance """Property to provide reference to `LogServiceCollection` instance
It is calculated once when it is queried for the first time. On It is calculated once when it is queried for the first time. On
refresh, this property is reset. refresh, this property is reset.
""" """
return power_zone.PowerZoneCollection( return log_service.LogServiceCollection(
self._conn, self._get_power_zone_collection_path(), self._conn,
redfish_version=self.redfish_version) utils.get_sub_resource_path_by(self, "LogServices"),
redfish_version=self.redfish_version,
def _get_power_path(self): )
"""Helper function to find the Power path"""
return utils.get_sub_resource_path_by(self, 'Power')
@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, self._get_power_path(),
redfish_version=self.redfish_version)
def _get_thermal_zone_collection_path(self):
"""Helper function to find the ThermalZoneCollection path"""
return utils.get_sub_resource_path_by(self, 'ThermalZones')
@property @property
@utils.cache_it @utils.cache_it
def thermal_zones(self): def thermal_zones(self):
"""Property to provide reference to `ThermalZoneCollection` instance """Property to provide reference to `ThermalZoneCollection` instance
It is calculated once when it is queried for the first time. On It is calculated once when it is queried for the first time. On
refresh, this property is reset. refresh, this property is reset.
""" """
return thermal_zone.ThermalZoneCollection( return thermal_zone.ThermalZoneCollection(
self._conn, self._get_thermal_zone_collection_path(), self._conn,
redfish_version=self.redfish_version) utils.get_sub_resource_path_by(self, "ThermalZones"),
redfish_version=self.redfish_version,
)
def _get_thermal_path(self): @property
"""Helper function to find the Thermal path""" @utils.cache_it
return utils.get_sub_resource_path_by(self, 'Thermal') def power_zones(self):
"""Property to provide reference to `PowerZoneCollection` instance
It is calculated once when it is queried for the first time. On
refresh, this property is reset.
"""
return power_zone.PowerZoneCollection(
self._conn,
utils.get_sub_resource_path_by(self, "PowerZones"),
redfish_version=self.redfish_version,
)
@property @property
@utils.cache_it @utils.cache_it
def thermal(self): def thermal(self):
"""Property to provide reference to `Thermal` instance """Property to provide reference to `Thermal` instance
It is calculated once when it is queried for the first time. On It is calculated once when it is queried for the first time. On
refresh, this property is reset. refresh, this property is reset.
""" """
return thermal.Thermal( return thermal.Thermal(
self._conn, self._get_thermal_path(), self._conn,
redfish_version=self.redfish_version) utils.get_sub_resource_path_by(self, "Thermal"),
redfish_version=self.redfish_version,
def _get_log_service_collection_path(self): )
"""Helper function to find the LogServices path"""
return utils.get_sub_resource_path_by(self, 'LogServices')
@property @property
@utils.cache_it @utils.cache_it
def log_services(self): def power(self):
"""Property to provide reference to `LogServices` instance """Property to provide reference to `Power` instance
It is calculated once when it is queried for the first time. On It is calculated once when it is queried for the first time. On
refresh, this property is reset. refresh, this property is reset.
""" """
return log_services.LogServicesCollection( return power.Power(
self._conn, self._get_log_service_collection_path(), self._conn,
redfish_version=self.redfish_version) utils.get_sub_resource_path_by(self, "Power"),
redfish_version=self.redfish_version,
)
def update(self, asset_tag=None, location_id=None): def update(self, asset_tag=None, location_id=None):
"""Update AssetTag and Location->Id properties """Update AssetTag and Location->Id properties
@@ -257,33 +281,17 @@ class Chassis(base.ResourceBase):
data = {} data = {}
if asset_tag is not None: if asset_tag is not None:
data['AssetTag'] = asset_tag data["AssetTag"] = asset_tag
if location_id is not None: if location_id is not None:
data['Oem'] = { data["Oem"] = {
"Intel_RackScale": { "Intel_RackScale": {"Location": {"Id": location_id}}
"Location": {
"Id": location_id
}
}
} }
self._conn.patch(self.path, data=data) self._conn.patch(self.path, data=data)
class ChassisCollection(base.ResourceCollectionBase): class ChassisCollection(rsd_lib_base.ResourceCollectionBase):
@property @property
def _resource_type(self): def _resource_type(self):
return Chassis return Chassis
def __init__(self, connector, path, redfish_version=None):
"""A class representing a Chassis Collection
:param connector: A Connector instance
:param path: The canonical path to the chassis collection resource
:param redfish_version: The version of RedFish. Used to construct
the object according to schema of the given version.
"""
super(ChassisCollection, self).__init__(connector,
path,
redfish_version)

View File

@@ -13,84 +13,93 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from rsd_lib import utils as rsd_lib_utils
from sushy.resources import base from sushy.resources import base
from sushy import utils
from rsd_lib import base as rsd_lib_base
from rsd_lib import utils as rsd_lib_utils
class LinksField(base.CompositeField): class LinksField(base.CompositeField):
OriginOfCondition = base.Field("OriginOfCondition",
adapter=utils.get_members_identities) origin_of_condition = base.Field(
"""The URI of the resource that caused the log entry""" "OriginOfCondition", adapter=rsd_lib_utils.get_resource_identity
)
"""This is the URI of the resource that caused the log entry"""
class LogEntry(base.ResourceBase): class LogEntry(rsd_lib_base.ResourceBase):
identity = base.Field('Id', required=True) """LogEntry resource class
"""The log entry identity string"""
description = base.Field('Description') This resource defines the record format for a log. It is designed to
"""The log entry description""" be used for SEL logs (from IPMI) as well as Event Logs and OEM-specific
log formats. The EntryType field indicates the type of log and the
name = base.Field('Name') resource includes several additional properties dependent on the
"""The log entry name""" EntryType.
"""
severity = base.Field("Severity") severity = base.Field("Severity")
"""The severity of the log entry""" """This is the severity of the log entry."""
created = base.Field("Created") created = base.Field("Created")
"""The time the log entry was created""" """The time the log entry was created."""
entry_type = base.Field("EntryType") entry_type = base.Field("EntryType")
""""The type of log entry""" """his is the type of log entry."""
oem_record_format = base.Field("OemRecordFormat") oem_record_format = base.Field("OemRecordFormat")
"""The log entry oem record format""" """If the entry type is Oem, this will contain more information about the
record format from the Oem.
"""
entry_code = base.Field("EntryCode") entry_code = base.Field("EntryCode")
"""The log entry code""" """If the EntryType is SEL, this will have the entry code for the log
entry.
"""
sensor_type = base.Field("SensorType") sensor_type = base.Field("SensorType")
"""The log entry sensor type""" """If the EntryType is SEL, this will have the sensor type that the log
entry pertains to.
"""
sensor_number = base.Field("SensorNumber", sensor_number = base.Field(
adapter=rsd_lib_utils.num_or_none) "SensorNumber", adapter=rsd_lib_utils.num_or_none
"""The log entry sensor number""" )
"""This property decodes from EntryType: If it is SEL, it is the sensor
number; if Event then the count of events. Otherwise, it is Oem
specific.
"""
message = base.Field("Message") message = base.Field("Message")
"""The log entry message""" """This property decodes from EntryType: If it is Event then it is a
message string. Otherwise, it is SEL or Oem specific. In most cases,
this will be the actual Log Entry.
"""
message_id = base.Field("MessageId") message_id = base.Field("MessageId")
"""The log entry message id""" """This property decodes from EntryType: If it is Event then it is a
message id. Otherwise, it is SEL or Oem specific. This value is only
used for registries - for more information, see the specification.
"""
message_args = base.Field("MessageArgs") message_args = base.Field("MessageArgs")
"""The log entry message args""" """The values of this property shall be any arguments for the message."""
links = LinksField("Links") links = LinksField("Links")
"""The log entry links""" """Contains references to other resources that are related to this
resource.
"""
event_type = base.Field("EventType") event_type = base.Field("EventType")
"""The type of an event recorded in this log""" """This indicates the type of an event recorded in this log."""
event_id = base.Field("EventId") event_id = base.Field("EventId")
"""A unique instance identifier of an event""" """This is a unique instance identifier of an event."""
event_timestamp = base.Field("EventTimestamp") event_timestamp = base.Field("EventTimestamp")
"""Time the event occurred""" """This is time the event occurred."""
class LogEntryCollection(base.ResourceCollectionBase): class LogEntryCollection(rsd_lib_base.ResourceCollectionBase):
@property @property
def _resource_type(self): def _resource_type(self):
return LogEntry return LogEntry
def __init__(self, connector, path, redfish_version=None):
"""A class representing a LogEntry Collection
:param connector: A Connector instance
:param path: The canonical path to the LogEntry Collection resource
:param redfish_version: The version of RedFish. Used to construct
the object according to schema of the given version.
"""
super(LogEntryCollection, self).__init__(connector,
path,
redfish_version)

View File

@@ -0,0 +1,77 @@
# 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 sushy import utils
from rsd_lib import base as rsd_lib_base
from rsd_lib.resources.v2_1.chassis import log_entry
from rsd_lib import utils as rsd_lib_utils
class LogService(rsd_lib_base.ResourceBase):
"""LogService resource class
This resource represents the log service for the resource or service to
which it is associated.
"""
service_enabled = base.Field("ServiceEnabled", adapter=bool)
"""This indicates whether this service is enabled."""
max_number_of_records = base.Field(
"MaxNumberOfRecords", adapter=rsd_lib_utils.num_or_none
)
"""The maximum number of log entries this service can have."""
over_write_policy = base.Field("OverWritePolicy")
"""The overwrite policy for this service that takes place when the log is
full.
"""
date_time = base.Field("DateTime")
"""The current DateTime (with offset) for the log service, used to set or
read time.
"""
date_time_local_offset = base.Field("DateTimeLocalOffset")
"""The time offset from UTC that the DateTime property is set to in
format: +06:00 .
"""
status = rsd_lib_base.StatusField("Status")
"""This indicates the known state of the resource, such as if it is
enabled.
"""
@property
@utils.cache_it
def entries(self):
"""Property to provide reference to `LogEntryCollection` instance
It is calculated once when it is queried for the first time. On
refresh, this property is reset.
"""
return log_entry.LogEntryCollection(
self._conn,
utils.get_sub_resource_path_by(self, "Entries"),
redfish_version=self.redfish_version,
)
class LogServiceCollection(rsd_lib_base.ResourceCollectionBase):
@property
def _resource_type(self):
return LogService

View File

@@ -1,101 +0,0 @@
# 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 sushy import utils
from rsd_lib import common as rsd_lib_common
from rsd_lib.resources.v2_1.chassis import log_entry
from rsd_lib import utils as rsd_lib_utils
class LogService(base.ResourceBase):
identity = base.Field('Id', required=True)
"""The log service identity string"""
description = base.Field('Description')
"""The log service description"""
name = base.Field('Name')
"""The log service name"""
status = rsd_lib_common.StatusField('Status')
"""The log service status"""
service_enabled = base.Field("ServiceEnabled", adapter=bool)
"""This indicates whether this service is enabled"""
max_number_of_records = base.Field("MaxNumberOfRecords",
adapter=rsd_lib_utils.num_or_none)
"""The maximum number of log entries this service can have"""
overwrite_policy = base.Field("OverWritePolicy")
"""The overwrite policy for this service that
takes place when the log is full
"""
date_time = base.Field("DateTime")
"""The current DateTime (with offset) for the log
service, used to set or read time
"""
date_time_local_offset = base.Field("DateTimeLocalOffset")
"""The time offset from UTC that the DateTime
property is set to in format: +06:00
"""
def __init__(self, connector, identity, redfish_version=None):
"""A class representing a LogService
:param connector: A Connector instance
:param identity: The identity of the log service resource
:param redfish_version: The version of RedFish. Used to construct
the object according to schema of the given version.
"""
super(LogService, self).__init__(connector, identity, redfish_version)
def _get_entry_collection_path(self):
"""Helper function to find the LogEntryCollection path"""
return utils.get_sub_resource_path_by(self, 'Entries')
@property
@utils.cache_it
def log_entries(self):
"""Property to provide reference to `LogEntryCollection` instance
It is calculated once when it is queried for the first time. On
refresh, this property is reset.
"""
return log_entry.LogEntryCollection(
self._conn, self._get_entry_collection_path(),
redfish_version=self.redfish_version)
class LogServicesCollection(base.ResourceCollectionBase):
@property
def _resource_type(self):
return LogService
def __init__(self, connector, path, redfish_version=None):
"""A class representing a LogService Collection
:param connector: A Connector instance
:param path: The canonical path to the LogService Collection resource
:param redfish_version: The version of RedFish. Used to construct
the object according to schema of the given version.
"""
super(LogServicesCollection, self).__init__(connector,
path,
redfish_version)

View File

@@ -16,378 +16,322 @@
from sushy.resources import base from sushy.resources import base
from sushy import utils from sushy import utils
from rsd_lib import common as rsd_lib_common from rsd_lib import base as rsd_lib_base
from rsd_lib import utils as rsd_lib_utils from rsd_lib import utils as rsd_lib_utils
class PowerMetricsField(base.CompositeField): class PowerMetricField(base.CompositeField):
interval_in_min = base.Field( interval_in_min = base.Field(
'IntervalInMin', adapter=rsd_lib_utils.num_or_none) "IntervalInMin", adapter=rsd_lib_utils.num_or_none
"""The time interval (or window) in which the PowerMetrics are )
measured over """The time interval (or window) in which the PowerMetrics are measured
over.
""" """
min_consumed_watts = base.Field( min_consumed_watts = base.Field(
'MinConsumedWatts', adapter=rsd_lib_utils.num_or_none) "MinConsumedWatts", adapter=rsd_lib_utils.num_or_none
"""The lowest power consumption level over the measurement window )
(the last IntervalInMin minutes) """The lowest power consumption level over the measurement window (the
last IntervalInMin minutes).
""" """
max_consumed_watts = base.Field( max_consumed_watts = base.Field(
'MaxConsumedWatts', adapter=rsd_lib_utils.num_or_none) "MaxConsumedWatts", adapter=rsd_lib_utils.num_or_none
)
"""The highest power consumption level that has occured over the """The highest power consumption level that has occured over the
measurement window (the last IntervalInMin minutes) measurement window (the last IntervalInMin minutes).
""" """
average_consumed_watts = base.Field( average_consumed_watts = base.Field(
'AverageConsumedWatts', adapter=rsd_lib_utils.num_or_none) "AverageConsumedWatts", adapter=rsd_lib_utils.num_or_none
"""The average power level over the measurement window )
(the last IntervalInMin minutes) """The average power level over the measurement window (the last
IntervalInMin minutes).
""" """
class PowerLimitField(base.CompositeField): class PowerLimitField(base.CompositeField):
limit_in_watts = base.Field( """PowerLimit field
'LimitInWatts', adapter=rsd_lib_utils.num_or_none)
"""The Power limit in watts. Set to null to disable power capping"""
limit_exception = base.Field('LimitException') This object contains power limit status and configuration information
"""The action that is taken if the power cannot be maintained below for the chassis.
the LimitInWatts """
limit_in_watts = base.Field(
"LimitInWatts", adapter=rsd_lib_utils.num_or_none
)
"""The Power limit in watts. Set to null to disable power capping."""
limit_exception = base.Field("LimitException")
"""The action that is taken if the power cannot be maintained below the
LimitInWatts.
""" """
correction_in_ms = base.Field( correction_in_ms = base.Field(
'CorrectionInMs', adapter=rsd_lib_utils.num_or_none) "CorrectionInMs", adapter=rsd_lib_utils.num_or_none
)
"""The time required for the limiting process to reduce power consumption """The time required for the limiting process to reduce power consumption
to below the limit to below the limit.
""" """
class PowerControlField(base.ListField): class InputRangeCollectionField(rsd_lib_base.ReferenceableMemberField):
name = base.Field('Name')
"""The Power Control name"""
member_id = base.Field('MemberId') input_type = base.Field("InputType")
"""The Power Control member identity""" """The Input type (AC or DC)"""
minimum_voltage = base.Field(
"MinimumVoltage", adapter=rsd_lib_utils.num_or_none
)
"""The minimum line input voltage at which this power supply input range
is effective
"""
maximum_voltage = base.Field(
"MaximumVoltage", adapter=rsd_lib_utils.num_or_none
)
"""The maximum line input voltage at which this power supply input range
is effective
"""
minimum_frequency_hz = base.Field(
"MinimumFrequencyHz", adapter=rsd_lib_utils.num_or_none
)
"""The minimum line input frequency at which this power supply input range
is effective
"""
maximum_frequency_hz = base.Field(
"MaximumFrequencyHz", adapter=rsd_lib_utils.num_or_none
)
"""The maximum line input frequency at which this power supply input range
is effective
"""
output_wattage = base.Field(
"OutputWattage", adapter=rsd_lib_utils.num_or_none
)
"""The maximum capacity of this Power Supply when operating in this input
range
"""
class VoltageCollectionField(rsd_lib_base.ReferenceableMemberField):
name = base.Field("Name")
"""Voltage sensor name."""
sensor_number = base.Field(
"SensorNumber", adapter=rsd_lib_utils.num_or_none
)
"""A numerical identifier to represent the voltage sensor"""
status = rsd_lib_base.StatusField("Status")
"""This indicates the known state of the resource, such as if it is
enabled.
"""
reading_volts = base.Field(
"ReadingVolts", adapter=rsd_lib_utils.num_or_none
)
"""The current value of the voltage sensor."""
upper_threshold_non_critical = base.Field(
"UpperThresholdNonCritical", adapter=rsd_lib_utils.num_or_none
)
"""Above normal range"""
upper_threshold_critical = base.Field(
"UpperThresholdCritical", adapter=rsd_lib_utils.num_or_none
)
"""Above normal range but not yet fatal."""
upper_threshold_fatal = base.Field(
"UpperThresholdFatal", adapter=rsd_lib_utils.num_or_none
)
"""Above normal range and is fatal"""
lower_threshold_non_critical = base.Field(
"LowerThresholdNonCritical", adapter=rsd_lib_utils.num_or_none
)
"""Below normal range"""
lower_threshold_critical = base.Field(
"LowerThresholdCritical", adapter=rsd_lib_utils.num_or_none
)
"""Below normal range but not yet fatal."""
lower_threshold_fatal = base.Field(
"LowerThresholdFatal", adapter=rsd_lib_utils.num_or_none
)
"""Below normal range and is fatal"""
min_reading_range = base.Field(
"MinReadingRange", adapter=rsd_lib_utils.num_or_none
)
"""Minimum value for CurrentReading"""
max_reading_range = base.Field(
"MaxReadingRange", adapter=rsd_lib_utils.num_or_none
)
"""Maximum value for CurrentReading"""
physical_context = base.Field("PhysicalContext")
"""Describes the area or device to which this voltage measurement applies.
"""
related_item = base.Field(
"RelatedItem", adapter=utils.get_members_identities
)
"""Describes the areas or devices to which this voltage measurement
applies.
"""
class PowerControlCollectionField(rsd_lib_base.ReferenceableMemberField):
name = base.Field("Name")
"""Power Control Function name."""
power_consumed_watts = base.Field( power_consumed_watts = base.Field(
'PowerConsumedWatts', adapter=rsd_lib_utils.num_or_none) "PowerConsumedWatts", adapter=rsd_lib_utils.num_or_none
"""The actual power being consumed by the chassis""" )
"""The actual power being consumed by the chassis."""
power_requested_watts = base.Field( power_requested_watts = base.Field(
'PowerRequestedWatts', adapter=rsd_lib_utils.num_or_none) "PowerRequestedWatts", adapter=rsd_lib_utils.num_or_none
"""The potential power that the chassis resources are requesting which )
may be higher than the current level being consumed since requested """The potential power that the chassis resources are requesting which may
power includes budget that the chassis resource wants for future use be higher than the current level being consumed since requested power
includes budget that the chassis resource wants for future use.
""" """
power_available_watts = base.Field( power_available_watts = base.Field(
'PowerAvailableWatts', adapter=rsd_lib_utils.num_or_none) "PowerAvailableWatts", adapter=rsd_lib_utils.num_or_none
)
"""The amount of power not already budgeted and therefore available for """The amount of power not already budgeted and therefore available for
additional allocation. (powerCapacity - powerAllocated). This additional allocation. (powerCapacity - powerAllocated). This
indicates how much reserve power capacity is left. indicates how much reserve power capacity is left.
""" """
power_capacity_watts = base.Field( power_capacity_watts = base.Field(
'PowerCapacityWatts', adapter=rsd_lib_utils.num_or_none) "PowerCapacityWatts", adapter=rsd_lib_utils.num_or_none
"""The total amount of power available to the chassis for allocation. )
This may the power supply capacity, or power budget assigned to the """The total amount of power available to the chassis for allocation. This
chassis from an up-stream chassis. may the power supply capacity, or power budget assigned to the chassis
from an up-stream chassis.
""" """
power_allocated_watts = base.Field( power_allocated_watts = base.Field(
'PowerAllocatedWatts', adapter=rsd_lib_utils.num_or_none) "PowerAllocatedWatts", adapter=rsd_lib_utils.num_or_none
"""The total amount of power that has been allocated (or budegeted) to )
chassis resources """The total amount of power that has been allocated (or budegeted)to
chassis resources.
""" """
status = rsd_lib_common.StatusField('Status') power_metrics = PowerMetricField("PowerMetrics")
"""The Power Control status""" """Power readings for this chassis."""
power_metrics = PowerMetricsField('PowerMetrics') power_limit = PowerLimitField("PowerLimit")
"""Power readings for this chassis"""
power_limit = PowerLimitField('PowerLimit')
"""Power limit status and configuration information for this chassis""" """Power limit status and configuration information for this chassis"""
status = rsd_lib_base.StatusField("Status")
"""This indicates the known state of the resource, such as if it is
enabled.
"""
related_item = base.Field( related_item = base.Field(
'RelatedItem', adapter=utils.get_members_identities) "RelatedItem", adapter=utils.get_members_identities
)
"""The ID(s) of the resources associated with this Power Limit""" """The ID(s) of the resources associated with this Power Limit"""
class VoltageField(base.ListField): class PowerSupplyCollectionField(rsd_lib_base.ReferenceableMemberField):
name = base.Field('Name') """PowerSupply field
"""The Voltage sensor name"""
member_id = base.Field('MemberId') Details of a power supplies associated with this system or device
"""The Voltage sensor member identity"""
status = rsd_lib_common.StatusField('Status')
"""The Voltage sensor status"""
sensor_number = base.Field(
'SensorNumber', adapter=rsd_lib_utils.num_or_none)
"""A numerical identifier to represent the voltage sensor"""
reading_volts = base.Field(
'ReadingVolts', adapter=rsd_lib_utils.num_or_none)
"""The current value of the voltage sensor"""
upper_threshold_non_critical = base.Field(
'UpperThresholdNonCritical', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall indicate the CurrentReading is above
the normal range but is not critical. Units shall use the same units
as the related ReadingVolts property.
""" """
upper_threshold_critical = base.Field( name = base.Field("Name")
'UpperThresholdCritical', adapter=rsd_lib_utils.num_or_none) """The name of the Power Supply"""
"""The value of this property shall indicate the CurrentReading is above
the normal range but is not yet fatal. Units shall use the same units
as the related ReadingVolts property.
"""
upper_threshold_fatal = base.Field( power_supply_type = base.Field("PowerSupplyType")
'UpperThresholdFatal', adapter=rsd_lib_utils.num_or_none) """The Power Supply type (AC or DC)"""
"""The value of this property shall indicate the CurrentReading is above
the normal range and is fatal. Units shall use the same units as the
related ReadingVolts property.
"""
lower_threshold_non_critical = base.Field( line_input_voltage_type = base.Field("LineInputVoltageType")
'LowerThresholdNonCritical', adapter=rsd_lib_utils.num_or_none) """The line voltage type supported as an input to this Power Supply"""
"""The value of this property shall indicate the CurrentReading is below
the normal range but is not critical. Units shall use the same units
as the related ReadingVolts property.
"""
lower_threshold_critical = base.Field(
'LowerThresholdCritical', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall indicate the CurrentReading is below
the normal range but is not yet fatal. Units shall use the same units
as the related ReadingVolts property.
"""
lower_threshold_fatal = base.Field(
'LowerThresholdFatal', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall indicate the CurrentReading is below
the normal range and is fatal. Units shall use the same units as the
related ReadingVolts property.
"""
min_reading_range = base.Field(
'MinReadingRange', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall indicate the lowest possible value
for CurrentReading. Units shall use the same units as the related
ReadingVolts property.
"""
max_reading_range = base.Field(
'MaxReadingRange', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall indicate the highest possible value
for CurrentReading. Units shall use the same units as the related
ReadingVolts property.
"""
physical_context = base.Field('PhysicalContext')
"""Describes the area or device to which this voltage measurement
applies
"""
related_item = base.Field(
'RelatedItem', adapter=utils.get_members_identities)
"""Describes the areas or devices to which this voltage measurement
applies
"""
class InputRangesField(base.ListField):
input_type = base.Field('InputType')
"""This property shall contain the input type (AC or DC) of the
associated range.
"""
minimum_voltage = base.Field(
'MinimumVoltage', adapter=rsd_lib_utils.num_or_none)
"""This property shall contain the value in Volts of the minimum line
input voltage which the power supply is capable of consuming for
this range.
"""
maximum_voltage = base.Field(
'MaximumVoltage', adapter=rsd_lib_utils.num_or_none)
"""This property shall contain the value in Volts of the maximum line
input voltage which the power supply is capable of consuming for
this range.
"""
minimum_frequency_hz = base.Field(
'MinimumFrequencyHz', adapter=rsd_lib_utils.num_or_none)
"""This property shall contain the value in Hertz of the minimum line
input frequency which the power supply is capable of consuming for
this range.
"""
maximum_frequency_hz = base.Field(
'MaximumFrequencyHz', adapter=rsd_lib_utils.num_or_none)
"""This property shall contain the value in Hertz of the maximum line
input frequency which the power supply is capable of consuming for
this range.
"""
output_wattage = base.Field(
'OutputWattage', adapter=rsd_lib_utils.num_or_none)
"""This property shall contiain the maximum amount of power, in Watts,
that the associated power supply is rated to deliver while operating
in this input range.
"""
oem = base.Field("Oem")
"""The oem field"""
class PowerSuppliesField(base.ListField):
name = base.Field('Name')
"""The Power Supply name"""
member_id = base.Field('MemberId')
"""The Power Supply member identity"""
status = rsd_lib_common.StatusField('Status')
"""The Power Supply status"""
power_supply_type = base.Field('PowerSupplyType')
"""This property shall contain the input power type (AC or DC) of the
associated power supply
"""
line_input_voltage_type = base.Field('LineInputVoltageType')
"""This property shall contain the type of input line voltage supported
by the associated power supply
"""
line_input_voltage = base.Field( line_input_voltage = base.Field(
'LineInputVoltage', adapter=rsd_lib_utils.num_or_none) "LineInputVoltage", adapter=rsd_lib_utils.num_or_none
"""This property shall contain the value in Volts of the line input )
voltage (measured or configured for) that the power supply has been """The line input voltage at which the Power Supply is operating"""
configured to operate with or is currently receiving.
"""
power_capacity_watts = base.Field( power_capacity_watts = base.Field(
'PowerCapacityWatts', adapter=rsd_lib_utils.num_or_none) "PowerCapacityWatts", adapter=rsd_lib_utils.num_or_none
"""This property shall contiain the maximum amount of power, in Watts, )
that the associated power supply is rated to deliver. """The maximum capacity of this Power Supply"""
"""
last_power_output_watts = base.Field( last_power_output_watts = base.Field(
'LastPowerOutputWatts', adapter=rsd_lib_utils.num_or_none) "LastPowerOutputWatts", adapter=rsd_lib_utils.num_or_none
"""This property shall contain the average power output, measured in )
Watts, of the associated power supply. """The average power output of this Power Supply"""
"""
model = base.Field('Model') model = base.Field("Model")
"""This property shall contain the model information as defined by the """The model number for this Power Supply"""
manufacturer for the associated power supply.
"""
manufacturer = base.Field('Manufacturer') firmware_version = base.Field("FirmwareVersion")
"""The manufacturer for this Power Supply""" """The firmware version for this Power Supply"""
firmware_version = base.Field('FirmwareVersion') serial_number = base.Field("SerialNumber")
"""This property shall contain the firwmare version as defined by the """The serial number for this Power Supply"""
manufacturer for the associated power supply.
"""
serial_number = base.Field('SerialNumber') part_number = base.Field("PartNumber")
"""This property shall contain the serial number as defined by the """The part number for this Power Supply"""
manufacturer for the associated power supply.
"""
part_number = base.Field('PartNumber') spare_part_number = base.Field("SparePartNumber")
"""This property shall contain the part number as defined by the """The spare part number for this Power Supply"""
manufacturer for the associated power supply.
"""
spare_part_number = base.Field('SparePartNumber') status = rsd_lib_base.StatusField("Status")
"""This property shall contain the spare or replacement part number as """This indicates the known state of the resource, such as if it is
defined by the manufacturer for the associated power supply. enabled.
""" """
related_item = base.Field( related_item = base.Field(
'RelatedItem', adapter=utils.get_members_identities) "RelatedItem", adapter=utils.get_members_identities
)
"""The ID(s) of the resources associated with this Power Limit""" """The ID(s) of the resources associated with this Power Limit"""
redundancy = base.Field( redundancy = rsd_lib_base.RedundancyCollectionField("Redundancy")
'Redundancy', adapter=utils.get_members_identities) """This structure is used to show redundancy for power supplies. The
"""The values of the properties in this array shall be used to show Component ids will reference the members of the redundancy groups.
redundancy for power supplies and other elements in this resource.
The use of IDs within these arrays shall reference the members of the
redundancy groups.
""" """
input_ranges = InputRangesField('InputRanges') manufacturer = base.Field("Manufacturer")
"""This is the input ranges that the power supply can use""" """This is the manufacturer of this power supply."""
indicator_led = base.Field('IndicatorLED') input_ranges = InputRangeCollectionField("InputRanges")
"""The value of this property shall contain the indicator light state for """This is the input ranges that the power supply can use."""
the indicator light associated with this power supply.
class Power(rsd_lib_base.ResourceBase):
"""Power resource class
This is the schema definition for the Power Metrics. It represents the
properties for Power Consumption and Power Limiting.
""" """
power_control = PowerControlCollectionField("PowerControl")
class RedundancyField(base.ListField): """This is the definition for power control function (power
name = base.Field('Name') reading/limiting).
"""The Redundant device name"""
member_id = base.Field('MemberId')
"""The Redundant device identity"""
status = rsd_lib_common.StatusField('Status')
"""The Redundant device status"""
mode = base.Field('Mode')
"""This is the redundancy mode of the group"""
max_num_supported = base.Field(
'MaxNumSupported', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall contain the maximum number of
members allowed in the redundancy group.
""" """
min_num_needed = base.Field( voltages = VoltageCollectionField("Voltages")
'MinNumNeeded', adapter=rsd_lib_utils.num_or_none) """This is the definition for voltage sensors."""
"""The value of this property shall contain the minimum number of members
allowed in the redundancy group for the current redundancy mode to
still be fault tolerant.
"""
redundancy_set = base.Field( power_supplies = PowerSupplyCollectionField("PowerSupplies")
'RedundancySet', adapter=utils.get_members_identities)
"""The value of this property shall contain the ids of components that
are part of this redundancy set. The id values may or may not be
dereferenceable.
"""
class Power(base.ResourceBase):
identity = base.Field('Id', required=True)
"""The Power identity string"""
name = base.Field('Name')
"""The Power name"""
description = base.Field('Description')
"""The Power description"""
power_control = PowerControlField('PowerControl')
"""The details of power control function"""
voltages = VoltageField('Voltages')
"""The details of voltage sensors"""
power_supplies = PowerSuppliesField('PowerSupplies')
"""Details of the power supplies associated with this system or device""" """Details of the power supplies associated with this system or device"""
redundancy = RedundancyField('Redundancy') redundancy = rsd_lib_base.RedundancyCollectionField("Redundancy")
"""Redundancy information for the power subsystem of this system or """Redundancy information for the power subsystem of this system or device
device
""" """

View File

@@ -15,83 +15,80 @@
from sushy.resources import base from sushy.resources import base
from rsd_lib import common as rsd_lib_common from rsd_lib import base as rsd_lib_base
from rsd_lib import utils as rsd_lib_utils from rsd_lib import utils as rsd_lib_utils
class RackLocationField(base.CompositeField): class RackLocationField(base.CompositeField):
rack_units = base.Field('RackUnits')
rack_units = base.Field("RackUnits")
"""Indicates the rack unit type""" """Indicates the rack unit type"""
xlocation = base.Field('XLocation', adapter=rsd_lib_utils.num_or_none) xlocation = base.Field("XLocation", adapter=rsd_lib_utils.num_or_none)
"""The horizontal location within uLocation, from left to right """The horizontal location within uLocation, from left to right
(1.. MAXIMUM) 0 indicate not available (1.. MAXIMUM) 0 indicate not available
""" """
ulocation = base.Field('ULocation', adapter=rsd_lib_utils.num_or_none) ulocation = base.Field("ULocation", adapter=rsd_lib_utils.num_or_none)
"""The index of the top-most U of the component, from top to bottom """The index of the top-most U of the component, from top to bottom
(1.. MAXIMUM) 0 indicate not available (1.. MAXIMUM) 0 indicate not available
""" """
uheight = base.Field('UHeight', adapter=rsd_lib_utils.num_or_none) uheight = base.Field("UHeight", adapter=rsd_lib_utils.num_or_none)
"""The height of managed zone, e.g. 8 for 8U, 16 for 16U""" """The height of managed zone, e.g. 8 for 8U, 16 for 16U"""
class PowerSuppliesField(base.ListField): class PowerSupplyCollectionField(rsd_lib_base.ReferenceableMemberField):
name = base.Field('Name')
name = base.Field("Name")
"""The Power Supply name""" """The Power Supply name"""
power_capacity_watts = base.Field( power_capacity_watts = base.Field(
'PowerCapacityWatts', adapter=rsd_lib_utils.num_or_none) "PowerCapacityWatts", adapter=rsd_lib_utils.num_or_none
)
"""The maximum capacity of this Power Supply""" """The maximum capacity of this Power Supply"""
last_power_output_watts = base.Field( last_power_output_watts = base.Field(
'LastPowerOutputWatts', adapter=rsd_lib_utils.num_or_none) "LastPowerOutputWatts", adapter=rsd_lib_utils.num_or_none
)
"""The average power output of this Power Supply""" """The average power output of this Power Supply"""
manufacturer = base.Field('Manufacturer') manufacturer = base.Field("Manufacturer")
"""The manufacturer of this Power Supply""" """The manufacturer of this Power Supply"""
model_number = base.Field('ModelNumber') model_number = base.Field("ModelNumber")
"""The model number for this Power Supply""" """The model number for this Power Supply"""
firmware_revision = base.Field('FirmwareRevision') firmware_revision = base.Field("FirmwareRevision")
"""The firmware version for this Power Supply""" """The firmware version for this Power Supply"""
serial_number = base.Field('SerialNumber') serial_number = base.Field("SerialNumber")
"""The serial number for this Power Supply""" """The serial number for this Power Supply"""
part_number = base.Field('PartNumber') part_number = base.Field("PartNumber")
"""The part number for this Power Supply""" """The part number for this Power Supply"""
status = rsd_lib_common.StatusField('Status') status = rsd_lib_base.StatusField("Status")
"""The Power supply status""" """The Power supply status"""
rack_location = RackLocationField('RackLocation') rack_location = RackLocationField("RackLocation")
"""The PowerZone physical location""" """The PowerZone physical location"""
class PowerZone(base.ResourceBase): class PowerZone(rsd_lib_base.ResourceBase):
identity = base.Field('Id', required=True)
"""The PowerZone identity string"""
name = base.Field('Name') status = rsd_lib_base.StatusField("Status")
"""The PowerZone name"""
description = base.Field('Description')
"""The PowerZone description"""
status = rsd_lib_common.StatusField('Status')
"""The PowerZone status""" """The PowerZone status"""
rack_location = RackLocationField('RackLocation') rack_location = RackLocationField("RackLocation")
"""The PowerZone physical location""" """The PowerZone physical location"""
max_psus_supported = base.Field( max_psus_supported = base.Field(
'MaxPSUsSupported', adapter=rsd_lib_utils.num_or_none) "MaxPSUsSupported", adapter=rsd_lib_utils.num_or_none
)
"""The maximum number of Power Supply Units supported by PowerZone""" """The maximum number of Power Supply Units supported by PowerZone"""
presence = base.Field('Presence') presence = base.Field("Presence")
"""Indicates the aggregated Power Supply Unit presence information """Indicates the aggregated Power Supply Unit presence information
Aggregated Power Supply Unit presence format: Length of string indicate Aggregated Power Supply Unit presence format: Length of string indicate
total slot of Power Supply Units in PowerZone. total slot of Power Supply Units in PowerZone.
@@ -102,40 +99,32 @@ class PowerZone(base.ResourceBase):
""" """
number_of_psus_present = base.Field( number_of_psus_present = base.Field(
'NumberOfPSUsPresent', adapter=rsd_lib_utils.num_or_none) "NumberOfPSUsPresent", adapter=rsd_lib_utils.num_or_none
)
"""Indicates the number of existing Power Supply Units in PowerZone""" """Indicates the number of existing Power Supply Units in PowerZone"""
power_consumed_watts = base.Field( power_consumed_watts = base.Field(
'PowerConsumedWatts', adapter=rsd_lib_utils.num_or_none) "PowerConsumedWatts", adapter=rsd_lib_utils.num_or_none
)
"""The total power consumption of PowerZone, sum of trays' """The total power consumption of PowerZone, sum of trays'
power consumption power consumption
""" """
power_output_watts = base.Field( power_output_watts = base.Field(
'PowerOutputWatts', adapter=rsd_lib_utils.num_or_none) "PowerOutputWatts", adapter=rsd_lib_utils.num_or_none
)
"""The total power production of PowerZone, sum of PSUs' output""" """The total power production of PowerZone, sum of PSUs' output"""
power_capacity_watts = base.Field( power_capacity_watts = base.Field(
'PowerCapacityWatts', adapter=rsd_lib_utils.num_or_none) "PowerCapacityWatts", adapter=rsd_lib_utils.num_or_none
)
"""The maximum power capacity supported by PowerZone""" """The maximum power capacity supported by PowerZone"""
power_supplies = PowerSuppliesField('PowerSupplies') power_supplies = PowerSupplyCollectionField("PowerSupplies")
"""Details of the power supplies associated with this system or device""" """Details of the power supplies associated with this system or device"""
class PowerZoneCollection(base.ResourceCollectionBase): class PowerZoneCollection(rsd_lib_base.ResourceCollectionBase):
@property @property
def _resource_type(self): def _resource_type(self):
return PowerZone 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)

View File

@@ -16,262 +16,175 @@
from sushy.resources import base from sushy.resources import base
from sushy import utils from sushy import utils
from rsd_lib import common as rsd_lib_common from rsd_lib import base as rsd_lib_base
from rsd_lib import utils as rsd_lib_utils from rsd_lib import utils as rsd_lib_utils
class TemperaturesField(base.ListField): class FanCollectionField(rsd_lib_base.ReferenceableMemberField):
name = base.Field('Name')
"""The temperature sensor name"""
member_id = base.Field('MemberId') fan_name = base.Field("FanName")
"""The temperature sensor member identity""" """Name of the fan"""
status = rsd_lib_common.StatusField('Status') physical_context = base.Field("PhysicalContext")
"""The temperature sensor status""" """Describes the area or device associated with this fan."""
status = rsd_lib_base.StatusField("Status")
"""This indicates the known state of the resource, such as if it is
enabled.
"""
reading = base.Field("Reading", adapter=rsd_lib_utils.num_or_none)
"""Current fan speed"""
upper_threshold_non_critical = base.Field(
"UpperThresholdNonCritical", adapter=rsd_lib_utils.num_or_none
)
"""Above normal range"""
upper_threshold_critical = base.Field(
"UpperThresholdCritical", adapter=rsd_lib_utils.num_or_none
)
"""Above normal range but not yet fatal"""
upper_threshold_fatal = base.Field(
"UpperThresholdFatal", adapter=rsd_lib_utils.num_or_none
)
"""Above normal range and is fatal"""
lower_threshold_non_critical = base.Field(
"LowerThresholdNonCritical", adapter=rsd_lib_utils.num_or_none
)
"""Below normal range"""
lower_threshold_critical = base.Field(
"LowerThresholdCritical", adapter=rsd_lib_utils.num_or_none
)
"""Below normal range but not yet fatal"""
lower_threshold_fatal = base.Field(
"LowerThresholdFatal", adapter=rsd_lib_utils.num_or_none
)
"""Below normal range and is fatal"""
min_reading_range = base.Field(
"MinReadingRange", adapter=rsd_lib_utils.num_or_none
)
"""Minimum value for Reading"""
max_reading_range = base.Field(
"MaxReadingRange", adapter=rsd_lib_utils.num_or_none
)
"""Maximum value for Reading"""
related_item = base.Field(
"RelatedItem", adapter=utils.get_members_identities
)
"""The ID(s) of the resources serviced with this fan"""
redundancy = rsd_lib_base.RedundancyCollectionField("Redundancy")
"""This structure is used to show redundancy for fans. The Component ids
will reference the members of the redundancy groups.
"""
reading_units = base.Field("ReadingUnits")
"""Units in which the reading and thresholds are measured."""
name = base.Field("Name")
"""Name of the fan"""
class TemperatureCollectionField(rsd_lib_base.ReferenceableMemberField):
name = base.Field("Name")
"""Temperature sensor name."""
sensor_number = base.Field( sensor_number = base.Field(
'SensorNumber', adapter=rsd_lib_utils.num_or_none) "SensorNumber", adapter=rsd_lib_utils.num_or_none
)
"""A numerical identifier to represent the temperature sensor""" """A numerical identifier to represent the temperature sensor"""
status = rsd_lib_base.StatusField("Status")
"""This indicates the known state of the resource, such as if it is
enabled.
"""
reading_celsius = base.Field( reading_celsius = base.Field(
'ReadingCelsius', adapter=rsd_lib_utils.num_or_none) "ReadingCelsius", adapter=rsd_lib_utils.num_or_none
"""The current value of the Temperature sensor""" )
"""Temperature"""
upper_threshold_non_critical = base.Field( upper_threshold_non_critical = base.Field(
'UpperThresholdNonCritical', adapter=rsd_lib_utils.num_or_none) "UpperThresholdNonCritical", adapter=rsd_lib_utils.num_or_none
"""The value of this property shall indicate the CurrentReading is above )
the normal range but is not critical. Units shall use the same units """Above normal range"""
as the related ReadingVolts property.
"""
upper_threshold_critical = base.Field( upper_threshold_critical = base.Field(
'UpperThresholdCritical', adapter=rsd_lib_utils.num_or_none) "UpperThresholdCritical", adapter=rsd_lib_utils.num_or_none
"""The value of this property shall indicate the CurrentReading is above )
the normal range but is not yet fatal. Units shall use the same units """Above normal range but not yet fatal."""
as the related ReadingVolts property.
"""
upper_threshold_fatal = base.Field( upper_threshold_fatal = base.Field(
'UpperThresholdFatal', adapter=rsd_lib_utils.num_or_none) "UpperThresholdFatal", adapter=rsd_lib_utils.num_or_none
"""The value of this property shall indicate the CurrentReading is above )
the normal range and is fatal. Units shall use the same units as the """Above normal range and is fatal"""
related ReadingVolts property.
"""
lower_threshold_non_critical = base.Field( lower_threshold_non_critical = base.Field(
'LowerThresholdNonCritical', adapter=rsd_lib_utils.num_or_none) "LowerThresholdNonCritical", adapter=rsd_lib_utils.num_or_none
"""The value of this property shall indicate the CurrentReading is below )
the normal range but is not critical. Units shall use the same units """Below normal range"""
as the related ReadingVolts property.
"""
lower_threshold_critical = base.Field( lower_threshold_critical = base.Field(
'LowerThresholdCritical', adapter=rsd_lib_utils.num_or_none) "LowerThresholdCritical", adapter=rsd_lib_utils.num_or_none
"""The value of this property shall indicate the CurrentReading is below )
the normal range but is not yet fatal. Units shall use the same units """Below normal range but not yet fatal."""
as the related ReadingVolts property.
"""
lower_threshold_fatal = base.Field( lower_threshold_fatal = base.Field(
'LowerThresholdFatal', adapter=rsd_lib_utils.num_or_none) "LowerThresholdFatal", adapter=rsd_lib_utils.num_or_none
"""The value of this property shall indicate the CurrentReading is below )
the normal range and is fatal. Units shall use the same units as the """Below normal range and is fatal"""
related ReadingVolts property.
"""
min_reading_range = base.Field(
'MinReadingRange', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall indicate the lowest possible value
for CurrentReading. Units shall use the same units as the related
ReadingVolts property.
"""
min_reading_range_temp = base.Field( min_reading_range_temp = base.Field(
'MinReadingRangeTemp', adapter=rsd_lib_utils.num_or_none) "MinReadingRangeTemp", adapter=rsd_lib_utils.num_or_none
"""The value of this property shall indicate the lowest possible value for )
ReadingCelsius. The units shall be the same units as the """Minimum value for ReadingCelsius"""
related ReadingCelsius property.
"""
max_reading_range_temp = base.Field( max_reading_range_temp = base.Field(
'MaxReadingRangeTemp', adapter=rsd_lib_utils.num_or_none) "MaxReadingRangeTemp", adapter=rsd_lib_utils.num_or_none
"""The value of this property shall indicate the highest possible value )
for ReadingCelsius. The units shall be the same units as the related """Maximum value for ReadingCelsius"""
ReadingCelsius property.
"""
max_reading_range = base.Field(
'MaxReadingRange', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall indicate the highest possible value
for CurrentReading. Units shall use the same units as the related
ReadingVolts property.
"""
physical_context = base.Field('PhysicalContext') physical_context = base.Field("PhysicalContext")
"""Describes the area or device to which this temperature measurement """Describes the area or device to which this temperature measurement
applies applies.
""" """
related_item = base.Field( related_item = base.Field(
'RelatedItem', adapter=utils.get_members_identities) "RelatedItem", adapter=utils.get_members_identities
)
"""Describes the areas or devices to which this temperature measurement """Describes the areas or devices to which this temperature measurement
applies applies.
""" """
class FansField(base.ListField): class Thermal(rsd_lib_base.ResourceBase):
name = base.Field('Name') """Thermal resource class
"""The fan sensor name"""
member_id = base.Field('MemberId') This is the schema definition for the Thermal properties. It
"""The fan sensor member identity""" represents the properties for Temperature and Cooling.
status = rsd_lib_common.StatusField('Status')
"""The fan sensor status"""
sensor_number = base.Field(
'SensorNumber', adapter=rsd_lib_utils.num_or_none)
"""A numerical identifier to represent the fan sensor"""
reading = base.Field('Reading', adapter=rsd_lib_utils.num_or_none)
"""The current value of the fan sensor"""
reading_units = base.Field('ReadingUnits')
"""The value of this property shall be the units in which the fan's
reading and thresholds are measured.
""" """
upper_threshold_non_critical = base.Field( status = rsd_lib_base.StatusField("Status")
'UpperThresholdNonCritical', adapter=rsd_lib_utils.num_or_none) """This indicates the known state of the resource, such as if it is
"""The value of this property shall indicate the CurrentReading is above enabled.
the normal range but is not critical. The units shall be the same units
as the related Reading property.
""" """
upper_threshold_critical = base.Field( temperatures = TemperatureCollectionField("Temperatures")
'UpperThresholdCritical', adapter=rsd_lib_utils.num_or_none) """This is the definition for temperature sensors."""
"""The value of this property shall indicate the CurrentReading is above
the normal range but is not yet fatal. Units shall use the same units fans = FanCollectionField("Fans")
as the related Reading property. """This is the definition for fans."""
"""
redundancy = rsd_lib_base.RedundancyCollectionField("Redundancy")
upper_threshold_fatal = base.Field( """This structure is used to show redundancy for fans. The Component ids
'UpperThresholdFatal', adapter=rsd_lib_utils.num_or_none) will reference the members of the redundancy groups.
"""The value of this property shall indicate the CurrentReading is above
the normal range and is fatal. Units shall use the same units as the
related Reading property.
"""
lower_threshold_non_critical = base.Field(
'LowerThresholdNonCritical', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall indicate the CurrentReading is below
the normal range but is not critical. Units shall use the same units
as the related Reading property.
"""
lower_threshold_critical = base.Field(
'LowerThresholdCritical', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall indicate the CurrentReading is below
the normal range but is not yet fatal. Units shall use the same units
as the related Reading property.
"""
lower_threshold_fatal = base.Field(
'LowerThresholdFatal', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall indicate the CurrentReading is below
the normal range and is fatal. Units shall use the same units as the
related Reading property.
"""
min_reading_range = base.Field(
'MinReadingRange', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall indicate the lowest possible value
for CurrentReading. Units shall use the same units as the related
Reading property.
"""
max_reading_range = base.Field(
'MaxReadingRange', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall indicate the highest possible value
for CurrentReading. Units shall use the same units as the related
Reading property.
"""
physical_context = base.Field('PhysicalContext')
"""Describes the area or device to which this fan measurement
applies
"""
related_item = base.Field(
'RelatedItem', adapter=utils.get_members_identities)
"""Describes the areas or devices to which this fan measurement
applies
"""
redundancy = base.Field(
'Redundancy', adapter=utils.get_members_identities)
"""The values of the properties in this array shall be used to show
redundancy for fans and other elements in this resource. The use of
IDs within these arrays shall reference the members of the redundancy
groups.
"""
class RedundancyField(base.ListField):
name = base.Field('Name')
"""The Redundant device name"""
member_id = base.Field('MemberId')
"""The Redundant device identity"""
status = rsd_lib_common.StatusField('Status')
"""The Redundant device status"""
mode = base.Field('Mode')
"""This is the redundancy mode of the group"""
max_num_supported = base.Field(
'MaxNumSupported', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall contain the maximum number of
members allowed in the redundancy group.
"""
min_num_needed = base.Field(
'MinNumNeeded', adapter=rsd_lib_utils.num_or_none)
"""The value of this property shall contain the minimum number of members
allowed in the redundancy group for the current redundancy mode to
still be fault tolerant.
"""
redundancy_set = base.Field(
'RedundancySet', adapter=utils.get_members_identities)
"""The value of this property shall contain the ids of components that
are part of this redundancy set. The id values may or may not be
dereferenceable.
"""
redundancy_enabled = base.Field(
'RedundancyEnabled', adapter=bool)
"""The value of this property shall be a boolean indicating whether the
redundancy is enabled.
"""
class Thermal(base.ResourceBase):
identity = base.Field('Id', required=True)
"""The Power identity string"""
name = base.Field('Name')
"""The Power name"""
description = base.Field('Description')
"""The Power description"""
temperatures = TemperaturesField('Temperatures')
"""The details of temperatures senor"""
fans = FansField('Fans')
"""The details of fans"""
redundancy = RedundancyField('Redundancy')
"""Redundancy information for the power subsystem of this system or
device
""" """

View File

@@ -15,51 +15,40 @@
from sushy.resources import base from sushy.resources import base
from rsd_lib import common as rsd_lib_common from rsd_lib import base as rsd_lib_base
from rsd_lib import utils as rsd_lib_utils from rsd_lib import utils as rsd_lib_utils
class RackLocationField(base.CompositeField): class RackLocationField(base.CompositeField):
rack_units = base.Field('RackUnits')
rack_units = base.Field("RackUnits")
"""Indicates the rack unit type""" """Indicates the rack unit type"""
xlocation = base.Field('XLocation', adapter=rsd_lib_utils.num_or_none) xlocation = base.Field("XLocation", adapter=rsd_lib_utils.num_or_none)
"""The horizontal location within uLocation, from left to right """The horizontal location within uLocation, from left to right
(1.. MAXIMUM) 0 indicate not available (1.. MAXIMUM) 0 indicate not available
""" """
ulocation = base.Field('ULocation', adapter=rsd_lib_utils.num_or_none) ulocation = base.Field("ULocation", adapter=rsd_lib_utils.num_or_none)
"""The index of the top-most U of the component, from top to bottom """The index of the top-most U of the component, from top to bottom
(1.. MAXIMUM) 0 indicate not available (1.. MAXIMUM) 0 indicate not available
""" """
uheight = base.Field('UHeight', adapter=rsd_lib_utils.num_or_none) uheight = base.Field("UHeight", adapter=rsd_lib_utils.num_or_none)
"""The height of managed zone, e.g. 8 for 8U, 16 for 16U""" """The height of managed zone, e.g. 8 for 8U, 16 for 16U"""
class FansField(base.ListField): class TemperatureSensorCollectionField(rsd_lib_base.ReferenceableMemberField):
name = base.Field('Name')
"""The Power Supply name"""
reading_rpm = base.Field('ReadingRPM', adapter=rsd_lib_utils.num_or_none) name = base.Field("Name")
"""Fan RPM reading"""
status = rsd_lib_common.StatusField('Status')
"""The Fan status"""
rack_location = RackLocationField('RackLocation')
"""The Fan physical location"""
class TemperaturesField(base.ListField):
name = base.Field('Name')
"""The Power Supply name""" """The Power Supply name"""
reading_celsius = base.Field( reading_celsius = base.Field(
'ReadingCelsius', adapter=rsd_lib_utils.num_or_none) "ReadingCelsius", adapter=rsd_lib_utils.num_or_none
)
"""Current value of the temperature sensor's reading""" """Current value of the temperature sensor's reading"""
physical_context = base.Field('PhysicalContext') physical_context = base.Field("PhysicalContext")
"""Describes the area or device to which this temperature measurement """Describes the area or device to which this temperature measurement
applies: applies:
"Intake" - The intake point of the chassis "Intake" - The intake point of the chassis
@@ -71,27 +60,34 @@ class TemperaturesField(base.ListField):
"PowerSupplyBay" - Within a power supply bay "PowerSupplyBay" - Within a power supply bay
""" """
status = rsd_lib_common.StatusField('Status') status = rsd_lib_base.StatusField("Status")
"""The temperature sensors status""" """The temperature sensors status"""
class ThermalZone(base.ResourceBase): class FanCollectionField(rsd_lib_base.ReferenceableMemberField):
identity = base.Field('Id', required=True)
"""The ThermalZone identity string"""
name = base.Field('Name') name = base.Field("Name")
"""The ThermalZone name""" """The Power Supply name"""
description = base.Field('Description') reading_rpm = base.Field("ReadingRPM", adapter=rsd_lib_utils.num_or_none)
"""The ThermalZone description""" """Fan RPM reading"""
status = rsd_lib_common.StatusField('Status') status = rsd_lib_base.StatusField("Status")
"""The Fan status"""
rack_location = RackLocationField("RackLocation")
"""The Fan physical location"""
class ThermalZone(rsd_lib_base.ResourceBase):
status = rsd_lib_base.StatusField("Status")
"""The ThermalZone status""" """The ThermalZone status"""
rack_location = RackLocationField('RackLocation') rack_location = RackLocationField("RackLocation")
"""The ThermalZone physical location""" """The ThermalZone physical location"""
presence = base.Field('Presence') presence = base.Field("Presence")
"""Indicates the aggregated Power Supply Unit presence information """Indicates the aggregated Power Supply Unit presence information
Aggregated Power Supply Unit presence format: Length of string indicate Aggregated Power Supply Unit presence format: Length of string indicate
total slot of Power Supply Units in PowerZone. total slot of Power Supply Units in PowerZone.
@@ -102,45 +98,38 @@ class ThermalZone(base.ResourceBase):
""" """
desired_speed_pwm = base.Field( desired_speed_pwm = base.Field(
'DesiredSpeedPWM', adapter=rsd_lib_utils.num_or_none) "DesiredSpeedPWM", adapter=rsd_lib_utils.num_or_none
)
"""The desired FAN speed in current ThermalZone present in PWM unit""" """The desired FAN speed in current ThermalZone present in PWM unit"""
desired_speed_rpm = base.Field( desired_speed_rpm = base.Field(
'DesiredSpeedRPM', adapter=rsd_lib_utils.num_or_none) "DesiredSpeedRPM", adapter=rsd_lib_utils.num_or_none
)
"""The desired FAN speed in current ThermalZone present in RPM unit""" """The desired FAN speed in current ThermalZone present in RPM unit"""
max_fans_supported = base.Field( max_fans_supported = base.Field(
'MaxFansSupported', adapter=rsd_lib_utils.num_or_none) "MaxFansSupported", adapter=rsd_lib_utils.num_or_none
)
"""Number of maximum fans that can be installed in a given Thermal Zone""" """Number of maximum fans that can be installed in a given Thermal Zone"""
number_of_fans_present = base.Field( number_of_fans_present = base.Field(
'NumberOfFansPresent', adapter=rsd_lib_utils.num_or_none) "NumberOfFansPresent", adapter=rsd_lib_utils.num_or_none
)
"""The existing number of fans in current ThermalZone""" """The existing number of fans in current ThermalZone"""
volumetric_airflow = base.Field( volumetric_airflow = base.Field(
'VolumetricAirflow', adapter=rsd_lib_utils.num_or_none) "VolumetricAirflow", adapter=rsd_lib_utils.num_or_none
)
"""Rack Level PTAS Telemetry - Volumetric airflow in current ThermalZone""" """Rack Level PTAS Telemetry - Volumetric airflow in current ThermalZone"""
fans = FansField('Fans') fans = FanCollectionField("Fans")
"""Details of the fans associated with this thermal zone""" """Details of the fans associated with this thermal zone"""
temperatures = TemperaturesField('Temperatures') temperatures = TemperatureSensorCollectionField("Temperatures")
"""Array of temperature sensors""" """Array of temperature sensors"""
class ThermalZoneCollection(base.ResourceCollectionBase): class ThermalZoneCollection(rsd_lib_base.ResourceCollectionBase):
@property @property
def _resource_type(self): def _resource_type(self):
return ThermalZone return ThermalZone
def __init__(self, connector, path, redfish_version=None):
"""A class representing a ThermalZone 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(ThermalZoneCollection, self).__init__(connector,
path,
redfish_version)

View File

@@ -95,12 +95,15 @@
"Oem": {} "Oem": {}
} }
], ],
"IndicatorLED": "Off",
"RelatedItem": [ "RelatedItem": [
{"@odata.id": "/redfish/v1/Chassis/Rack1"} {"@odata.id": "/redfish/v1/Chassis/Rack1"}
], ],
"Redundancy": [ "Redundancy": [
{"@odata.id": "/redfish/v1/Chassis/1/Power#/Redundancy/0"} {
"@odata.id": "/redfish/v1/Chassis/1/Power#/Redundancy/0",
"MemberId": "0",
"Name": "PowerSupply Redundancy Group 2"
}
] ]
} }
], ],

View File

@@ -22,8 +22,8 @@
"LowerThresholdNonCritical": 42, "LowerThresholdNonCritical": 42,
"LowerThresholdCritical": 5, "LowerThresholdCritical": 5,
"LowerThresholdFatal": 42, "LowerThresholdFatal": 42,
"MinReadingRange": 0, "MinReadingRangeTemp": 0,
"MaxReadingRange": 200, "MaxReadingRangeTemp": 200,
"PhysicalContext": "Intake", "PhysicalContext": "Intake",
"RelatedItem": [ "RelatedItem": [
{"@odata.id": "/redfish/v1/Chassis/Drawer1" } {"@odata.id": "/redfish/v1/Chassis/Drawer1" }
@@ -52,7 +52,8 @@
"MaxReadingRange": 5000, "MaxReadingRange": 5000,
"Redundancy" : [ "Redundancy" : [
{ {
"@odata.id": "/redfish/v1/Chassis/Rack1/Thermal#/Redundancy/0" "@odata.id": "/redfish/v1/Chassis/Rack1/Thermal#/Redundancy/0",
"Name": "Fans Redundancy Group 1"
} }
], ],
"RelatedItem" : [ "RelatedItem" : [

View File

@@ -13,7 +13,6 @@
import json import json
import mock import mock
from sushy import exceptions
from sushy.tests.unit import base from sushy.tests.unit import base
from rsd_lib.resources.v2_1.chassis import chassis from rsd_lib.resources.v2_1.chassis import chassis
@@ -24,151 +23,175 @@ from rsd_lib.resources.v2_1.chassis import thermal_zone
class TestChassis(base.TestCase): class TestChassis(base.TestCase):
def setUp(self): def setUp(self):
super(TestChassis, self).setUp() super(TestChassis, self).setUp()
self.conn = mock.Mock() self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/chassis.json', with open(
'r') as f: "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()) self.conn.get.return_value.json.return_value = json.loads(f.read())
self.chassis_inst = chassis.Chassis(self.conn, self.chassis_inst = chassis.Chassis(
'/redfish/v1/Chassis/chassis1', self.conn, "/redfish/v1/Chassis/chassis1", redfish_version="1.0.2"
redfish_version='1.0.2') )
def test_parse_attributes(self): def test_parse_attributes(self):
self.chassis_inst._parse_attributes() self.chassis_inst._parse_attributes()
self.assertEqual('1.0.2', self.chassis_inst.redfish_version) self.assertEqual("1.0.2", self.chassis_inst.redfish_version)
self.assertEqual('FlexChassis1', self.chassis_inst.asset_tag) self.assertEqual("FlexChassis1", self.chassis_inst.asset_tag)
self.assertEqual('RackMount', self.chassis_inst.chassis_type) self.assertEqual("RackMount", self.chassis_inst.chassis_type)
self.assertEqual( self.assertEqual(
'description-as-string', self.chassis_inst.description) "description-as-string", self.chassis_inst.description
self.assertEqual('1', self.chassis_inst.identity) )
self.assertEqual('Intel Corporation', self.chassis_inst.manufacturer) self.assertEqual("1", self.chassis_inst.identity)
self.assertEqual('name-as-string', self.chassis_inst.name) self.assertEqual("Intel Corporation", self.chassis_inst.manufacturer)
self.assertEqual("name-as-string", self.chassis_inst.name)
self.assertEqual( self.assertEqual(
'part-number-as-string', self.chassis_inst.part_number) "part-number-as-string", self.chassis_inst.part_number
)
self.assertEqual( self.assertEqual(
'serial-number-as-string', self.chassis_inst.serial_number) "serial-number-as-string", self.chassis_inst.serial_number
self.assertEqual('sku-as-string', self.chassis_inst.sku) )
self.assertEqual('model-as-string', self.chassis_inst.model) self.assertEqual("sku-as-string", self.chassis_inst.sku)
self.assertEqual('Unknown', self.chassis_inst.indicator_led) self.assertEqual("model-as-string", self.chassis_inst.model)
self.assertEqual('Enabled', self.chassis_inst.status.state) self.assertEqual("Unknown", self.chassis_inst.indicator_led)
self.assertEqual('OK', self.chassis_inst.status.health) self.assertEqual("Enabled", self.chassis_inst.status.state)
self.assertEqual("OK", self.chassis_inst.status.health)
self.assertEqual(None, self.chassis_inst.status.health_rollup) self.assertEqual(None, self.chassis_inst.status.health_rollup)
# chassis links section # chassis links section
self.assertEqual( self.assertEqual(
('/redfish/v1/Chassis/Drawer1',), self.chassis_inst.links.contains) ("/redfish/v1/Chassis/Drawer1",), self.chassis_inst.links.contains
)
self.assertEqual(None, self.chassis_inst.links.contained_by) self.assertEqual(None, self.chassis_inst.links.contained_by)
self.assertEqual( self.assertEqual(
('/redfish/v1/Systems/system1', '/redfish/v1/Systems/system2', (
'/redfish/v1/Systems/system3', '/redfish/v1/Systems/system4'), "/redfish/v1/Systems/system1",
self.chassis_inst.links.computer_systems) "/redfish/v1/Systems/system2",
"/redfish/v1/Systems/system3",
"/redfish/v1/Systems/system4",
),
self.chassis_inst.links.computer_systems,
)
self.assertEqual( self.assertEqual(
('/redfish/v1/Managers/RMM',), self.chassis_inst.links.managed_by) ("/redfish/v1/Managers/RMM",), self.chassis_inst.links.managed_by
)
self.assertEqual( self.assertEqual(
('/redfish/v1/Managers/RMM',), ("/redfish/v1/Managers/RMM",),
self.chassis_inst.links.managers_in_chassis) self.chassis_inst.links.managers_in_chassis,
self.assertEqual((), self.chassis_inst.links.switches) )
self.assertEqual(
(), self.chassis_inst.links.oem.intel_rackscale.switches
)
# chassis oem section # chassis oem section
self.assertEqual('Rack1', self.chassis_inst.oem.location.identity) self.assertEqual(
self.assertEqual('Pod1', self.chassis_inst.oem.location.parent_id) "Rack1", self.chassis_inst.oem.intel_rackscale.location.identity
self.assertEqual(True, self.chassis_inst.oem.rmm_present) )
self.assertEqual(
"Pod1", self.chassis_inst.oem.intel_rackscale.location.parent_id
)
self.assertEqual(
True, self.chassis_inst.oem.intel_rackscale.rmm_present
)
self.assertEqual( self.assertEqual(
True, True,
self.chassis_inst.oem.rack_supports_disaggregated_power_cooling) self.chassis_inst.oem.intel_rackscale.
self.assertEqual('Unique ID', self.chassis_inst.oem.uuid) rack_supports_disaggregated_power_cooling
self.assertEqual('54.348103, 18.645172', self.chassis_inst.oem.geo_tag) )
self.assertEqual('On', self.chassis_inst.power_state)
self.assertEqual( self.assertEqual(
1, self.chassis_inst.physical_security.intrusion_sensor_number) "Unique ID", self.chassis_inst.oem.intel_rackscale.uuid
)
self.assertEqual( self.assertEqual(
2, self.chassis_inst.physical_security.intrusion_sensor) "54.348103, 18.645172",
self.chassis_inst.oem.intel_rackscale.geo_tag,
)
self.assertEqual("On", self.chassis_inst.power_state)
self.assertEqual( self.assertEqual(
3, self.chassis_inst.physical_security.intrusion_sensor_rearm) 1, self.chassis_inst.physical_security.intrusion_sensor_number
self.assertEqual(('/redfish/v1/Drives/1',), )
self.chassis_inst.links.drives) self.assertEqual(
self.assertEqual(('/redfish/v1/Storage/1',), 2, self.chassis_inst.physical_security.intrusion_sensor
self.chassis_inst.links.storage) )
self.assertEqual(('/redfish/v1/Cool/1',), self.assertEqual(
self.chassis_inst.links.cooled_by) 3, self.chassis_inst.physical_security.intrusion_sensor_re_arm
self.assertEqual(('/redfish/v1/Power/1',), )
self.chassis_inst.links.powered_by) self.assertEqual(
("/redfish/v1/Drives/1",), self.chassis_inst.links.drives
def test__get_power_zone_collection_path(self): )
expected = '/redfish/v1/Chassis/Rack1/PowerZones' self.assertEqual(
result = self.chassis_inst._get_power_zone_collection_path() ("/redfish/v1/Storage/1",), self.chassis_inst.links.storage
self.assertEqual(expected, result) )
self.assertEqual(
def test__get_power_zone_collection_path_missing_power_zone_attr(self): ("/redfish/v1/Cool/1",), self.chassis_inst.links.cooled_by
self.chassis_inst._json.pop('PowerZones') )
self.assertRaisesRegex( self.assertEqual(
exceptions.MissingAttributeError, 'attribute PowerZones', ("/redfish/v1/Power/1",), self.chassis_inst.links.powered_by
self.chassis_inst._get_power_zone_collection_path) )
def test_power_zones(self): def test_power_zones(self):
# | GIVEN | # | GIVEN |
self.conn.get.return_value.json.reset_mock() self.conn.get.return_value.json.reset_mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'power_zone_collection.json', 'r') as f: "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.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN | # | WHEN |
actual_power_zones = self.chassis_inst.power_zones actual_power_zones = self.chassis_inst.power_zones
# | THEN | # | THEN |
self.assertIsInstance(actual_power_zones, self.assertIsInstance(
power_zone.PowerZoneCollection) actual_power_zones, power_zone.PowerZoneCollection
)
self.conn.get.return_value.json.assert_called_once_with() self.conn.get.return_value.json.assert_called_once_with()
# reset mock # reset mock
self.conn.get.return_value.json.reset_mock() self.conn.get.return_value.json.reset_mock()
# | WHEN & THEN | # | WHEN & THEN |
# tests for same object on invoking subsequently # tests for same object on invoking subsequently
self.assertIs(actual_power_zones, self.assertIs(actual_power_zones, self.chassis_inst.power_zones)
self.chassis_inst.power_zones)
self.conn.get.return_value.json.assert_not_called() self.conn.get.return_value.json.assert_not_called()
def test_power_zones_on_refresh(self): def test_power_zones_on_refresh(self):
# | GIVEN | # | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'power_zone_collection.json', 'r') as f: "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.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN | # | WHEN & THEN |
self.assertIsInstance(self.chassis_inst.power_zones, self.assertIsInstance(
power_zone.PowerZoneCollection) self.chassis_inst.power_zones, power_zone.PowerZoneCollection
)
# On refreshing the chassis instance... # On refreshing the chassis instance...
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'chassis.json', 'r') as f: "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()) self.conn.get.return_value.json.return_value = json.loads(f.read())
self.chassis_inst.invalidate() self.chassis_inst.invalidate()
self.chassis_inst.refresh(force=False) self.chassis_inst.refresh(force=False)
# | GIVEN | # | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'power_zone_collection.json', 'r') as f: "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.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN | # | WHEN & THEN |
self.assertIsInstance(self.chassis_inst.power_zones, self.assertIsInstance(
power_zone.PowerZoneCollection) self.chassis_inst.power_zones, power_zone.PowerZoneCollection
)
def test__get_power_path(self):
expected = '/redfish/v1/Chassis/Rack1/Power'
result = self.chassis_inst._get_power_path()
self.assertEqual(expected, result)
def test__get_power_path_missing_power_attr(self):
self.chassis_inst._json.pop('Power')
self.assertRaisesRegex(
exceptions.MissingAttributeError, 'attribute Power',
self.chassis_inst._get_power_path)
def test_power(self): def test_power(self):
# | GIVEN | # | GIVEN |
self.conn.get.return_value.json.reset_mock() self.conn.get.return_value.json.reset_mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'power.json', 'r') as f: "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.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN | # | WHEN |
actual_power = self.chassis_inst.power actual_power = self.chassis_inst.power
@@ -180,106 +203,99 @@ class TestChassis(base.TestCase):
self.conn.get.return_value.json.reset_mock() self.conn.get.return_value.json.reset_mock()
# | WHEN & THEN | # | WHEN & THEN |
# tests for same object on invoking subsequently # tests for same object on invoking subsequently
self.assertIs(actual_power, self.assertIs(actual_power, self.chassis_inst.power)
self.chassis_inst.power)
self.conn.get.return_value.json.assert_not_called() self.conn.get.return_value.json.assert_not_called()
def test_power_on_refresh(self): def test_power_on_refresh(self):
# | GIVEN | # | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'power.json', 'r') as f: "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.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN | # | WHEN & THEN |
self.assertIsInstance(self.chassis_inst.power, power.Power) self.assertIsInstance(self.chassis_inst.power, power.Power)
# On refreshing the chassis instance... # On refreshing the chassis instance...
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'chassis.json', 'r') as f: "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()) self.conn.get.return_value.json.return_value = json.loads(f.read())
self.chassis_inst.invalidate() self.chassis_inst.invalidate()
self.chassis_inst.refresh(force=False) self.chassis_inst.refresh(force=False)
# | GIVEN | # | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'power.json', 'r') as f: "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.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN | # | WHEN & THEN |
self.assertIsInstance(self.chassis_inst.power, power.Power) self.assertIsInstance(self.chassis_inst.power, power.Power)
def test__get_thermal_zone_collection_path(self):
expected = '/redfish/v1/Chassis/Rack1/ThermalZones'
result = self.chassis_inst._get_thermal_zone_collection_path()
self.assertEqual(expected, result)
def test__get_thermal_zone_collection_path_missing_thermal_zone_attr(self):
self.chassis_inst._json.pop('ThermalZones')
self.assertRaisesRegex(
exceptions.MissingAttributeError, 'attribute ThermalZones',
self.chassis_inst._get_thermal_zone_collection_path)
def test_thermal_zones(self): def test_thermal_zones(self):
# | GIVEN | # | GIVEN |
self.conn.get.return_value.json.reset_mock() self.conn.get.return_value.json.reset_mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'thermal_zone_collection.json', 'r') as f: "rsd_lib/tests/unit/json_samples/v2_1/"
"thermal_zone_collection.json",
"r",
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN | # | WHEN |
actual_thermal_zones = self.chassis_inst.thermal_zones actual_thermal_zones = self.chassis_inst.thermal_zones
# | THEN | # | THEN |
self.assertIsInstance(actual_thermal_zones, self.assertIsInstance(
thermal_zone.ThermalZoneCollection) actual_thermal_zones, thermal_zone.ThermalZoneCollection
)
self.conn.get.return_value.json.assert_called_once_with() self.conn.get.return_value.json.assert_called_once_with()
# reset mock # reset mock
self.conn.get.return_value.json.reset_mock() self.conn.get.return_value.json.reset_mock()
# | WHEN & THEN | # | WHEN & THEN |
# tests for same object on invoking subsequently # tests for same object on invoking subsequently
self.assertIs(actual_thermal_zones, self.assertIs(actual_thermal_zones, self.chassis_inst.thermal_zones)
self.chassis_inst.thermal_zones)
self.conn.get.return_value.json.assert_not_called() self.conn.get.return_value.json.assert_not_called()
def test_thermal_zones_on_refresh(self): def test_thermal_zones_on_refresh(self):
# | GIVEN | # | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'thermal_zone_collection.json', 'r') as f: "rsd_lib/tests/unit/json_samples/v2_1/"
"thermal_zone_collection.json",
"r",
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN | # | WHEN & THEN |
self.assertIsInstance(self.chassis_inst.thermal_zones, self.assertIsInstance(
thermal_zone.ThermalZoneCollection) self.chassis_inst.thermal_zones, thermal_zone.ThermalZoneCollection
)
# On refreshing the chassis instance... # On refreshing the chassis instance...
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'chassis.json', 'r') as f: "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()) self.conn.get.return_value.json.return_value = json.loads(f.read())
self.chassis_inst.invalidate() self.chassis_inst.invalidate()
self.chassis_inst.refresh(force=False) self.chassis_inst.refresh(force=False)
# | GIVEN | # | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'thermal_zone_collection.json', 'r') as f: "rsd_lib/tests/unit/json_samples/v2_1/"
"thermal_zone_collection.json",
"r",
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN | # | WHEN & THEN |
self.assertIsInstance(self.chassis_inst.thermal_zones, self.assertIsInstance(
thermal_zone.ThermalZoneCollection) self.chassis_inst.thermal_zones, thermal_zone.ThermalZoneCollection
)
def test__get_thermal_path(self):
expected = '/redfish/v1/Chassis/Rack1/Thermal'
result = self.chassis_inst._get_thermal_path()
self.assertEqual(expected, result)
def test__get_thermal_path_missing_thermal_attr(self):
self.chassis_inst._json.pop('Thermal')
self.assertRaisesRegex(
exceptions.MissingAttributeError, 'attribute Thermal',
self.chassis_inst._get_thermal_path)
def test_thermal(self): def test_thermal(self):
# | GIVEN | # | GIVEN |
self.conn.get.return_value.json.reset_mock() self.conn.get.return_value.json.reset_mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'thermal.json', 'r') as f: "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()) self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN | # | WHEN |
actual_thermal = self.chassis_inst.thermal actual_thermal = self.chassis_inst.thermal
@@ -296,88 +312,88 @@ class TestChassis(base.TestCase):
def test_thermal_on_refresh(self): def test_thermal_on_refresh(self):
# | GIVEN | # | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'thermal.json', 'r') as f: "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()) self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN | # | WHEN & THEN |
self.assertIsInstance(self.chassis_inst.thermal, thermal.Thermal) self.assertIsInstance(self.chassis_inst.thermal, thermal.Thermal)
# On refreshing the chassis instance... # On refreshing the chassis instance...
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'chassis.json', 'r') as f: "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()) self.conn.get.return_value.json.return_value = json.loads(f.read())
self.chassis_inst.invalidate() self.chassis_inst.invalidate()
self.chassis_inst.refresh(force=False) self.chassis_inst.refresh(force=False)
# | GIVEN | # | GIVEN |
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'thermal.json', 'r') as f: "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()) self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN | # | WHEN & THEN |
self.assertIsInstance(self.chassis_inst.thermal, thermal.Thermal) self.assertIsInstance(self.chassis_inst.thermal, thermal.Thermal)
def test_update(self): def test_update(self):
self.chassis_inst.update(asset_tag='Rack#1', location_id='1234') self.chassis_inst.update(asset_tag="Rack#1", location_id="1234")
self.chassis_inst._conn.patch.assert_called_once_with( self.chassis_inst._conn.patch.assert_called_once_with(
'/redfish/v1/Chassis/chassis1', "/redfish/v1/Chassis/chassis1",
data={ data={
"AssetTag": "Rack#1", "AssetTag": "Rack#1",
"Oem": { "Oem": {"Intel_RackScale": {"Location": {"Id": "1234"}}},
"Intel_RackScale": { },
"Location": { )
"Id": "1234"}}}})
self.chassis_inst._conn.patch.reset_mock() self.chassis_inst._conn.patch.reset_mock()
self.chassis_inst.update(asset_tag='Rack#1') self.chassis_inst.update(asset_tag="Rack#1")
self.chassis_inst._conn.patch.assert_called_once_with( self.chassis_inst._conn.patch.assert_called_once_with(
'/redfish/v1/Chassis/chassis1', "/redfish/v1/Chassis/chassis1", data={"AssetTag": "Rack#1"}
data={ )
"AssetTag": "Rack#1"})
self.chassis_inst._conn.patch.reset_mock() self.chassis_inst._conn.patch.reset_mock()
self.chassis_inst.update(location_id='1234') self.chassis_inst.update(location_id="1234")
self.chassis_inst._conn.patch.assert_called_once_with( self.chassis_inst._conn.patch.assert_called_once_with(
'/redfish/v1/Chassis/chassis1', "/redfish/v1/Chassis/chassis1",
data={ data={"Oem": {"Intel_RackScale": {"Location": {"Id": "1234"}}}},
"Oem": { )
"Intel_RackScale": {
"Location": {
"Id": "1234"}}}})
class TestChassisCollection(base.TestCase): class TestChassisCollection(base.TestCase):
def setUp(self): def setUp(self):
super(TestChassisCollection, self).setUp() super(TestChassisCollection, self).setUp()
self.conn = mock.Mock() self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'chassis_collection.json', 'r') as f: "rsd_lib/tests/unit/json_samples/v2_1/" "chassis_collection.json",
"r",
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
self.chassis_col = chassis.ChassisCollection(self.conn, self.chassis_col = chassis.ChassisCollection(
'/redfish/v1/Systems', self.conn, "/redfish/v1/Systems", redfish_version="1.0.2"
redfish_version='1.0.2') )
def test__parse_attributes(self): def test__parse_attributes(self):
self.chassis_col._parse_attributes() self.chassis_col._parse_attributes()
self.assertEqual('1.0.2', self.chassis_col.redfish_version) self.assertEqual("1.0.2", self.chassis_col.redfish_version)
self.assertEqual('Chassis Collection', self.chassis_col.name) self.assertEqual("Chassis Collection", self.chassis_col.name)
self.assertIn('/redfish/v1/Chassis/Chassis1', self.assertIn(
self.chassis_col.members_identities) "/redfish/v1/Chassis/Chassis1", self.chassis_col.members_identities
)
@mock.patch.object(chassis, 'Chassis', autospec=True) @mock.patch.object(chassis, "Chassis", autospec=True)
def test_get_member(self, mock_chassis): def test_get_member(self, mock_chassis):
self.chassis_col.get_member('/redfish/v1/Chassis/Chassis1') self.chassis_col.get_member("/redfish/v1/Chassis/Chassis1")
mock_chassis.assert_called_once_with( mock_chassis.assert_called_once_with(
self.chassis_col._conn, self.chassis_col._conn,
'/redfish/v1/Chassis/Chassis1', "/redfish/v1/Chassis/Chassis1",
redfish_version=self.chassis_col.redfish_version redfish_version=self.chassis_col.redfish_version,
) )
@mock.patch.object(chassis, 'Chassis', autospec=True) @mock.patch.object(chassis, "Chassis", autospec=True)
def test_get_members(self, mock_chassis): def test_get_members(self, mock_chassis):
members = self.chassis_col.get_members() members = self.chassis_col.get_members()
self.assertEqual(mock_chassis.call_count, 8) self.assertEqual(mock_chassis.call_count, 8)

View File

@@ -21,161 +21,215 @@ from rsd_lib.resources.v2_1.chassis import power
class PowerTestCase(testtools.TestCase): class PowerTestCase(testtools.TestCase):
def setUp(self): def setUp(self):
super(PowerTestCase, self).setUp() super(PowerTestCase, self).setUp()
self.conn = mock.Mock() self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'power.json', 'r') as f: "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.conn.get.return_value.json.return_value = json.loads(f.read())
self.power_inst = power.Power( self.power_inst = power.Power(
self.conn, '/redfish/v1/Chassis/Rack1/Power', self.conn,
redfish_version='1.1.0') "/redfish/v1/Chassis/Rack1/Power",
redfish_version="1.1.0",
)
def test__parse_attributes(self): def test__parse_attributes(self):
self.power_inst._parse_attributes() self.power_inst._parse_attributes()
self.assertEqual('Power', self.power_inst.identity) self.assertEqual("Power", self.power_inst.identity)
self.assertEqual('PowerName', self.power_inst.name) self.assertEqual("PowerName", self.power_inst.name)
self.assertEqual('PowerSubsystem', self.assertEqual("PowerSubsystem", self.power_inst.description)
self.power_inst.description)
# PowerControl section # PowerControl section
self.assertEqual( self.assertEqual(
'System Power Control', self.power_inst.power_control[0].name) "System Power Control", self.power_inst.power_control[0].name
self.assertEqual('0', self.power_inst.power_control[0].member_id) )
self.assertEqual("0", self.power_inst.power_control[0].member_id)
self.assertEqual( self.assertEqual(
8000, self.power_inst.power_control[0].power_consumed_watts) 8000, self.power_inst.power_control[0].power_consumed_watts
)
self.assertEqual( self.assertEqual(
8500, self.power_inst.power_control[0].power_requested_watts) 8500, self.power_inst.power_control[0].power_requested_watts
)
self.assertEqual( self.assertEqual(
8500, self.power_inst.power_control[0].power_available_watts) 8500, self.power_inst.power_control[0].power_available_watts
)
self.assertEqual( self.assertEqual(
10000, self.power_inst.power_control[0].power_capacity_watts) 10000, self.power_inst.power_control[0].power_capacity_watts
)
self.assertEqual( self.assertEqual(
8500, self.power_inst.power_control[0].power_allocated_watts) 8500, self.power_inst.power_control[0].power_allocated_watts
)
self.assertEqual( self.assertEqual(
'Enabled', self.power_inst.power_control[0].status.state) "Enabled", self.power_inst.power_control[0].status.state
self.assertEqual('OK', self.power_inst.power_control[0].status.health) )
self.assertEqual("OK", self.power_inst.power_control[0].status.health)
self.assertEqual( self.assertEqual(
'OK', self.power_inst.power_control[0].status.health_rollup) "OK", self.power_inst.power_control[0].status.health_rollup
)
self.assertEqual( self.assertEqual(
30, self.power_inst.power_control[0].power_metrics.interval_in_min) 30, self.power_inst.power_control[0].power_metrics.interval_in_min
)
self.assertEqual( self.assertEqual(
7500, 7500,
self.power_inst.power_control[0].power_metrics.min_consumed_watts) self.power_inst.power_control[0].power_metrics.min_consumed_watts,
)
self.assertEqual( self.assertEqual(
8200, 8200,
self.power_inst.power_control[0].power_metrics.max_consumed_watts) self.power_inst.power_control[0].power_metrics.max_consumed_watts,
)
self.assertEqual( self.assertEqual(
8000, 8000,
self.power_inst.power_control[0].power_metrics. self.power_inst.power_control[
average_consumed_watts) 0
].power_metrics.average_consumed_watts,
)
self.assertEqual( self.assertEqual(
9000, self.power_inst.power_control[0].power_limit.limit_in_watts) 9000, self.power_inst.power_control[0].power_limit.limit_in_watts
)
self.assertEqual( self.assertEqual(
'LogEventOnly', "LogEventOnly",
self.power_inst.power_control[0].power_limit.limit_exception) self.power_inst.power_control[0].power_limit.limit_exception,
)
self.assertEqual( self.assertEqual(
42, self.power_inst.power_control[0].power_limit.correction_in_ms) 42, self.power_inst.power_control[0].power_limit.correction_in_ms
)
self.assertEqual( self.assertEqual(
('/redfish/v1/Chassis/Drawer1', '/redfish/v1/Systems/System1'), ("/redfish/v1/Chassis/Drawer1", "/redfish/v1/Systems/System1"),
self.power_inst.power_control[0].related_item) self.power_inst.power_control[0].related_item,
)
# voltage sensors section # voltage sensors section
self.assertEqual('VRM1 Voltage', self.power_inst.voltages[0].name) self.assertEqual("VRM1 Voltage", self.power_inst.voltages[0].name)
self.assertEqual('0', self.power_inst.voltages[0].member_id) self.assertEqual("0", self.power_inst.voltages[0].member_id)
self.assertEqual('Enabled', self.power_inst.voltages[0].status.state) self.assertEqual("Enabled", self.power_inst.voltages[0].status.state)
self.assertEqual('OK', self.power_inst.voltages[0].status.health) self.assertEqual("OK", self.power_inst.voltages[0].status.health)
self.assertEqual( self.assertEqual(
None, self.power_inst.voltages[0].status.health_rollup) None, self.power_inst.voltages[0].status.health_rollup
)
self.assertEqual(11, self.power_inst.voltages[0].sensor_number) self.assertEqual(11, self.power_inst.voltages[0].sensor_number)
self.assertEqual(12, self.power_inst.voltages[0].reading_volts) self.assertEqual(12, self.power_inst.voltages[0].reading_volts)
self.assertEqual( self.assertEqual(
100.5, self.power_inst.voltages[0].upper_threshold_non_critical) 100.5, self.power_inst.voltages[0].upper_threshold_non_critical
)
self.assertEqual( self.assertEqual(
13, self.power_inst.voltages[0].upper_threshold_critical) 13, self.power_inst.voltages[0].upper_threshold_critical
)
self.assertEqual(15, self.power_inst.voltages[0].upper_threshold_fatal) self.assertEqual(15, self.power_inst.voltages[0].upper_threshold_fatal)
self.assertEqual( self.assertEqual(
11.5, self.power_inst.voltages[0].lower_threshold_non_critical) 11.5, self.power_inst.voltages[0].lower_threshold_non_critical
)
self.assertEqual( self.assertEqual(
11, self.power_inst.voltages[0].lower_threshold_critical) 11, self.power_inst.voltages[0].lower_threshold_critical
)
self.assertEqual(10, self.power_inst.voltages[0].lower_threshold_fatal) self.assertEqual(10, self.power_inst.voltages[0].lower_threshold_fatal)
self.assertEqual(0, self.power_inst.voltages[0].min_reading_range) self.assertEqual(0, self.power_inst.voltages[0].min_reading_range)
self.assertEqual(20, self.power_inst.voltages[0].max_reading_range) self.assertEqual(20, self.power_inst.voltages[0].max_reading_range)
self.assertEqual( self.assertEqual(
'VoltageRegulator', self.power_inst.voltages[0].physical_context) "VoltageRegulator", self.power_inst.voltages[0].physical_context
self.assertEqual(('/redfish/v1/Systems/System1',), )
self.power_inst.voltages[0].related_item) self.assertEqual(
("/redfish/v1/Systems/System1",),
self.power_inst.voltages[0].related_item,
)
# power supply section # power supply section
self.assertEqual( self.assertEqual(
'Power Supply Bay 1', self.power_inst.power_supplies[0].name) "Power Supply Bay 1", self.power_inst.power_supplies[0].name
self.assertEqual('0', self.power_inst.power_supplies[0].member_id) )
self.assertEqual("0", self.power_inst.power_supplies[0].member_id)
self.assertEqual( self.assertEqual(
'Enabled', self.power_inst.power_supplies[0].status.state) "Enabled", self.power_inst.power_supplies[0].status.state
)
self.assertEqual( self.assertEqual(
'Warning', self.power_inst.power_supplies[0].status.health) "Warning", self.power_inst.power_supplies[0].status.health
)
self.assertEqual( self.assertEqual(
None, self.power_inst.power_supplies[0].status.health_rollup) None, self.power_inst.power_supplies[0].status.health_rollup
)
self.assertEqual( self.assertEqual(
'DC', self.power_inst.power_supplies[0].power_supply_type) "DC", self.power_inst.power_supplies[0].power_supply_type
)
self.assertEqual( self.assertEqual(
'DCNeg48V', "DCNeg48V",
self.power_inst.power_supplies[0].line_input_voltage_type) self.power_inst.power_supplies[0].line_input_voltage_type,
)
self.assertEqual( self.assertEqual(
-48, self.power_inst.power_supplies[0].line_input_voltage) -48, self.power_inst.power_supplies[0].line_input_voltage
)
self.assertEqual( self.assertEqual(
400, self.power_inst.power_supplies[0].power_capacity_watts) 400, self.power_inst.power_supplies[0].power_capacity_watts
)
self.assertEqual( self.assertEqual(
192, self.power_inst.power_supplies[0].last_power_output_watts) 192, self.power_inst.power_supplies[0].last_power_output_watts
self.assertEqual('499253-B21', self.power_inst.power_supplies[0].model) )
self.assertEqual("499253-B21", self.power_inst.power_supplies[0].model)
self.assertEqual( self.assertEqual(
'ManufacturerName', self.power_inst.power_supplies[0].manufacturer) "ManufacturerName", self.power_inst.power_supplies[0].manufacturer
)
self.assertEqual( self.assertEqual(
'1.00', self.power_inst.power_supplies[0].firmware_version) "1.00", self.power_inst.power_supplies[0].firmware_version
)
self.assertEqual( self.assertEqual(
'1z0000001', self.power_inst.power_supplies[0].serial_number) "1z0000001", self.power_inst.power_supplies[0].serial_number
)
self.assertEqual( self.assertEqual(
'1z0000001A3a', self.power_inst.power_supplies[0].part_number) "1z0000001A3a", self.power_inst.power_supplies[0].part_number
)
self.assertEqual( self.assertEqual(
'0000001A3a', self.power_inst.power_supplies[0].spare_part_number) "0000001A3a", self.power_inst.power_supplies[0].spare_part_number
)
self.assertEqual( self.assertEqual(
('/redfish/v1/Chassis/Rack1',), ("/redfish/v1/Chassis/Rack1",),
self.power_inst.power_supplies[0].related_item) self.power_inst.power_supplies[0].related_item,
)
self.assertEqual( self.assertEqual(
('/redfish/v1/Chassis/1/Power#/Redundancy/0',), "PowerSupply Redundancy Group 2",
self.power_inst.power_supplies[0].redundancy) self.power_inst.power_supplies[0].redundancy[0].name,
)
self.assertEqual( self.assertEqual(
'Off', self.power_inst.power_supplies[0].indicator_led) "0", self.power_inst.power_supplies[0].redundancy[0].member_id
)
self.assertEqual( self.assertEqual(
'DC', self.power_inst.power_supplies[0].input_ranges[0].input_type) "DC", self.power_inst.power_supplies[0].input_ranges[0].input_type
)
self.assertEqual( self.assertEqual(
-47, -47,
self.power_inst.power_supplies[0].input_ranges[0].minimum_voltage) self.power_inst.power_supplies[0].input_ranges[0].minimum_voltage,
)
self.assertEqual( self.assertEqual(
-49, -49,
self.power_inst.power_supplies[0].input_ranges[0].maximum_voltage) self.power_inst.power_supplies[0].input_ranges[0].maximum_voltage,
)
self.assertEqual( self.assertEqual(
50, 50,
self.power_inst.power_supplies[0].input_ranges[0]. self.power_inst.power_supplies[0]
minimum_frequency_hz) .input_ranges[0]
.minimum_frequency_hz,
)
self.assertEqual( self.assertEqual(
60, 60,
self.power_inst.power_supplies[0].input_ranges[0]. self.power_inst.power_supplies[0]
maximum_frequency_hz) .input_ranges[0]
.maximum_frequency_hz,
)
self.assertEqual( self.assertEqual(
400, 400,
self.power_inst.power_supplies[0].input_ranges[0].output_wattage) self.power_inst.power_supplies[0].input_ranges[0].output_wattage,
)
# redundancy device section # redundancy device section
self.assertEqual( self.assertEqual(
'PowerSupply Redundancy Group 1', "PowerSupply Redundancy Group 1",
self.power_inst.redundancy[0].name) self.power_inst.redundancy[0].name,
self.assertEqual('0', self.power_inst.redundancy[0].member_id) )
self.assertEqual('Offline', self.power_inst.redundancy[0].status.state) self.assertEqual("0", self.power_inst.redundancy[0].member_id)
self.assertEqual('OK', self.power_inst.redundancy[0].status.health) self.assertEqual("Offline", self.power_inst.redundancy[0].status.state)
self.assertEqual("OK", self.power_inst.redundancy[0].status.health)
self.assertEqual( self.assertEqual(
None, self.power_inst.redundancy[0].status.health_rollup) None, self.power_inst.redundancy[0].status.health_rollup
self.assertEqual('Failover', self.power_inst.redundancy[0].mode) )
self.assertEqual("Failover", self.power_inst.redundancy[0].mode)
self.assertEqual(2, self.power_inst.redundancy[0].max_num_supported) self.assertEqual(2, self.power_inst.redundancy[0].max_num_supported)
self.assertEqual(1, self.power_inst.redundancy[0].min_num_needed) self.assertEqual(1, self.power_inst.redundancy[0].min_num_needed)
self.assertEqual( self.assertEqual(
('/redfish/v1/Chassis/1/Power#/PowerSupplies/0',), ("/redfish/v1/Chassis/1/Power#/PowerSupplies/0",),
self.power_inst.redundancy[0].redundancy_set) self.power_inst.redundancy[0].redundancy_set,
)

View File

@@ -21,106 +21,132 @@ from rsd_lib.resources.v2_1.chassis import power_zone
class PowerZoneTestCase(testtools.TestCase): class PowerZoneTestCase(testtools.TestCase):
def setUp(self): def setUp(self):
super(PowerZoneTestCase, self).setUp() super(PowerZoneTestCase, self).setUp()
self.conn = mock.Mock() self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'power_zone.json', 'r') as f: "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.conn.get.return_value.json.return_value = json.loads(f.read())
self.power_zone_inst = power_zone.PowerZone( self.power_zone_inst = power_zone.PowerZone(
self.conn, '/redfish/v1/Chassis/Rack1/PowerZones/1', self.conn,
redfish_version='1.1.0') "/redfish/v1/Chassis/Rack1/PowerZones/1",
redfish_version="1.1.0",
)
def test__parse_attributes(self): def test__parse_attributes(self):
self.power_zone_inst._parse_attributes() self.power_zone_inst._parse_attributes()
self.assertEqual('1', self.power_zone_inst.identity) self.assertEqual("1", self.power_zone_inst.identity)
self.assertEqual('power zone 1', self.power_zone_inst.name) self.assertEqual("power zone 1", self.power_zone_inst.name)
self.assertEqual('power zone 1 description', self.assertEqual(
self.power_zone_inst.description) "power zone 1 description", self.power_zone_inst.description
self.assertEqual('Enabled', self.power_zone_inst.status.state) )
self.assertEqual('OK', self.power_zone_inst.status.health) self.assertEqual("Enabled", self.power_zone_inst.status.state)
self.assertEqual('OK', self.power_zone_inst.status.health_rollup) self.assertEqual("OK", self.power_zone_inst.status.health)
self.assertEqual('OU', self.power_zone_inst.rack_location.rack_units) 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(0, self.power_zone_inst.rack_location.xlocation)
self.assertEqual(1, self.power_zone_inst.rack_location.ulocation) self.assertEqual(1, self.power_zone_inst.rack_location.ulocation)
self.assertEqual(8, self.power_zone_inst.rack_location.uheight) self.assertEqual(8, self.power_zone_inst.rack_location.uheight)
self.assertEqual(6, self.power_zone_inst.max_psus_supported) self.assertEqual(6, self.power_zone_inst.max_psus_supported)
self.assertEqual('111111', self.power_zone_inst.presence) self.assertEqual("111111", self.power_zone_inst.presence)
self.assertEqual(6, self.power_zone_inst.number_of_psus_present) 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_consumed_watts)
self.assertEqual(2000, self.power_zone_inst.power_output_watts) self.assertEqual(2000, self.power_zone_inst.power_output_watts)
self.assertEqual(3000, self.power_zone_inst.power_capacity_watts) self.assertEqual(3000, self.power_zone_inst.power_capacity_watts)
self.assertEqual( self.assertEqual(
'Power supply 1', self.power_zone_inst.power_supplies[0].name) "Power supply 1", self.power_zone_inst.power_supplies[0].name
)
self.assertEqual( self.assertEqual(
300, self.power_zone_inst.power_supplies[0].power_capacity_watts) 300, self.power_zone_inst.power_supplies[0].power_capacity_watts
)
self.assertEqual( self.assertEqual(
48, self.power_zone_inst.power_supplies[0].last_power_output_watts) 48, self.power_zone_inst.power_supplies[0].last_power_output_watts
)
self.assertEqual( self.assertEqual(
'', self.power_zone_inst.power_supplies[0].manufacturer) "", self.power_zone_inst.power_supplies[0].manufacturer
)
self.assertEqual( self.assertEqual(
'', self.power_zone_inst.power_supplies[0].model_number) "", self.power_zone_inst.power_supplies[0].model_number
)
self.assertEqual( self.assertEqual(
'', self.power_zone_inst.power_supplies[0].firmware_revision) "", self.power_zone_inst.power_supplies[0].firmware_revision
)
self.assertEqual( self.assertEqual(
'', self.power_zone_inst.power_supplies[0].serial_number) "", self.power_zone_inst.power_supplies[0].serial_number
)
self.assertEqual( self.assertEqual(
'', self.power_zone_inst.power_supplies[0].part_number) "", self.power_zone_inst.power_supplies[0].part_number
)
self.assertEqual( self.assertEqual(
'Enabled', self.power_zone_inst.power_supplies[0].status.state) "Enabled", self.power_zone_inst.power_supplies[0].status.state
)
self.assertEqual( self.assertEqual(
'OK', self.power_zone_inst.power_supplies[0].status.health) "OK", self.power_zone_inst.power_supplies[0].status.health
)
self.assertEqual( self.assertEqual(
'OK', self.power_zone_inst.power_supplies[0].status.health_rollup) "OK", self.power_zone_inst.power_supplies[0].status.health_rollup
)
self.assertEqual( self.assertEqual(
'OU', "OU",
self.power_zone_inst.power_supplies[0].rack_location.rack_units) self.power_zone_inst.power_supplies[0].rack_location.rack_units,
)
self.assertEqual( self.assertEqual(
0, self.power_zone_inst.power_supplies[0].rack_location.xlocation) 0, self.power_zone_inst.power_supplies[0].rack_location.xlocation
)
self.assertEqual( self.assertEqual(
1, self.power_zone_inst.power_supplies[0].rack_location.ulocation) 1, self.power_zone_inst.power_supplies[0].rack_location.ulocation
)
self.assertEqual( self.assertEqual(
8, self.power_zone_inst.power_supplies[0].rack_location.uheight) 8, self.power_zone_inst.power_supplies[0].rack_location.uheight
)
class PowerZoneCollectionTestCase(testtools.TestCase): class PowerZoneCollectionTestCase(testtools.TestCase):
def setUp(self): def setUp(self):
super(PowerZoneCollectionTestCase, self).setUp() super(PowerZoneCollectionTestCase, self).setUp()
self.conn = mock.Mock() self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'power_zone_collection.json', 'r') as f: "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.conn.get.return_value.json.return_value = json.loads(f.read())
self.power_zone_col = power_zone.\ self.power_zone_col = power_zone.PowerZoneCollection(
PowerZoneCollection( self.conn,
self.conn, '/redfish/v1/Chassis/Rack1/PowerZones', "/redfish/v1/Chassis/Rack1/PowerZones",
redfish_version='1.1.0') redfish_version="1.1.0",
)
def test__parse_attributes(self): def test__parse_attributes(self):
self.power_zone_col._parse_attributes() self.power_zone_col._parse_attributes()
self.assertEqual('1.1.0', self.power_zone_col.redfish_version) self.assertEqual("1.1.0", self.power_zone_col.redfish_version)
self.assertEqual(('/redfish/v1/Chassis/Rack1/PowerZones/Power1',), self.assertEqual(
self.power_zone_col.members_identities) ("/redfish/v1/Chassis/Rack1/PowerZones/Power1",),
self.power_zone_col.members_identities,
)
@mock.patch.object(power_zone, 'PowerZone', autospec=True) @mock.patch.object(power_zone, "PowerZone", autospec=True)
def test_get_member(self, mock_power_zone): def test_get_member(self, mock_power_zone):
self.power_zone_col.get_member( self.power_zone_col.get_member(
'/redfish/v1/Chassis/Rack1/PowerZones/Power1') "/redfish/v1/Chassis/Rack1/PowerZones/Power1"
)
mock_power_zone.assert_called_once_with( mock_power_zone.assert_called_once_with(
self.power_zone_col._conn, self.power_zone_col._conn,
'/redfish/v1/Chassis/Rack1/PowerZones/Power1', "/redfish/v1/Chassis/Rack1/PowerZones/Power1",
redfish_version=self.power_zone_col.redfish_version) redfish_version=self.power_zone_col.redfish_version,
)
@mock.patch.object(power_zone, 'PowerZone', autospec=True) @mock.patch.object(power_zone, "PowerZone", autospec=True)
def test_get_members(self, mock_power_zone): def test_get_members(self, mock_power_zone):
members = self.power_zone_col.get_members() members = self.power_zone_col.get_members()
calls = [ calls = [
mock.call(self.power_zone_col._conn, mock.call(
'/redfish/v1/Chassis/Rack1/PowerZones/Power1', self.power_zone_col._conn,
redfish_version=self.power_zone_col. "/redfish/v1/Chassis/Rack1/PowerZones/Power1",
redfish_version) redfish_version=self.power_zone_col.redfish_version,
)
] ]
mock_power_zone.assert_has_calls(calls) mock_power_zone.assert_has_calls(calls)
self.assertIsInstance(members, list) self.assertIsInstance(members, list)

View File

@@ -21,98 +21,124 @@ from rsd_lib.resources.v2_1.chassis import thermal
class ThermalTestCase(testtools.TestCase): class ThermalTestCase(testtools.TestCase):
def setUp(self): def setUp(self):
super(ThermalTestCase, self).setUp() super(ThermalTestCase, self).setUp()
self.conn = mock.Mock() self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'thermal.json', 'r') as f: "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()) self.conn.get.return_value.json.return_value = json.loads(f.read())
self.thermal_inst = thermal.Thermal( self.thermal_inst = thermal.Thermal(
self.conn, '/redfish/v1/Chassis/Rack1/Thermal', self.conn,
redfish_version='1.1.0') "/redfish/v1/Chassis/Rack1/Thermal",
redfish_version="1.1.0",
)
def test__parse_attributes(self): def test__parse_attributes(self):
self.thermal_inst._parse_attributes() self.thermal_inst._parse_attributes()
self.assertEqual('Thermal', self.thermal_inst.identity) self.assertEqual("Thermal", self.thermal_inst.identity)
self.assertEqual('ThermalName', self.thermal_inst.name) self.assertEqual("ThermalName", self.thermal_inst.name)
self.assertEqual('Thermal Subsystem', self.assertEqual("Thermal Subsystem", self.thermal_inst.description)
self.thermal_inst.description)
# voltage sensors section # voltage sensors section
self.assertEqual( self.assertEqual(
'Drawer inlet Temp', self.thermal_inst.temperatures[0].name) "Drawer inlet Temp", self.thermal_inst.temperatures[0].name
self.assertEqual('0', self.thermal_inst.temperatures[0].member_id) )
self.assertEqual("0", self.thermal_inst.temperatures[0].member_id)
self.assertEqual( self.assertEqual(
'Enabled', self.thermal_inst.temperatures[0].status.state) "Enabled", self.thermal_inst.temperatures[0].status.state
self.assertEqual('OK', self.thermal_inst.temperatures[0].status.health) )
self.assertEqual("OK", self.thermal_inst.temperatures[0].status.health)
self.assertEqual( self.assertEqual(
None, self.thermal_inst.temperatures[0].status.health_rollup) None, self.thermal_inst.temperatures[0].status.health_rollup
)
self.assertEqual(42, self.thermal_inst.temperatures[0].sensor_number) self.assertEqual(42, self.thermal_inst.temperatures[0].sensor_number)
self.assertEqual(21, self.thermal_inst.temperatures[0].reading_celsius) self.assertEqual(21, self.thermal_inst.temperatures[0].reading_celsius)
self.assertEqual( self.assertEqual(
42, self.thermal_inst.temperatures[0].upper_threshold_non_critical) 42, self.thermal_inst.temperatures[0].upper_threshold_non_critical
)
self.assertEqual( self.assertEqual(
42, self.thermal_inst.temperatures[0].upper_threshold_critical) 42, self.thermal_inst.temperatures[0].upper_threshold_critical
)
self.assertEqual( self.assertEqual(
42, self.thermal_inst.temperatures[0].upper_threshold_fatal) 42, self.thermal_inst.temperatures[0].upper_threshold_fatal
)
self.assertEqual( self.assertEqual(
42, self.thermal_inst.temperatures[0].lower_threshold_non_critical) 42, self.thermal_inst.temperatures[0].lower_threshold_non_critical
)
self.assertEqual( self.assertEqual(
5, self.thermal_inst.temperatures[0].lower_threshold_critical) 5, self.thermal_inst.temperatures[0].lower_threshold_critical
)
self.assertEqual( self.assertEqual(
42, self.thermal_inst.temperatures[0].lower_threshold_fatal) 42, self.thermal_inst.temperatures[0].lower_threshold_fatal
)
self.assertEqual( self.assertEqual(
0, self.thermal_inst.temperatures[0].min_reading_range) 0, self.thermal_inst.temperatures[0].min_reading_range_temp
)
self.assertEqual( self.assertEqual(
200, self.thermal_inst.temperatures[0].max_reading_range) 200, self.thermal_inst.temperatures[0].max_reading_range_temp
)
self.assertEqual( self.assertEqual(
'Intake', self.thermal_inst.temperatures[0].physical_context) "Intake", self.thermal_inst.temperatures[0].physical_context
self.assertEqual(('/redfish/v1/Chassis/Drawer1',), )
self.thermal_inst.temperatures[0].related_item) self.assertEqual(
("/redfish/v1/Chassis/Drawer1",),
self.thermal_inst.temperatures[0].related_item,
)
# fans section # fans section
self.assertEqual( self.assertEqual(
'BaseBoard System Fan', self.thermal_inst.fans[0].name) "BaseBoard System Fan", self.thermal_inst.fans[0].name
self.assertEqual('0', self.thermal_inst.fans[0].member_id) )
self.assertEqual('Enabled', self.thermal_inst.fans[0].status.state) self.assertEqual("0", self.thermal_inst.fans[0].member_id)
self.assertEqual('OK', self.thermal_inst.fans[0].status.health) self.assertEqual("Enabled", self.thermal_inst.fans[0].status.state)
self.assertEqual( self.assertEqual("OK", self.thermal_inst.fans[0].status.health)
None, self.thermal_inst.fans[0].status.health_rollup) self.assertEqual(None, self.thermal_inst.fans[0].status.health_rollup)
self.assertEqual(2100, self.thermal_inst.fans[0].reading) self.assertEqual(2100, self.thermal_inst.fans[0].reading)
self.assertEqual('RPM', self.thermal_inst.fans[0].reading_units) self.assertEqual("RPM", self.thermal_inst.fans[0].reading_units)
self.assertEqual( self.assertEqual(
42, self.thermal_inst.fans[0].upper_threshold_non_critical) 42, self.thermal_inst.fans[0].upper_threshold_non_critical
)
self.assertEqual( self.assertEqual(
4200, self.thermal_inst.fans[0].upper_threshold_critical) 4200, self.thermal_inst.fans[0].upper_threshold_critical
)
self.assertEqual(42, self.thermal_inst.fans[0].upper_threshold_fatal) self.assertEqual(42, self.thermal_inst.fans[0].upper_threshold_fatal)
self.assertEqual( self.assertEqual(
42, self.thermal_inst.fans[0].lower_threshold_non_critical) 42, self.thermal_inst.fans[0].lower_threshold_non_critical
self.assertEqual( )
5, self.thermal_inst.fans[0].lower_threshold_critical) self.assertEqual(5, self.thermal_inst.fans[0].lower_threshold_critical)
self.assertEqual(42, self.thermal_inst.fans[0].lower_threshold_fatal) self.assertEqual(42, self.thermal_inst.fans[0].lower_threshold_fatal)
self.assertEqual(0, self.thermal_inst.fans[0].min_reading_range) self.assertEqual(0, self.thermal_inst.fans[0].min_reading_range)
self.assertEqual(5000, self.thermal_inst.fans[0].max_reading_range) self.assertEqual(5000, self.thermal_inst.fans[0].max_reading_range)
self.assertEqual( self.assertEqual(
'Backplane', self.thermal_inst.fans[0].physical_context) "Backplane", self.thermal_inst.fans[0].physical_context
self.assertEqual(('/redfish/v1/Chassis/Rack1',), )
self.thermal_inst.fans[0].related_item) self.assertEqual(
self.assertEqual(('/redfish/v1/Chassis/Rack1/Thermal#/Redundancy/0',), ("/redfish/v1/Chassis/Rack1",),
self.thermal_inst.fans[0].redundancy) self.thermal_inst.fans[0].related_item,
)
self.assertEqual(
"Fans Redundancy Group 1",
self.thermal_inst.fans[0].redundancy[0].name,
)
# redundancy device section # redundancy device section
self.assertEqual( self.assertEqual(
'BaseBoard System Fans', "BaseBoard System Fans", self.thermal_inst.redundancy[0].name
self.thermal_inst.redundancy[0].name) )
self.assertEqual('0', self.thermal_inst.redundancy[0].member_id) self.assertEqual("0", self.thermal_inst.redundancy[0].member_id)
self.assertEqual( self.assertEqual(
'Disabled', self.thermal_inst.redundancy[0].status.state) "Disabled", self.thermal_inst.redundancy[0].status.state
self.assertEqual('OK', self.thermal_inst.redundancy[0].status.health) )
self.assertEqual("OK", self.thermal_inst.redundancy[0].status.health)
self.assertEqual( self.assertEqual(
None, self.thermal_inst.redundancy[0].status.health_rollup) None, self.thermal_inst.redundancy[0].status.health_rollup
self.assertEqual('N+m', self.thermal_inst.redundancy[0].mode) )
self.assertEqual("N+m", self.thermal_inst.redundancy[0].mode)
self.assertEqual(2, self.thermal_inst.redundancy[0].max_num_supported) self.assertEqual(2, self.thermal_inst.redundancy[0].max_num_supported)
self.assertEqual(1, self.thermal_inst.redundancy[0].min_num_needed) self.assertEqual(1, self.thermal_inst.redundancy[0].min_num_needed)
self.assertEqual( self.assertEqual(
('/redfish/v1/Chassis/1/Thermal#/Fans/0',), ("/redfish/v1/Chassis/1/Thermal#/Fans/0",),
self.thermal_inst.redundancy[0].redundancy_set) self.thermal_inst.redundancy[0].redundancy_set,
)
self.assertEqual( self.assertEqual(
False, self.thermal_inst.redundancy[0].redundancy_enabled) False, self.thermal_inst.redundancy[0].redundancy_enabled
)

View File

@@ -21,118 +21,143 @@ from rsd_lib.resources.v2_1.chassis import thermal_zone
class ThermalZoneTestCase(testtools.TestCase): class ThermalZoneTestCase(testtools.TestCase):
def setUp(self): def setUp(self):
super(ThermalZoneTestCase, self).setUp() super(ThermalZoneTestCase, self).setUp()
self.conn = mock.Mock() self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'thermal_zone.json', 'r') as f: "rsd_lib/tests/unit/json_samples/v2_1/" "thermal_zone.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
self.thermal_zone_inst = thermal_zone.ThermalZone( self.thermal_zone_inst = thermal_zone.ThermalZone(
self.conn, '/redfish/v1/Chassis/Rack1/ThermalZones/Thermal1', self.conn,
redfish_version='1.1.0') "/redfish/v1/Chassis/Rack1/ThermalZones/Thermal1",
redfish_version="1.1.0",
)
def test__parse_attributes(self): def test__parse_attributes(self):
self.thermal_zone_inst._parse_attributes() self.thermal_zone_inst._parse_attributes()
self.assertEqual('1', self.thermal_zone_inst.identity) self.assertEqual("1", self.thermal_zone_inst.identity)
self.assertEqual('thermal zone 1', self.thermal_zone_inst.name) self.assertEqual("thermal zone 1", self.thermal_zone_inst.name)
self.assertEqual('thermal zone 1 description', self.assertEqual(
self.thermal_zone_inst.description) "thermal zone 1 description", self.thermal_zone_inst.description
self.assertEqual('Enabled', self.thermal_zone_inst.status.state) )
self.assertEqual('OK', self.thermal_zone_inst.status.health) self.assertEqual("Enabled", self.thermal_zone_inst.status.state)
self.assertEqual("OK", self.thermal_zone_inst.status.health)
self.assertEqual(None, self.thermal_zone_inst.status.health_rollup) self.assertEqual(None, self.thermal_zone_inst.status.health_rollup)
self.assertEqual('OU', self.thermal_zone_inst.rack_location.rack_units) self.assertEqual("OU", self.thermal_zone_inst.rack_location.rack_units)
self.assertEqual(0, self.thermal_zone_inst.rack_location.xlocation) self.assertEqual(0, self.thermal_zone_inst.rack_location.xlocation)
self.assertEqual(1, self.thermal_zone_inst.rack_location.ulocation) self.assertEqual(1, self.thermal_zone_inst.rack_location.ulocation)
self.assertEqual(8, self.thermal_zone_inst.rack_location.uheight) self.assertEqual(8, self.thermal_zone_inst.rack_location.uheight)
self.assertEqual('111100', self.thermal_zone_inst.presence) self.assertEqual("111100", self.thermal_zone_inst.presence)
self.assertEqual(50, self.thermal_zone_inst.desired_speed_pwm) self.assertEqual(50, self.thermal_zone_inst.desired_speed_pwm)
self.assertEqual(3000, self.thermal_zone_inst.desired_speed_rpm) self.assertEqual(3000, self.thermal_zone_inst.desired_speed_rpm)
self.assertEqual(6, self.thermal_zone_inst.max_fans_supported) self.assertEqual(6, self.thermal_zone_inst.max_fans_supported)
self.assertEqual(6, self.thermal_zone_inst.number_of_fans_present) self.assertEqual(6, self.thermal_zone_inst.number_of_fans_present)
self.assertEqual(80, self.thermal_zone_inst.volumetric_airflow) self.assertEqual(80, self.thermal_zone_inst.volumetric_airflow)
self.assertEqual("Fan 1", self.thermal_zone_inst.fans[0].name)
self.assertEqual(0, self.thermal_zone_inst.fans[0].reading_rpm)
self.assertEqual( self.assertEqual(
'Fan 1', self.thermal_zone_inst.fans[0].name) "Enabled", self.thermal_zone_inst.fans[0].status.state
)
self.assertEqual("OK", self.thermal_zone_inst.fans[0].status.health)
self.assertEqual( self.assertEqual(
0, self.thermal_zone_inst.fans[0].reading_rpm) None, self.thermal_zone_inst.fans[0].status.health_rollup
)
self.assertEqual( self.assertEqual(
'Enabled', self.thermal_zone_inst.fans[0].status.state) "OU", self.thermal_zone_inst.fans[0].rack_location.rack_units
)
self.assertEqual( self.assertEqual(
'OK', self.thermal_zone_inst.fans[0].status.health) 0, self.thermal_zone_inst.fans[0].rack_location.xlocation
)
self.assertEqual( self.assertEqual(
None, self.thermal_zone_inst.fans[0].status.health_rollup) 1, self.thermal_zone_inst.fans[0].rack_location.ulocation
)
self.assertEqual( self.assertEqual(
'OU', 8, self.thermal_zone_inst.fans[0].rack_location.uheight
self.thermal_zone_inst.fans[0].rack_location.rack_units) )
self.assertEqual( self.assertEqual(
0, self.thermal_zone_inst.fans[0].rack_location.xlocation) "Inlet Temperature", self.thermal_zone_inst.temperatures[0].name
)
self.assertEqual( self.assertEqual(
1, self.thermal_zone_inst.fans[0].rack_location.ulocation) "Enabled", self.thermal_zone_inst.temperatures[0].status.state
)
self.assertEqual( self.assertEqual(
8, self.thermal_zone_inst.fans[0].rack_location.uheight) "OK", self.thermal_zone_inst.temperatures[0].status.health
)
self.assertEqual( self.assertEqual(
'Inlet Temperature', self.thermal_zone_inst.temperatures[0].name) None, self.thermal_zone_inst.temperatures[0].status.health_rollup
)
self.assertEqual( self.assertEqual(
'Enabled', self.thermal_zone_inst.temperatures[0].status.state) 21, self.thermal_zone_inst.temperatures[0].reading_celsius
)
self.assertEqual( self.assertEqual(
'OK', self.thermal_zone_inst.temperatures[0].status.health) "Intake", self.thermal_zone_inst.temperatures[0].physical_context
)
self.assertEqual( self.assertEqual(
None, self.thermal_zone_inst.temperatures[0].status.health_rollup) "Outlet Temperature", self.thermal_zone_inst.temperatures[1].name
)
self.assertEqual( self.assertEqual(
21, self.thermal_zone_inst.temperatures[0].reading_celsius) "Enabled", self.thermal_zone_inst.temperatures[1].status.state
)
self.assertEqual( self.assertEqual(
'Intake', self.thermal_zone_inst.temperatures[0].physical_context) "OK", self.thermal_zone_inst.temperatures[1].status.health
)
self.assertEqual( self.assertEqual(
'Outlet Temperature', self.thermal_zone_inst.temperatures[1].name) None, self.thermal_zone_inst.temperatures[1].status.health_rollup
)
self.assertEqual( self.assertEqual(
'Enabled', self.thermal_zone_inst.temperatures[1].status.state) 35, self.thermal_zone_inst.temperatures[1].reading_celsius
)
self.assertEqual( self.assertEqual(
'OK', self.thermal_zone_inst.temperatures[1].status.health) "Exhaust", self.thermal_zone_inst.temperatures[1].physical_context
self.assertEqual( )
None, self.thermal_zone_inst.temperatures[1].status.health_rollup)
self.assertEqual(
35, self.thermal_zone_inst.temperatures[1].reading_celsius)
self.assertEqual(
'Exhaust', self.thermal_zone_inst.temperatures[1].physical_context)
class ThermalZoneCollectionTestCase(testtools.TestCase): class ThermalZoneCollectionTestCase(testtools.TestCase):
def setUp(self): def setUp(self):
super(ThermalZoneCollectionTestCase, self).setUp() super(ThermalZoneCollectionTestCase, self).setUp()
self.conn = mock.Mock() self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/' with open(
'thermal_zone_collection.json', 'r') as f: "rsd_lib/tests/unit/json_samples/v2_1/"
"thermal_zone_collection.json",
"r",
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read()) self.conn.get.return_value.json.return_value = json.loads(f.read())
self.thermal_zone_col = thermal_zone.\ self.thermal_zone_col = thermal_zone.ThermalZoneCollection(
ThermalZoneCollection( self.conn,
self.conn, '/redfish/v1/Chassis/Rack1/ThermalZones', "/redfish/v1/Chassis/Rack1/ThermalZones",
redfish_version='1.1.0') redfish_version="1.1.0",
)
def test__parse_attributes(self): def test__parse_attributes(self):
self.thermal_zone_col._parse_attributes() self.thermal_zone_col._parse_attributes()
self.assertEqual('1.1.0', self.thermal_zone_col.redfish_version) self.assertEqual("1.1.0", self.thermal_zone_col.redfish_version)
self.assertEqual(('/redfish/v1/Chassis/Rack1/ThermalZones/Thermal1',), self.assertEqual(
self.thermal_zone_col.members_identities) ("/redfish/v1/Chassis/Rack1/ThermalZones/Thermal1",),
self.thermal_zone_col.members_identities,
)
@mock.patch.object(thermal_zone, 'ThermalZone', autospec=True) @mock.patch.object(thermal_zone, "ThermalZone", autospec=True)
def test_get_member(self, mock_thermal_zone): def test_get_member(self, mock_thermal_zone):
self.thermal_zone_col.get_member( self.thermal_zone_col.get_member(
'/redfish/v1/Chassis/Rack1/ThermalZones/Thermal1') "/redfish/v1/Chassis/Rack1/ThermalZones/Thermal1"
)
mock_thermal_zone.assert_called_once_with( mock_thermal_zone.assert_called_once_with(
self.thermal_zone_col._conn, self.thermal_zone_col._conn,
'/redfish/v1/Chassis/Rack1/ThermalZones/Thermal1', "/redfish/v1/Chassis/Rack1/ThermalZones/Thermal1",
redfish_version=self.thermal_zone_col.redfish_version) redfish_version=self.thermal_zone_col.redfish_version,
)
@mock.patch.object(thermal_zone, 'ThermalZone', autospec=True) @mock.patch.object(thermal_zone, "ThermalZone", autospec=True)
def test_get_members(self, mock_thermal_zone): def test_get_members(self, mock_thermal_zone):
members = self.thermal_zone_col.get_members() members = self.thermal_zone_col.get_members()
calls = [ calls = [
mock.call(self.thermal_zone_col._conn, mock.call(
'/redfish/v1/Chassis/Rack1/ThermalZones/Thermal1', self.thermal_zone_col._conn,
redfish_version=self.thermal_zone_col. "/redfish/v1/Chassis/Rack1/ThermalZones/Thermal1",
redfish_version) redfish_version=self.thermal_zone_col.redfish_version,
)
] ]
mock_thermal_zone.assert_has_calls(calls) mock_thermal_zone.assert_has_calls(calls)
self.assertIsInstance(members, list) self.assertIsInstance(members, list)