From 92b7d26ea2c515cc42487f9c22a83d059da4e277 Mon Sep 17 00:00:00 2001 From: Lin Yang Date: Tue, 29 Jan 2019 11:55:13 -0800 Subject: [PATCH] Update reset method of RSD 2.1 fabric switch Change-Id: I9ae73aae023cf4750eba621ab7638b4a204b6d14 --- rsd_lib/resources/v2_1/fabric/switch.py | 49 +++++++++++++------ .../unit/resources/v2_1/fabric/test_switch.py | 47 +++++++++++++++--- 2 files changed, 75 insertions(+), 21 deletions(-) diff --git a/rsd_lib/resources/v2_1/fabric/switch.py b/rsd_lib/resources/v2_1/fabric/switch.py index 46ce1bd..6f8ceae 100644 --- a/rsd_lib/resources/v2_1/fabric/switch.py +++ b/rsd_lib/resources/v2_1/fabric/switch.py @@ -14,7 +14,10 @@ # under the License. import logging + +from sushy import exceptions from sushy.resources import base +from sushy.resources import common from sushy import utils from rsd_lib.resources.v2_1.fabric import port @@ -33,17 +36,8 @@ class LinksField(base.CompositeField): chassis = base.Field("Chassis", adapter=utils.get_members_identities) -class SwitchResetField(base.CompositeField): - target = base.Field("target") - """The switch reset target""" - - reset_type_allowable_values = base.Field("ResetType@Redfish." - "AllowableValues") - """The switch reset reset type reset allowable values""" - - class ActionsField(base.CompositeField): - switch_reset = SwitchResetField("#Switch.Reset") + reset = common.ResetActionField('#Switch.Reset') """The actions switch reset""" @@ -114,12 +108,37 @@ class Switch(base.ResourceBase): super(Switch, self).__init__(connector, identity, redfish_version) - def reset_switch(self): - """A post method to reset switch""" + def _get_reset_action_element(self): + reset_action = self.actions.reset + if not reset_action: + raise exceptions.MissingActionError(action='#Switch.Reset', + resource=self._path) + return reset_action - data = {"ResetType": "GracefulRestart"} - target_uri = self.actions.switch_reset.target - self._conn.post(target_uri, data=data) + def get_allowed_reset_switch_values(self): + """Get the allowed values for resetting the switch. + + :returns: A set with the allowed values. + """ + reset_action = self._get_reset_action_element() + + return reset_action.allowed_values + + def reset_switch(self, value): + """Reset the switch. + + :param value: The target value. + :raises: InvalidParameterValueError, if the target value is not + allowed. + """ + valid_resets = self.get_allowed_reset_switch_values() + if value not in valid_resets: + raise exceptions.InvalidParameterValueError( + parameter='value', value=value, valid_values=valid_resets) + + target_uri = self._get_reset_action_element().target_uri + + self._conn.post(target_uri, data={'ResetType': value}) def _get_ports_path(self): """Helper function to find the network protocol path""" diff --git a/rsd_lib/tests/unit/resources/v2_1/fabric/test_switch.py b/rsd_lib/tests/unit/resources/v2_1/fabric/test_switch.py index 5458f48..0c75428 100644 --- a/rsd_lib/tests/unit/resources/v2_1/fabric/test_switch.py +++ b/rsd_lib/tests/unit/resources/v2_1/fabric/test_switch.py @@ -15,10 +15,12 @@ import json import mock +import testtools + +from sushy import exceptions from rsd_lib.resources.v2_1.fabric import port from rsd_lib.resources.v2_1.fabric import switch -import testtools class SwitchTestCase(testtools.TestCase): @@ -57,15 +59,48 @@ class SwitchTestCase(testtools.TestCase): switch_inst. links.chassis) self.assertEqual("/redfish/v1/Fabrics/PCIe/Switches/1/Actions/Switch." - "Reset", self.switch_inst.actions.switch_reset.target) + "Reset", self.switch_inst.actions.reset.target_uri) self.assertEqual(["GracefulRestart"], self.switch_inst.actions. - switch_reset.reset_type_allowable_values) + reset.allowed_values) - def test_reset_switch(self): - self.switch_inst.reset_switch() + def test__parse_attributes_missing_reset_target(self): + self.switch_inst.json['Actions']['#Switch.Reset'].pop( + 'target') + self.assertRaisesRegex( + exceptions.MissingAttributeError, + 'attribute Actions/#Switch.Reset/target', + self.switch_inst._parse_attributes) + + def test_get__reset_action_element(self): + value = self.switch_inst._get_reset_action_element() + self.assertEqual("/redfish/v1/Fabrics/PCIe/Switches/1/Actions/" + "Switch.Reset", + value.target_uri) + self.assertEqual(["GracefulRestart"], value.allowed_values) + + def test__get_reset_action_element_missing_reset_action(self): + self.switch_inst.actions.reset = None + self.assertRaisesRegex( + exceptions.MissingActionError, 'action #Switch.Reset', + self.switch_inst._get_reset_action_element) + + def test_get_allowed_reset_switch_values(self): + values = self.switch_inst.get_allowed_reset_switch_values() + expected = ["GracefulRestart"] + self.assertEqual(expected, values) + self.assertIsInstance(values, list) + + def test_reset_node(self): + self.switch_inst.reset_switch('GracefulRestart') self.switch_inst._conn.post.assert_called_once_with( '/redfish/v1/Fabrics/PCIe/Switches/1/Actions/Switch.Reset', - data={"ResetType": "GracefulRestart"}) + data={'ResetType': 'GracefulRestart'}) + + def test_reset_node_invalid_value(self): + self.assertRaisesRegex( + exceptions.InvalidParameterValueError, + '"value" value "ForceRestart" is invalid.', + self.switch_inst.reset_switch, 'ForceRestart') def test__get_ports_path(self): expected = '/redfish/v1/Fabrics/PCIe/Switches/1/Ports'