summaryrefslogtreecommitdiff
path: root/ironic/tests
diff options
context:
space:
mode:
Diffstat (limited to 'ironic/tests')
-rw-r--r--ironic/tests/api/v1/test_nodes.py17
-rw-r--r--ironic/tests/db/test_conductor.py14
-rw-r--r--ironic/tests/db/test_nodes.py10
-rw-r--r--ironic/tests/drivers/ilo/test_deploy.py78
-rw-r--r--ironic/tests/drivers/test_agent.py69
-rw-r--r--ironic/tests/drivers/test_deploy_utils.py46
-rw-r--r--ironic/tests/drivers/test_ipmitool.py80
-rw-r--r--ironic/tests/drivers/test_iscsi_deploy.py19
-rw-r--r--ironic/tests/drivers/test_seamicro.py3
-rw-r--r--ironic/tests/drivers/test_utils.py35
-rw-r--r--ironic/tests/stubs.py12
-rw-r--r--ironic/tests/test_glance_service.py17
-rw-r--r--ironic/tests/test_images.py11
-rw-r--r--ironic/tests/test_pxe_utils.py37
14 files changed, 326 insertions, 122 deletions
diff --git a/ironic/tests/api/v1/test_nodes.py b/ironic/tests/api/v1/test_nodes.py
index c2b510173..dbb95daaf 100644
--- a/ironic/tests/api/v1/test_nodes.py
+++ b/ironic/tests/api/v1/test_nodes.py
@@ -1813,17 +1813,14 @@ class TestPut(test_api_base.FunctionalTest):
True, 'test-topic')
def test_provision_node_in_maintenance_fail(self):
- with mock.patch.object(rpcapi.ConductorAPI, 'do_node_deploy') as dnd:
- self.node.maintenance = True
- self.node.save()
- dnd.side_effect = exception.NodeInMaintenance(op='provisioning',
- node=self.node.uuid)
+ self.node.maintenance = True
+ self.node.save()
- ret = self.put_json('/nodes/%s/states/provision' % self.node.uuid,
- {'target': states.ACTIVE},
- expect_errors=True)
- self.assertEqual(400, ret.status_code)
- self.assertTrue(ret.json['error_message'])
+ ret = self.put_json('/nodes/%s/states/provision' % self.node.uuid,
+ {'target': states.ACTIVE},
+ expect_errors=True)
+ self.assertEqual(400, ret.status_code)
+ self.assertTrue(ret.json['error_message'])
@mock.patch.object(rpcapi.ConductorAPI, 'set_boot_device')
def test_set_boot_device(self, mock_sbd):
diff --git a/ironic/tests/db/test_conductor.py b/ironic/tests/db/test_conductor.py
index d93aad120..1ff182615 100644
--- a/ironic/tests/db/test_conductor.py
+++ b/ironic/tests/db/test_conductor.py
@@ -64,7 +64,7 @@ class DbConductorTestCase(base.DbTestCase):
self.dbapi.unregister_conductor,
c.hostname)
- @mock.patch.object(timeutils, 'utcnow')
+ @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_touch_conductor(self, mock_utcnow):
test_time = datetime.datetime(2000, 1, 1, 0, 0)
mock_utcnow.return_value = test_time
@@ -110,7 +110,7 @@ class DbConductorTestCase(base.DbTestCase):
self.assertEqual('hostname2', node2.reservation)
self.assertIsNone(node3.reservation)
- @mock.patch.object(timeutils, 'utcnow')
+ @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_get_active_driver_dict_one_host_no_driver(self, mock_utcnow):
h = 'fake-host'
expected = {}
@@ -120,7 +120,7 @@ class DbConductorTestCase(base.DbTestCase):
result = self.dbapi.get_active_driver_dict()
self.assertEqual(expected, result)
- @mock.patch.object(timeutils, 'utcnow')
+ @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_get_active_driver_dict_one_host_one_driver(self, mock_utcnow):
h = 'fake-host'
d = 'fake-driver'
@@ -131,7 +131,7 @@ class DbConductorTestCase(base.DbTestCase):
result = self.dbapi.get_active_driver_dict()
self.assertEqual(expected, result)
- @mock.patch.object(timeutils, 'utcnow')
+ @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_get_active_driver_dict_one_host_many_drivers(self, mock_utcnow):
h = 'fake-host'
d1 = 'driver-one'
@@ -143,7 +143,7 @@ class DbConductorTestCase(base.DbTestCase):
result = self.dbapi.get_active_driver_dict()
self.assertEqual(expected, result)
- @mock.patch.object(timeutils, 'utcnow')
+ @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_get_active_driver_dict_many_hosts_one_driver(self, mock_utcnow):
h1 = 'host-one'
h2 = 'host-two'
@@ -156,7 +156,7 @@ class DbConductorTestCase(base.DbTestCase):
result = self.dbapi.get_active_driver_dict()
self.assertEqual(expected, result)
- @mock.patch.object(timeutils, 'utcnow')
+ @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_get_active_driver_dict_many_hosts_and_drivers(self, mock_utcnow):
h1 = 'host-one'
h2 = 'host-two'
@@ -172,7 +172,7 @@ class DbConductorTestCase(base.DbTestCase):
result = self.dbapi.get_active_driver_dict()
self.assertEqual(expected, result)
- @mock.patch.object(timeutils, 'utcnow')
+ @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_get_active_driver_dict_with_old_conductor(self, mock_utcnow):
past = datetime.datetime(2000, 1, 1, 0, 0)
present = past + datetime.timedelta(minutes=2)
diff --git a/ironic/tests/db/test_nodes.py b/ironic/tests/db/test_nodes.py
index 7e3450345..be44943b4 100644
--- a/ironic/tests/db/test_nodes.py
+++ b/ironic/tests/db/test_nodes.py
@@ -136,7 +136,7 @@ class DbNodeTestCase(base.DbTestCase):
res = self.dbapi.get_node_list(filters={'maintenance': False})
self.assertEqual([node1.id], [r.id for r in res])
- @mock.patch.object(timeutils, 'utcnow')
+ @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_get_nodeinfo_list_provision(self, mock_utcnow):
past = datetime.datetime(2000, 1, 1, 0, 0)
next = past + datetime.timedelta(minutes=8)
@@ -161,7 +161,7 @@ class DbNodeTestCase(base.DbTestCase):
states.DEPLOYWAIT})
self.assertEqual([node2.id], [r[0] for r in res])
- @mock.patch.object(timeutils, 'utcnow')
+ @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_get_nodeinfo_list_inspection(self, mock_utcnow):
past = datetime.datetime(2000, 1, 1, 0, 0)
next = past + datetime.timedelta(minutes=8)
@@ -354,7 +354,7 @@ class DbNodeTestCase(base.DbTestCase):
node2.id,
{'instance_uuid': new_i_uuid})
- @mock.patch.object(timeutils, 'utcnow')
+ @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_update_node_provision(self, mock_utcnow):
mocked_time = datetime.datetime(2000, 1, 1, 0, 0)
mock_utcnow.return_value = mocked_time
@@ -378,7 +378,7 @@ class DbNodeTestCase(base.DbTestCase):
self.assertIsNone(res['provision_updated_at'])
self.assertIsNone(res['inspection_started_at'])
- @mock.patch.object(timeutils, 'utcnow')
+ @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_update_node_inspection_started_at(self, mock_utcnow):
mocked_time = datetime.datetime(2000, 1, 1, 0, 0)
mock_utcnow.return_value = mocked_time
@@ -390,7 +390,7 @@ class DbNodeTestCase(base.DbTestCase):
timeutils.normalize_time(result))
self.assertIsNone(res['inspection_finished_at'])
- @mock.patch.object(timeutils, 'utcnow')
+ @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_update_node_inspection_finished_at(self, mock_utcnow):
mocked_time = datetime.datetime(2000, 1, 1, 0, 0)
mock_utcnow.return_value = mocked_time
diff --git a/ironic/tests/drivers/ilo/test_deploy.py b/ironic/tests/drivers/ilo/test_deploy.py
index 8cc70cab4..f44e532b9 100644
--- a/ironic/tests/drivers/ilo/test_deploy.py
+++ b/ironic/tests/drivers/ilo/test_deploy.py
@@ -124,7 +124,7 @@ class IloDeployPrivateMethodsTestCase(db_base.DbTestCase):
boot_iso_expected = 'boot-iso-uuid'
self.assertEqual(boot_iso_expected, boot_iso_actual)
- @mock.patch.object(driver_utils, 'get_boot_mode_for_deploy')
+ @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy')
@mock.patch.object(images, 'get_image_properties')
@mock.patch.object(ilo_deploy, '_parse_deploy_info')
def test__get_boot_iso_uefi_no_glance_image(self,
@@ -293,19 +293,6 @@ class IloDeployPrivateMethodsTestCase(db_base.DbTestCase):
ilo_deploy._update_secure_boot_mode(task, False)
self.assertFalse(func_set_secure_boot_mode.called)
- @mock.patch.object(driver_utils, 'add_node_capability')
- @mock.patch.object(driver_utils, 'rm_node_capability')
- def test__enable_uefi_capability(self, func_rm_node_capability,
- func_add_node_capability):
- with task_manager.acquire(self.context, self.node.uuid,
- shared=False) as task:
- ilo_deploy._enable_uefi_capability(task)
- func_rm_node_capability.assert_called_once_with(task,
- 'boot_mode')
- func_add_node_capability.assert_called_once_with(task,
- 'boot_mode',
- 'uefi')
-
@mock.patch.object(ilo_common, 'set_secure_boot_mode')
@mock.patch.object(ilo_common, 'get_secure_boot_mode')
def test__disable_secure_boot_false(self,
@@ -349,67 +336,86 @@ class IloDeployPrivateMethodsTestCase(db_base.DbTestCase):
self.assertFalse(returned_state)
@mock.patch.object(ilo_common, 'update_boot_mode')
- @mock.patch.object(deploy_utils, 'is_secure_boot_requested')
@mock.patch.object(ilo_deploy, '_disable_secure_boot')
@mock.patch.object(manager_utils, 'node_power_action')
def test__prepare_node_for_deploy(self,
func_node_power_action,
func_disable_secure_boot,
- func_is_secure_boot_requested,
func_update_boot_mode):
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
func_disable_secure_boot.return_value = False
- func_is_secure_boot_requested.return_value = False
ilo_deploy._prepare_node_for_deploy(task)
func_node_power_action.assert_called_once_with(task,
states.POWER_OFF)
func_disable_secure_boot.assert_called_once_with(task)
- func_is_secure_boot_requested.assert_called_once_with(task.node)
func_update_boot_mode.assert_called_once_with(task)
+ bootmode = driver_utils.get_node_capability(task.node, "boot_mode")
+ self.assertIsNone(bootmode)
@mock.patch.object(ilo_common, 'update_boot_mode')
- @mock.patch.object(deploy_utils, 'is_secure_boot_requested')
@mock.patch.object(ilo_deploy, '_disable_secure_boot')
@mock.patch.object(manager_utils, 'node_power_action')
def test__prepare_node_for_deploy_sec_boot_on(self,
func_node_power_action,
func_disable_secure_boot,
- func_is_secure_boot_req,
func_update_boot_mode):
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
func_disable_secure_boot.return_value = True
- func_is_secure_boot_req.return_value = False
ilo_deploy._prepare_node_for_deploy(task)
func_node_power_action.assert_called_once_with(task,
states.POWER_OFF)
func_disable_secure_boot.assert_called_once_with(task)
- func_is_secure_boot_req.assert_called_once_with(task.node)
self.assertFalse(func_update_boot_mode.called)
+ ret_boot_mode = task.node.instance_info['deploy_boot_mode']
+ self.assertEqual('uefi', ret_boot_mode)
+ bootmode = driver_utils.get_node_capability(task.node, "boot_mode")
+ self.assertIsNone(bootmode)
+
+ @mock.patch.object(ilo_common, 'update_boot_mode')
+ @mock.patch.object(ilo_deploy, '_disable_secure_boot')
+ @mock.patch.object(manager_utils, 'node_power_action')
+ def test__prepare_node_for_deploy_inst_info(self,
+ func_node_power_action,
+ func_disable_secure_boot,
+ func_update_boot_mode):
+ instance_info = {'capabilities': '{"secure_boot": "true"}'}
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ func_disable_secure_boot.return_value = False
+ task.node.instance_info = instance_info
+ ilo_deploy._prepare_node_for_deploy(task)
+ func_node_power_action.assert_called_once_with(task,
+ states.POWER_OFF)
+ func_disable_secure_boot.assert_called_once_with(task)
+ func_update_boot_mode.assert_called_once_with(task)
+ bootmode = driver_utils.get_node_capability(task.node, "boot_mode")
+ self.assertIsNone(bootmode)
+ deploy_boot_mode = task.node.instance_info.get('deploy_boot_mode')
+ self.assertIsNone(deploy_boot_mode)
@mock.patch.object(ilo_common, 'update_boot_mode')
- @mock.patch.object(ilo_deploy, '_enable_uefi_capability')
- @mock.patch.object(deploy_utils, 'is_secure_boot_requested')
@mock.patch.object(ilo_deploy, '_disable_secure_boot')
@mock.patch.object(manager_utils, 'node_power_action')
- def test__prepare_node_for_deploy_sec_boot_req(self,
- func_node_power_action,
- func_disable_secure_boot,
- func_is_secure_boot_req,
- func_enable_uefi_cap,
- func_update_boot_mode):
+ def test__prepare_node_for_deploy_sec_boot_on_inst_info(self,
+ func_node_power_action,
+ func_disable_secure_boot,
+ func_update_boot_mode):
+ instance_info = {'capabilities': '{"secure_boot": "true"}'}
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
func_disable_secure_boot.return_value = True
- func_is_secure_boot_req.return_value = True
+ task.node.instance_info = instance_info
ilo_deploy._prepare_node_for_deploy(task)
func_node_power_action.assert_called_once_with(task,
states.POWER_OFF)
func_disable_secure_boot.assert_called_once_with(task)
- func_is_secure_boot_req.assert_called_once_with(task.node)
- func_enable_uefi_cap.assert_called_once_with(task)
self.assertFalse(func_update_boot_mode.called)
+ bootmode = driver_utils.get_node_capability(task.node, "boot_mode")
+ self.assertIsNone(bootmode)
+ deploy_boot_mode = task.node.instance_info.get('deploy_boot_mode')
+ self.assertIsNone(deploy_boot_mode)
class IloVirtualMediaIscsiDeployTestCase(db_base.DbTestCase):
@@ -1179,8 +1185,10 @@ class IloVirtualMediaAgentVendorInterfaceTestCase(db_base.DbTestCase):
@mock.patch.object(agent.AgentVendorInterface, 'reboot_to_instance')
@mock.patch.object(agent.AgentVendorInterface, 'check_deploy_success')
+ @mock.patch.object(ilo_common, 'update_boot_mode')
@mock.patch.object(ilo_deploy, '_update_secure_boot_mode')
def test_reboot_to_instance(self, func_update_secure_boot_mode,
+ func_update_boot_mode,
check_deploy_success_mock,
agent_reboot_to_instance_mock):
kwargs = {'address': '123456'}
@@ -1189,14 +1197,17 @@ class IloVirtualMediaAgentVendorInterfaceTestCase(db_base.DbTestCase):
shared=False) as task:
task.driver.vendor.reboot_to_instance(task, **kwargs)
check_deploy_success_mock.called_once_with(task.node)
+ func_update_boot_mode.assert_called_once_with(task)
func_update_secure_boot_mode.assert_called_once_with(task, True)
agent_reboot_to_instance_mock.assert_called_once_with(task,
**kwargs)
@mock.patch.object(agent.AgentVendorInterface, 'reboot_to_instance')
@mock.patch.object(agent.AgentVendorInterface, 'check_deploy_success')
+ @mock.patch.object(ilo_common, 'update_boot_mode')
@mock.patch.object(ilo_deploy, '_update_secure_boot_mode')
def test_reboot_to_instance_deploy_fail(self, func_update_secure_boot_mode,
+ func_update_boot_mode,
check_deploy_success_mock,
agent_reboot_to_instance_mock):
kwargs = {'address': '123456'}
@@ -1205,6 +1216,7 @@ class IloVirtualMediaAgentVendorInterfaceTestCase(db_base.DbTestCase):
shared=False) as task:
task.driver.vendor.reboot_to_instance(task, **kwargs)
check_deploy_success_mock.called_once_with(task.node)
+ self.assertFalse(func_update_boot_mode.called)
self.assertFalse(func_update_secure_boot_mode.called)
agent_reboot_to_instance_mock.assert_called_once_with(task,
**kwargs)
diff --git a/ironic/tests/drivers/test_agent.py b/ironic/tests/drivers/test_agent.py
index b9ea638e0..bb9675f3f 100644
--- a/ironic/tests/drivers/test_agent.py
+++ b/ironic/tests/drivers/test_agent.py
@@ -164,6 +164,14 @@ class TestAgentDeploy(db_base.DbTestCase):
self.assertIn('driver_info.deploy_ramdisk', str(e))
self.assertIn('driver_info.deploy_kernel', str(e))
+ def test_validate_driver_info_manage_tftp_false(self):
+ self.config(manage_tftp=False, group='agent')
+ self.node.driver_info = {}
+ self.node.save()
+ with task_manager.acquire(
+ self.context, self.node['uuid'], shared=False) as task:
+ self.driver.validate(task)
+
def test_validate_instance_info_missing_params(self):
self.node.instance_info = {}
self.node.save()
@@ -199,6 +207,37 @@ class TestAgentDeploy(db_base.DbTestCase):
self.assertRaises(exception.InvalidParameterValue,
task.driver.deploy.validate, task)
+ @mock.patch.object(agent, '_cache_tftp_images')
+ @mock.patch.object(pxe_utils, 'create_pxe_config')
+ @mock.patch.object(agent, '_build_pxe_config_options')
+ @mock.patch.object(agent, '_get_tftp_image_info')
+ def test__prepare_pxe_boot(self, pxe_info_mock, options_mock,
+ create_mock, cache_mock):
+ with task_manager.acquire(
+ self.context, self.node['uuid'], shared=False) as task:
+ agent._prepare_pxe_boot(task)
+ pxe_info_mock.assert_called_once_with(task.node)
+ options_mock.assert_called_once_with(task.node, mock.ANY)
+ create_mock.assert_called_once_with(
+ task, mock.ANY, CONF.agent.agent_pxe_config_template)
+ cache_mock.assert_called_once_with(task.context, task.node,
+ mock.ANY)
+
+ @mock.patch.object(agent, '_cache_tftp_images')
+ @mock.patch.object(pxe_utils, 'create_pxe_config')
+ @mock.patch.object(agent, '_build_pxe_config_options')
+ @mock.patch.object(agent, '_get_tftp_image_info')
+ def test__prepare_pxe_boot_manage_tftp_false(
+ self, pxe_info_mock, options_mock, create_mock, cache_mock):
+ self.config(manage_tftp=False, group='agent')
+ with task_manager.acquire(
+ self.context, self.node['uuid'], shared=False) as task:
+ agent._prepare_pxe_boot(task)
+ self.assertFalse(pxe_info_mock.called)
+ self.assertFalse(options_mock.called)
+ self.assertFalse(create_mock.called)
+ self.assertFalse(cache_mock.called)
+
@mock.patch.object(dhcp_factory.DHCPFactory, 'update_dhcp')
@mock.patch('ironic.conductor.utils.node_set_boot_device')
@mock.patch('ironic.conductor.utils.node_power_action')
@@ -221,6 +260,36 @@ class TestAgentDeploy(db_base.DbTestCase):
power_mock.assert_called_once_with(task, states.POWER_OFF)
self.assertEqual(driver_return, states.DELETED)
+ @mock.patch.object(pxe_utils, 'clean_up_pxe_config')
+ @mock.patch.object(agent, 'AgentTFTPImageCache')
+ @mock.patch('ironic.common.utils.unlink_without_raise')
+ @mock.patch.object(agent, '_get_tftp_image_info')
+ def test__clean_up_pxe(self, info_mock, unlink_mock, cache_mock,
+ clean_mock):
+ info_mock.return_value = {'label': ['fake1', 'fake2']}
+ with task_manager.acquire(
+ self.context, self.node['uuid'], shared=False) as task:
+ agent._clean_up_pxe(task)
+ info_mock.assert_called_once_with(task.node)
+ unlink_mock.assert_called_once_with('fake2')
+ clean_mock.assert_called_once_with(task)
+
+ @mock.patch.object(pxe_utils, 'clean_up_pxe_config')
+ @mock.patch.object(agent.AgentTFTPImageCache, 'clean_up')
+ @mock.patch('ironic.common.utils.unlink_without_raise')
+ @mock.patch.object(agent, '_get_tftp_image_info')
+ def test__clean_up_pxe_manage_tftp_false(
+ self, info_mock, unlink_mock, cache_mock, clean_mock):
+ self.config(manage_tftp=False, group='agent')
+ info_mock.return_value = {'label': ['fake1', 'fake2']}
+ with task_manager.acquire(
+ self.context, self.node['uuid'], shared=False) as task:
+ agent._clean_up_pxe(task)
+ self.assertFalse(info_mock.called)
+ self.assertFalse(unlink_mock.called)
+ self.assertFalse(cache_mock.called)
+ self.assertFalse(clean_mock.called)
+
@mock.patch('ironic.dhcp.neutron.NeutronDHCPApi.delete_cleaning_ports')
@mock.patch('ironic.dhcp.neutron.NeutronDHCPApi.create_cleaning_ports')
@mock.patch('ironic.drivers.modules.agent._do_pxe_boot')
diff --git a/ironic/tests/drivers/test_deploy_utils.py b/ironic/tests/drivers/test_deploy_utils.py
index 033bd89d5..fdb6653a3 100644
--- a/ironic/tests/drivers/test_deploy_utils.py
+++ b/ironic/tests/drivers/test_deploy_utils.py
@@ -1020,13 +1020,18 @@ class WorkOnDiskTestCase(tests_base.TestCase):
self.swap_part = '/dev/fake-part1'
self.root_part = '/dev/fake-part2'
- self.mock_ibd = mock.patch.object(utils, 'is_block_device').start()
- self.mock_mp = mock.patch.object(utils, 'make_partitions').start()
- self.addCleanup(self.mock_ibd.stop)
- self.addCleanup(self.mock_mp.stop)
- self.mock_remlbl = mock.patch.object(utils,
- 'destroy_disk_metadata').start()
- self.addCleanup(self.mock_remlbl.stop)
+ self.mock_ibd_obj = mock.patch.object(
+ utils, 'is_block_device', autospec=True)
+ self.mock_ibd = self.mock_ibd_obj.start()
+ self.addCleanup(self.mock_ibd_obj.stop)
+ self.mock_mp_obj = mock.patch.object(
+ utils, 'make_partitions', autospec=True)
+ self.mock_mp = self.mock_mp_obj.start()
+ self.addCleanup(self.mock_mp_obj.stop)
+ self.mock_remlbl_obj = mock.patch.object(
+ utils, 'destroy_disk_metadata', autospec=True)
+ self.mock_remlbl = self.mock_remlbl_obj.start()
+ self.addCleanup(self.mock_remlbl_obj.stop)
self.mock_mp.return_value = {'swap': self.swap_part,
'root': self.root_part}
@@ -1044,7 +1049,7 @@ class WorkOnDiskTestCase(tests_base.TestCase):
boot_mode="bios")
def test_no_swap_partition(self):
- self.mock_ibd.side_effect = [True, False]
+ self.mock_ibd.side_effect = iter([True, False])
calls = [mock.call(self.root_part),
mock.call(self.swap_part)]
self.assertRaises(exception.InstanceDeployFailure,
@@ -1068,7 +1073,7 @@ class WorkOnDiskTestCase(tests_base.TestCase):
self.mock_mp.return_value = {'ephemeral': ephemeral_part,
'swap': swap_part,
'root': root_part}
- self.mock_ibd.side_effect = [True, True, False]
+ self.mock_ibd.side_effect = iter([True, True, False])
calls = [mock.call(root_part),
mock.call(swap_part),
mock.call(ephemeral_part)]
@@ -1096,7 +1101,7 @@ class WorkOnDiskTestCase(tests_base.TestCase):
self.mock_mp.return_value = {'swap': swap_part,
'configdrive': configdrive_part,
'root': root_part}
- self.mock_ibd.side_effect = [True, True, False]
+ self.mock_ibd.side_effect = iter([True, True, False])
calls = [mock.call(root_part),
mock.call(swap_part),
mock.call(configdrive_part)]
@@ -1465,6 +1470,27 @@ class ParseInstanceInfoCapabilitiesTestCase(tests_base.TestCase):
self.node.instance_info = {'capabilities': {"secure_boot": "invalid"}}
self.assertFalse(utils.is_secure_boot_requested(self.node))
+ def test_get_boot_mode_for_deploy_using_capabilities(self):
+ properties = {'capabilities': 'boot_mode:uefi,cap2:value2'}
+ self.node.properties = properties
+
+ result = utils.get_boot_mode_for_deploy(self.node)
+ self.assertEqual('uefi', result)
+
+ def test_get_boot_mode_for_deploy_using_instance_info_cap(self):
+ instance_info = {'capabilities': {'secure_boot': 'True'}}
+ self.node.instance_info = instance_info
+
+ result = utils.get_boot_mode_for_deploy(self.node)
+ self.assertEqual('uefi', result)
+
+ def test_get_boot_mode_for_deploy_using_instance_info(self):
+ instance_info = {'deploy_boot_mode': 'bios'}
+ self.node.instance_info = instance_info
+
+ result = utils.get_boot_mode_for_deploy(self.node)
+ self.assertEqual('bios', result)
+
class TrySetBootDeviceTestCase(db_base.DbTestCase):
diff --git a/ironic/tests/drivers/test_ipmitool.py b/ironic/tests/drivers/test_ipmitool.py
index a27060d0f..2e0097fba 100644
--- a/ironic/tests/drivers/test_ipmitool.py
+++ b/ironic/tests/drivers/test_ipmitool.py
@@ -840,6 +840,86 @@ class IPMIToolPrivateMethodTestCase(db_base.DbTestCase):
mock_support.assert_called_once_with('timing')
mock_pwf.assert_called_once_with(self.info['password'])
mock_exec.assert_called_once_with(*args)
+ self.assertEqual(1, mock_exec.call_count)
+
+ @mock.patch.object(ipmi, '_is_option_supported', autospec=True)
+ @mock.patch.object(utils, 'execute', autospec=True)
+ def test__exec_ipmitool_exception_retry(self,
+ mock_exec, mock_support, mock_sleep):
+
+ ipmi.LAST_CMD_TIME = {}
+ mock_support.return_value = False
+ mock_exec.side_effect = iter([
+ processutils.ProcessExecutionError(
+ stderr="insufficient resources for session"
+ ),
+ (None, None)
+ ])
+
+ # Directly set the configuration values such that
+ # the logic will cause _exec_ipmitool to retry twice.
+ self.config(min_command_interval=1, group='ipmi')
+ self.config(retry_timeout=2, group='ipmi')
+
+ ipmi._exec_ipmitool(self.info, 'A B C')
+
+ mock_support.assert_called_once_with('timing')
+ self.assertEqual(2, mock_exec.call_count)
+
+ @mock.patch.object(ipmi, '_is_option_supported', autospec=True)
+ @mock.patch.object(utils, 'execute', autospec=True)
+ def test__exec_ipmitool_exception_retries_exceeded(self,
+ mock_exec, mock_support, mock_sleep):
+
+ ipmi.LAST_CMD_TIME = {}
+ mock_support.return_value = False
+
+ mock_exec.side_effect = processutils.ProcessExecutionError(
+ stderr="insufficient resources for session"
+ )
+
+ # Directly set the configuration values such that
+ # the logic will cause _exec_ipmitool to timeout.
+ self.config(min_command_interval=1, group='ipmi')
+ self.config(retry_timeout=1, group='ipmi')
+
+ self.assertRaises(processutils.ProcessExecutionError,
+ ipmi._exec_ipmitool,
+ self.info, 'A B C')
+ mock_support.assert_called_once_with('timing')
+ self.assertEqual(1, mock_exec.call_count)
+
+ @mock.patch.object(ipmi, '_is_option_supported', autospec=True)
+ @mock.patch.object(utils, 'execute', autospec=True)
+ def test__exec_ipmitool_exception_non_retryable_failure(self,
+ mock_exec, mock_support, mock_sleep):
+
+ ipmi.LAST_CMD_TIME = {}
+ mock_support.return_value = False
+
+ # Return a retryable error, then an error that cannot
+ # be retried thus resulting in a single retry
+ # attempt by _exec_ipmitool.
+ mock_exec.side_effect = iter([
+ processutils.ProcessExecutionError(
+ stderr="insufficient resources for session"
+ ),
+ processutils.ProcessExecutionError(
+ stderr="Unknown"
+ ),
+ ])
+
+ # Directly set the configuration values such that
+ # the logic will cause _exec_ipmitool to retry up
+ # to 3 times.
+ self.config(min_command_interval=1, group='ipmi')
+ self.config(retry_timeout=3, group='ipmi')
+
+ self.assertRaises(processutils.ProcessExecutionError,
+ ipmi._exec_ipmitool,
+ self.info, 'A B C')
+ mock_support.assert_called_once_with('timing')
+ self.assertEqual(2, mock_exec.call_count)
@mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
def test__power_status_on(self, mock_exec, mock_sleep):
diff --git a/ironic/tests/drivers/test_iscsi_deploy.py b/ironic/tests/drivers/test_iscsi_deploy.py
index a0b1f40ba..4d3803542 100644
--- a/ironic/tests/drivers/test_iscsi_deploy.py
+++ b/ironic/tests/drivers/test_iscsi_deploy.py
@@ -487,6 +487,25 @@ class IscsiDeployMethodsTestCase(db_base.DbTestCase):
self._test_build_deploy_ramdisk_options(mock_alnum, fake_api_url,
expected_boot_option=expected)
+ @mock.patch.object(keystone, 'get_service_url', autospec=True)
+ @mock.patch.object(utils, 'random_alnum', autospec=True)
+ def test_build_deploy_ramdisk_options_whole_disk_image(self, mock_alnum,
+ mock_get_url):
+ """Tests a hack to boot_option for whole disk images.
+
+ This hack is in place to fix bug #1441556.
+ """
+ self.node.instance_info = {'capabilities': '{"boot_option": "local"}'}
+ dii = self.node.driver_internal_info
+ dii['is_whole_disk_image'] = True
+ self.node.driver_internal_info = dii
+ self.node.save()
+ expected = 'netboot'
+ fake_api_url = 'http://127.0.0.1:6385'
+ self.config(api_url=fake_api_url, group='conductor')
+ self._test_build_deploy_ramdisk_options(mock_alnum, fake_api_url,
+ expected_boot_option=expected)
+
def test_get_boot_option(self):
self.node.instance_info = {'capabilities': '{"boot_option": "local"}'}
result = iscsi_deploy.get_boot_option(self.node)
diff --git a/ironic/tests/drivers/test_seamicro.py b/ironic/tests/drivers/test_seamicro.py
index ad4586828..e477cddd4 100644
--- a/ironic/tests/drivers/test_seamicro.py
+++ b/ironic/tests/drivers/test_seamicro.py
@@ -129,6 +129,7 @@ class SeaMicroValidateParametersTestCase(db_base.DbTestCase):
node)
+@mock.patch('eventlet.greenthread.sleep', lambda n: None)
class SeaMicroPrivateMethodsTestCase(db_base.DbTestCase):
def setUp(self):
@@ -144,8 +145,6 @@ class SeaMicroPrivateMethodsTestCase(db_base.DbTestCase):
self.config(action_timeout=0, group='seamicro')
self.config(max_retry=2, group='seamicro')
- self.patcher = mock.patch('eventlet.greenthread.sleep')
- self.mock_sleep = self.patcher.start()
self.info = seamicro._parse_driver_info(self.node)
@mock.patch.object(seamicro_client, "Client")
diff --git a/ironic/tests/drivers/test_utils.py b/ironic/tests/drivers/test_utils.py
index 5eb9b5ace..cd14b464f 100644
--- a/ironic/tests/drivers/test_utils.py
+++ b/ironic/tests/drivers/test_utils.py
@@ -112,27 +112,6 @@ class UtilsTestCase(db_base.DbTestCase):
self.assertEqual('a:b,c:d,a:b',
task.node.properties['capabilities'])
- def test_rm_node_capability(self):
- with task_manager.acquire(self.context, self.node.uuid,
- shared=False) as task:
- task.node.properties['capabilities'] = 'a:b'
- driver_utils.rm_node_capability(task, 'a')
- self.assertIsNone(task.node.properties['capabilities'])
-
- def test_rm_node_capability_exists(self):
- with task_manager.acquire(self.context, self.node.uuid,
- shared=False) as task:
- task.node.properties['capabilities'] = 'a:b,c:d,x:y'
- self.assertIsNone(driver_utils.rm_node_capability(task, 'c'))
- self.assertEqual('a:b,x:y', task.node.properties['capabilities'])
-
- def test_rm_node_capability_non_existent(self):
- with task_manager.acquire(self.context, self.node.uuid,
- shared=False) as task:
- task.node.properties['capabilities'] = 'a:b'
- self.assertIsNone(driver_utils.rm_node_capability(task, 'x'))
- self.assertEqual('a:b', task.node.properties['capabilities'])
-
def test_validate_capability(self):
properties = {'capabilities': 'cat:meow,cap2:value2'}
self.node.properties = properties
@@ -191,17 +170,3 @@ class UtilsTestCase(db_base.DbTestCase):
self.assertRaises(exception.InvalidParameterValue,
driver_utils.validate_secure_boot_capability,
self.node)
-
- def test_get_boot_mode_for_deploy_using_capabilities(self):
- properties = {'capabilities': 'boot_mode:uefi,cap2:value2'}
- self.node.properties = properties
-
- result = driver_utils.get_boot_mode_for_deploy(self.node)
- self.assertEqual('uefi', result)
-
- def test_get_boot_mode_for_deploy_using_instance_info(self):
- instance_info = {'deploy_boot_mode': 'uefi'}
- self.node.instance_info = instance_info
-
- result = driver_utils.get_boot_mode_for_deploy(self.node)
- self.assertEqual('uefi', result)
diff --git a/ironic/tests/stubs.py b/ironic/tests/stubs.py
index 7d43d2676..d20c1fd8a 100644
--- a/ironic/tests/stubs.py
+++ b/ironic/tests/stubs.py
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from ironic.common import exception
+from glanceclient import exc as glance_exc
NOW_GLANCE_FORMAT = "2010-10-11T10:30:22"
@@ -40,7 +40,7 @@ class StubGlanceClient(object):
index += 1
break
else:
- raise exception.BadRequest('Marker not found')
+ raise glance_exc.BadRequest('Marker not found')
return self._images[index:index + limit]
@@ -48,7 +48,7 @@ class StubGlanceClient(object):
for image in self._images:
if image.id == str(image_id):
return image
- raise exception.ImageNotFound(image_id)
+ raise glance_exc.NotFound(image_id)
def data(self, image_id):
self.get(image_id)
@@ -76,7 +76,7 @@ class StubGlanceClient(object):
for k, v in metadata.items():
setattr(self._images[i], k, v)
return self._images[i]
- raise exception.NotFound(image_id)
+ raise glance_exc.NotFound(image_id)
def delete(self, image_id):
for i, image in enumerate(self._images):
@@ -86,10 +86,10 @@ class StubGlanceClient(object):
# HTTPForbidden.
image_data = self._images[i]
if image_data.deleted:
- raise exception.Forbidden()
+ raise glance_exc.Forbidden()
image_data.deleted = True
return
- raise exception.NotFound(image_id)
+ raise glance_exc.NotFound(image_id)
class FakeImage(object):
diff --git a/ironic/tests/test_glance_service.py b/ironic/tests/test_glance_service.py
index 8482ed751..6c3276da6 100644
--- a/ironic/tests/test_glance_service.py
+++ b/ironic/tests/test_glance_service.py
@@ -20,8 +20,11 @@ import os
import tempfile
import time
+from glanceclient import exc as glance_exc
import mock
+from oslo_config import cfg
from oslo_context import context
+from oslo_serialization import jsonutils
import testtools
@@ -33,8 +36,6 @@ from ironic.tests import base
from ironic.tests import matchers
from ironic.tests import stubs
-from oslo_config import cfg
-from oslo_serialization import jsonutils
CONF = cfg.CONF
@@ -468,7 +469,7 @@ class TestGlanceImageService(base.TestCase):
def get(self, image_id):
if tries[0] == 0:
tries[0] = 1
- raise exception.ServiceUnavailable('')
+ raise glance_exc.ServiceUnavailable('')
else:
return {}
@@ -536,7 +537,7 @@ class TestGlanceImageService(base.TestCase):
class MyGlanceStubClient(stubs.StubGlanceClient):
"""A client that raises a Forbidden exception."""
def get(self, image_id):
- raise exception.Forbidden(image_id)
+ raise glance_exc.Forbidden(image_id)
stub_client = MyGlanceStubClient()
stub_context = context.RequestContext(auth_token=True)
@@ -552,7 +553,7 @@ class TestGlanceImageService(base.TestCase):
class MyGlanceStubClient(stubs.StubGlanceClient):
"""A client that raises a HTTPForbidden exception."""
def get(self, image_id):
- raise exception.HTTPForbidden(image_id)
+ raise glance_exc.HTTPForbidden(image_id)
stub_client = MyGlanceStubClient()
stub_context = context.RequestContext(auth_token=True)
@@ -568,7 +569,7 @@ class TestGlanceImageService(base.TestCase):
class MyGlanceStubClient(stubs.StubGlanceClient):
"""A client that raises a NotFound exception."""
def get(self, image_id):
- raise exception.NotFound(image_id)
+ raise glance_exc.NotFound(image_id)
stub_client = MyGlanceStubClient()
stub_context = context.RequestContext(auth_token=True)
@@ -584,7 +585,7 @@ class TestGlanceImageService(base.TestCase):
class MyGlanceStubClient(stubs.StubGlanceClient):
"""A client that raises a HTTPNotFound exception."""
def get(self, image_id):
- raise exception.HTTPNotFound(image_id)
+ raise glance_exc.HTTPNotFound(image_id)
stub_client = MyGlanceStubClient()
stub_context = context.RequestContext(auth_token=True)
@@ -635,7 +636,7 @@ def _create_failing_glance_client(info):
def get(self, image_id):
info['num_calls'] += 1
if info['num_calls'] == 1:
- raise exception.ServiceUnavailable('')
+ raise glance_exc.ServiceUnavailable('')
return {}
return MyGlanceStubClient()
diff --git a/ironic/tests/test_images.py b/ironic/tests/test_images.py
index fb1da9dbc..b610d4b0a 100644
--- a/ironic/tests/test_images.py
+++ b/ironic/tests/test_images.py
@@ -424,12 +424,15 @@ class FsImageTestCase(base.TestCase):
self.assertEqual(expected_cfg, cfg)
def test__generate_grub_cfg(self):
-
kernel_params = ['key1=value1', 'key2']
options = {'linux': '/vmlinuz', 'initrd': '/initrd'}
- expected_cfg = ("menuentry \"install\" {\n"
- "linux /vmlinuz key1=value1 key2 --\n"
- "initrd /initrd\n"
+ expected_cfg = ("set default=0\n"
+ "set timeout=5\n"
+ "set hidden_timeout_quiet=false\n"
+ "\n"
+ "menuentry \"boot_partition\" {\n"
+ "linuxefi /vmlinuz key1=value1 key2 --\n"
+ "initrdefi /initrd\n"
"}")
cfg = images._generate_cfg(kernel_params,
diff --git a/ironic/tests/test_pxe_utils.py b/ironic/tests/test_pxe_utils.py
index f16cd3e1b..1792d840a 100644
--- a/ironic/tests/test_pxe_utils.py
+++ b/ironic/tests/test_pxe_utils.py
@@ -144,7 +144,40 @@ class TestPXEUtils(db_base.DbTestCase):
]
unlink_calls = [
mock.call('/tftpboot/pxelinux.cfg/01-00-11-22-33-44-55-66'),
- mock.call('/tftpboot/pxelinux.cfg/01-00-11-22-33-44-55-67')
+ mock.call('/tftpboot/pxelinux.cfg/01-00-11-22-33-44-55-67'),
+ ]
+ with task_manager.acquire(self.context, self.node.uuid) as task:
+ pxe_utils._link_mac_pxe_configs(task)
+
+ unlink_mock.assert_has_calls(unlink_calls)
+ create_link_mock.assert_has_calls(create_link_calls)
+
+ @mock.patch('ironic.common.utils.create_link_without_raise', autospec=True)
+ @mock.patch('ironic.common.utils.unlink_without_raise', autospec=True)
+ @mock.patch('ironic.drivers.utils.get_node_mac_addresses', autospec=True)
+ def test__write_mac_ipxe_configs(self, get_macs_mock, unlink_mock,
+ create_link_mock):
+ self.config(ipxe_enabled=True, group='pxe')
+ macs = [
+ '00:11:22:33:44:55:66',
+ '00:11:22:33:44:55:67'
+ ]
+ get_macs_mock.return_value = macs
+ create_link_calls = [
+ mock.call(u'/httpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/config',
+ '/httpboot/pxelinux.cfg/00-11-22-33-44-55-66'),
+ mock.call(u'/httpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/config',
+ '/httpboot/pxelinux.cfg/00112233445566'),
+ mock.call(u'/httpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/config',
+ '/httpboot/pxelinux.cfg/00-11-22-33-44-55-67'),
+ mock.call(u'/httpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/config',
+ '/httpboot/pxelinux.cfg/00112233445567'),
+ ]
+ unlink_calls = [
+ mock.call('/httpboot/pxelinux.cfg/00-11-22-33-44-55-66'),
+ mock.call('/httpboot/pxelinux.cfg/00112233445566'),
+ mock.call('/httpboot/pxelinux.cfg/00-11-22-33-44-55-67'),
+ mock.call('/httpboot/pxelinux.cfg/00112233445567'),
]
with task_manager.acquire(self.context, self.node.uuid) as task:
pxe_utils._link_mac_pxe_configs(task)
@@ -218,7 +251,7 @@ class TestPXEUtils(db_base.DbTestCase):
self.config(ipxe_enabled=True, group='pxe')
self.config(http_root='/httpboot', group='pxe')
mac = '00:11:22:33:AA:BB:CC'
- self.assertEqual('/httpboot/pxelinux.cfg/00112233aabbcc',
+ self.assertEqual('/httpboot/pxelinux.cfg/00-11-22-33-aa-bb-cc',
pxe_utils._get_pxe_mac_path(mac))
def test__get_pxe_ip_address_path(self):