Update process attributes in RSD 2.2

Change-Id: I2781e6cc9fa379103c02a2bacc83674eb77fe765
This commit is contained in:
Lin Yang 2019-03-12 23:07:37 -07:00
parent 7c872a9979
commit 5836a2f06d
6 changed files with 303 additions and 9 deletions

52
rsd_lib/base.py Normal file
View File

@ -0,0 +1,52 @@
# Copyright 2019 Intel, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import copy
from sushy.resources import base
from rsd_lib import utils as rsd_lib_utils
class DynamicField(base.Field):
"""Base class for fields consisting of several dynamic attributes."""
def __init__(self, *args, **kwargs):
super(DynamicField, self).__init__(*args, **kwargs)
self._subfields = None
def _load(self, body, resource, nested_in=None):
"""Load the all attributes.
:param body: parent JSON body.
:param resource: parent resource.
:param nested_in: parent resource name (for error reporting only).
:returns: a new object with sub-fields attached to it.
"""
nested_in = (nested_in or []) + self._path
value = super(DynamicField, self)._load(body, resource)
if value is None:
return None
# We need a new instance, as this method is called a singleton instance
# that is attached to a class (not instance) of a resource or another
# CompositeField. We don't want to end up modifying this instance.
instance = copy.copy(self)
for name, attr in value.items():
setattr(
instance, rsd_lib_utils.camelcase_to_underscore_joined(name),
attr)
return instance

View File

@ -13,17 +13,80 @@
# License for the specific language governing permissions and limitations
# under the License.
from sushy.resources.system import processor
from sushy.resources import base
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.system import processor
from rsd_lib.resources.v2_2.system import processor_metrics
from rsd_lib import utils as rsd_lib_utils
class OnPackageMemoryField(base.ListField):
memory_type = base.Field('Type')
"""Type of memory"""
capacity_mb = base.Field('CapacityMB', adapter=rsd_lib_utils.num_or_none)
"""Memory capacity"""
speed_mhz = base.Field('SpeedMHz', adapter=rsd_lib_utils.num_or_none)
"""Memory speed"""
class FpgaField(base.CompositeField):
fpga_type = base.Field('Type')
"""Type of FPGA"""
bit_stream_version = base.Field('BitStreamVersion')
"""Version of BitStream loaded on FPGA"""
hssi_configuration = base.Field('HSSIConfiguration')
"""High Speed Serial Interface configuration"""
hssi_sideband = base.Field('HSSISideband')
"""High Speed Serial Interface sideband interface type"""
reconfiguration_slots = base.Field(
'ReconfigurationSlots', adapter=rsd_lib_utils.num_or_none)
"""Number of supported reconfiguration slots"""
class IntelRackScaleField(processor.IntelRackScaleField):
on_package_memory = OnPackageMemoryField('OnPackageMemory')
"""An array of references to the endpoints that connect to this processor
"""
thermal_design_power_watt = base.Field(
'ThermalDesignPowerWatt', adapter=rsd_lib_utils.num_or_none)
"""Thermal Design Power (TDP) of this processor"""
metrics = base.Field(
'Metrics', adapter=rsd_lib_utils.get_resource_identity)
"""A reference to the Metrics associated with this Processor"""
extended_identification_registers = rsd_lib_base.DynamicField(
'ExtendedIdentificationRegisters')
"""Extended contents of the Identification Registers (CPUID) for this
processor
"""
fpga = FpgaField('FPGA')
"""FPGA specific properties for FPGA ProcessorType"""
class OemField(base.CompositeField):
intel_rackscale = IntelRackScaleField('Intel_RackScale')
"""Intel Rack Scale Design extensions ('Intel_RackScale' object)"""
class Processor(processor.Processor):
status = rsd_lib_common.StatusField('Status')
"""The processor status"""
oem = OemField('Oem')
"""Oem extension object"""
def _get_metrics_path(self):
"""Helper function to find the System process metrics path"""

View File

