Follow-up patch for 8fe2904a62

This addresses the nit comments left over
from the parent patch 8fe2904a62.
Adds the missing test case from the parent patch.

Change-Id: Ic60235834284302331e29122417d6490a3207bf8
This commit is contained in:
Nisha Agarwal 2017-10-10 21:43:45 -07:00
parent 8fe2904a62
commit 2f746cbdad
7 changed files with 106 additions and 23 deletions

View File

@ -0,0 +1,7 @@
---
other:
- |
Changes the values for the constants ``HEALTH_STATE_ENABLED``,
``HEALTH_STATE_DISABLED``, ``HEALTH_OK``, ``HEALTH_WARNING``
and ``HEALTH_CRITICAL``. These could be correctly used
with their mapped values in mappings.py.

View File

@ -110,8 +110,8 @@ PROCESSOR_ARCH_MIPS = 'MIPS'
PROCESSOR_ARCH_OEM = 'OEM-defined'
# Health related constants.
HEALTH_STATE_ENABLED = 'Enabled'
HEALTH_STATE_DISABLED = 'Disabled'
HEALTH_OK = 'OK'
HEALTH_WARNING = 'Warning'
HEALTH_CRITICAL = 'Critical'
HEALTH_STATE_ENABLED = 'enabled'
HEALTH_STATE_DISABLED = 'disabled'
HEALTH_OK = 'ok'
HEALTH_WARNING = 'warning'
HEALTH_CRITICAL = 'critical'

View File

