Update process attributes in RSD 2.2
Change-Id: I2781e6cc9fa379103c02a2bacc83674eb77fe765
This commit is contained in:
parent
7c872a9979
commit
5836a2f06d
52
rsd_lib/base.py
Normal file
52
rsd_lib/base.py
Normal 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
|
@ -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"""
|
||||
|
@ -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",
|
||||
|
@ -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',
|
||||
|
@ -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, '')
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user