Update Memory_metrics in RSD 2.2
Change-Id: I9e7498fa39d45697e557389607698194d7046af8
This commit is contained in:
parent
f810ae597c
commit
ed6150f06b
@ -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={})
|
||||||
|
@ -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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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={},
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user