Add missing attributes in ComputerSystemMetrics in RSD 2.2

Change-Id: I3aa7c778f1bdf6913a06de605247272667e0b59c
This commit is contained in:
Lin Yang 2019-05-24 11:25:54 -07:00
parent ed6150f06b
commit f96b095e35
9 changed files with 492 additions and 389 deletions

View File

@ -24,68 +24,83 @@ LOG = logging.getLogger(__name__)
class NodeCollection(v2_1_node.NodeCollection):
def _create_compose_request(self, name=None, description=None,
processor_req=None, memory_req=None,
remote_drive_req=None, local_drive_req=None,
ethernet_interface_req=None,
security_req=None, total_system_core_req=None,
total_system_memory_req=None):
def _create_compose_request(
self,
name=None,
description=None,
processor_req=None,
memory_req=None,
remote_drive_req=None,
local_drive_req=None,
ethernet_interface_req=None,
security_req=None,
total_system_core_req=None,
total_system_memory_req=None,
):
request = {}
if name is not None:
request['Name'] = name
request["Name"] = name
if description is not None:
request['Description'] = description
request["Description"] = description
if processor_req is not None:
validate(processor_req,
node_schemas.processor_req_schema)
request['Processors'] = processor_req
validate(processor_req, node_schemas.processor_req_schema)
request["Processors"] = processor_req
if memory_req is not None:
validate(memory_req,
node_schemas.memory_req_schema)
request['Memory'] = memory_req
validate(memory_req, node_schemas.memory_req_schema)
request["Memory"] = memory_req
if remote_drive_req is not None:
validate(remote_drive_req,
node_schemas.remote_drive_req_schema)
request['RemoteDrives'] = remote_drive_req
validate(remote_drive_req, node_schemas.remote_drive_req_schema)
request["RemoteDrives"] = remote_drive_req
if local_drive_req is not None:
validate(local_drive_req,
node_schemas.local_drive_req_schema)
request['LocalDrives'] = local_drive_req
validate(local_drive_req, node_schemas.local_drive_req_schema)
request["LocalDrives"] = local_drive_req
if ethernet_interface_req is not None:
validate(ethernet_interface_req,
node_schemas.ethernet_interface_req_schema)
request['EthernetInterfaces'] = ethernet_interface_req
validate(
ethernet_interface_req,
node_schemas.ethernet_interface_req_schema,
)
request["EthernetInterfaces"] = ethernet_interface_req
if security_req is not None:
validate(security_req,
node_schemas.security_req_schema)
request['Security'] = security_req
validate(security_req, node_schemas.security_req_schema)
request["Security"] = security_req
if total_system_core_req is not None:
validate(total_system_core_req,
node_schemas.total_system_core_req_schema)
request['TotalSystemCoreCount'] = total_system_core_req
validate(
total_system_core_req,
node_schemas.total_system_core_req_schema,
)
request["TotalSystemCoreCount"] = total_system_core_req
if total_system_memory_req is not None:
validate(total_system_memory_req,
node_schemas.total_system_memory_req_schema)
request['TotalSystemMemoryMiB'] = total_system_memory_req
validate(
total_system_memory_req,
node_schemas.total_system_memory_req_schema,
)
request["TotalSystemMemoryMiB"] = total_system_memory_req
return request
def compose_node(self, name=None, description=None,
processor_req=None, memory_req=None,
remote_drive_req=None, local_drive_req=None,
ethernet_interface_req=None, security_req=None,
total_system_core_req=None, total_system_memory_req=None):
def compose_node(
self,
name=None,
description=None,
processor_req=None,
memory_req=None,
remote_drive_req=None,
local_drive_req=None,
ethernet_interface_req=None,
security_req=None,
total_system_core_req=None,
total_system_memory_req=None,
):
"""Compose a node from RackScale hardware
:param name: Name of node
@ -115,7 +130,8 @@ class NodeCollection(v2_1_node.NodeCollection):
"""
target_uri = self._get_compose_action_element().target_uri
properties = self._create_compose_request(
name=name, description=description,
name=name,
description=description,
processor_req=processor_req,
memory_req=memory_req,
remote_drive_req=remote_drive_req,
@ -123,8 +139,9 @@ class NodeCollection(v2_1_node.NodeCollection):
ethernet_interface_req=ethernet_interface_req,
security_req=security_req,
total_system_core_req=total_system_core_req,
total_system_memory_req=total_system_memory_req)
total_system_memory_req=total_system_memory_req,
)
resp = self._conn.post(target_uri, data=properties)
LOG.info("Node created at %s", resp.headers['Location'])
node_url = resp.headers['Location']
LOG.info("Node created at %s", resp.headers["Location"])
node_url = resp.headers["Location"]
return node_url[node_url.find(self._path):]

