summaryrefslogtreecommitdiff
path: root/ironic/tests
diff options
context:
space:
mode:
authorRichard Pioso <richard.pioso@dell.com>2017-12-25 16:29:58 -0500
committerRichard Pioso <richard.pioso@dell.com>2018-08-04 18:55:30 -0400
commit6222091015d67c0e779edc45bf78d1da7011efbe (patch)
tree6b774578b967851f6f73609319d0ca1b141a8663 /ironic/tests
parent909cdce36dcc5dfa9264c974188e77560d945ced (diff)
downloadironic-6222091015d67c0e779edc45bf78d1da7011efbe.tar.gz
Fix iDRAC hardware type does not work with UEFI
This fixes an issue that caused the integrated Dell Remote Access Controller (iDRAC) management hardware interface implementation, 'idrac', to fail to boot nodes in Unified Extensible Firmware Interface (UEFI) boot mode. That interface is supported by the 'idrac' hardware type. The following errors appear in the ironic conductor log: ERROR ironic.drivers.modules.agent_base_vendor File "/opt/stack/new/ironic/ironic/drivers/modules/drac/management.py", line 106, in set_boot_device ERROR ironic.drivers.modules.agent_base_vendor in drac_boot_devices[PERSISTENT_BOOT_MODE] ERROR ironic.drivers.modules.agent_base_vendor KeyError: 'IPL' ERROR ironic.drivers.modules.agent_base_vendor ERROR ironic.conductor.utils [None req-80b5a61c-4ae1-41ea-875f-5a722142be01 None None] Error rebooting node cddff129-7353-4de1-b436-810b1ae0dd92 after deploy. KeyError: 'IPL' DEBUG ironic.common.states [None req-80b5a61c-4ae1-41ea-875f-5a722142be01 None None] Exiting old state 'deploying' in response to event 'fail' {{(pid=23850) on_exit /opt/stack/new/ironic/ironic/common/states.py:263}} DEBUG ironic.common.states [None req-80b5a61c-4ae1-41ea-875f-5a722142be01 None None] Entering new state 'deploy failed' in response to event 'fail' {{(pid=23850) on_enter /opt/stack/new/ironic/ironic/common/states.py:269}} The issue is resolved for Dell EMC PowerEdge 13th and 14th generation servers. It is not resolved for PowerEdge 12th generation and earlier servers. Prior to this change, the set_boot_device() function in ironic.drivers.modules.drac.management could successfully set a boot device that would persist during future boots only when the server's boot mode was configured to be BIOS. The root cause was that function understood only a single persistent boot mode, BIOS, and it was hard coded. PERSISTENT_BOOT_MODE = 'IPL' Initial Program Load (IPL) is a synonym for legacy BIOS boot mode. The iDRAC does not report nor make visible the boot source lists for persistent boot modes that are not configured as the server's current boot mode. Only the list associated with the configured boot mode is reported and can be modified. So, when the boot mode is configured to be UEFI, the iDRAC permits only its boot source list to be modified. However, set_boot_device() had been capable of only modifying the boot source list for BIOS (IPL), which was not reported. Its attempt to access the wrong, unreported boot source list failed. This change fixes the issue by determining the configured persistent boot mode at run-time and modifying its boot source list. The hard coding of a persistent boot mode has been eliminated. Now, nodes managed by the iDRAC hardware type successfully boot in either persistent boot mode, BIOS or UEFI. More information about using the iDRAC for boot management is available in the "Dell EMC BIOS and Boot Management Profile", Version 4.0.0, section 7.2 Boot Management, pp. 44-47 [1]. The way the iDRAC hardware type deploys the operating system, by copying it to a disk, posed an additional challenge to this fix. UEFI discovers new boot sources during the next boot. How could the server be configured to directly boot into the newly deployed operating system when its boot source is unknown? It was overcome by using new iDRAC BIOS attributes named 'SetBootOrderFqddNN' [2]. Those make it possible to specify the boot source for the next boot without requiring it to be present in the current boot's boot source list. The server is configured to directly boot from the disk on which the operating system was just deployed. An additional reboot is not required. Note that those new attributes are presently available on only 13th and 14th generation servers. Also, this approach is only possible for configuring a persistent boot source. [1] http://en.community.dell.com/techcenter/extras/m/white_papers/20444495 [2] "Configuring server boot options on 14th generation Dell EMC PowerEdge servers", section 3.5.2 SetBootOrderFqddNN, pp. 13-14 (http://en.community.dell.com/techcenter/extras/m/white_papers/20487489) Conflicts: ironic/tests/unit/drivers/modules/drac/test_management.py Story: 1656841 Task: 9711 Change-Id: Idad1db1807420eab62c44318afafe10ea8c52ee5 (cherry picked from commit eb14f5750f6387a0a6b771caffb9f17a9bce5ba0)
Diffstat (limited to 'ironic/tests')
-rw-r--r--ironic/tests/unit/drivers/modules/drac/test_management.py304
1 files changed, 288 insertions, 16 deletions
diff --git a/ironic/tests/unit/drivers/modules/drac/test_management.py b/ironic/tests/unit/drivers/modules/drac/test_management.py
index db3e3fffe..281b0578c 100644
--- a/ironic/tests/unit/drivers/modules/drac/test_management.py
+++ b/ironic/tests/unit/drivers/modules/drac/test_management.py
@@ -2,6 +2,7 @@
#
# Copyright 2014 Red Hat, Inc.
# All Rights Reserved.
+# Copyright (c) 2017-2018 Dell Inc. or its subsidiaries.
#
# 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
@@ -20,6 +21,7 @@ Test class for DRAC management interface
"""
import mock
+from oslo_utils import importutils
import ironic.common.boot_devices
from ironic.common import exception
@@ -33,6 +35,8 @@ from ironic.tests.unit.db import utils as db_utils
from ironic.tests.unit.drivers.modules.drac import utils as test_utils
from ironic.tests.unit.objects import utils as obj_utils
+dracclient_exceptions = importutils.try_import('dracclient.exceptions')
+
INFO_DICT = db_utils.get_test_drac_info()
@@ -58,29 +62,44 @@ class DracManagementInternalMethodsTestCase(db_base.DbTestCase):
driver='fake_drac',
driver_info=INFO_DICT)
- self.boot_device_pxe = {
+ boot_device_ipl_pxe = {
'id': 'BIOS.Setup.1-1#BootSeq#NIC.Embedded.1-1-1',
'boot_mode': 'IPL',
'current_assigned_sequence': 0,
'pending_assigned_sequence': 0,
'bios_boot_string': 'Embedded NIC 1 Port 1 Partition 1'}
- self.boot_device_disk = {
+ boot_device_ipl_disk = {
'id': 'BIOS.Setup.1-1#BootSeq#HardDisk.List.1-1',
'boot_mode': 'IPL',
'current_assigned_sequence': 1,
'pending_assigned_sequence': 1,
'bios_boot_string': 'Hard drive C: BootSeq'}
- self.ipl_boot_devices = [
- test_utils.dict_to_namedtuple(values=self.boot_device_pxe),
- test_utils.dict_to_namedtuple(values=self.boot_device_disk)]
- self.boot_devices = {'IPL': self.ipl_boot_devices,
- 'OneTime': self.ipl_boot_devices}
+ ipl_boot_device_namedtuples = [
+ test_utils.dict_to_namedtuple(values=boot_device_ipl_pxe),
+ test_utils.dict_to_namedtuple(values=boot_device_ipl_disk)]
+ ipl_boot_devices = {'IPL': ipl_boot_device_namedtuples,
+ 'OneTime': ipl_boot_device_namedtuples}
+
+ boot_device_uefi_pxe = {
+ 'id': 'UEFI:BIOS.Setup.1-1#UefiBootSeq#NIC.PxeDevice.1-1',
+ 'boot_mode': 'UEFI',
+ 'current_assigned_sequence': 0,
+ 'pending_assigned_sequence': 0,
+ 'bios_boot_string':
+ 'PXE Device 1: Integrated NIC 1 Port 1 Partition 1'}
+ uefi_boot_device_namedtuples = [
+ test_utils.dict_to_namedtuple(values=boot_device_uefi_pxe)]
+ uefi_boot_devices = {'UEFI': uefi_boot_device_namedtuples,
+ 'OneTime': uefi_boot_device_namedtuples}
+
+ self.boot_devices = {'IPL': ipl_boot_devices,
+ 'UEFI': uefi_boot_devices}
def test__get_boot_device(self, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
mock_client.list_boot_modes.return_value = self.boot_modes('IPL')
- mock_client.list_boot_devices.return_value = self.boot_devices
+ mock_client.list_boot_devices.return_value = self.boot_devices['IPL']
boot_device = drac_mgmt._get_boot_device(self.node)
@@ -96,7 +115,7 @@ class DracManagementInternalMethodsTestCase(db_base.DbTestCase):
# persistent boot modes
mock_client.list_boot_modes.return_value = self.boot_modes('IPL',
'OneTime')
- mock_client.list_boot_devices.return_value = self.boot_devices
+ mock_client.list_boot_devices.return_value = self.boot_devices['IPL']
boot_device = drac_mgmt._get_boot_device(self.node)
@@ -105,6 +124,20 @@ class DracManagementInternalMethodsTestCase(db_base.DbTestCase):
mock_client.list_boot_modes.assert_called_once_with()
mock_client.list_boot_devices.assert_called_once_with()
+ def test__get_boot_device_with_no_boot_device(self,
+ mock_get_drac_client):
+ mock_client = mock.Mock()
+ mock_get_drac_client.return_value = mock_client
+ mock_client.list_boot_modes.return_value = self.boot_modes('IPL')
+ mock_client.list_boot_devices.return_value = {}
+
+ boot_device = drac_mgmt._get_boot_device(self.node)
+
+ expected_boot_device = {'boot_device': None, 'persistent': True}
+ self.assertEqual(expected_boot_device, boot_device)
+ mock_client.list_boot_modes.assert_called_once_with()
+ mock_client.list_boot_devices.assert_called_once_with()
+
def test__get_boot_device_with_empty_boot_mode_list(self,
mock_get_drac_client):
mock_client = mock.Mock()
@@ -114,19 +147,124 @@ class DracManagementInternalMethodsTestCase(db_base.DbTestCase):
self.assertRaises(exception.DracOperationError,
drac_mgmt._get_boot_device, self.node)
+ def test__get_next_persistent_boot_mode(self, mock_get_drac_client):
+ mock_client = mock.Mock()
+ mock_get_drac_client.return_value = mock_client
+ mock_client.list_boot_modes.return_value = self.boot_modes('IPL')
+
+ boot_mode = drac_mgmt._get_next_persistent_boot_mode(self.node)
+
+ mock_get_drac_client.assert_called_once_with(self.node)
+ mock_client.list_boot_modes.assert_called_once_with()
+ expected_boot_mode = 'IPL'
+ self.assertEqual(expected_boot_mode, boot_mode)
+
+ def test__get_next_persistent_boot_mode_with_non_persistent_boot_mode(
+ self, mock_get_drac_client):
+ mock_client = mock.Mock()
+ mock_get_drac_client.return_value = mock_client
+ mock_client.list_boot_modes.return_value = self.boot_modes('IPL',
+ 'OneTime')
+
+ boot_mode = drac_mgmt._get_next_persistent_boot_mode(self.node)
+
+ mock_get_drac_client.assert_called_once_with(self.node)
+ mock_client.list_boot_modes.assert_called_once_with()
+ expected_boot_mode = 'IPL'
+ self.assertEqual(expected_boot_mode, boot_mode)
+
+ def test__get_next_persistent_boot_mode_list_boot_modes_fail(
+ self, mock_get_drac_client):
+ mock_client = mock.Mock()
+ mock_get_drac_client.return_value = mock_client
+ exc = dracclient_exceptions.BaseClientException('boom')
+ mock_client.list_boot_modes.side_effect = exc
+
+ self.assertRaises(exception.DracOperationError,
+ drac_mgmt._get_next_persistent_boot_mode, self.node)
+
+ mock_get_drac_client.assert_called_once_with(self.node)
+ mock_client.list_boot_modes.assert_called_once_with()
+
+ def test__get_next_persistent_boot_mode_with_empty_boot_mode_list(
+ self, mock_get_drac_client):
+ mock_client = mock.Mock()
+ mock_get_drac_client.return_value = mock_client
+ mock_client.list_boot_modes.return_value = []
+
+ self.assertRaises(exception.DracOperationError,
+ drac_mgmt._get_next_persistent_boot_mode, self.node)
+
+ mock_get_drac_client.assert_called_once_with(self.node)
+ mock_client.list_boot_modes.assert_called_once_with()
+
+ def test__is_boot_order_flexibly_programmable(self, mock_get_drac_client):
+ self.assertTrue(drac_mgmt._is_boot_order_flexibly_programmable(
+ persistent=True, bios_settings={'SetBootOrderFqdd1': ()}))
+
+ def test__is_boot_order_flexibly_programmable_not_persistent(
+ self, mock_get_drac_client):
+ self.assertFalse(drac_mgmt._is_boot_order_flexibly_programmable(
+ persistent=False, bios_settings={'SetBootOrderFqdd1': ()}))
+
+ def test__is_boot_order_flexibly_programmable_with_no_bios_setting(
+ self, mock_get_drac_client):
+ self.assertFalse(drac_mgmt._is_boot_order_flexibly_programmable(
+ persistent=True, bios_settings={}))
+
+ def test__flexibly_program_boot_order_for_disk_and_bios(
+ self, mock_get_drac_client):
+ settings = drac_mgmt._flexibly_program_boot_order(
+ ironic.common.boot_devices.DISK, drac_boot_mode='Bios')
+
+ expected_settings = {'SetBootOrderFqdd1': 'HardDisk.List.1-1'}
+ self.assertEqual(expected_settings, settings)
+
+ def test__flexibly_program_boot_order_for_disk_and_uefi(
+ self, mock_get_drac_client):
+ settings = drac_mgmt._flexibly_program_boot_order(
+ ironic.common.boot_devices.DISK, drac_boot_mode='Uefi')
+
+ expected_settings = {
+ 'SetBootOrderFqdd1': '*.*.*',
+ 'SetBootOrderFqdd2': 'NIC.*.*',
+ 'SetBootOrderFqdd3': 'Optical.*.*',
+ 'SetBootOrderFqdd4': 'Floppy.*.*',
+ }
+ self.assertEqual(expected_settings, settings)
+
+ def test__flexibly_program_boot_order_for_pxe(self, mock_get_drac_client):
+ settings = drac_mgmt._flexibly_program_boot_order(
+ ironic.common.boot_devices.PXE, drac_boot_mode='Uefi')
+
+ expected_settings = {'SetBootOrderFqdd1': 'NIC.*.*'}
+ self.assertEqual(expected_settings, settings)
+
+ def test__flexibly_program_boot_order_for_cdrom(self,
+ mock_get_drac_client):
+ settings = drac_mgmt._flexibly_program_boot_order(
+ ironic.common.boot_devices.CDROM, drac_boot_mode='Uefi')
+
+ expected_settings = {'SetBootOrderFqdd1': 'Optical.*.*'}
+ self.assertEqual(expected_settings, settings)
+
+ @mock.patch.object(drac_mgmt, '_get_next_persistent_boot_mode',
+ spec_set=True, autospec=True)
@mock.patch.object(drac_mgmt, '_get_boot_device', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
def test_set_boot_device(self, mock_validate_job_queue,
- mock__get_boot_device, mock_get_drac_client):
+ mock__get_boot_device,
+ mock__get_next_persistent_boot_mode,
+ mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
- mock_client.list_boot_modes.return_value = self.boot_modes('IPL')
- mock_client.list_boot_devices.return_value = self.boot_devices
+ mock_client.list_boot_devices.return_value = self.boot_devices['IPL']
boot_device = {'boot_device': ironic.common.boot_devices.DISK,
'persistent': True}
mock__get_boot_device.return_value = boot_device
+ mock__get_next_persistent_boot_mode.return_value = 'IPL'
boot_device = drac_mgmt.set_boot_device(
self.node, ironic.common.boot_devices.PXE, persistent=False)
@@ -134,39 +272,172 @@ class DracManagementInternalMethodsTestCase(db_base.DbTestCase):
mock_validate_job_queue.assert_called_once_with(self.node)
mock_client.change_boot_device_order.assert_called_once_with(
'OneTime', 'BIOS.Setup.1-1#BootSeq#NIC.Embedded.1-1-1')
+ self.assertEqual(0, mock_client.set_bios_settings.call_count)
mock_client.commit_pending_bios_changes.assert_called_once_with()
+ @mock.patch.object(drac_mgmt, '_get_next_persistent_boot_mode',
+ spec_set=True, autospec=True)
@mock.patch.object(drac_mgmt, '_get_boot_device', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
def test_set_boot_device_called_with_no_change(
self, mock_validate_job_queue, mock__get_boot_device,
- mock_get_drac_client):
+ mock__get_next_persistent_boot_mode, mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
- mock_client.list_boot_modes.return_value = self.boot_modes('IPL')
- mock_client.list_boot_devices.return_value = self.boot_devices
+ mock_client.list_boot_devices.return_value = self.boot_devices['IPL']
boot_device = {'boot_device': ironic.common.boot_devices.PXE,
'persistent': True}
mock__get_boot_device.return_value = boot_device
+ mock__get_next_persistent_boot_mode.return_value = 'IPL'
boot_device = drac_mgmt.set_boot_device(
self.node, ironic.common.boot_devices.PXE, persistent=True)
mock_validate_job_queue.assert_called_once_with(self.node)
self.assertEqual(0, mock_client.change_boot_device_order.call_count)
+ self.assertEqual(0, mock_client.set_bios_settings.call_count)
self.assertEqual(0, mock_client.commit_pending_bios_changes.call_count)
+ @mock.patch.object(drac_mgmt, '_flexibly_program_boot_order',
+ spec_set=True, autospec=True)
+ @mock.patch.object(drac_mgmt, '_is_boot_order_flexibly_programmable',
+ spec_set=True, autospec=True)
+ @mock.patch.object(drac_mgmt, '_get_next_persistent_boot_mode',
+ spec_set=True, autospec=True)
@mock.patch.object(drac_mgmt, '_get_boot_device', spec_set=True,
autospec=True)
@mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
autospec=True)
- def test_set_boot_device_with_invalid_job_queue(
+ def test_set_boot_device_called_with_no_drac_boot_device(
+ self, mock_validate_job_queue, mock__get_boot_device,
+ mock__get_next_persistent_boot_mode,
+ mock__is_boot_order_flexibly_programmable,
+ mock__flexibly_program_boot_order,
+ mock_get_drac_client):
+ mock_client = mock.Mock()
+ mock_get_drac_client.return_value = mock_client
+ mock_client.list_boot_devices.return_value = self.boot_devices['UEFI']
+ boot_device = {'boot_device': ironic.common.boot_devices.PXE,
+ 'persistent': False}
+ mock__get_boot_device.return_value = boot_device
+ mock__get_next_persistent_boot_mode.return_value = 'UEFI'
+ settings = [
+ {
+ 'name': 'BootMode',
+ 'instance_id': 'BIOS.Setup.1-1:BootMode',
+ 'current_value': 'Uefi',
+ 'pending_value': None,
+ 'read_only': False,
+ 'possible_values': ['Bios', 'Uefi']
+ },
+ ]
+ bios_settings = {
+ s['name']: test_utils.dict_to_namedtuple(
+ values=s) for s in settings}
+ mock_client.list_bios_settings.return_value = bios_settings
+ mock__is_boot_order_flexibly_programmable.return_value = True
+ flexibly_program_settings = {
+ 'SetBootOrderFqdd1': '*.*.*',
+ 'SetBootOrderFqdd2': 'NIC.*.*',
+ 'SetBootOrderFqdd3': 'Optical.*.*',
+ 'SetBootOrderFqdd4': 'Floppy.*.*',
+ }
+ mock__flexibly_program_boot_order.return_value = \
+ flexibly_program_settings
+
+ drac_mgmt.set_boot_device(self.node, ironic.common.boot_devices.DISK,
+ persistent=True)
+
+ mock_validate_job_queue.assert_called_once_with(self.node)
+ self.assertEqual(0, mock_client.change_boot_device_order.call_count)
+ mock_client.set_bios_settings.assert_called_once_with(
+ flexibly_program_settings)
+ mock_client.commit_pending_bios_changes.assert_called_once_with()
+
+ @mock.patch.object(drac_mgmt, '_is_boot_order_flexibly_programmable',
+ spec_set=True, autospec=True)
+ @mock.patch.object(drac_mgmt, '_get_next_persistent_boot_mode',
+ spec_set=True, autospec=True)
+ @mock.patch.object(drac_mgmt, '_get_boot_device', spec_set=True,
+ autospec=True)
+ @mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
+ autospec=True)
+ def test_set_boot_device_called_with_not_flexibly_programmable(
+ self, mock_validate_job_queue, mock__get_boot_device,
+ mock__get_next_persistent_boot_mode,
+ mock__is_boot_order_flexibly_programmable,
+ mock_get_drac_client):
+ mock_client = mock.Mock()
+ mock_get_drac_client.return_value = mock_client
+ mock_client.list_boot_devices.return_value = self.boot_devices['UEFI']
+ boot_device = {'boot_device': ironic.common.boot_devices.PXE,
+ 'persistent': False}
+ mock__get_boot_device.return_value = boot_device
+ mock__get_next_persistent_boot_mode.return_value = 'UEFI'
+ mock__is_boot_order_flexibly_programmable.return_value = False
+
+ self.assertRaises(exception.InvalidParameterValue,
+ drac_mgmt.set_boot_device, self.node,
+ ironic.common.boot_devices.CDROM, persistent=False)
+
+ mock_validate_job_queue.assert_called_once_with(self.node)
+ self.assertEqual(0, mock_client.change_boot_device_order.call_count)
+ self.assertEqual(0, mock_client.set_bios_settings.call_count)
+ self.assertEqual(0, mock_client.commit_pending_bios_changes.call_count)
+
+ @mock.patch.object(drac_mgmt, '_is_boot_order_flexibly_programmable',
+ spec_set=True, autospec=True)
+ @mock.patch.object(drac_mgmt, '_get_next_persistent_boot_mode',
+ spec_set=True, autospec=True)
+ @mock.patch.object(drac_mgmt, '_get_boot_device', spec_set=True,
+ autospec=True)
+ @mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
+ autospec=True)
+ def test_set_boot_device_called_with_unknown_boot_mode(
self, mock_validate_job_queue, mock__get_boot_device,
+ mock__get_next_persistent_boot_mode,
+ mock__is_boot_order_flexibly_programmable,
mock_get_drac_client):
mock_client = mock.Mock()
mock_get_drac_client.return_value = mock_client
+ mock_client.list_boot_devices.return_value = self.boot_devices['UEFI']
+ boot_device = {'boot_device': ironic.common.boot_devices.PXE,
+ 'persistent': False}
+ mock__get_boot_device.return_value = boot_device
+ mock__get_next_persistent_boot_mode.return_value = 'UEFI'
+ settings = [
+ {
+ 'name': 'BootMode',
+ 'instance_id': 'BIOS.Setup.1-1:BootMode',
+ 'current_value': 'Bad',
+ 'pending_value': None,
+ 'read_only': False,
+ 'possible_values': ['Bios', 'Uefi', 'Bad']
+ },
+ ]
+ bios_settings = {
+ s['name']: test_utils.dict_to_namedtuple(
+ values=s) for s in settings}
+ mock_client.list_bios_settings.return_value = bios_settings
+ mock__is_boot_order_flexibly_programmable.return_value = True
+
+ self.assertRaises(exception.DracOperationError,
+ drac_mgmt.set_boot_device, self.node,
+ ironic.common.boot_devices.DISK, persistent=True)
+
+ mock_validate_job_queue.assert_called_once_with(self.node)
+ self.assertEqual(0, mock_client.change_boot_device_order.call_count)
+ self.assertEqual(0, mock_client.set_bios_settings.call_count)
+ self.assertEqual(0, mock_client.commit_pending_bios_changes.call_count)
+
+ @mock.patch.object(drac_job, 'validate_job_queue', spec_set=True,
+ autospec=True)
+ def test_set_boot_device_with_invalid_job_queue(
+ self, mock_validate_job_queue, mock_get_drac_client):
+ mock_client = mock.Mock()
+ mock_get_drac_client.return_value = mock_client
mock_validate_job_queue.side_effect = exception.DracOperationError(
'boom')
@@ -175,6 +446,7 @@ class DracManagementInternalMethodsTestCase(db_base.DbTestCase):
ironic.common.boot_devices.PXE, persistent=True)
self.assertEqual(0, mock_client.change_boot_device_order.call_count)
+ self.assertEqual(0, mock_client.set_bios_settings.call_count)
self.assertEqual(0, mock_client.commit_pending_bios_changes.call_count)