diff options
Diffstat (limited to 'ironic/tests')
-rw-r--r-- | ironic/tests/unit/drivers/modules/drac/test_management.py | 304 |
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) |