View File

@ -13,198 +13,225 @@
# under the License.
processor_req_schema = {
'type': 'array',
'items': [{
'type': 'object',
'properties': {
'Model': {'type': 'string'},
'TotalCores': {'type': 'number'},
'AchievableSpeedMHz': {'type': 'number'},
'InstructionSet': {
'type': 'string',
'enum': ['x86', 'x86-64', 'IA-64', 'ARM-A32',
'ARM-A64', 'MIPS32', 'MIPS64', 'OEM']
},
'Oem': {
'type': 'object',
'properties': {
'Brand': {
'type': 'string',
'enum': ['E3', 'E5', 'E7', 'X3', 'X5', 'X7', 'I3',
'I5', 'I7', 'Silver', 'Gold', 'Platinum',
'Unknown']
"type": "array",
"items": [
{
"type": "object",
"properties": {
"Model": {"type": "string"},
"TotalCores": {"type": "number"},
"AchievableSpeedMHz": {"type": "number"},
"InstructionSet": {
"type": "string",
"enum": [
"x86",
"x86-64",
"IA-64",
"ARM-A32",
"ARM-A64",
"MIPS32",
"MIPS64",
"OEM",
],
},
"Oem": {
"type": "object",
"properties": {
"Brand": {
"type": "string",
"enum": [
"E3",
"E5",
"E7",
"X3",
"X5",
"X7",
"I3",
"I5",
"I7",
"Silver",
"Gold",
"Platinum",
"Unknown",
],
},
"Capabilities": {
"type": "array",
"items": [{"type": "string"}],
},
},
'Capabilities': {
'type': 'array',
'items': [{'type': 'string'}]
}
}
},
"Resource": {
"type": "object",
"properties": {"@odata.id": {"type": "string"}},
},
"Chassis": {
"type": "object",
"properties": {"@odata.id": {"type": "string"}},
},
"ProcessorType": {
"type": "string",
"enum": [
"CPU",
"FPGA",
"GPU",
"DSP",
"Accelerator",
"OEM",
],
},
},
'Resource': {
'type': 'object',
'properties': {
'@odata.id': {'type': 'string'}
}
},
'Chassis': {
'type': 'object',
'properties': {
'@odata.id': {'type': 'string'}
}
},
'ProcessorType': {
'type': 'string',
'enum': ['CPU', 'FPGA', 'GPU', 'DSP', 'Accelerator', 'OEM']
}
},
'additionalProperties': False,
}]
"additionalProperties": False,
}
],
}
memory_req_schema = {
'type': 'array',
'items': [{
'type': 'object',
'properties': {
'CapacityMiB': {'type': 'number'},
'MemoryDeviceType': {
'type': 'string',
'enum': ['DDR', 'DDR2', 'DDR3', 'DDR4', 'DDR4_SDRAM',
'DDR4E_SDRAM', 'LPDDR4_SDRAM', 'DDR3_SDRAM',
'LPDDR3_SDRAM', 'DDR2_SDRAM', 'DDR2_SDRAM_FB_DIMM',
'DDR2_SDRAM_FB_DIMM_PROBE', 'DDR_SGRAM',
'DDR_SDRAM', 'ROM', 'SDRAM', 'EDO',
'FastPageMode', 'PipelinedNibble']
"type": "array",
"items": [
{
"type": "object",
"properties": {
"CapacityMiB": {"type": "number"},
"MemoryDeviceType": {
"type": "string",
"enum": [
"DDR",
"DDR2",
"DDR3",
"DDR4",
"DDR4_SDRAM",
"DDR4E_SDRAM",
"LPDDR4_SDRAM",
"DDR3_SDRAM",
"LPDDR3_SDRAM",
"DDR2_SDRAM",
"DDR2_SDRAM_FB_DIMM",
"DDR2_SDRAM_FB_DIMM_PROBE",
"DDR_SGRAM",
"DDR_SDRAM",
"ROM",
"SDRAM",
"EDO",
"FastPageMode",
"PipelinedNibble",
],
},
"SpeedMHz": {"type": "number"},
"Manufacturer": {"type": "string"},
"DataWidthBits": {"type": "number"},
"Resource": {
"type": "object",
"properties": {"@odata.id": {"type": "string"}},
},
"Chassis": {
"type": "object",
"properties": {"@odata.id": {"type": "string"}},
},
},
'SpeedMHz': {'type': 'number'},
'Manufacturer': {'type': 'string'},
'DataWidthBits': {'type': 'number'},
'Resource': {
'type': 'object',
'properties': {
'@odata.id': {'type': 'string'}
}
},
'Chassis': {
'type': 'object',
'properties': {
'@odata.id': {'type': 'string'}
}
}
},
'additionalProperties': False,
}]
"additionalProperties": False,
}
],
}
remote_drive_req_schema = {
'type': 'array',
'items': [{
'type': 'object',
'properties': {
'CapacityGiB': {'type': 'number'},
'iSCSIAddress': {'type': 'string'},
'Master': {
'type': 'object',
'properties': {
'Type': {
'type': 'string',
'enum': ['Snapshot', 'Clone']
"type": "array",
"items": [
{
"type": "object",
"properties": {
"CapacityGiB": {"type": "number"},
"iSCSIAddress": {"type": "string"},
"Master": {
"type": "object",
"properties": {
"Type": {
"type": "string",
"enum": ["Snapshot", "Clone"],
},
"Address": {
"type": "object",
"properties": {"@odata.id": {"type": "string"}},
},
},
'Address': {
'type': 'object',
'properties': {
'@odata.id': {'type': 'string'}
}
}
}
}
},
'additionalProperties': False,
}]
},
},
"additionalProperties": False,
}
],
}
local_drive_req_schema = {
'type': 'array',
'items': [{
'type': 'object',
'properties': {
'CapacityGiB': {'type': 'number'},
'Type': {
'type': 'string',
'enum': ['HDD', 'SSD']
"type": "array",
"items": [
{
"type": "object",
"properties": {
"CapacityGiB": {"type": "number"},
"Type": {"type": "string", "enum": ["HDD", "SSD"]},
"MinRPM": {"type": "number"},
"SerialNumber": {"type": "string"},
"Interface": {
"type": "string",
"enum": ["SAS", "SATA", "NVMe"],
},
"Resource": {
"type": "object",
"properties": {"@odata.id": {"type": "string"}},
},
"Chassis": {
"type": "object",
"properties": {"@odata.id": {"type": "string"}},
},
"FabricSwitch": {"type": "boolean"},
},
'MinRPM': {'type': 'number'},
'SerialNumber': {'type': 'string'},
'Interface': {
'type': 'string',
'enum': ['SAS', 'SATA', 'NVMe']
},
'Resource': {
'type': 'object',
'properties': {
'@odata.id': {'type': 'string'}
}
},
'Chassis': {
'type': 'object',
'properties': {
'@odata.id': {'type': 'string'}
}
},
'FabricSwitch': {'type': 'boolean'}
},
'additionalProperties': False,
}]
"additionalProperties": False,
}
],
}
ethernet_interface_req_schema = {
'type': 'array',
'items': [{
'type': 'object',
'properties': {
'SpeedMbps': {'type': 'number'},
'PrimaryVLAN': {'type': 'number'},
'VLANs': {
'type': 'array',
'additionalItems': {
'type': 'object',
'properties': {
'VLANId': {'type': 'number'},
'Tagged': {'type': 'boolean'}
}
}
"type": "array",
"items": [
{
"type": "object",
"properties": {
"SpeedMbps": {"type": "number"},
"PrimaryVLAN": {"type": "number"},
"VLANs": {
"type": "array",
"additionalItems": {
"type": "object",
"properties": {
"VLANId": {"type": "number"},
"Tagged": {"type": "boolean"},
},
},
},
"Resource": {
"type": "object",
"properties": {"@odata.id": {"type": "string"}},
},
"Chassis": {
"type": "object",
"properties": {"@odata.id": {"type": "string"}},
},
},
'Resource': {
'type': 'object',
'properties': {
'@odata.id': {'type': 'string'}
}
},
'Chassis': {
'type': 'object',
'properties': {
'@odata.id': {'type': 'string'}
}
}
},
'additionalProperties': False,
}]
"additionalProperties": False,
}
],
}
security_req_schema = {
'type': 'object',
'properties': {
'TpmPresent': {'type': 'boolean'},
'TpmInterfaceType': {'type': 'string'},
'TxtEnabled': {'type': 'boolean'},
"type": "object",
"properties": {
"TpmPresent": {"type": "boolean"},
"TpmInterfaceType": {"type": "string"},
"TxtEnabled": {"type": "boolean"},
},
'additionalProperties': False,
"additionalProperties": False,
}
total_system_core_req_schema = {
'type': 'number'
}
total_system_core_req_schema = {"type": "number"}
total_system_memory_req_schema = {
'type': 'number'
}
total_system_memory_req_schema = {"type": "number"}

View File

@ -0,0 +1,64 @@
# Copyright 2018 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 rsd_lib import base as rsd_lib_base
from rsd_lib import utils as rsd_lib_utils
class ComputerSystemMetrics(rsd_lib_base.ResourceBase):
"""ComputerSystemMetrics resource class
ComputerSystemMetrics contains usage and health statistics for a
ComputerSystem (all Cores) .
"""
processor_bandwidth_percent = base.Field(
"ProcessorBandwidthPercent", adapter=rsd_lib_utils.num_or_none
)
"""CPU Bandwidth in Percent."""
memory_bandwidth_percent = base.Field(
"MemoryBandwidthPercent", adapter=rsd_lib_utils.num_or_none
)
"""Memory Bandwidth in Percent"""
memory_throttled_cycles_percent = base.Field(
"MemoryThrottledCyclesPercent", adapter=rsd_lib_utils.num_or_none
)
"""The percentage of memory cycles that were throttled due to power
limiting (all packages and memory controllers).
"""
processor_power_watt = base.Field(
"ProcessorPowerWatt", adapter=rsd_lib_utils.num_or_none
)
"""Power consumed by Processor resource"""
memory_power_watt = base.Field(
"MemoryPowerWatt", adapter=rsd_lib_utils.num_or_none
)
"""Power consumed by Memory domain resource"""
io_bandwidth_gbps = base.Field(
"IOBandwidthGBps", adapter=rsd_lib_utils.num_or_none
)
"""IO Bandwidth rate in ComputerSystem resource based on PCIe data
transmission rate in GB/s
"""
health = base.Field("Health")
"""ComputerSystem Health as a discrete sensor reading"""

View File

@ -1,56 +0,0 @@
# Copyright 2018 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 rsd_lib import utils as rsd_lib_utils
class Metrics(base.ResourceBase):
name = base.Field('Name')
"""The metrics name"""
description = base.Field('Description')
"""The metrics description"""
identity = base.Field('Id')
"""The metrics identity"""
processor_bandwidth_percent = base.Field('ProcessorBandwidthPercent',
adapter=rsd_lib_utils.num_or_none)
"""The processor bandwidth percent"""
memory_bandwidth_percent = base.Field('MemoryBandwidthPercent',
adapter=rsd_lib_utils.num_or_none)
"""The memory bandwidth percent"""
memory_throttled_cycles_percent = base.Field(
'MemoryThrottledCyclesPercent', adapter=rsd_lib_utils.num_or_none)
"""The memory throttled cycles percent"""
processor_power_watt = base.Field('ProcessorPowerWatt',
adapter=rsd_lib_utils.num_or_none)
"""The processor power watt"""
memory_power_watt = base.Field('MemoryPowerWatt',
adapter=rsd_lib_utils.num_or_none)
"""The memory power watt"""
io_bandwidth_gbps = base.Field('IOBandwidthGBps',
adapter=rsd_lib_utils.num_or_none)
"""The io bandwidth GBps"""
health = base.Field('Health')
"""The detail health information"""

View File

@ -18,8 +18,8 @@ from sushy import utils
from rsd_lib import base as rsd_lib_base
from rsd_lib.resources.v2_1.system import system
from rsd_lib.resources.v2_2.system import computer_system_metrics
from rsd_lib.resources.v2_2.system import memory
from rsd_lib.resources.v2_2.system import metrics
from rsd_lib.resources.v2_2.system import processor
from rsd_lib import utils as rsd_lib_utils
@ -91,12 +91,12 @@ class System(system.System):
@property
@utils.cache_it
def metrics(self):
"""Property to provide reference to `Metrics` instance
"""Property to provide reference to `ComputerSystemMetrics` instance
It is calculated once the first time it is queried. On refresh,
this property is reset.
"""
return metrics.Metrics(
return computer_system_metrics.ComputerSystemMetrics(
self._conn,
self._get_metrics_path(),
redfish_version=self.redfish_version,

View File

@ -23,169 +23,195 @@ from rsd_lib.tests.unit.fakes import request_fakes
class NodeCollectionTestCase(testtools.TestCase):
def setUp(self):
super(NodeCollectionTestCase, self).setUp()
self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_1/node_collection.json',
'r') as f:
with open(
"rsd_lib/tests/unit/json_samples/v2_1/node_collection.json", "r"
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.conn.post.return_value = request_fakes.fake_request_post(
None, headers={"Location": "https://localhost:8443/"
"redfish/v1/Nodes/1"})
None,
headers={
"Location": "https://localhost:8443/" "redfish/v1/Nodes/1"
},
)
self.node_col = node.NodeCollection(
self.conn, '/redfish/v1/Nodes', redfish_version='1.0.2')
self.conn, "/redfish/v1/Nodes", redfish_version="1.0.2"
)
def test_compose_node(self):
reqs = {
'Name': 'test',
'Description': 'this is a test node',
'Processors': [{
'TotalCores': 4,
'ProcessorType': 'FPGA',
'Oem': {
'Brand': 'Platinum',
'Capabilities': ['sse']
"Name": "test",
"Description": "this is a test node",
"Processors": [
{
"TotalCores": 4,
"ProcessorType": "FPGA",
"Oem": {"Brand": "Platinum", "Capabilities": ["sse"]},
}
}],
'Memory': [{
'CapacityMiB': 8000
}],
'Security': {
'TpmPresent': True,
'TpmInterfaceType': 'TPM2_0',
'TxtEnabled': True
],
"Memory": [{"CapacityMiB": 8000}],
"Security": {
"TpmPresent": True,
"TpmInterfaceType": "TPM2_0",
"TxtEnabled": True,
},
'TotalSystemCoreCount': 8,
'TotalSystemMemoryMiB': 16000
"TotalSystemCoreCount": 8,
"TotalSystemMemoryMiB": 16000,
}
result = self.node_col.compose_node(
name='test', description='this is a test node',
processor_req=[{
'TotalCores': 4,
'ProcessorType': 'FPGA',
'Oem': {
'Brand': 'Platinum',
'Capabilities': ['sse']
name="test",
description="this is a test node",
processor_req=[
{
"TotalCores": 4,
"ProcessorType": "FPGA",
"Oem": {"Brand": "Platinum", "Capabilities": ["sse"]},
}
}],
memory_req=[{'CapacityMiB': 8000}],
],
memory_req=[{"CapacityMiB": 8000}],
security_req={
'TpmPresent': True,
'TpmInterfaceType': 'TPM2_0',
'TxtEnabled': True
"TpmPresent": True,
"TpmInterfaceType": "TPM2_0",
"TxtEnabled": True,
},
total_system_core_req=8,
total_system_memory_req=16000)
total_system_memory_req=16000,
)
self.node_col._conn.post.assert_called_once_with(
'/redfish/v1/Nodes/Actions/Allocate', data=reqs)
self.assertEqual(result, '/redfish/v1/Nodes/1')
"/redfish/v1/Nodes/Actions/Allocate", data=reqs
)
self.assertEqual(result, "/redfish/v1/Nodes/1")
def test_compose_node_with_invalid_reqs(self):
# Wrong processor type
with self.assertRaisesRegex(
jsonschema.exceptions.ValidationError,
("'invalid' is not one of \['CPU', 'FPGA', 'GPU', 'DSP', "
"'Accelerator', 'OEM'\]")):
(
"'invalid' is not one of \['CPU', 'FPGA', 'GPU', 'DSP', "
"'Accelerator', 'OEM'\]"
),
):
self.node_col.compose_node(
name='test', description='this is a test node',
processor_req=[{
'TotalCores': 4,
'ProcessorType': 'invalid'}])
name="test",
description="this is a test node",
processor_req=[{"TotalCores": 4, "ProcessorType": "invalid"}],
)
# Wrong processor Oem Brand
with self.assertRaisesRegex(
jsonschema.exceptions.ValidationError,
("'invalid' is not one of \['E3', 'E5'")):
("'invalid' is not one of \['E3', 'E5'"),
):
self.node_col.compose_node(
name='test', description='this is a test node',
processor_req=[{
'TotalCores': 4,
'Oem': {
'Brand': 'invalid',
'Capabilities': ['sse']
name="test",
description="this is a test node",
processor_req=[
{
"TotalCores": 4,
"Oem": {"Brand": "invalid", "Capabilities": ["sse"]},
}
}])
],
)
# Wrong processor Oem Capabilities
with self.assertRaisesRegex(
jsonschema.exceptions.ValidationError,
("'sse' is not of type 'array'")):
("'sse' is not of type 'array'"),
):
self.node_col.compose_node(
name='test', description='this is a test node',
processor_req=[{
'TotalCores': 4,
'Oem': {
'Brand': 'E3',
'Capabilities': 'sse'
name="test",
description="this is a test node",
processor_req=[
{
"TotalCores": 4,
"Oem": {"Brand": "E3", "Capabilities": "sse"},
}
}])
],
)
# Wrong processor Oem Capabilities
with self.assertRaisesRegex(
jsonschema.exceptions.ValidationError,
("0 is not of type 'string'")):
("0 is not of type 'string'"),
):
self.node_col.compose_node(
name='test', description='this is a test node',
processor_req=[{
'TotalCores': 4,
'Oem': {
'Brand': 'E3',
'Capabilities': [0]
name="test",
description="this is a test node",
processor_req=[
{
"TotalCores": 4,
"Oem": {"Brand": "E3", "Capabilities": [0]},
}
}])
],
)
# Wrong security parameter "TpmPresent"
with self.assertRaisesRegex(
jsonschema.exceptions.ValidationError,
"'invalid' is not of type 'boolean'"):
"'invalid' is not of type 'boolean'",
):
self.node_col.compose_node(
name='test', description='this is a test node',
name="test",
description="this is a test node",
security_req={
'TpmPresent': 'invalid',
'TpmInterfaceType': 'TPM2_0',
'TxtEnabled': True
})
"TpmPresent": "invalid",
"TpmInterfaceType": "TPM2_0",
"TxtEnabled": True,
},
)
# Wrong security parameter "TpmInterfaceType"
with self.assertRaisesRegex(
jsonschema.exceptions.ValidationError,
"True is not of type 'string'"):
"True is not of type 'string'",
):
self.node_col.compose_node(
name='test', description='this is a test node',
name="test",
description="this is a test node",
security_req={
'TpmPresent': False,
'TpmInterfaceType': True,
'TxtEnabled': True
})
"TpmPresent": False,
"TpmInterfaceType": True,
"TxtEnabled": True,
},
)
# Wrong security parameter "TxtEnabled"
with self.assertRaisesRegex(
jsonschema.exceptions.ValidationError,
"'invalid' is not of type 'boolean'"):
"'invalid' is not of type 'boolean'",
):
self.node_col.compose_node(
name='test', description='this is a test node',
name="test",
description="this is a test node",
security_req={
'TpmPresent': True,
'TpmInterfaceType': 'TPM2_0',
'TxtEnabled': 'invalid'
})
"TpmPresent": True,
"TpmInterfaceType": "TPM2_0",
"TxtEnabled": "invalid",
},
)
# Wrong additional security parameter
with self.assertRaisesRegex(
jsonschema.exceptions.ValidationError,
("Additional properties are not allowed \('invalid-key' was "
"unexpected\)")):
(
"Additional properties are not allowed \('invalid-key' was "
"unexpected\)"
),
):
self.node_col.compose_node(
name='test', description='this is a test node',
name="test",
description="this is a test node",
security_req={
'TpmPresent': True,
'TpmInterfaceType': 'TPM2_0',
'TxtEnabled': False,
'invalid-key': 'invalid-value'
})
"TpmPresent": True,
"TpmInterfaceType": "TPM2_0",
"TxtEnabled": False,
"invalid-key": "invalid-value",
},
)

View File

@ -18,36 +18,47 @@ import json
import mock
import testtools
from rsd_lib.resources.v2_2.system import metrics
from rsd_lib.resources.v2_2.system import computer_system_metrics
class MetricsTestCase(testtools.TestCase):
def setUp(self):
super(MetricsTestCase, self).setUp()
self.conn = mock.Mock()
with open('rsd_lib/tests/unit/json_samples/v2_2/system_metrics.json',
'r') as f:
with open(
"rsd_lib/tests/unit/json_samples/v2_2/"
"computer_system_metrics.json",
"r",
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.system_metrics_inst = metrics.Metrics(
self.conn, '/redfish/v1/Systems/System1/Metrics',
redfish_version='1.0.2')
self.system_metrics_inst = computer_system_metrics.\
ComputerSystemMetrics(
self.conn,
"/redfish/v1/Systems/System1/Metrics",
redfish_version="1.0.2",
)
def test__parse_attributes(self):
self.system_metrics_inst._parse_attributes()
self.assertEqual('1.0.2', self.system_metrics_inst.redfish_version)
self.assertEqual('Computer System Metrics for System1',
self.system_metrics_inst.name)
self.assertEqual('description-as-string',
self.system_metrics_inst.description)
self.assertEqual('Metrics for System1',
self.system_metrics_inst.identity)
self.assertEqual("1.0.2", self.system_metrics_inst.redfish_version)
self.assertEqual(
17, self.system_metrics_inst.processor_bandwidth_percent)
"Computer System Metrics for System1",
self.system_metrics_inst.name,
)
self.assertEqual(
"description-as-string", self.system_metrics_inst.description
)
self.assertEqual(
"Metrics for System1", self.system_metrics_inst.identity
)
self.assertEqual(
17, self.system_metrics_inst.processor_bandwidth_percent
)
self.assertEqual(23, self.system_metrics_inst.memory_bandwidth_percent)
self.assertEqual(
13, self.system_metrics_inst.memory_throttled_cycles_percent)
13, self.system_metrics_inst.memory_throttled_cycles_percent
)
self.assertEqual(120, self.system_metrics_inst.processor_power_watt)
self.assertEqual(48, self.system_metrics_inst.memory_power_watt)
self.assertEqual(4, self.system_metrics_inst.io_bandwidth_gbps)

View File

@ -20,8 +20,8 @@ import testtools
from sushy import exceptions
from rsd_lib.resources.v2_1.system import system as v2_1_system
from rsd_lib.resources.v2_2.system import computer_system_metrics
from rsd_lib.resources.v2_2.system import memory
from rsd_lib.resources.v2_2.system import metrics
from rsd_lib.resources.v2_2.system import processor
from rsd_lib.resources.v2_2.system import system
@ -99,13 +99,17 @@ class SystemTestCase(testtools.TestCase):
# | GIVEN |
self.conn.get.return_value.json.reset_mock()
with open(
"rsd_lib/tests/unit/json_samples/v2_2/system_metrics.json", "r"
"rsd_lib/tests/unit/json_samples/v2_2/"
"computer_system_metrics.json",
"r",
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN |
actual_metrics = self.system_inst.metrics
# | THEN |
self.assertIsInstance(actual_metrics, metrics.Metrics)
self.assertIsInstance(
actual_metrics, computer_system_metrics.ComputerSystemMetrics
)
self.conn.get.return_value.json.assert_called_once_with()
# reset mock
@ -118,11 +122,16 @@ class SystemTestCase(testtools.TestCase):
def test_metrics_on_refresh(self):
# | GIVEN |
with open(
"rsd_lib/tests/unit/json_samples/v2_2/system_metrics.json", "r"
"rsd_lib/tests/unit/json_samples/v2_2/"
"computer_system_metrics.json",
"r",
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN |
self.assertIsInstance(self.system_inst.metrics, metrics.Metrics)
self.assertIsInstance(
self.system_inst.metrics,
computer_system_metrics.ComputerSystemMetrics,
)
# On refreshing the system instance...
with open(
@ -135,11 +144,16 @@ class SystemTestCase(testtools.TestCase):
# | GIVEN |
with open(
"rsd_lib/tests/unit/json_samples/v2_2/system_metrics.json", "r"
"rsd_lib/tests/unit/json_samples/v2_2/"
"computer_system_metrics.json",
"r",
) as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
# | WHEN & THEN |
self.assertIsInstance(self.system_inst.metrics, metrics.Metrics)
self.assertIsInstance(
self.system_inst.metrics,
computer_system_metrics.ComputerSystemMetrics,
)
def test_processors(self):
# | GIVEN |