Merge "Follow-up for agent rescue implementation"
This commit is contained in:
@@ -1344,7 +1344,6 @@ class AgentRescueTestCase(db_base.DbTestCase):
|
||||
mock_prepare_instance,
|
||||
mock_conf_tenant_net,
|
||||
mock_remove_rescue_net):
|
||||
"""Test unrescue in case where boot driver prepares instance reboot."""
|
||||
self.config(manage_agent_boot=False, group='agent')
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
result = task.driver.rescue.unrescue(task)
|
||||
@@ -1366,24 +1365,24 @@ class AgentRescueTestCase(db_base.DbTestCase):
|
||||
self.assertFalse(mock_validate_network.called)
|
||||
mock_boot_validate.assert_called_once_with(mock.ANY, task)
|
||||
|
||||
@mock.patch.object(neutron_common, 'validate_network', autospec=True)
|
||||
@mock.patch('ironic.drivers.modules.network.neutron.NeutronNetwork.'
|
||||
'get_rescuing_network_uuid', autospec=True)
|
||||
@mock.patch.object(fake.FakeBoot, 'validate', autospec=True)
|
||||
def test_agent_rescue_validate_neutron_net(self, mock_boot_validate,
|
||||
mock_validate_network):
|
||||
mock_rescuing_net):
|
||||
self.config(enabled_network_interfaces=['neutron'])
|
||||
self.node.network_interface = 'neutron'
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
task.driver.rescue.validate(task)
|
||||
mock_validate_network.assert_called_once_with(
|
||||
CONF.neutron.rescuing_network, 'rescuing network',
|
||||
context=task.context)
|
||||
mock_rescuing_net.assert_called_once_with(mock.ANY, task)
|
||||
mock_boot_validate.assert_called_once_with(mock.ANY, task)
|
||||
|
||||
@mock.patch.object(neutron_common, 'validate_network', autospec=True)
|
||||
@mock.patch('ironic.drivers.modules.network.neutron.NeutronNetwork.'
|
||||
'get_rescuing_network_uuid', autospec=True)
|
||||
@mock.patch.object(fake.FakeBoot, 'validate', autospec=True)
|
||||
def test_agent_rescue_validate_no_manage_agent(self, mock_boot_validate,
|
||||
mock_validate_network):
|
||||
mock_rescuing_net):
|
||||
# If ironic's not managing booting of ramdisks, we don't set up PXE for
|
||||
# the ramdisk/kernel, so validation can pass without this info
|
||||
self.config(manage_agent_boot=False, group='agent')
|
||||
@@ -1394,76 +1393,85 @@ class AgentRescueTestCase(db_base.DbTestCase):
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
task.driver.rescue.validate(task)
|
||||
self.assertFalse(mock_validate_network.called)
|
||||
self.assertFalse(mock_rescuing_net.called)
|
||||
self.assertFalse(mock_boot_validate.called)
|
||||
|
||||
@mock.patch.object(neutron_common, 'validate_network', autospec=True)
|
||||
@mock.patch('ironic.drivers.modules.network.neutron.NeutronNetwork.'
|
||||
'get_rescuing_network_uuid', autospec=True)
|
||||
@mock.patch.object(fake.FakeBoot, 'validate', autospec=True)
|
||||
def test_agent_rescue_validate_fails_no_rescue_ramdisk(
|
||||
self, mock_boot_validate, mock_validate_network):
|
||||
self, mock_boot_validate, mock_rescuing_net):
|
||||
driver_info = self.node.driver_info
|
||||
del driver_info['rescue_ramdisk']
|
||||
self.node.driver_info = driver_info
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.MissingParameterValue,
|
||||
task.driver.rescue.validate, task)
|
||||
self.assertFalse(mock_validate_network.called)
|
||||
self.assertRaisesRegex(exception.MissingParameterValue,
|
||||
'Node.*missing.*rescue_ramdisk',
|
||||
task.driver.rescue.validate, task)
|
||||
self.assertFalse(mock_rescuing_net.called)
|
||||
mock_boot_validate.assert_called_once_with(mock.ANY, task)
|
||||
|
||||
@mock.patch.object(neutron_common, 'validate_network', autospec=True)
|
||||
@mock.patch('ironic.drivers.modules.network.neutron.NeutronNetwork.'
|
||||
'get_rescuing_network_uuid', autospec=True)
|
||||
@mock.patch.object(fake.FakeBoot, 'validate', autospec=True)
|
||||
def test_agent_rescue_validate_fails_no_rescue_kernel(
|
||||
self, mock_boot_validate, mock_validate_network):
|
||||
self, mock_boot_validate, mock_rescuing_net):
|
||||
driver_info = self.node.driver_info
|
||||
del driver_info['rescue_kernel']
|
||||
self.node.driver_info = driver_info
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.MissingParameterValue,
|
||||
task.driver.rescue.validate, task)
|
||||
self.assertFalse(mock_validate_network.called)
|
||||
self.assertRaisesRegex(exception.MissingParameterValue,
|
||||
'Node.*missing.*rescue_kernel',
|
||||
task.driver.rescue.validate, task)
|
||||
self.assertFalse(mock_rescuing_net.called)
|
||||
mock_boot_validate.assert_called_once_with(mock.ANY, task)
|
||||
|
||||
@mock.patch.object(neutron_common, 'validate_network', autospec=True)
|
||||
@mock.patch('ironic.drivers.modules.network.neutron.NeutronNetwork.'
|
||||
'get_rescuing_network_uuid', autospec=True)
|
||||
@mock.patch.object(fake.FakeBoot, 'validate', autospec=True)
|
||||
def test_agent_rescue_validate_fails_no_rescue_password(
|
||||
self, mock_boot_validate, mock_validate_network):
|
||||
self, mock_boot_validate, mock_rescuing_net):
|
||||
instance_info = self.node.instance_info
|
||||
del instance_info['rescue_password']
|
||||
self.node.instance_info = instance_info
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.MissingParameterValue,
|
||||
task.driver.rescue.validate, task)
|
||||
self.assertFalse(mock_validate_network.called)
|
||||
self.assertRaisesRegex(exception.MissingParameterValue,
|
||||
'Node.*missing.*rescue_password',
|
||||
task.driver.rescue.validate, task)
|
||||
self.assertFalse(mock_rescuing_net.called)
|
||||
mock_boot_validate.assert_called_once_with(mock.ANY, task)
|
||||
|
||||
@mock.patch.object(neutron_common, 'validate_network', autospec=True)
|
||||
@mock.patch('ironic.drivers.modules.network.neutron.NeutronNetwork.'
|
||||
'get_rescuing_network_uuid', autospec=True)
|
||||
@mock.patch.object(fake.FakeBoot, 'validate', autospec=True)
|
||||
def test_agent_rescue_validate_fails_empty_rescue_password(
|
||||
self, mock_boot_validate, mock_validate_network):
|
||||
self, mock_boot_validate, mock_rescuing_net):
|
||||
instance_info = self.node.instance_info
|
||||
instance_info['rescue_password'] = " "
|
||||
self.node.instance_info = instance_info
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.InvalidParameterValue,
|
||||
task.driver.rescue.validate, task)
|
||||
self.assertFalse(mock_validate_network.called)
|
||||
self.assertRaisesRegex(exception.InvalidParameterValue,
|
||||
"'instance_info/rescue_password'.*empty",
|
||||
task.driver.rescue.validate, task)
|
||||
self.assertFalse(mock_rescuing_net.called)
|
||||
mock_boot_validate.assert_called_once_with(mock.ANY, task)
|
||||
|
||||
@mock.patch.object(neutron_common, 'validate_network', autospec=True)
|
||||
@mock.patch('ironic.drivers.modules.network.neutron.NeutronNetwork.'
|
||||
'get_rescuing_network_uuid', autospec=True)
|
||||
@mock.patch.object(reflection, 'get_signature', autospec=True)
|
||||
@mock.patch.object(fake.FakeBoot, 'validate', autospec=True)
|
||||
def test_agent_rescue_validate_incompat_exc(self, mock_boot_validate,
|
||||
mock_get_signature,
|
||||
mock_validate_network):
|
||||
mock_rescuing_net):
|
||||
mock_get_signature.return_value.parameters = ['task']
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.IncompatibleInterface,
|
||||
task.driver.rescue.validate, task)
|
||||
self.assertFalse(mock_validate_network.called)
|
||||
self.assertFalse(mock_rescuing_net.called)
|
||||
self.assertFalse(mock_boot_validate.called)
|
||||
|
||||
@mock.patch.object(flat_network.FlatNetwork, 'remove_rescuing_network',
|
||||
|
||||
@@ -30,7 +30,6 @@ from ironic.drivers.modules import agent_base_vendor
|
||||
from ironic.drivers.modules import agent_client
|
||||
from ironic.drivers.modules import deploy_utils
|
||||
from ironic.drivers.modules import fake
|
||||
from ironic.drivers.modules.network import flat as flat_network
|
||||
from ironic.drivers.modules import pxe
|
||||
from ironic.drivers import utils as driver_utils
|
||||
from ironic import objects
|
||||
@@ -146,10 +145,10 @@ class HeartbeatMixinTest(AgentDeployMixinBaseTest):
|
||||
self.deploy.heartbeat(task, 'http://127.0.0.1:8080', '1.0.0')
|
||||
failed_mock.assert_called_once_with(
|
||||
task, mock.ANY, collect_logs=True)
|
||||
log_mock.assert_called_once_with(
|
||||
'Asynchronous exception: Failed checking if deploy is done. '
|
||||
'Exception: LlamaException for node %(node)s',
|
||||
{'node': '1be26c0b-03f2-4d2e-ae87-c02d7f33c123'})
|
||||
log_mock.assert_called_once_with(
|
||||
'Asynchronous exception: Failed checking if deploy is done. '
|
||||
'Exception: LlamaException for node %(node)s',
|
||||
{'node': task.node.uuid})
|
||||
|
||||
@mock.patch.object(agent_base_vendor.HeartbeatMixin,
|
||||
'deploy_has_started', autospec=True)
|
||||
@@ -178,10 +177,10 @@ class HeartbeatMixinTest(AgentDeployMixinBaseTest):
|
||||
# within the driver_failue, hearbeat should not call
|
||||
# deploy_utils.set_failed_state anymore
|
||||
self.assertFalse(failed_mock.called)
|
||||
log_mock.assert_called_once_with(
|
||||
'Asynchronous exception: Failed checking if deploy is done. '
|
||||
'Exception: LlamaException for node %(node)s',
|
||||
{'node': '1be26c0b-03f2-4d2e-ae87-c02d7f33c123'})
|
||||
log_mock.assert_called_once_with(
|
||||
'Asynchronous exception: Failed checking if deploy is done. '
|
||||
'Exception: LlamaException for node %(node)s',
|
||||
{'node': task.node.uuid})
|
||||
|
||||
@mock.patch.object(objects.node.Node, 'touch_provisioning', autospec=True)
|
||||
@mock.patch.object(agent_base_vendor.HeartbeatMixin,
|
||||
@@ -280,9 +279,11 @@ class HeartbeatMixinTest(AgentDeployMixinBaseTest):
|
||||
mock_continue.assert_called_once_with(mock.ANY, task)
|
||||
mock_handler.assert_called_once_with(task, mock.ANY)
|
||||
|
||||
@mock.patch.object(manager_utils, 'rescuing_error_handler')
|
||||
@mock.patch.object(agent_base_vendor.HeartbeatMixin, '_finalize_rescue',
|
||||
autospec=True)
|
||||
def test_heartbeat_rescue(self, mock_finalize_rescue):
|
||||
def test_heartbeat_rescue(self, mock_finalize_rescue,
|
||||
mock_rescue_err_handler):
|
||||
self.node.provision_state = states.RESCUEWAIT
|
||||
self.node.save()
|
||||
with task_manager.acquire(
|
||||
@@ -290,6 +291,7 @@ class HeartbeatMixinTest(AgentDeployMixinBaseTest):
|
||||
self.deploy.heartbeat(task, 'http://127.0.0.1:8080', '1.0.0')
|
||||
|
||||
mock_finalize_rescue.assert_called_once_with(mock.ANY, task)
|
||||
self.assertFalse(mock_rescue_err_handler.called)
|
||||
|
||||
@mock.patch.object(manager_utils, 'rescuing_error_handler')
|
||||
@mock.patch.object(agent_base_vendor.HeartbeatMixin, '_finalize_rescue',
|
||||
@@ -328,56 +330,30 @@ class HeartbeatMixinTest(AgentDeployMixinBaseTest):
|
||||
mock_touch.assert_called_once_with(mock.ANY)
|
||||
|
||||
|
||||
class AgentRescueTests(db_base.DbTestCase):
|
||||
class AgentRescueTests(AgentDeployMixinBaseTest):
|
||||
|
||||
def setUp(self):
|
||||
super(AgentRescueTests, self).setUp()
|
||||
for iface in drivers_base.ALL_INTERFACES:
|
||||
impl = 'fake'
|
||||
if iface == 'deploy':
|
||||
impl = 'direct'
|
||||
if iface == 'boot':
|
||||
impl = 'pxe'
|
||||
if iface == 'rescue':
|
||||
impl = 'agent'
|
||||
if iface == 'network':
|
||||
impl = 'flat'
|
||||
config_kwarg = {'enabled_%s_interfaces' % iface: [impl],
|
||||
'default_%s_interface' % iface: impl}
|
||||
self.config(**config_kwarg)
|
||||
self.config(enabled_hardware_types=['fake-hardware'])
|
||||
instance_info = INSTANCE_INFO
|
||||
driver_info = DRIVER_INFO
|
||||
self.deploy = agent_base_vendor.AgentDeployMixin()
|
||||
n = {
|
||||
'driver': 'fake-hardware',
|
||||
'instance_info': instance_info,
|
||||
'driver_info': driver_info,
|
||||
'driver_internal_info': DRIVER_INTERNAL_INFO,
|
||||
}
|
||||
self.node = object_utils.create_test_node(self.context, **n)
|
||||
|
||||
@mock.patch.object(flat_network.FlatNetwork, 'configure_tenant_networks',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(agent.AgentRescue, 'clean_up',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(agent_client.AgentClient, 'finalize_rescue',
|
||||
spec=types.FunctionType)
|
||||
def test__finalize_rescue(self, mock_finalize_rescue,
|
||||
mock_clean_up, mock_conf_tenant_net):
|
||||
mock_clean_up):
|
||||
node = self.node
|
||||
node.provision_state = states.RESCUEWAIT
|
||||
node.save()
|
||||
mock_finalize_rescue.return_value = {'command_status': 'SUCCEEDED'}
|
||||
with task_manager.acquire(self.context, self.node['uuid'],
|
||||
shared=False) as task:
|
||||
task.driver.network.configure_tenant_networks = mock.Mock()
|
||||
task.process_event = mock.Mock()
|
||||
self.deploy._finalize_rescue(task)
|
||||
mock_finalize_rescue.assert_called_once_with(task.node)
|
||||
task.process_event.assert_has_calls([mock.call('resume'),
|
||||
mock.call('done')])
|
||||
mock_clean_up.assert_called_once_with(mock.ANY, task)
|
||||
mock_conf_tenant_net.assert_called_once_with(mock.ANY, task)
|
||||
|
||||
@mock.patch.object(agent_client.AgentClient, 'finalize_rescue',
|
||||
spec=types.FunctionType)
|
||||
|
||||
@@ -96,7 +96,7 @@ class IPMIHardwareTestCase(db_base.DbTestCase):
|
||||
self._validate_interfaces(task, storage=cinder.CinderStorage)
|
||||
|
||||
def test_override_with_agent_rescue(self):
|
||||
self.config(enabled_rescue_interfaces=['agent'])
|
||||
self.config(enabled_rescue_interfaces=['no-rescue', 'agent'])
|
||||
node = obj_utils.create_test_node(
|
||||
self.context, driver='ipmi',
|
||||
rescue_interface='agent')
|
||||
|
||||
Reference in New Issue
Block a user