@ -62,20 +62,26 @@ class EthernetInterfaceCollection(base.ResourceCollectionBase):
@property
def summary(self):
"""Summary MAC addresses and interfaces state
"""Summary of MAC addresses and interfaces state
This filters the MACs whose health is OK,
which means the MACs in both 'Enabled' and 'Disabled' States
are returned.
:returns dictionary in the format {'aa:bb:cc:dd:ee:ff': 'Enabled'}
:returns: dictionary in the format
{'aa:bb:cc:dd:ee:ff': 'Enabled',
'aa:bb:aa:aa:aa:aa': 'Disabled'}
"""
if self._summary is None:
mac_dict = {}
for eth in self.get_members():
if eth.mac_address is not None:
if (eth.status is not None and
eth.status.health == sys_cons.HEALTH_OK):
mac_dict[eth.mac_address] = eth.status.state
if (eth.mac_address is not None and eth.status is not None):
if (eth.status.health ==
sys_map.HEALTH_VALUE_MAP_REV.get(
sys_cons.HEALTH_OK)):
state = sys_map.HEALTH_STATE_VALUE_MAP_REV.get(
eth.status.state)
mac_dict[eth.mac_address] = state
self._summary = mac_dict
return self._summary

View File

@ -16,6 +16,7 @@ import mock
from sushy.resources.system import constants as sys_cons
from sushy.resources.system import ethernet_interface
from sushy.resources.system import mappings as sys_map
from sushy.tests.unit import base
@ -42,7 +43,7 @@ class EthernetInterfaceTestCase(base.TestCase):
self.assertEqual(
'12:44:6A:3B:04:11', self.sys_eth.permanent_mac_address)
self.assertEqual('12:44:6A:3B:04:11', self.sys_eth.mac_address)
self.assertEqual('Enabled', self.sys_eth.status.state)
self.assertEqual('enabled', self.sys_eth.status.state)
self.assertEqual('OK', self.sys_eth.status.health)
self.assertEqual(1000, self.sys_eth.speed_mbps)
@ -92,12 +93,15 @@ class EthernetInterfaceCollectionTestCase(base.TestCase):
self.assertIsInstance(members, list)
self.assertEqual(1, len(members))
def test_eth_summary(self):
def test_summary(self):
self.assertIsNone(self.sys_eth_col._summary)
self.conn.get.return_value.json.reset_mock()
path = 'sushy/tests/unit/json_samples/ethernet_interfaces.json'
with open(path, 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
expected_summary = {'12:44:6A:3B:04:11': sys_cons.HEALTH_STATE_ENABLED}
expected_summary = {
'12:44:6A:3B:04:11':
sys_map.HEALTH_STATE_VALUE_MAP_REV.get(
sys_cons.HEALTH_STATE_ENABLED)}
actual_summary = self.sys_eth_col.summary
self.assertEqual(expected_summary, actual_summary)

View File

@ -21,6 +21,7 @@ import sushy
from sushy import exceptions
from sushy.resources.system import constants as sys_cons
from sushy.resources.system import ethernet_interface
from sushy.resources.system import mappings as sys_map
from sushy.resources.system import processor
from sushy.resources.system import system
from sushy.tests.unit import base
@ -358,8 +359,11 @@ class SystemTestCase(base.TestCase):
self.assertIsNone(self.sys_inst._ethernet_interfaces)
actual_macs = self.sys_inst.ethernet_interfaces.summary
self.assertEqual({'12:44:6A:3B:04:11': sys_cons.HEALTH_STATE_ENABLED},
actual_macs)
expected_macs = (
{'12:44:6A:3B:04:11':
sys_map.HEALTH_STATE_VALUE_MAP_REV.get(
sys_cons.HEALTH_STATE_ENABLED)})
self.assertEqual(expected_macs, actual_macs)
self.assertIsInstance(self.sys_inst._ethernet_interfaces,
ethernet_interface.EthernetInterfaceCollection)

View File

@ -13,9 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
import mock
from sushy import exceptions
from sushy.resources.system import system
from sushy.tests.unit import base
from sushy import utils
@ -39,3 +42,51 @@ class UtilsTestCase(base.TestCase):
def test_int_or_none(self):
self.assertEqual(1, utils.int_or_none('1'))
self.assertIsNone(None, utils.int_or_none(None))
def setUp(self):
super(UtilsTestCase, self).setUp()
self.conn = mock.MagicMock()
with open('sushy/tests/unit/json_samples/system.json', 'r') as f:
system_json = json.loads(f.read())
self.conn.get.return_value.json.return_value = system_json
self.sys_inst = system.System(self.conn,
'/redfish/v1/Systems/437XR1138R2',
redfish_version='1.0.2')
def test_get_sub_resource_path_by(self):
subresource_path = 'EthernetInterfaces'
expected_result = '/redfish/v1/Systems/437XR1138R2/EthernetInterfaces'
value = utils.get_sub_resource_path_by(self.sys_inst,
subresource_path)
self.assertEqual(expected_result, value)
def test_get_sub_resource_path_by_list(self):
subresource_path = ['EthernetInterfaces']
expected_result = '/redfish/v1/Systems/437XR1138R2/EthernetInterfaces'
value = utils.get_sub_resource_path_by(self.sys_inst,
subresource_path)
self.assertEqual(expected_result, value)
def test_get_sub_resource_path_by_fails(self):
subresource_path = ['Links', 'Chassis']
expected_result = 'attribute Links/Chassis/@odata.id is missing'
self.assertRaisesRegex(
exceptions.MissingAttributeError,
expected_result,
utils.get_sub_resource_path_by,
self.sys_inst, subresource_path)
def test_get_sub_resource_path_by_fails_with_empty_path(self):
self.assertRaisesRegex(
ValueError,
'"subresource_name" cannot be empty',
utils.get_sub_resource_path_by,
self.sys_inst, [])
def test_get_sub_resource_path_by_fails_with_empty_string(self):
self.assertRaisesRegex(
ValueError,
'"subresource_name" cannot be empty',
utils.get_sub_resource_path_by,
self.sys_inst, '')

View File

@ -69,12 +69,23 @@ def get_sub_resource_path_by(resource, subresource_name):
:param subresource_name: name of the resource field to
fetch the '@odata.id' from.
"""
subresource_element = resource.json.get(subresource_name)
if not subresource_element:
raise exceptions.MissingAttributeError(attribute=subresource_name,
resource=resource.path)
if '@odata.id' not in subresource_element:
if not subresource_name:
raise ValueError('"subresource_name" cannot be empty')
if not isinstance(subresource_name, list):
subresource_name = [subresource_name]
body = resource.json
for path_item in subresource_name:
body = body.get(path_item, {})
if not body:
raise exceptions.MissingAttributeError(
attribute=(subresource_name + '/@odata.id'),
attribute='/'.join(subresource_name), resource=resource.path)
if '@odata.id' not in body:
raise exceptions.MissingAttributeError(
attribute='/'.join(subresource_name) + '/@odata.id',
resource=resource.path)
return subresource_element['@odata.id']
return body['@odata.id']