@ -51,6 +51,13 @@
"Metrics": {
"@odata.id": "/redfish/v1/Systems/System1/Processors/CPU1/Metrics"
},
"FPGA": {
"Type": "Integrated",
"BitStreamVersion": "Blue1",
"HSSIConfiguration": "4x10G",
"HSSISideband": "I2C",
"ReconfigurationSlots": 1
},
"ExtendedIdentificationRegisters": {
"EAX_00h": "0x0429943FFFFFFFFF",
"EAX_01h": "0x0429943FFFFFFFFF",

View File

@ -40,21 +40,146 @@ class ProcessorTestCase(testtools.TestCase):
self.processor_inst._parse_attributes()
self.assertEqual('1.1.0', self.processor_inst.redfish_version)
self.assertEqual('CPU1', self.processor_inst.identity)
self.assertEqual('Processor', self.processor_inst.name)
self.assertEqual(None, self.processor_inst.description)
self.assertEqual('CPU 1', self.processor_inst.socket)
self.assertEqual('CPU', self.processor_inst.processor_type)
self.assertEqual('x86 or x86-64',
self.processor_inst.processor_architecture)
self.assertEqual('x86', self.processor_inst.processor_architecture)
self.assertEqual('x86-64', self.processor_inst.instruction_set)
self.assertEqual('Intel(R) Corporation',
self.processor_inst.manufacturer)
self.assertEqual('Multi-Core Intel(R) Xeon(R) processor 7xxx Series',
self.processor_inst.model)
self.assertEqual(3700, self.processor_inst.max_speed_mhz)
self.assertEqual(8, self.processor_inst.total_cores)
self.assertEqual(16, self.processor_inst.total_threads)
self.assertEqual('Enabled', self.processor_inst.status.state)
self.assertEqual(
'0x42', self.processor_inst.processor_id.effective_family)
self.assertEqual(
'0x61', self.processor_inst.processor_id.effective_model)
self.assertEqual(
'0x34AC34DC8901274A',
self.processor_inst.processor_id.identification_registers)
self.assertEqual(
'0x429943', self.processor_inst.processor_id.microcode_info)
self.assertEqual('0x1', self.processor_inst.processor_id.step)
self.assertEqual(
'GenuineIntel', self.processor_inst.processor_id.vendor_id)
self.assertEqual('OK', self.processor_inst.status.health)
self.assertEqual('OK', self.processor_inst.status.health_rollup)
self.assertEqual('Enabled', self.processor_inst.status.state)
self.assertEqual(8, self.processor_inst.total_cores)
self.assertEqual(16, self.processor_inst.total_threads)
self.assertEqual('E5', self.processor_inst.oem.intel_rackscale.brand)
self.assertEqual(
['sse', 'sse2', 'sse3'],
self.processor_inst.oem.intel_rackscale.capabilities)
self.assertEqual(
'L2Cache',
self.processor_inst.oem.intel_rackscale.on_package_memory[0].
memory_type)
self.assertEqual(
2,
self.processor_inst.oem.intel_rackscale.on_package_memory[0].
capacity_mb)
self.assertEqual(
None,
self.processor_inst.oem.intel_rackscale.on_package_memory[0].
speed_mhz)
self.assertEqual(
'L3Cache',
self.processor_inst.oem.intel_rackscale.on_package_memory[1].
memory_type)
self.assertEqual(
20,
self.processor_inst.oem.intel_rackscale.on_package_memory[1].
capacity_mb)
self.assertEqual(
None,
self.processor_inst.oem.intel_rackscale.on_package_memory[1].
speed_mhz)
self.assertEqual(
160,
self.processor_inst.oem.intel_rackscale.thermal_design_power_watt)
self.assertEqual(
'/redfish/v1/Systems/System1/Processors/CPU1/Metrics',
self.processor_inst.oem.intel_rackscale.metrics)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_00h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_01h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_02h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_03h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_04h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_05h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_07h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_80000000h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_80000001h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_80000002h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_80000003h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_80000004h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_80000005h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_80000006h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_80000007h)
self.assertEqual(
"0x0429943FFFFFFFFF",
self.processor_inst.oem.intel_rackscale.
extended_identification_registers.eax_80000008h)
self.assertEqual(
'Integrated',
self.processor_inst.oem.intel_rackscale.fpga.fpga_type)
self.assertEqual(
'Blue1',
self.processor_inst.oem.intel_rackscale.fpga.bit_stream_version)
self.assertEqual(
'4x10G',
self.processor_inst.oem.intel_rackscale.fpga.hssi_configuration)
self.assertEqual(
'I2C', self.processor_inst.oem.intel_rackscale.fpga.hssi_sideband)
self.assertEqual(
1,
self.processor_inst.oem.intel_rackscale.fpga.reconfiguration_slots)
def test__get_metrics_path(self):
self.assertEqual('/redfish/v1/Systems/System1/Processors/CPU1/Metrics',

View File

@ -76,3 +76,24 @@ class UtilsTestCase(testtools.TestCase):
mock_resource,
'Links'
)
def test_camelcase_to_underscore_joined(self):
input_vs_expected = [
('GarbageCollection', 'garbage_collection'),
('DD', 'dd'),
('rr', 'rr'),
('AABbbC', 'aa_bbb_c'),
('AABbbCCCDd', 'aa_bbb_ccc_dd'),
('Manager', 'manager'),
('EthernetInterfaceCollection', 'ethernet_interface_collection'),
(' ', ' '),
]
for inp, exp in input_vs_expected:
self.assertEqual(
exp, rsd_lib_utils.camelcase_to_underscore_joined(inp))
def test_camelcase_to_underscore_joined_fails_with_empty_string(self):
self.assertRaisesRegex(
ValueError,
'"camelcase_str" cannot be empty',
rsd_lib_utils.camelcase_to_underscore_joined, '')

View File

@ -65,3 +65,29 @@ def get_sub_resource_path_list_by(resource, subresource_name):
attribute='/'.join(subresource_name), resource=resource.path)
return [item.get('@data.id') for item in body]
# TODO(linyang): Use the same function in sushy utils after sushy 1.8.1
# is released
def camelcase_to_underscore_joined(camelcase_str):
"""Convert camelCase string to underscore_joined string
:param camelcase_str: The camelCase string
:returns: the equivalent underscore_joined string
"""
if not camelcase_str:
raise ValueError('"camelcase_str" cannot be empty')
r = camelcase_str[0].lower()
for i, letter in enumerate(camelcase_str[1:], 1):
if letter.isupper():
try:
if (camelcase_str[i - 1].islower()
or camelcase_str[i + 1].islower()):
r += '_'
except IndexError:
pass
r += letter.lower()
return r