Update Memory_metrics in RSD 2.2

Change-Id: I9e7498fa39d45697e557389607698194d7046af8
This commit is contained in:
HeyIns 2019-05-21 16:25:50 +08:00 committed by Lin Yang
parent f810ae597c
commit ed6150f06b
3 changed files with 239 additions and 27 deletions

View File

@ -13,26 +13,196 @@
# 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 sushy import exceptions
from sushy.resources import base from sushy.resources import base
from sushy.resources import 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 MemoryMetrics(base.ResourceBase): class CurrentPeriodField(base.CompositeField):
"""CurrentPeriod field
name = base.Field('Name') This object contains the Memory metrics since last reset or
"""The metrics name""" ClearCurrentPeriod action.
"""
description = base.Field('Description') blocks_read = base.Field("BlocksRead", adapter=rsd_lib_utils.num_or_none)
"""The metrics description""" """Number of blocks read since reset."""
identity = base.Field('Id') blocks_written = base.Field(
"""The metrics identity""" "BlocksWritten", adapter=rsd_lib_utils.num_or_none
)
"""Number of blocks written since reset."""
class LifeTimeField(base.CompositeField):
"""LifeTime field
This object contains the Memory metrics for the lifetime of the Memory.
"""
blocks_read = base.Field("BlocksRead", adapter=rsd_lib_utils.num_or_none)
"""Number of blocks read for the lifetime of the Memory."""
blocks_written = base.Field(
"BlocksWritten", adapter=rsd_lib_utils.num_or_none
)
"""Number of blocks written for the lifetime of the Memory."""
class AlarmTripsField(base.CompositeField):
"""AlarmTrips field
Alarm trip information about the memory.
"""
temperature = base.Field("Temperature", adapter=bool)
"""Temperature threshold crossing alarm trip detected status."""
spare_block = base.Field("SpareBlock", adapter=bool)
"""Spare block capacity crossing alarm trip detected status."""
uncorrectable_ecc_error = base.Field("UncorrectableECCError", adapter=bool)
"""Uncorrectable data error threshold crossing alarm trip detected status.
"""
correctable_ecc_error = base.Field("CorrectableECCError", adapter=bool)
"""Correctable data error threshold crossing alarm trip detected status."""
address_parity_error = base.Field("AddressParityError", adapter=bool)
"""Address parity error detected status."""
class HealthDataField(base.CompositeField):
"""HealthData field
This type describes the health information of the memory.
"""
remaining_spare_block_percentage = base.Field(
"RemainingSpareBlockPercentage", adapter=rsd_lib_utils.num_or_none
)
"""Remaining spare blocks in percentage."""
last_shutdown_success = base.Field("LastShutdownSuccess", adapter=bool)
"""Status of last shutdown."""
data_loss_detected = base.Field("DataLossDetected", adapter=bool)
"""Data loss detection status."""
performance_degraded = base.Field("PerformanceDegraded", adapter=bool)
"""Performance degraded mode status."""
alarm_trips = AlarmTripsField("AlarmTrips")
"""Alarm trip information about the memory."""
predicted_media_life_left_percent = base.Field(
"PredictedMediaLifeLeftPercent", adapter=rsd_lib_utils.num_or_none
)
"""The percentage of reads and writes that are predicted to still be
available for the media.
"""
class IntelRackScaleField(base.CompositeField):
temperature_celsius = base.Field( temperature_celsius = base.Field(
['Oem', 'Intel_RackScale', 'TemperatureCelsius'], "TemperatureCelsius", adapter=rsd_lib_utils.num_or_none
adapter=rsd_lib_utils.num_or_none) )
"""The memory temperature celsius""" """Temperature of the Memory resource"""
health = base.Field(['Oem', 'Intel_RackScale', 'Health']) bandwidth_percent = base.Field(
"""The detail health information""" "BandwidthPercent", adapter=rsd_lib_utils.num_or_none
)
"""Memory Bandwidth in Percent"""
throttled_cycles_percent = base.Field(
"ThrottledCyclesPercent", adapter=rsd_lib_utils.num_or_none
)
"""The percentage of memory cycles that were throttled due to power
limiting.
"""
consumed_power_watt = base.Field(
"ConsumedPowerWatt", adapter=rsd_lib_utils.num_or_none
)
"""Power consumed by Memory domain resource"""
thermal_margin_celsius = base.Field(
"ThermalMarginCelsius", adapter=rsd_lib_utils.num_or_none
)
"""Memory Thermal Margin in degree Celsius"""
ecc_errors_count = base.Field(
"ECCErrorsCount", adapter=rsd_lib_utils.num_or_none
)
"""Number of ECC Errors found on this Memory module"""
health = base.Field("Health")
"""Memory module Health as a discrete sensor reading"""
class OemField(base.CompositeField):
intel_rackscale = IntelRackScaleField("Intel_RackScale")
"""Intel Rack Scale Design specific properties."""
class ActionsField(base.CompositeField):
clear_current_period = common.ActionField(
"#MemoryMetrics.ClearCurrentPeriod"
)
class MemoryMetrics(rsd_lib_base.ResourceBase):
"""MemoryMetrics resource class
MemoryMetrics contains usage and health statistics for a single Memory
module or device instance.
"""
block_size_bytes = base.Field(
"BlockSizeBytes", adapter=rsd_lib_utils.num_or_none
)
"""Block size in bytes."""
current_period = CurrentPeriodField("CurrentPeriod")
"""This object contains the Memory metrics since last reset or
ClearCurrentPeriod action.
"""
life_time = LifeTimeField("LifeTime")
"""This object contains the Memory metrics for the lifetime of the Memory.
"""
health_data = HealthDataField("HealthData")
"""This object describes the health information of the memory."""
oem = OemField("Oem")
"""Oem specific properties."""
_actions = ActionsField("Actions")
"""The Actions property shall contain the
available actions for this resource.
"""
def _get_clear_current_period_action_element(self):
clear_current_period_action = self._actions.clear_current_period
if not clear_current_period_action:
raise exceptions.MissingActionError(
action="#MemoryMetrics.ClearCurrentPeriod", resource=self._path
)
return clear_current_period_action
def clear_current_period(self):
"""Clear the current the period of memory_metrics.
:raises: MissingActionError, if no clear_current_period action exists.
"""
target_uri = self._get_clear_current_period_action_element().target_uri
self._conn.post(target_uri, data={})

