Add port metrics of RSD 2.2
Change-Id: Idcd2706fc3f70f868e8cbe37418c46eb0e83b7b3
This commit is contained in:
parent
45a1869582
commit
bcdf6d2e32
0
rsd_lib/resources/v2_2/ethernet_switch/__init__.py
Normal file
0
rsd_lib/resources/v2_2/ethernet_switch/__init__.py
Normal file
52
rsd_lib/resources/v2_2/ethernet_switch/port.py
Normal file
52
rsd_lib/resources/v2_2/ethernet_switch/port.py
Normal file
@ -0,0 +1,52 @@
|
||||
# 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 import exceptions
|
||||
|
||||
from rsd_lib.resources.v2_1.ethernet_switch import port as v2_1_port
|
||||
from rsd_lib.resources.v2_2.ethernet_switch import port_metrics
|
||||
|
||||
from rsd_lib import utils
|
||||
|
||||
|
||||
class Port(v2_1_port.Port):
|
||||
|
||||
_metrics = None # ref to Port metrics instance
|
||||
|
||||
def _get_metrics_path(self):
|
||||
"""Helper function to find the Port metrics path"""
|
||||
metrics = self.json.get('Metrics')
|
||||
if not metrics:
|
||||
raise exceptions.MissingAttributeError(attribute='Metrics',
|
||||
resource=self._path)
|
||||
return utils.get_resource_identity(metrics)
|
||||
|
||||
@property
|
||||
def metrics(self):
|
||||
"""Property to provide reference to `Metrics` instance
|
||||
|
||||
It is calculated once the first time it is queried. On refresh,
|
||||
this property is reset.
|
||||
"""
|
||||
if self._metrics is None:
|
||||
self._metrics = port_metrics.PortMetrics(
|
||||
self._conn, self._get_metrics_path(),
|
||||
redfish_version=self.redfish_version)
|
||||
|
||||
return self._metrics
|
||||
|
||||
def refresh(self):
|
||||
super(Port, self).refresh()
|
||||
self._metrics = None
|
63
rsd_lib/resources/v2_2/ethernet_switch/port_metrics.py
Normal file
63
rsd_lib/resources/v2_2/ethernet_switch/port_metrics.py
Normal file
@ -0,0 +1,63 @@
|
||||
# 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 ReceivedField(base.CompositeField):
|
||||
packets = base.Field('Packets', adapter=rsd_lib_utils.int_or_none)
|
||||
dropped_packets = base.Field('DroppedPackets',
|
||||
adapter=rsd_lib_utils.int_or_none)
|
||||
error_packets = base.Field('ErrorPackets',
|
||||
adapter=rsd_lib_utils.int_or_none)
|
||||
broadcast_packets = base.Field('BroadcastPackets',
|
||||
adapter=rsd_lib_utils.int_or_none)
|
||||
multicast_packets = base.Field('MulticastPackets',
|
||||
adapter=rsd_lib_utils.int_or_none)
|
||||
errors = base.Field('Errors', adapter=rsd_lib_utils.int_or_none)
|
||||
received_bytes = base.Field('Bytes', adapter=rsd_lib_utils.int_or_none)
|
||||
|
||||
|
||||
class TransmittedField(base.CompositeField):
|
||||
packets = base.Field('Packets', adapter=rsd_lib_utils.int_or_none)
|
||||
dropped_packets = base.Field('DroppedPackets',
|
||||
adapter=rsd_lib_utils.int_or_none)
|
||||
error_packets = base.Field('ErrorPackets',
|
||||
adapter=rsd_lib_utils.int_or_none)
|
||||
broadcast_packets = base.Field('BroadcastPackets',
|
||||
adapter=rsd_lib_utils.int_or_none)
|
||||
multicast_packets = base.Field('MulticastPackets',
|
||||
adapter=rsd_lib_utils.int_or_none)
|
||||
errors = base.Field('Errors', adapter=rsd_lib_utils.int_or_none)
|
||||
transmitted_bytes = base.Field('Bytes', adapter=rsd_lib_utils.int_or_none)
|
||||
|
||||
|
||||
class PortMetrics(base.ResourceBase):
|
||||
name = base.Field('Name')
|
||||
"""The metrics name"""
|
||||
|
||||
identity = base.Field('Id')
|
||||
"""The metrics identity"""
|
||||
|
||||
received = ReceivedField('Received')
|
||||
"""The received packets status"""
|
||||
|
||||
transmitted = TransmittedField('Transmitted')
|
||||
"""The transmitted packets status"""
|
||||
|
||||
collisions = base.Field('Collisions', adapter=rsd_lib_utils.int_or_none)
|
||||
"""The collisions status"""
|
73
rsd_lib/tests/unit/json_samples/v2_2/port.json
Normal file
73
rsd_lib/tests/unit/json_samples/v2_2/port.json
Normal file
@ -0,0 +1,73 @@
|
||||
{
|
||||
"@odata.context":
|
||||
"/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
|
||||
"@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1",
|
||||
"@odata.type": "#EthernetSwitchPort.v1_1_0.EthernetSwitchPort",
|
||||
"Id": "Port1",
|
||||
"Name": "RSA Switch Port",
|
||||
"Description": "description-as-string",
|
||||
"PortId": "sw0p10",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK",
|
||||
"HealthRollup": null
|
||||
},
|
||||
"LinkType": "Ethernet",
|
||||
"OperationalState": "Up",
|
||||
"AdministrativeState": "Up",
|
||||
"LinkSpeedMbps": 10000,
|
||||
"NeighborInfo": {
|
||||
"SwitchId": "unique switch id",
|
||||
"PortId": "11",
|
||||
"CableId": "CustomerWritableThing"
|
||||
},
|
||||
"NeighborMAC": "00:11:22:33:44:55",
|
||||
"FrameSize": 1520,
|
||||
"Autosense": true,
|
||||
"FullDuplex": true,
|
||||
"MACAddress": "2c:60:0c:72:e6:33",
|
||||
"IPv4Addresses": [{
|
||||
"Address": "192.168.0.10",
|
||||
"SubnetMask": "255.255.252.0",
|
||||
"AddressOrigin": "Static",
|
||||
"Gateway": "192.168.0.1"
|
||||
}],
|
||||
"IPv6Addresses": [{
|
||||
"Address": "fe80::1ec1:deff:fe6f:1e24",
|
||||
"PrefixLength": 64,
|
||||
"AddressOrigin": "Static",
|
||||
"AddressState": "Preferred"
|
||||
}],
|
||||
"PortClass": "Logical",
|
||||
"PortMode": "LinkAggregationStatic",
|
||||
"PortType": "Upstream",
|
||||
"Oem": {},
|
||||
"VLANs": {
|
||||
"@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/VLANs"
|
||||
},
|
||||
"StaticMACs": {
|
||||
"@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/StaticMACs"
|
||||
},
|
||||
"Metrics": {
|
||||
"@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/Metrics"
|
||||
},
|
||||
"Links": {
|
||||
"@odata.type": "#EthernetSwitchPort.v1_1_0.Links",
|
||||
"PrimaryVLAN": {
|
||||
"@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/VLANs/VLAN1"
|
||||
},
|
||||
"Switch": {
|
||||
"@odata.id": "/redfish/v1/EthernetSwitches/Switch1"
|
||||
},
|
||||
"MemberOfPort": {
|
||||
"@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/LAG1"
|
||||
},
|
||||
"PortMembers": [],
|
||||
"ActiveACLs": [{
|
||||
"@odata.id": "/redfish/v1/EthernetSwitches/Switch1/ACLs/ACL1"
|
||||
}]
|
||||
},
|
||||
"NeighborInterface": {
|
||||
"@odata.id": "/redfish/v1/Systems/System1/EthernetInterfaces/LAN1"
|
||||
}
|
||||
}
|
27
rsd_lib/tests/unit/json_samples/v2_2/port_metrics.json
Normal file
27
rsd_lib/tests/unit/json_samples/v2_2/port_metrics.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#EthernetSwitchPortMetrics.EthernetSwitchPortMetrics",
|
||||
"@odata.id": "/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/Metrics",
|
||||
"@odata.type": "#EthernetSwitchPortMetrics.v1_0_0.EthernetSwitchPortMetrics",
|
||||
"Name": "Ethernet Switch Port Metrics",
|
||||
"Id": "Metrics",
|
||||
"Received": {
|
||||
"Packets": 8,
|
||||
"DroppedPackets": 5,
|
||||
"ErrorPackets": 4,
|
||||
"BroadcastPackets": 3,
|
||||
"MulticastPackets": 2,
|
||||
"Errors": 0,
|
||||
"Bytes": 64
|
||||
},
|
||||
"Transmitted": {
|
||||
"Packets": 128,
|
||||
"DroppedPackets": 1,
|
||||
"ErrorPackets": 2,
|
||||
"BroadcastPackets": 3,
|
||||
"MulticastPackets": 4,
|
||||
"Errors": 5,
|
||||
"Bytes": 512
|
||||
},
|
||||
"Collisions": 0,
|
||||
"Oem": {}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
# 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.
|
||||
|
||||
import json
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from sushy import exceptions
|
||||
|
||||
from rsd_lib.resources.v2_2.ethernet_switch import port
|
||||
from rsd_lib.resources.v2_2.ethernet_switch import port_metrics
|
||||
|
||||
|
||||
class PortTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(PortTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('rsd_lib/tests/unit/json_samples/v2_2/port.json',
|
||||
'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
|
||||
self.port_inst = port.Port(
|
||||
self.conn, '/redfish/v1/EthernetSwitches/Switch1/Ports/Port1',
|
||||
redfish_version='1.0.2')
|
||||
|
||||
def test__get_metrics_path(self):
|
||||
self.assertEqual(
|
||||
'/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/Metrics',
|
||||
self.port_inst._get_metrics_path())
|
||||
|
||||
def test__get_metrics_path_missing_ports_attr(self):
|
||||
self.port_inst._json.pop('Metrics')
|
||||
with self.assertRaisesRegex(
|
||||
exceptions.MissingAttributeError, 'attribute Metrics'):
|
||||
self.port_inst._get_metrics_path()
|
||||
|
||||
def test_metrics(self):
|
||||
# check for the underneath variable value
|
||||
self.assertIsNone(self.port_inst._metrics)
|
||||
# | GIVEN |
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
with open('rsd_lib/tests/unit/json_samples/v2_2/port_metrics.json',
|
||||
'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
# | WHEN |
|
||||
actual_metrics = self.port_inst.metrics
|
||||
# | THEN |
|
||||
self.assertIsInstance(actual_metrics,
|
||||
port_metrics.PortMetrics)
|
||||
self.conn.get.return_value.json.assert_called_once_with()
|
||||
|
||||
# reset mock
|
||||
self.conn.get.return_value.json.reset_mock()
|
||||
# | WHEN & THEN |
|
||||
# tests for same object on invoking subsequently
|
||||
self.assertIs(actual_metrics,
|
||||
self.port_inst.metrics)
|
||||
self.conn.get.return_value.json.assert_not_called()
|
||||
|
||||
def test_metrics_on_refresh(self):
|
||||
# | GIVEN |
|
||||
with open('rsd_lib/tests/unit/json_samples/v2_2/port_metrics.json',
|
||||
'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
# | WHEN & THEN |
|
||||
self.assertIsInstance(self.port_inst.metrics,
|
||||
port_metrics.PortMetrics)
|
||||
|
||||
# On refreshing the port instance...
|
||||
with open('rsd_lib/tests/unit/json_samples/v2_2/port.json',
|
||||
'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
self.port_inst.refresh()
|
||||
# | WHEN & THEN |
|
||||
self.assertIsNone(self.port_inst._metrics)
|
||||
|
||||
# | GIVEN |
|
||||
with open('rsd_lib/tests/unit/json_samples/v2_2/port_metrics.json',
|
||||
'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
# | WHEN & THEN |
|
||||
self.assertIsInstance(self.port_inst.metrics,
|
||||
port_metrics.PortMetrics)
|
@ -0,0 +1,66 @@
|
||||
# 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.
|
||||
|
||||
import json
|
||||
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from rsd_lib.resources.v2_2.ethernet_switch import port_metrics
|
||||
|
||||
|
||||
class PortMetricsTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(PortMetricsTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
with open('rsd_lib/tests/unit/json_samples/v2_2/'
|
||||
'port_metrics.json', 'r') as f:
|
||||
self.conn.get.return_value.json.return_value = json.loads(f.read())
|
||||
|
||||
self.port_metrics_inst = port_metrics.PortMetrics(
|
||||
self.conn,
|
||||
'/redfish/v1/EthernetSwitches/Switch1/Ports/Port1/Metrics',
|
||||
redfish_version='1.1.0')
|
||||
|
||||
def test__parse_attributes(self):
|
||||
self.port_metrics_inst._parse_attributes()
|
||||
self.assertEqual('1.1.0', self.port_metrics_inst.redfish_version)
|
||||
self.assertEqual('Ethernet Switch Port Metrics',
|
||||
self.port_metrics_inst.name)
|
||||
self.assertEqual('Metrics',
|
||||
self.port_metrics_inst.identity)
|
||||
|
||||
self.assertEqual(8, self.port_metrics_inst.received.packets)
|
||||
self.assertEqual(5, self.port_metrics_inst.received.dropped_packets)
|
||||
self.assertEqual(4, self.port_metrics_inst.received.error_packets)
|
||||
self.assertEqual(3, self.port_metrics_inst.received.broadcast_packets)
|
||||
self.assertEqual(2, self.port_metrics_inst.received.multicast_packets)
|
||||
self.assertEqual(0, self.port_metrics_inst.received.errors)
|
||||
self.assertEqual(64, self.port_metrics_inst.received.received_bytes)
|
||||
|
||||
self.assertEqual(128, self.port_metrics_inst.transmitted.packets)
|
||||
self.assertEqual(
|
||||
1, self.port_metrics_inst.transmitted.dropped_packets)
|
||||
self.assertEqual(2, self.port_metrics_inst.transmitted.error_packets)
|
||||
self.assertEqual(
|
||||
3, self.port_metrics_inst.transmitted.broadcast_packets)
|
||||
self.assertEqual(
|
||||
4, self.port_metrics_inst.transmitted.multicast_packets)
|
||||
self.assertEqual(5, self.port_metrics_inst.transmitted.errors)
|
||||
self.assertEqual(
|
||||
512, self.port_metrics_inst.transmitted.transmitted_bytes)
|
||||
|
||||
self.assertEqual(0, self.port_metrics_inst.collisions)
|
Loading…
x
Reference in New Issue
Block a user