summaryrefslogtreecommitdiff
path: root/ironic/tests
diff options
context:
space:
mode:
authorBill Dodd <billdodd@gmail.com>2018-07-12 12:34:08 -0500
committerBill Dodd <billdodd@gmail.com>2018-11-29 12:05:48 -0600
commit9880262defb96531245234abdbe24ae1b9236c73 (patch)
treea1da49a64a1bc1103cece0eea8d08250c959bd2e /ironic/tests
parentc5414620c5c3bd9b7085fd64f1dac40e83ec22df (diff)
downloadironic-9880262defb96531245234abdbe24ae1b9236c73.tar.gz
Add BIOS interface to Redfish hardware type
The Redfish hardware type does not currently implement the new BIOS hardware interface. This patch implements the Redfish BIOS interface, allowing operators to perform BIOS configuration actions on Ironic Redfish nodes. Change-Id: I44a2a465b08bc15465b7096b1e4838aebb460c1b Story: 2001791 Task: 12507
Diffstat (limited to 'ironic/tests')
-rw-r--r--ironic/tests/unit/drivers/modules/redfish/test_bios.py226
-rw-r--r--ironic/tests/unit/drivers/modules/redfish/test_management.py3
-rw-r--r--ironic/tests/unit/drivers/modules/redfish/test_power.py3
-rw-r--r--ironic/tests/unit/drivers/test_redfish.py3
4 files changed, 232 insertions, 3 deletions
diff --git a/ironic/tests/unit/drivers/modules/redfish/test_bios.py b/ironic/tests/unit/drivers/modules/redfish/test_bios.py
new file mode 100644
index 000000000..3edcbf1e1
--- /dev/null
+++ b/ironic/tests/unit/drivers/modules/redfish/test_bios.py
@@ -0,0 +1,226 @@
+# Copyright 2018 DMTF. 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 mock
+from oslo_utils import importutils
+
+from ironic.common import exception
+from ironic.common import states
+from ironic.conductor import task_manager
+from ironic.conductor import utils as manager_utils
+from ironic.drivers.modules.redfish import bios as redfish_bios
+from ironic.drivers.modules.redfish import utils as redfish_utils
+from ironic import objects
+from ironic.tests.unit.db import base as db_base
+from ironic.tests.unit.db import utils as db_utils
+from ironic.tests.unit.objects import utils as obj_utils
+
+sushy = importutils.try_import('sushy')
+
+INFO_DICT = db_utils.get_test_redfish_info()
+
+
+class MockedSushyError(Exception):
+ pass
+
+
+@mock.patch('eventlet.greenthread.sleep', lambda _t: None)
+class RedfishBiosTestCase(db_base.DbTestCase):
+
+ def setUp(self):
+ super(RedfishBiosTestCase, self).setUp()
+ self.config(enabled_bios_interfaces=['redfish'],
+ enabled_hardware_types=['redfish'],
+ enabled_power_interfaces=['redfish'],
+ enabled_management_interfaces=['redfish'])
+ self.node = obj_utils.create_test_node(
+ self.context, driver='redfish', driver_info=INFO_DICT)
+
+ @mock.patch.object(redfish_bios, 'sushy', None)
+ def test_loading_error(self):
+ self.assertRaisesRegex(
+ exception.DriverLoadError,
+ 'Unable to import the sushy library',
+ redfish_bios.RedfishBIOS)
+
+ def test_get_properties(self):
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=True) as task:
+ properties = task.driver.get_properties()
+ for prop in redfish_utils.COMMON_PROPERTIES:
+ self.assertIn(prop, properties)
+
+ @mock.patch.object(redfish_utils, 'parse_driver_info', autospec=True)
+ def test_validate(self, mock_parse_driver_info):
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=True) as task:
+ task.driver.bios.validate(task)
+ mock_parse_driver_info.assert_called_once_with(task.node)
+
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ @mock.patch.object(objects, 'BIOSSettingList', autospec=True)
+ def test_cache_bios_settings_noop(self, mock_setting_list,
+ mock_get_system):
+ create_list = []
+ update_list = []
+ delete_list = []
+ nochange_list = [{'name': 'EmbeddedSata', 'value': 'Raid'},
+ {'name': 'NicBoot1', 'value': 'NetworkBoot'}]
+ mock_setting_list.sync_node_setting.return_value = (
+ create_list, update_list, delete_list, nochange_list
+ )
+
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=True) as task:
+ attributes = mock_get_system(task.node).bios.attributes
+ settings = [{'name': k, 'value': v} for k, v in attributes.items()]
+ mock_get_system.reset_mock()
+
+ task.driver.bios.cache_bios_settings(task)
+ mock_get_system.assert_called_once_with(task.node)
+ mock_setting_list.sync_node_setting.assert_called_once_with(
+ task.context, task.node.id, settings)
+ mock_setting_list.create.assert_not_called()
+ mock_setting_list.save.assert_not_called()
+ mock_setting_list.delete.assert_not_called()
+
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ @mock.patch.object(objects, 'BIOSSettingList', autospec=True)
+ def test_cache_bios_settings(self, mock_setting_list, mock_get_system):
+ create_list = [{'name': 'DebugMode', 'value': 'enabled'}]
+ update_list = [{'name': 'BootMode', 'value': 'Uefi'},
+ {'name': 'NicBoot2', 'value': 'NetworkBoot'}]
+ delete_list = [{'name': 'AdminPhone', 'value': '555-867-5309'}]
+ nochange_list = [{'name': 'EmbeddedSata', 'value': 'Raid'},
+ {'name': 'NicBoot1', 'value': 'NetworkBoot'}]
+ delete_names = []
+ for setting in delete_list:
+ delete_names.append(setting.get('name'))
+ mock_setting_list.sync_node_setting.return_value = (
+ create_list, update_list, delete_list, nochange_list
+ )
+
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=True) as task:
+ attributes = mock_get_system(task.node).bios.attributes
+ settings = [{'name': k, 'value': v} for k, v in attributes.items()]
+ mock_get_system.reset_mock()
+
+ task.driver.bios.cache_bios_settings(task)
+ mock_get_system.assert_called_once_with(task.node)
+ mock_setting_list.sync_node_setting.assert_called_once_with(
+ task.context, task.node.id, settings)
+ mock_setting_list.create.assert_called_once_with(
+ task.context, task.node.id, create_list)
+ mock_setting_list.save.assert_called_once_with(
+ task.context, task.node.id, update_list)
+ mock_setting_list.delete.assert_called_once_with(
+ task.context, task.node.id, delete_names)
+
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
+ def test_factory_reset(self, mock_power_action, mock_get_system):
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ task.driver.bios.factory_reset(task)
+ mock_get_system.assert_called_with(task.node)
+ mock_power_action.assert_called_once_with(task, states.REBOOT)
+ bios = mock_get_system(task.node).bios
+ bios.reset_bios.assert_called_once()
+
+ @mock.patch('ironic.drivers.modules.redfish.bios.sushy')
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ def test_factory_reset_fail(self, mock_get_system, mock_sushy):
+ mock_sushy.exceptions.SushyError = MockedSushyError
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ bios = mock_get_system(task.node).bios
+ bios.reset_bios.side_effect = MockedSushyError
+ self.assertRaisesRegex(
+ exception.RedfishError, 'BIOS factory reset failed',
+ task.driver.bios.factory_reset, task)
+
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
+ def test_apply_configuration_step1(self, mock_power_action,
+ mock_get_system):
+ settings = [{'name': 'ProcTurboMode', 'value': 'Disabled'},
+ {'name': 'NicBoot1', 'value': 'NetworkBoot'}]
+ attributes = {s['name']: s['value'] for s in settings}
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ task.driver.bios.apply_configuration(task, settings)
+ mock_get_system.assert_called_with(task.node)
+ mock_power_action.assert_called_once_with(task, states.REBOOT)
+ bios = mock_get_system(task.node).bios
+ bios.set_attributes.assert_called_once_with(attributes)
+
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ def test_apply_configuration_step2(self, mock_get_system):
+ settings = [{'name': 'ProcTurboMode', 'value': 'Disabled'},
+ {'name': 'NicBoot1', 'value': 'NetworkBoot'}]
+ requested_attrs = {'ProcTurboMode': 'Enabled'}
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ task.node.driver_internal_info[
+ 'post_config_reboot_requested'] = True
+ task.node.driver_internal_info[
+ 'requested_bios_attrs'] = requested_attrs
+ task.driver.bios._clear_reboot_requested = mock.MagicMock()
+ task.driver.bios.apply_configuration(task, settings)
+ mock_get_system.assert_called_with(task.node)
+ task.driver.bios._clear_reboot_requested\
+ .assert_called_once_with(task)
+
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ def test_check_bios_attrs(self, mock_get_system):
+ settings = [{'name': 'ProcTurboMode', 'value': 'Disabled'},
+ {'name': 'NicBoot1', 'value': 'NetworkBoot'}]
+ requested_attrs = {'ProcTurboMode': 'Enabled'}
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ attributes = mock_get_system(task.node).bios.attributes
+ task.node.driver_internal_info[
+ 'post_config_reboot_requested'] = True
+ task.node.driver_internal_info[
+ 'requested_bios_attrs'] = requested_attrs
+ task.driver.bios._check_bios_attrs = mock.MagicMock()
+ task.driver.bios.apply_configuration(task, settings)
+ task.driver.bios._check_bios_attrs \
+ .assert_called_once_with(task, attributes, requested_attrs)
+
+ @mock.patch('ironic.drivers.modules.redfish.bios.sushy')
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ def test_apply_configuration_fail(self, mock_get_system, mock_sushy):
+ settings = [{'name': 'ProcTurboMode', 'value': 'Disabled'},
+ {'name': 'NicBoot1', 'value': 'NetworkBoot'}]
+ mock_sushy.exceptions.SushyError = MockedSushyError
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ bios = mock_get_system(task.node).bios
+ bios.set_attributes.side_effect = MockedSushyError
+ self.assertRaisesRegex(
+ exception.RedfishError, 'BIOS apply configuration failed',
+ task.driver.bios.apply_configuration, task, settings)
+
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ def test_post_configuration(self, mock_get_system):
+ settings = [{'name': 'ProcTurboMode', 'value': 'Disabled'},
+ {'name': 'NicBoot1', 'value': 'NetworkBoot'}]
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=True) as task:
+ task.driver.bios.post_configuration = mock.MagicMock()
+ task.driver.bios.apply_configuration(task, settings)
+ task.driver.bios.post_configuration\
+ .assert_called_once_with(task, settings)
diff --git a/ironic/tests/unit/drivers/modules/redfish/test_management.py b/ironic/tests/unit/drivers/modules/redfish/test_management.py
index cce6c829e..7876b2087 100644
--- a/ironic/tests/unit/drivers/modules/redfish/test_management.py
+++ b/ironic/tests/unit/drivers/modules/redfish/test_management.py
@@ -38,7 +38,8 @@ class RedfishManagementTestCase(db_base.DbTestCase):
self.config(enabled_hardware_types=['redfish'],
enabled_power_interfaces=['redfish'],
enabled_management_interfaces=['redfish'],
- enabled_inspect_interfaces=['redfish'])
+ enabled_inspect_interfaces=['redfish'],
+ enabled_bios_interfaces=['redfish'])
self.node = obj_utils.create_test_node(
self.context, driver='redfish', driver_info=INFO_DICT)
diff --git a/ironic/tests/unit/drivers/modules/redfish/test_power.py b/ironic/tests/unit/drivers/modules/redfish/test_power.py
index 4c3f61d6f..96903328e 100644
--- a/ironic/tests/unit/drivers/modules/redfish/test_power.py
+++ b/ironic/tests/unit/drivers/modules/redfish/test_power.py
@@ -38,7 +38,8 @@ class RedfishPowerTestCase(db_base.DbTestCase):
self.config(enabled_hardware_types=['redfish'],
enabled_power_interfaces=['redfish'],
enabled_management_interfaces=['redfish'],
- enabled_inspect_interfaces=['redfish'])
+ enabled_inspect_interfaces=['redfish'],
+ enabled_bios_interfaces=['redfish'])
self.node = obj_utils.create_test_node(
self.context, driver='redfish', driver_info=INFO_DICT)
diff --git a/ironic/tests/unit/drivers/test_redfish.py b/ironic/tests/unit/drivers/test_redfish.py
index 073df7d77..1b4e44585 100644
--- a/ironic/tests/unit/drivers/test_redfish.py
+++ b/ironic/tests/unit/drivers/test_redfish.py
@@ -31,7 +31,8 @@ class RedfishHardwareTestCase(db_base.DbTestCase):
self.config(enabled_hardware_types=['redfish'],
enabled_power_interfaces=['redfish'],
enabled_management_interfaces=['redfish'],
- enabled_inspect_interfaces=['redfish'])
+ enabled_inspect_interfaces=['redfish'],
+ enabled_bios_interfaces=['redfish'])
def test_default_interfaces(self):
node = obj_utils.create_test_node(self.context, driver='redfish')