View File

@ -10,5 +10,10 @@
"TemperatureCelsius": 46, "TemperatureCelsius": 46,
"Health": ["OK"] "Health": ["OK"]
} }
},
"Actions": {
"#MemoryMetrics.ClearCurrentPeriod": {
"target": "/redfish/v1/Systems/3/Memory/Dimm1/Metrics/Actions/MemoryMetrics.ClearCurrentPeriod"
}
} }
} }

View File

@ -14,34 +14,71 @@
# under the License. # under the License.
import json import json
import mock import mock
import testtools import testtools
from sushy import exceptions
from rsd_lib.resources.v2_2.system import memory_metrics from rsd_lib.resources.v2_2.system import memory_metrics
class MemoryMetricsTestCase(testtools.TestCase): class MemoryMetricsTestCase(testtools.TestCase):
def setUp(self): def setUp(self):
super(MemoryMetricsTestCase, self).setUp() super(MemoryMetricsTestCase, self).setUp()
self.conn = mock.Mock() self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_2/' with open(
'memory_metrics.json', 'r') as f: "rsd_lib/tests/unit/json_samples/v2_2/" "memory_metrics.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.memory_metrics_inst = memory_metrics.MemoryMetrics( self.memory_metrics_inst = memory_metrics.MemoryMetrics(
self.conn, '/redfish/v1/Systems/3/Memory/Dimm1/Metrics', self.conn,
redfish_version='1.1.0') "/redfish/v1/Systems/3/Memory/Dimm1/Metrics",
redfish_version="1.1.0",
)
def test__parse_attributes(self): def test__parse_attributes(self):
self.memory_metrics_inst._parse_attributes() self.memory_metrics_inst._parse_attributes()
self.assertEqual('1.1.0', self.memory_metrics_inst.redfish_version) self.assertEqual("1.1.0", self.memory_metrics_inst.redfish_version)
self.assertEqual('Memory Metrics for DIMM1', self.assertEqual(
self.memory_metrics_inst.name) "Memory Metrics for DIMM1", self.memory_metrics_inst.name
self.assertEqual('description-as-string', )
self.memory_metrics_inst.description) self.assertEqual(
self.assertEqual('Metrics for DIMM1', "description-as-string", self.memory_metrics_inst.description
self.memory_metrics_inst.identity) )
self.assertEqual(46, self.memory_metrics_inst.temperature_celsius) self.assertEqual(
self.assertEqual(["OK"], self.memory_metrics_inst.health) "Metrics for DIMM1", self.memory_metrics_inst.identity
)
self.assertEqual(
46,
self.memory_metrics_inst.oem.intel_rackscale.temperature_celsius,
)
self.assertEqual(
["OK"], self.memory_metrics_inst.oem.intel_rackscale.health
)
def test_get_clear_current_period_action_element(self):
value = (
self.memory_metrics_inst._get_clear_current_period_action_element()
)
self.assertEqual(
"/redfish/v1/Systems/3/Memory/Dimm1/Metrics/"
"Actions/MemoryMetrics.ClearCurrentPeriod",
value.target_uri,
)
def test_get_clear_current_period_action_element_missing_action(self):
self.memory_metrics_inst._actions.clear_current_period = None
with self.assertRaisesRegex(
exceptions.MissingActionError,
"action #MemoryMetrics.ClearCurrentPeriod",
):
self.memory_metrics_inst._get_clear_current_period_action_element()
def test_clear_current_period(self):
self.memory_metrics_inst.clear_current_period()
self.memory_metrics_inst._conn.post.assert_called_once_with(
"/redfish/v1/Systems/3/Memory/Dimm1/Metrics/"
"Actions/MemoryMetrics.ClearCurrentPeriod",
data={},
)